/*
 * Module_CCS.c
 *
 *  Created on: 2020/-3/16
 *      Author: foluswen
 */
#include "Module_CCS.h"
#include "define_ccs.h"
#include "main.h"


struct SysConfigAndInfo *ShmSysConfigAndInfo;
struct StatusCodeData *ShmStatusCodeData;
struct CcsData *ShmCcsData;
struct InternalComm *ShmInternalComm;
struct Charger *ShmCharger;

struct appHandEXIDocument ccs_handshake;
struct dinEXIDocument ccs_exi_doc_DIN;
struct iso1EXIDocument ccs_exi_doc_ISO1;
struct iso2EXIDocument ccs_exi_doc_ISO2;
unsigned char V2GTP_Tx_buf[V2GTP_MSG_TX_BUFFER_SIZE];   //64*1024 = 65,536 = 65.5KB
unsigned char buf_log_evcomm[SIZE_OF_LOG_BUFFER];
unsigned char buf_log_evcomm_fork1[SIZE_OF_LOG_BUFFER];
unsigned char buf_log_evcomm_fork2[SIZE_OF_LOG_BUFFER];
unsigned char buf_log_evcomm_fork3[SIZE_OF_LOG_BUFFER];

pid_t CP_Detection_Pid = 0;
pid_t PP_Detection_Pid = 0;
pid_t Error_Monitor_Pid = 0;
int TcpAcceptFd;
enum MsgFlowStatus V2gFlowStatus;
int RawSock,UdpSock,TcpSock;
unsigned char V2gtpMsgRxBuf[V2GTP_MSG_RX_BUFFER_SIZE] = {0};
unsigned char V2gtpMsgTxBuf[V2GTP_MSG_TX_BUFFER_SIZE] = {0};

unsigned short Aag[64];
struct MmeHeader SendMmePacket;
int SendMmePacketSize;
unsigned char CsuMac[6],QcaMac[6],EvMac[6],SlacRunId[8];
struct sockaddr_ll DestSocketAddress;
struct ifreq Req;
unsigned int PwmStartTime;
struct timeb SeqStartTime, SeqEndTime;
unsigned char AagGroupsNum, MnbcSoundNum, AttenProfileCnt;
unsigned char NewNmkKey[16], Nid[7];

uint8_t get_V2G_Status_Name(uint8_t statusCode, char *statusName)
{
	int result = PASS;

	switch(statusCode)
	{
		case IDLE:
			sprintf(statusName, "IDLE");
			break;
		case CM_SLAC_PARM_REQ:
			sprintf(statusName, "CM_SLAC_PARM_REQ");
			break;
		case CM_SLAC_PARM_CONF:
			sprintf(statusName, "CM_SLAC_PARM_CONF");
			break;
		case CM_START_ATTEN_CHAR_IND:
			sprintf(statusName, "CM_START_ATTEN_CHAR_IND");
			break;
		case CM_MNBC_SOUND_IND:
			sprintf(statusName, "CM_MNBC_SOUND_IND");
			break;
		case CM_ATTEN_CHAR_IND:
			sprintf(statusName, "CM_ATTEN_CHAR_IND");
			break;
		case CM_ATTEN_CHAR_RSP:
			sprintf(statusName, "CM_ATTEN_CHAR_RSP");
			break;
		case CM_VALIDATE_REQ:
			sprintf(statusName, "CM_VALIDATE_REQ");
			break;
		case CM_VALIDATE_CNF:
			sprintf(statusName, "CM_VALIDATE_CNF");
			break;
		case CM_SLAC_MATCH_REQ:
			sprintf(statusName, "CM_SLAC_MATCH_REQ");
			break;
		case CM_SLAC_MATCH_CNF:
			sprintf(statusName, "CM_SLAC_MATCH_CNF");
			break;
		case CM_AMP_MAP_REQ:
			sprintf(statusName, "CM_AMP_MAP_REQ");
			break;
		case CM_AMP_MAP_CNF:
			sprintf(statusName, "CM_AMP_MAP_CNF");
			break;
		case CM_SET_KEY_REQ:
			sprintf(statusName, "CM_SET_KEY_REQ");
			break;
		case CM_SET_KEY_CNF:
			sprintf(statusName, "CM_SET_KEY_CNF");
			break;
		case SLACC_SDP_UDP_Connection:
			sprintf(statusName, "SLACC_SDP_UDP_Connection");
			break;
		case SLACC_SDP_TCP_Connection:
			sprintf(statusName, "SLACC_SDP_TCP_Connection");
			break;
		case SupportedAppProtocolRequest:
			sprintf(statusName, "SupportedAppProtocolRequest");
			break;
		case SupportedAppProtocolResponse:
			sprintf(statusName, "SupportedAppProtocolResponse");
			break;
		case SessionSetupRequest:
			sprintf(statusName, "SessionSetupRequest");
			break;
		case SessionSetupResponse:
			sprintf(statusName, "UnSessionSetupResponseknown");
			break;
		case ServiceDiscoveryRequest:
			sprintf(statusName, "ServiceDiscoveryRequest");
			break;
		case ServiceDiscoveryResponse:
			sprintf(statusName, "ServiceDiscoveryResponse");
			break;
		case ServiceDetailRequest:
			sprintf(statusName, "ServiceDetailRequest");
			break;
		case ServiceDetailResponse:
			sprintf(statusName, "ServiceDetailResponse");
			break;
		case ServiceAndPaymentSelectionRequest:
			sprintf(statusName, "ServiceAndPaymentSelectionRequest");
			break;
		case ServiceAndPaymentSelectionResponse:
			sprintf(statusName, "ServiceAndPaymentSelectionResponse");
			break;
		case PaymentDetailsRequest:
			sprintf(statusName, "PaymentDetailsRequest");
			break;
		case PaymentDetailsResponse:
			sprintf(statusName, "PaymentDetailsResponse");
			break;
		case AuthorizationRequest:
			sprintf(statusName, "AuthorizationRequest");
			break;
		case AuthorizationResponse:
			sprintf(statusName, "AuthorizationResponse");
			break;
		case CertificateUpdateRequest:
			sprintf(statusName, "CertificateUpdateRequest");
			break;
		case CertificateUpdateResponse:
			sprintf(statusName, "CertificateUpdateResponse");
			break;
		case CertificateInstallationRequest:
			sprintf(statusName, "CertificateInstallationRequest");
			break;
		case CertificateInstallationResponse:
			sprintf(statusName, "CertificateInstallationResponse");
			break;
		case ChargeParameterDiscoveryRequest:
			sprintf(statusName, "ChargeParameterDiscoveryRequest");
			break;
		case ChargeParameterDiscoveryResponse:
			sprintf(statusName, "ChargeParameterDiscoveryResponse");
			break;
		case CableCheckRequest:
			sprintf(statusName, "CableCheckRequest");
			break;
		case CableCheckResponse:
			sprintf(statusName, "CableCheckResponse");
			break;
		case PreChargeRequest:
			sprintf(statusName, "PreChargeRequest");
			break;
		case PreChargeResponse:
			sprintf(statusName, "PreChargeResponse");
			break;
		case PowerDeliveryRequestStart:
			sprintf(statusName, "PowerDeliveryRequestStart");
			break;
		case PowerDeliveryResponsetStart:
			sprintf(statusName, "PowerDeliveryResponsetStart");
			break;
		case ChargingStatusRequest:
			sprintf(statusName, "ChargingStatusRequest");
			break;
		case ChargingStatusResponse:
			sprintf(statusName, "ChargingStatusResponse");
			break;
		case CurrentDemandRequest:
			sprintf(statusName, "CurrentDemandRequest");
			break;
		case CurrentDemandResponse:
			sprintf(statusName, "CurrentDemandResponse");
			break;
		case MeteringReceiptRequest:
			sprintf(statusName, "MeteringReceiptRequest");
			break;
		case MeteringReceiptResponse:
			sprintf(statusName, "MeteringReceiptResponse");
			break;
		case PowerDeliveryRequestStop:
			sprintf(statusName, "PowerDeliveryRequestStop");
			break;
		case PowerDeliveryResponseStop:
			sprintf(statusName, "PowerDeliveryResponseStop");
			break;
		case WeldingDetectionRequest:
			sprintf(statusName, "WeldingDetectionRequest");
			break;
		case WeldingDetectionResponse:
			sprintf(statusName, "WeldingDetectionResponse");
			break;
		case SessionStopRequest:
			sprintf(statusName, "SessionStopRequest");
			break;
		case SessionStopResponse:
			sprintf(statusName, "SessionStopResponse");
			break;
		case Performance_Timeout:
			sprintf(statusName, "Performance_Timeout");
			break;
		case Sequence_Timeout:
			sprintf(statusName, "Sequence_Timeout");
			break;
		case Other_Fault:
			sprintf(statusName, "Other_Fault");
			break;
		default:
			sprintf(statusName, "Unknown");
			result = FAIL;
			break;
	}

	return result;
}

/*===========================================================================
FUNCTION: Check_V2G_Flow_Status
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
unsigned char Check_V2G_Flow_Status()
{
    unsigned char result = 0;

    switch (ShmCcsData->CommProtocol)
    {
        case V2GT_MSG_PROTOCOL_DIN70121:        //0
        {
            result = ShmCcsData->V2GMessage_DIN70121.PresentMsgFlowStatus;
            break;
        }

        case V2GT_MSG_PROTOCOL_ISO15118_2014:   //1
        {
            result = ShmCcsData->V2GMessage_ISO15118_2014.PresentMsgFlowStatus;
            break;
        }

        case V2GT_MSG_PROTOCOL_ISO15118_2018:   //2
        {
            result = ShmCcsData->V2GMessage_ISO15118_2018.PresentMsgFlowStatus;
            break;
        }

        default:
            break;
    }
    return result;
}


/*===========================================================================
FUNCTION: CAN_Tx_MSG
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int CAN_Tx_MSG(int Fd, unsigned int MsgId, unsigned char SlaveAddress, unsigned char DataLength, unsigned char *SendData)
{
#if 0
    struct can_frame frame;
    struct timeb StartTime, EndTime;
    unsigned int tmp = 0;
    int nbytes = 0;
    int i = 0;

    //Protection: To avoid unexpected length for CAN bus payload.
    if (DataLength > 8)
    {
        DataLength = 8;
    }

    memset(&frame, 0, sizeof(struct can_frame));
    frame.can_id = 0x80000000 | CAN_SEND_DIRECTION | MsgId | SlaveAddress;  //0x80000000: extension ID format
    frame.can_dlc = DataLength;
    memcpy(frame.data, SendData, DataLength);
    nbytes = write(Fd, &frame, sizeof(struct can_frame));

    #if 0
    DEBUG_PRINTF_EVCOMM_DETAIL("[SeccComm][CAN_Tx_MSG] <%X> ", frame.can_id);
    for (i = 0; i < frame.can_dlc; i++)
    {
        DEBUG_PRINTF_EVCOMM_DETAIL("%02X ", frame.data[i]);
    }
    DEBUG_PRINTF_EVCOMM_DETAIL("(%d Bytes)\n", frame.can_dlc);
    #endif

    return nbytes;
#else
    return -1;
#endif
}

/*===========================================================================
FUNCTION: Proc_EVStopRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_EVStopRes(int Fd)
{
    int nbytes;
    unsigned char Buffer[8];

    memset(Buffer, 0, sizeof(Buffer));
    if (CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency == TRUE)
    {
        Buffer[0] = EV_EMERGENCY_STOP;  //2
    }
    else
    {
        Buffer[0] = EV_NORMAL_STOP;     //1
    }

    /*
    if(strlen(ShmStatusCodeData->PresentStatusCode[0]) > 0)
    {
        memcpy(Buffer + 2, ShmStatusCodeData->PresentStatusCode[0], 6);
    }
    */
    Buffer[1] = ShmStatusCodeData->PresentStatusCode[0][0];
    Buffer[2] = ShmStatusCodeData->PresentStatusCode[0][1];
    Buffer[3] = ShmStatusCodeData->PresentStatusCode[0][2];
    Buffer[4] = ShmStatusCodeData->PresentStatusCode[0][3];
    Buffer[5] = ShmStatusCodeData->PresentStatusCode[0][4];
    Buffer[6] = ShmStatusCodeData->PresentStatusCode[0][5];


    nbytes = CAN_Tx_MSG(Fd, CAN_CMD_EV_STOP_EVENT, ShmInternalComm->SlaveAddress, 7, Buffer);
    //system("echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle"); //for test only

    //system("echo 0 > /sys/class/gpio/gpio89/value");    //for test

    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_EVStopRes] Sending STOP Command to CSU");

    CSUCOMMDC_TASK_FLAG.Send_EVStopReq = FALSE;

    return nbytes;
}

/*===========================================================================
FUNCTION: Sniffer_Candump
DESCRIPTION:
    1. Only used in End_Process(), which is in fork2 of SeccComm task.
PRE-CONDITION:
INPUT:
OUTPUT:
    0: accept
   -1: invalid
GLOBAL VARIABLES:
=============================================================================*/
int Sniffer_Candump(char cmd)
{
#if (CANDUMP_PACKETS_SNIFFER_SWITCH == ENABLE)
    if (cmd == ENABLE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[candump]init");
        system("cd /mnt/;rm -rf candump/");
        system("cd /mnt/;mkdir candump");
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[candump]on");
        system("cd /mnt/candump;candump -l can0 &");
        return 0;
    }
    else if (cmd == DISABLE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[candump]off");
        system("killall candump");

        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[candump]save");
        system("cd /;cp -rfv /mnt/candump /Storage/SystemLog/");
        return 0;
    }
    else
    {
        sprintf((char*)buf_log_evcomm_fork2, "[candump]unexpected cmd(%d)", cmd);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork2);
        return -1;
    }
#endif

    return 0;
}

/*===========================================================================
FUNCTION: Sniffer_Tcpdump
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Sniffer_Tcpdump(char cmd)
{
    #if (TCPDUMP_PACKETS_SNIFFER_SWITCH == ENABLE)
    if (cmd == ENABLE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[tcpdump]init...");
        system("cd /mnt/;rm -rf tcpdump/");
        system("cd /mnt/;mkdir tcpdump");

        unsigned char buf[256];
        time_t CurrentTime;
        struct tm *tm;
        struct timeval tv;

        memset(buf, 0, sizeof(buf));
        CurrentTime = time(NULL);
        tm = localtime(&CurrentTime);
        gettimeofday(&tv, NULL); // get microseconds, 10^-6
        sprintf((char*)buf,
                "tcpdump -i eth1 -w /mnt/tcpdump/[%s][%04d%02d%02d-%02d:%02d:%02d.%06d]packets.pcap&",
                FIRMWARE_VERSION,
                tm->tm_year + 1900,
                tm->tm_mon + 1,
                tm->tm_mday,
                tm->tm_hour,
                tm->tm_min,
                tm->tm_sec,
                tv.tv_usec
                );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[tcpdump]on");
        system(buf);
        return 0;
    }
    else if (cmd == DISABLE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[tcpdump]off");
        system("killall tcpdump");
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[tcpdump]wait: 2s");
        sleep(1);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[tcpdump]wait: 1s");
        sleep(1);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[tcpdump]save");
        system("cd /;cp -rfv /mnt/tcpdump /Storage/SystemLog/");
        return 0;
    }
    else
    {
        sprintf((char*)buf_log_evcomm, "[tcpdump]unexpected cmd(%d)", cmd);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        return -1;
    }
    #endif

    return 0;
}

/*===========================================================================
FUNCTION: Check_V2G_Flow_Status_pre
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
unsigned char Check_V2G_Flow_Status_pre()
{
    unsigned char result = 0;

    switch (ShmCcsData->CommProtocol)
    {
        case V2GT_MSG_PROTOCOL_DIN70121:        //0
        {
            result = ShmCcsData->V2GMessage_DIN70121.PresentMsgFlowStatus_pre;
            break;
        }

        case V2GT_MSG_PROTOCOL_ISO15118_2014:   //1
        {
            result = ShmCcsData->V2GMessage_ISO15118_2014.PresentMsgFlowStatus_pre;
            break;
        }

        case V2GT_MSG_PROTOCOL_ISO15118_2018:   //2
        {
            result = ShmCcsData->V2GMessage_ISO15118_2018.PresentMsgFlowStatus_pre;
            break;
        }

        default:
            break;
    }
    return result;
}


/*===========================================================================
FUNCTION: Update_V2G_Flow_Status
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
        1. V2gFlowStatus

GLOBAL VARIABLES:
        1. V2gFlowStatus
=============================================================================*/
int Update_V2G_Flow_Status(unsigned int state_new)
{
    unsigned char state_now;
    char nameNow[64], nameNew[64];

    state_now = Check_V2G_Flow_Status();
    get_V2G_Status_Name(state_now, nameNow);
    get_V2G_Status_Name(state_new, nameNew);

    if (EVCOMM_SYS_INFO.End_Process_inused == TRUE ||
        CSUCOMMDC_TASK_FLAG.FW_Update_Task_inused == TRUE)
    {
        if (state_now != Performance_Timeout &&     //253
            state_now != Sequence_Timeout &&        //254
            state_now != Other_Fault)               //255
        {
            sprintf((char*)buf_log_evcomm,
                    "[Warning]state-%s(%d) change: ignored (End_Process_inused:%d, FW_Update_Task_inused:%d)",
					nameNew, state_new,
                    EVCOMM_SYS_INFO.End_Process_inused,
                    CSUCOMMDC_TASK_FLAG.FW_Update_Task_inused
                    );
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            return -1;
        }
    }
    if (state_now != state_new)
    {
        //Step 1: Check if Error Occours
        if (state_now == Performance_Timeout ||     //253
            state_now == Sequence_Timeout ||        //254
            state_now == Other_Fault)               //255
        {
            if (state_new != IDLE)
            {
                if (EVCOMM_SYS_INFO.State_Change_Ignored_Notice == FALSE)
                {
                    EVCOMM_SYS_INFO.State_Change_Ignored_Notice = TRUE;
                    sprintf((char*)buf_log_evcomm,
                            "[Warning]state-%s(%d) change: ignored(now in error state-%s(%d))",
							nameNow, state_new,
							nameNew, state_now);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                }
                return -1;
            }
        }

        //Updating the state formally.

        sprintf((char*)buf_log_evcomm,
                "%s(%02d) >> %s(%02d)",
				nameNow, state_now,
				nameNew, state_new
                );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

        V2gFlowStatus = state_new;
        state_now = state_new;

        switch (ShmCcsData->CommProtocol)
        {
            case V2GT_MSG_PROTOCOL_DIN70121:        //0
            {
                ShmCcsData->V2GMessage_DIN70121.PresentMsgFlowStatus_pre = ShmCcsData->V2GMessage_DIN70121.PresentMsgFlowStatus;
                ShmCcsData->V2GMessage_DIN70121.PresentMsgFlowStatus = V2gFlowStatus;
                break;
            }

            case V2GT_MSG_PROTOCOL_ISO15118_2014:   //1
            {
                ShmCcsData->V2GMessage_ISO15118_2014.PresentMsgFlowStatus_pre = ShmCcsData->V2GMessage_ISO15118_2014.PresentMsgFlowStatus;
                ShmCcsData->V2GMessage_ISO15118_2014.PresentMsgFlowStatus = V2gFlowStatus;
                break;
            }

            case V2GT_MSG_PROTOCOL_ISO15118_2018:   //2
            {
                ShmCcsData->V2GMessage_ISO15118_2018.PresentMsgFlowStatus_pre = ShmCcsData->V2GMessage_ISO15118_2018.PresentMsgFlowStatus;
                ShmCcsData->V2GMessage_ISO15118_2018.PresentMsgFlowStatus = V2gFlowStatus;
                break;
            }

            default:
                break;
        }
    }

    return 0;
}

double DiffTimeb(struct timeb ST, struct timeb ET)
{
    //return milli-second
    double StartTime, EndTime;
    double t_diff;

    StartTime = ((double)ST.time)*1000 + (double)ST.millitm;
    EndTime = ((double)ET.time)*1000 + (double)ET.millitm;
    t_diff = EndTime - StartTime;

    if (t_diff < 0)
    {
        #if 0
        if (t_diff < -1000)   //1000ms
        {
            sprintf((char*)buf_log_evcomm,
                    "[Warning]StartTime(%.02lf) > EndTime(%.02lf), d(%.02lf)",
                    StartTime,
                    EndTime,
                    t_diff);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        }
        #endif

        return -1;
    }
    return t_diff;
}

double DiffTimeb_fork1_Error_Monitor(struct timeb ST, struct timeb ET)
{
    //return milli-second
    static double StartTime, EndTime;
    static double t_diff;

    StartTime = ((double)ST.time)*1000 + (double)ST.millitm;
    EndTime = ((double)ET.time)*1000 + (double)ET.millitm;
    t_diff = EndTime - StartTime;

    if (t_diff < 0)
    {
        #if 0
        if (t_diff < -1000)   //1000ms
        {
            sprintf((char*)buf_log_evcomm_fork2,
                    "[fork1][Warning]S(%.02lf) > E(%.02lf), d(%.02lf)",
                    StartTime,
                    EndTime,
                    t_diff);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork2);
        }
        #endif

        return -1;
    }
    return t_diff;
}

double DiffTimeb_fork2_Error_Monitor(struct timeb ST, struct timeb ET)
{
    //return milli-second
    static double StartTime, EndTime;
    static double t_diff;

    StartTime = ((double)ST.time)*1000 + (double)ST.millitm;
    EndTime = ((double)ET.time)*1000 + (double)ET.millitm;
    t_diff = EndTime - StartTime;

    if (t_diff < 0)
    {
        #if 0
        if (t_diff < -1000)   //1000ms
        {
            sprintf((char*)buf_log_evcomm_fork2,
                    "[fork2][Warning]S(%.02lf) > E(%.02lf), d(%.02lf)",
                    StartTime,
                    EndTime,
                    t_diff);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork2);
        }
        #endif

        return -1;
    }
    return t_diff;
}

/*===========================================================================
FUNCTION: ShareMemory_Init
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int ShareMemory_Init()
{
    int MeterSMId;

    //create ShmSysConfigAndInfo
    if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), IPC_CREAT | 0777)) < 0)
    {
    	DEBUG_ERROR("ShareMemory_Init:shmget ShmSysConfigAndInfo NG");
        return 0;
    }
    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "ShareMemory_Init:shmat ShmSysConfigAndInfo NG");
        return 0;
    }

    //create ShmStatusCodeData
    if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  IPC_CREAT | 0777)) < 0)
    {
    	DEBUG_ERROR("ShareMemory_Init:shmget ShmStatusCodeData NG");
        return 0;
    }
    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	DEBUG_ERROR("ShareMemory_Init:shmat ShmStatusCodeData NG");
        return 0;
    }

    //create ShmCcsData
    if ((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData),  IPC_CREAT | 0777)) < 0)
    {
    	DEBUG_ERROR("ShareMemory_Init:shmget ShmCcsData NG");
        return 0;
    }
    else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	DEBUG_ERROR("ShareMemory_Init:shmat ShmCcsData NG");
        return 0;
    }

    //create ShmInternalComm
    if ((MeterSMId = shmget(ShmInternalCommKey, sizeof(struct InternalComm),   IPC_CREAT | 0777)) < 0)
    {
    	DEBUG_ERROR("ShareMemory_Init:shmget ShmInternalComm NG");
        return 0;
    }
    else if ((ShmInternalComm = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	DEBUG_ERROR("ShareMemory_Init:shmat ShmInternalComm NG");
        return 0;
    }

    //Initial ShmCharger
	if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), 0777)) < 0)
	{
		DEBUG_ERROR("shmget ShmChargerKey NG\r\n");
		return 0;
	}
	else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1)
	{
		DEBUG_ERROR("shmat ShmChargerKey NG\r\n");
		return 0;
	}

    //[To-Do] The initialization here is reduntant and should be removed partially.
    //SHM_Init_supportedAppProtocolRes(ShmCcsData);
    //SHM_Init_din_SessionSetupRes(ShmCcsData);
    //SHM_Init_din_ServiceDiscoveryRes(ShmCcsData);
    //SHM_Init_din_ServiceAndPaymentSelectionRes(ShmCcsData);
    //SHM_Init_din_ContractAuthenticationRes(ShmCcsData);
    SHM_Init_din_ChargeParameterDiscoveryRes(ShmCcsData);
    SHM_Init_din_CableCheckRes(ShmCcsData);
    SHM_Init_din_PreChargeRes(ShmCcsData);
    SHM_Init_din_PowerDeliveryRes(ShmCcsData);
    SHM_Init_din_CurrentDemandRes(ShmCcsData);
    SHM_Init_din_WeldingDetectionRes(ShmCcsData);
    SHM_Init_din_SessionStopRes(ShmCcsData);

    return 1;
}

/*===========================================================================
FUNCTION: GetEthMac
DESCRIPTION:
    1. Accessing current CsuMac address, if Eth = eth1
    2. The address of eth1(for QCA7000) is a random number, which will be modified
       after each time of booting up system.
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int GetEthMac(unsigned char *Eth, unsigned char *mac)
{
    //Parameters:MAC,IP,Mask,Gateway
    int fd;
    unsigned char addr[18], Buffer[128];

    memset(Buffer, 0, sizeof(Buffer));
    sprintf((char*)Buffer, "cat /sys/class/net/%s/address > /mnt/GetEthInfo", Eth);    //CsuMac (Eth = eth1)
    system((char*)Buffer);
    fd = open("/mnt/GetEthInfo", O_RDONLY);
    if(fd < 0)
    {
        system("rm -f /mnt/GetEthInfo");
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "GetEthMac: MAC Address open error");
        return 0;
    }
    memset(mac, 0, 6);
    memset(addr, 0, sizeof(addr));
    read(fd, addr, 17);
    close(fd);
    system("rm -f /mnt/GetEthInfo");
    sscanf((char*)addr, "%02x:%02x:%02x:%02x:%02x:%02x", (uint32_t *)&mac[0], (uint32_t *)&mac[1], (uint32_t *)&mac[2], (uint32_t *)&mac[3], (uint32_t *)&mac[4], (uint32_t *)&mac[5]);    //CsuMac (Eth = eth1)
    sprintf((char*)buf_log_evcomm,
            "[GetEthMac]EVSE MACAddr(CsuMac): %02x:%02x:%02x:%02x:%02x:%02x",
            mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);    //CsuMac (Eth = eth1)
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    return 1;
}

/*===========================================================================
FUNCTION: ReadAdcVolt
DESCRIPTION:
    1. fork1
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
float ReadAdcVolt(unsigned char AdcChannel)
{
    //AIN0=CCS GUN Temp 1
    //AIN1=CCS GUN Temp 2
    //AIN2=CCS_Proximity/2
    //AIN3=pilot voltage
#if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE))
	return 0;
#else
	if(AdcChannel == 3)
	{
		int fd,count,AvgTimes;
		unsigned char SampleBuf[4];
		float TmpVolt, MinSample, AvgSample = 0;

		fd = open("/sys/bus/iio/devices/iio\\:device0/in_voltage3_raw", O_RDONLY);
        if(fd > 0)
        {
            //system("echo 1 > /sys/class/gpio/gpio89/value");    //for test
            for(AvgTimes = 0; AvgTimes < 3; AvgTimes++) //period = 60~91 ms(renice -10, , CurrentDemand()) /*+++ 20200909, vern, extend detection time for interference ---*/
            {
                count = 0;
                MinSample = 2306;
                //system("echo 1 > /sys/class/gpio/gpio89/value");    //for test
                while(count < 40)  //period = 21~42ms (renice -10, CurrentDemand()) /*+++ 20200909, vern, extend detection time for interference ---*/
                {
                    //re-sampling period = 3~13ms (renice -10, SLAC())
                    //system("echo 1 > /sys/class/gpio/gpio89/value");    //for test
                    read(fd, SampleBuf, 4); //period = 3.2~10ms (renice -10, SLAC())
                    //system("echo 0 > /sys/class/gpio/gpio89/value");    //for test
                    TmpVolt = atoi((char*)SampleBuf);

                    if((TmpVolt < 2306) && (TmpVolt > 0))//positive voltage
                    {
                        if(TmpVolt < MinSample)
                        {
                            MinSample = TmpVolt;
                        }
                        count++;
                    }
                    lseek(fd, 0, SEEK_SET);
                }
                //system("echo 0 > /sys/class/gpio/gpio89/value");    //for test
                AvgSample += MinSample;
            }
            AvgSample /= AvgTimes;
            close(fd);
            //system("echo 0 > /sys/class/gpio/gpio89/value");    //for test
            return ((0.954-(1.8*AvgSample/4095))/0.06);
        }
		else
		{
			return -1;
		}
	}
	else
	{
		FILE *fp;
		unsigned char str[64];
		unsigned char AdcValue[8];

		if(AdcChannel > 7)
		{
		    return -1;
		}

		memset(str,0,sizeof(str));
		memset(AdcValue,0,sizeof(AdcValue));
		sprintf((char*)str, "cat /sys/bus/iio/devices/iio\\:device0/in_voltage%d_raw", AdcChannel);
		fp=popen((char*)str, "r");
		if(fgets((char*)AdcValue,sizeof(AdcValue),fp) == NULL)
		{
		    pclose(fp);
		    return -1;
		}
		pclose(fp);
		//Vin =  Vref *D / (2^n - 1)
		return ((float)1.8*(float)atoi((char*)AdcValue))/4095;
	}
#endif

}

/*===========================================================================
FUNCTION: ReadAdcVolt
DESCRIPTION:
    //AIN0=CCS GUN Temp 1
    //AIN1=CCS GUN Temp 2
    //AIN2=CCS_Proximity/2
    //AIN3=pilot voltage
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
float ReadAdcVolt_PP_fork3()
{
#if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE))
	return 0;
#else
    int fd, AvgTimes;
    unsigned char SampleBuf[4];
    float TmpVolt = 0;
    float AvgSample = 0;
    float V_pp = 0;

    fd = open("/sys/bus/iio/devices/iio\\:device0/in_voltage2_raw", O_RDONLY); //PP
    if(fd > 0)
    {
        for(AvgTimes = 0; AvgTimes < 5; AvgTimes++) //get 5 samples
        {
            read(fd, SampleBuf, 4);
            TmpVolt = atoi((char*)SampleBuf);
            lseek(fd, 0, SEEK_SET);

            AvgSample += TmpVolt;
        }
        close(fd);
        AvgSample /= AvgTimes;
        V_pp = (3.6*AvgSample)/4095;    //PP

        #if 0
        printf("PP_adc = %.02f, PP_v = %.02f\n", AvgSample, V_pp);
        usleep(3000000); //300ms
        #endif
        usleep(20000);  //20ms

        return V_pp;
    }
    else
    {
        return -1;
    }
#endif
}

/*===========================================================================
FUNCTION: Qca7kPowerReset
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Qca7kPowerReset()
{
    //printf("\n[CCS Board]Reset QCA7000...\n");
    system("echo 1 > /sys/class/gpio/gpio88/value");
    usleep(500000);
    system("echo 0 > /sys/class/gpio/gpio88/value");
}

/*===========================================================================
FUNCTION: SwitchCpStateE
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int SwitchCpStateE(unsigned char OnOff)
{
	/*
	 *	TODO: Request CP change to state E
	 */
    if((OnOff != ENABLE) && (OnOff != DISABLE))
    {
        return -1;
    }

    struct ChargingInfoData *ccs;
    ccs = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    ccs->SwitchCpStateE_status = OnOff;

    //OnOff = 1 => switch State to E
    //OnOff = 0 => return noraml
    #if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE))
    {
        if(OnOff == DISABLE)
        {
            //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "SwitchCpStateE: released\n");
            CSUCOMMAC_SHM.CpSetStateE = DISABLE;
        }
        else
        {
            OutputCpPwmDuty(100); //set CP duty as 100, firstly.
            CSUCOMMAC_SHM.CpSetStateE = ENABLE;
            //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "SwitchCpStateE: enabled!\n");
        }
    }
    #else //CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED
    {
        if(OnOff == DISABLE)
        {
            //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "SwitchCpStateE: released\n");
            system("echo 0 > /sys/class/gpio/gpio86/value");
        }
        else
        {
            OutputCpPwmDuty(100); //set CP duty as 100, firstly.
            system("echo 1 > /sys/class/gpio/gpio86/value");
            //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "SwitchCpStateE: enabled!\n");
        }
    }
    #endif

    if (ccs->SwitchCpStateE_status_pre != ccs->SwitchCpStateE_status)
    {
        sprintf((char*)buf_log_evcomm,
                "SwitchCpStateE: %d >> %d",
                ccs->SwitchCpStateE_status_pre,
                ccs->SwitchCpStateE_status
                );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        ccs->SwitchCpStateE_status_pre = ccs->SwitchCpStateE_status;
    }

    return 0;
}

/*===========================================================================
FUNCTION: OutputCpPwmDuty
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int OutputCpPwmDuty(unsigned char Duty)
{
#if ((CCS_ENERGY_TRANSFER_MODE != MODE_AC_SINGLE_PHASE_CORE) && (CCS_ENERGY_TRANSFER_MODE != MODE_AC_THREE_PHASE_CORE))
    int DutyInNanoSec;
#endif
    struct ChargingInfoData *ccs;
    ccs = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    if((Duty < 0)||(Duty > 100))
    {
        return -1;
    }

#if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE))
    {
        CSUCOMMAC_SHM.CpSetPWMDuty = Duty;
    }
#else //CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED
    {
        DutyInNanoSec = 10000 * Duty;
        sprintf((char*)buf_log_evcomm, "echo %d > /sys/class/pwm/pwmchip0/pwm0/duty_cycle", DutyInNanoSec);//nanoseconds
        system((char*)buf_log_evcomm);
    }
#endif

    ccs->CpDuty = Duty;

    //CP Duty
    if (ccs->CpDuty != ccs->CpDuty_pre)
    {
        //memset(buf_log_evcomm, 0, sizeof(buf_log_evcomm));
        sprintf((char*)buf_log_evcomm, "CP Duty: %d %% >> %d %%", ccs->CpDuty_pre, ccs->CpDuty);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

        ccs->CpDuty_pre = ccs->CpDuty;
    }

    return 0;
}

/*===========================================================================
FUNCTION: Check_Plugin_Status_Update_fork1
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
//#if SAVE_SYS_LOG_MSG_EVCOMM_SWITCH == ENABLE
void Check_Plugin_Status_Update_fork1(struct ChargingInfoData *ccs)
{
    if (ccs->ConnectorPlugIn != ccs->ConnectorPlugIn_new)
    {
        sprintf((char*)buf_log_evcomm_fork1, "[fork1]Plugin: %d >> %d (CP=%.2fV, PP=%.2fV)",
                ccs->ConnectorPlugIn,
                ccs->ConnectorPlugIn_new,
                ccs->CpVoltage,
                ccs->PpVoltage
                );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork1);

        ccs->ConnectorPlugIn_pre = ccs->ConnectorPlugIn;
        ccs->ConnectorPlugIn = ccs->ConnectorPlugIn_new;
        //ccs->CpVoltage_pre = ccs->CpVoltage;
    }
}
//#endif

/*===========================================================================
FUNCTION: ConnectorPlugIn
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
	0: Unplug
	1: Plug-in
GLOBAL VARIABLES:
=============================================================================*/
int CheckConnectorPlugIn()
{
	/*
	 *	TODO: Return connector status depedon CP
	 */

    static struct ChargingInfoData *ccs;
    ccs = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

#if (CP_PROTECTION_MECHANISM == ENABLE)
    return (int)ccs->ConnectorPlugIn;
#else
    return TRUE;
#endif
}

/*===========================================================================
FUNCTION: Check_CP_State_Error_fork1
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Check_CP_State_Error_fork1(struct ChargingInfoData *ccs)
{
#if (CP_PROTECTION_MECHANISM == DISABLE)
    {
        return -1;
    }
#endif

    unsigned char state = 0;
#if ((CCS_ENERGY_TRANSFER_MODE != MODE_AC_SINGLE_PHASE_CORE) && (CCS_ENERGY_TRANSFER_MODE != MODE_AC_THREE_PHASE_CORE))
    double time_diff = 0;
#endif
    state = Check_V2G_Flow_Status();

    //SLAC, SLAAC, SDP, ..., ChargeParameterDiscovery
    if (state >= CM_SLAC_PARM_CONF &&   //by considering 15118(SLAC first)
        state < ChargeParameterDiscoveryRequest &&
        state != IDLE &&
        state != CM_SET_KEY_REQ &&
        state != CM_SET_KEY_CNF &&
        state != CM_VALIDATE_REQ &&
        state != CM_VALIDATE_CNF)
    {
        #if (SLAC_FIRST_RESPONSE_METHOD == SET_5_PWM_ONCE_GET_PERMISSION_IN_AUTHORIZATIONRES)
        {
            if((ccs->CpState != 2) && (ccs->CpState != 3))
            {
                if (ccs->CpState_err == FALSE)
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[fork1][CP][Error]before CPD");    //CPD: ChargeParameterDiscoveryRequest
                    //CPD: ChargeParameterDiscovery
                }
                ccs->CpState_err = TRUE;
            }
        }
        #else
        {
            if(ccs->CpState != 3)
            {
                if (ccs->CpState_err == FALSE)
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[fork1][CP][Error]before CPD");    //CPD: ChargeParameterDiscoveryRequest
                    //CPD: ChargeParameterDiscovery
                }
                ccs->CpState_err = TRUE;
            }
        }
        #endif
    }

    #if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE))
    {
        //ChargeParameterDiscovery
        if(state >= ChargeParameterDiscoveryRequest &&        //35
           state <= ChargeParameterDiscoveryResponse)         //36
        {
            if(ccs->CpState != 3)
            {
                if (ccs->CpState_err == FALSE)
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[CP][Error]CPD");
                    //PRC: Precharge
                    //CUD: CurrentDemand
                }
                ccs->CpState_err = TRUE;
            }
        }

        //ChargingStatus
        if(state >= ChargingStatusRequest &&        //43
           state <= ChargingStatusResponse)         //44
        {
            if(ccs->CpState != 4 && ccs->CpState != 5)
            {
                if (ccs->CpState_err == FALSE)
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[CP][Error]CGS");
                    //PRC: Precharge
                    //CUD: CurrentDemand
                }
                ccs->CpState_err = TRUE;
            }
        }
    }
    #else //CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED
    {
        //ChargeParameterDiscovery, CableCheck
        if (state >= ChargeParameterDiscoveryRequest &&     //35
            state <= CableCheckResponse)                    //38
        {
            if(ccs->CableCheckPreCountDownDone == FALSE &&
            state >= CableCheckRequest)
            {
                ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_End);
                time_diff = DiffTimeb_fork1_Error_Monitor(EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_Start, EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_End);
                if(time_diff >= V2G_SECC_CP_Timeout_CableCheck)   //2 sec
                {
                    sprintf((char*)buf_log_evcomm_fork1,
                            "[fork1][CP]check C(4),D(5): ON (%.02lf of %dms)",
                            time_diff,
                            V2G_SECC_CP_Timeout_CableCheck);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork1);
                    ccs->CableCheckPreCountDownDone = TRUE;
                }
            }

            if(ccs->CableCheckPreCountDownDone == TRUE)
            {
                if(ccs->CpState != 4 && ccs->CpState != 5)
                {
                    if (ccs->CpState_err == FALSE)
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[CP][Error]CPD and CCK (after CNT)");
                        //CPD: ChargeParameterDiscovery
                        //CCK: CableCheck
                        //CNT: count down
                    }
                    ccs->CpState_err = TRUE;
                }
            }
            else
            {
                if(ccs->CpState != 3 && ccs->CpState != 4 && ccs->CpState != 5)
                {
                    if (ccs->CpState_err == FALSE)
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[CP][Error]CPD and CCK (before CNT)");
                        //CPD: ChargeParameterDiscovery
                        //CCK: CableCheck
                        //CNT: count down
                    }
                    ccs->CpState_err = TRUE;
                }
            }
        }

        //Precharge, CurrentDemand
        if(state >= PreChargeRequest &&      //39
        state <= CurrentDemandResponse)   //46
        {
            if(ccs->CpState != 4 && ccs->CpState != 5)
            {
                if (ccs->CpState_err == FALSE)
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[CP][Error]PRC and CUD");
                    //PRC: Precharge
                    //CUD: CurrentDemand
                }
                ccs->CpState_err = TRUE;
            }
        }
    }
    #endif

    if(ccs->CpState_err == TRUE && ccs->CpState_err_logged == FALSE)
    {
        OutputCpPwmDuty(100);
        //system("echo 1 > /sys/class/gpio/gpio89/value");    //for test

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_CP_State_Error (023889)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 8;
        ShmStatusCodeData->PresentStatusCode[0][4] = 8;
        ShmStatusCodeData->PresentStatusCode[0][5] = 9;
        CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;

        Proc_EVStopRes(ShmInternalComm->FD_CAN_Socket);
        sprintf((char*)buf_log_evcomm_fork1, "[fork1][Erorr]CP(%d) Error in state %d(%d)",
                ccs->CpState,
                state,
                ccs->CableCheckPreCountDownDone
                );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork1);
        ccs->CpState_err_logged = TRUE;
    }
    return 0;
}

/*===========================================================================
FUNCTION: Check_CP_State_Update_fork1
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
//#if SAVE_SYS_LOG_MSG_EVCOMM_SWITCH == ENABLE
void Check_CP_State_Update_fork1(struct ChargingInfoData *ccs)
{
    //CP State
    if (ccs->CpState != ccs->CpState_pre)
    {
        sprintf((char*)buf_log_evcomm_fork1, "[fork1]CP State: %d >> %d (%.2fV)",
                ccs->CpState_pre,
                ccs->CpState,
                ccs->CpVoltage
                );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork1);

        ccs->CpState_pre = ccs->CpState;
    }
}
//#endif

/*===========================================================================
FUNCTION: CP_Detection
DESCRIPTION:
        1. In order to detect CP in efficient response time, we creat an independent
           thead for this procedure.

        2. The priority of this thread is set as the same as other tasks.

        3. fork1

PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void CP_Detection()
{
    pid_t tmp = 0;
 //   struct timeb StartTime, EndTime;
#if ((CCS_ENERGY_TRANSFER_MODE != MODE_AC_SINGLE_PHASE_CORE) && (CCS_ENERGY_TRANSFER_MODE != MODE_AC_THREE_PHASE_CORE))
    unsigned char Statetmp;
    float TotalTmpVolt;
#endif
    struct ChargingInfoData *ccs;

    ccs = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    if(CP_Detection_Pid == 0)
    {
        tmp = fork();
        if(tmp > 0)
        {
            CP_Detection_Pid = tmp;

            #if 1
            unsigned char buf[64];
            memset(buf, 0, sizeof(buf));
            //sprintf((char*)buf, "renice -20 -p %d", tmp);
            sprintf((char*)buf, "renice -10 -p %d", tmp);
            system((char*)buf);
            #endif

            return;
        }
    }

    while(1)
    {
        //ADC_Voltage = (1+RE62/RE63)*0.9 - (RE62/RE63)*Pilot_Voltage,  RE62/RE63=0.06
        //=>Pilot_Voltage=(0.954-ADC_Voltage)/0.06

        #if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE))
        {
            ccs->CpVoltage = ShmInternalComm->AC_CpPositiveVoltage;
            ccs->CpState = ShmInternalComm->AC_CpPresentState;
        }
        #else //CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED
        {
            TotalTmpVolt = ReadAdcVolt(3);

            ccs->CpVoltage = TotalTmpVolt;

            if (ccs->CpVoltage_pre != ccs->CpVoltage)
            {
                ccs->CpVoltage_pre = ccs->CpVoltage;
            }

            //printf("TotalTmpVolt = %.02f\n", TotalTmpVolt);

            //If CP voltage is higer than 13.5V
            if(TotalTmpVolt >= 13.5)
            {
                //Pilot Error
                if((ccs->CpState == 1) &&
                (TotalTmpVolt < 13.75))
                {
                    //V_cp = 13.5 ~ 13.75
                    Statetmp = 1;
                }
                else
                {
                    //V_cp = 13.5 ~
                    Statetmp = 8;
                }
            }
            else if((TotalTmpVolt >= 10.5) && (TotalTmpVolt < 13.5)) //V_cp = 10.5 ~ 13.5
            {
                //State A (12V)
                if((ccs->CpState >= 2) &&
                (ccs->CpState <= 3) &&
                (TotalTmpVolt < 10.75))
                {
                    if((ccs->CpDuty >= 5) &&
                    (ccs->CpDuty < 100))
                    {
                        Statetmp = 3;
                    }
                    else
                    {
                        Statetmp = 2;
                    }
                }
                else if((ccs->CpState == 8) &&
                        (TotalTmpVolt >= 13.25))
                {
                    Statetmp = 8;
                }
                else
                {
                    Statetmp = 1;
                }
            }
            else if((TotalTmpVolt >= 7.5) && (TotalTmpVolt < 10.5))
            {
                //State B (9V)
                if((ccs->CpState == 4) && (TotalTmpVolt < 7.75))
                {
                    Statetmp = 4;
                }
                else if((ccs->CpState == 1) && (TotalTmpVolt >= 10.25))
                {
                    Statetmp = 1;
                }
                else
                {
                    if((ccs->CpDuty >= 5) && (ccs->CpDuty < 100))
                    {
                        Statetmp = 3;
                    }
                    else
                    {
                        Statetmp = 2;
                    }
                }
            }
            else if((TotalTmpVolt >= 4.5) && (TotalTmpVolt < 7.5))
            {
                //State C (6V)
                if((ccs->CpState == 5) && (TotalTmpVolt < 4.75))
                {
                    Statetmp = 5;
                }
                else if((ccs->CpState >= 2) && (ccs->CpState <= 3) && (TotalTmpVolt >= 7.25))
                {
                    if((ccs->CpDuty >= 5)&&(ccs->CpDuty < 100))
                    {
                        Statetmp = 3;
                    }
                    else
                    {
                        Statetmp = 2;
                    }
                }
                else
                {
                    Statetmp = 4;
                }
            }
            else if((TotalTmpVolt >= 1.5) && (TotalTmpVolt < 4.5))
            {
                //State D (3V)
                if((ccs->CpState == 6)&&(TotalTmpVolt < 1.75))
                {
                    Statetmp = 6;
                }
                else if((ccs->CpState == 4)&&(TotalTmpVolt >= 4.25))
                {
                    Statetmp = 4;
                }
                else
                {
                    Statetmp = 5;
                }
            }
            else if((TotalTmpVolt >= -1.5) && (TotalTmpVolt < 1.5)) //V_cp = -1.5V ~ 1.5V
            {
                //State E (0V)
                if((ccs->CpState == 8) &&
                (TotalTmpVolt < -1.25))
                {
                    Statetmp = 8;
                }
                else if((ccs->CpState == 5) &&
                        (TotalTmpVolt >= 1.25))
                {
                    Statetmp = 5;
                }
                else
                {
                    Statetmp = 6;
                }
            }
            else if((TotalTmpVolt >= -13.5) && (TotalTmpVolt < -10.5)) //V_cp = -10.5V ~ -13.5V
            {
                //State F (-12V)
                if((ccs->CpState == 8) &&
                (TotalTmpVolt >= -10.75))
                {
                    Statetmp = 8;
                }
                else
                {
                    Statetmp = 7;
                }
            }
            else
            {
                //null
            }

            ccs->CpState = Statetmp;
        }
        #endif

        Check_CP_State_Update_fork1(ccs);
        Check_CP_State_Error_fork1(ccs);

        //Updating Plugin status
        #if (PP_PROTECTION_MECHANISM == ENABLE)
        if((ccs->CpState >= 2 ) && (ccs->CpState <= 5 ) && (ccs->PpVoltage >= 1.0)) //PP >= 1.0V
        #else
        if((ccs->CpState >= 2 ) && (ccs->CpState <= 5 ))
        #endif
        {
            ccs->ConnectorPlugIn_new = TRUE;
        }
        else
        {
            ccs->ConnectorPlugIn_new = FALSE;
            OutputCpPwmDuty(100);
        }

        Check_Plugin_Status_Update_fork1(ccs);

        //ftime(&EndTime);
        //DEBUG_PRINTF_EVCOMM_DETAIL("duration:%.02lf\n", DiffTimeb(StartTime, EndTime));
        usleep(1000);
    }//while
}

/*===========================================================================
FUNCTION: PP_Detection
DESCRIPTION:
    0. SeccComm fork3
    1. In order to detect CP in efficient response time, we creat an independent
       thead for this procedure.

    2. The priority of this thread is set as the same as other tasks.
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void PP_Detection()
{
    pid_t tmp = 0;
 //   struct timeb StartTime, EndTime;
#if ((CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED))
    //unsigned char Statetmp;
#endif
    float TotalTmpVolt;

    if(PP_Detection_Pid == 0)
    {
        tmp = fork();
        if(tmp > 0)
        {
            PP_Detection_Pid = tmp;

            #if 0
            unsigned char buf[64];
            memset(buf, 0, sizeof(buf));
            sprintf((char*)buf, "renice -20 -p %d", tmp);
            system(buf);
            #endif

            return;
        }
    }

    while(1)
    {
        TotalTmpVolt = ReadAdcVolt_PP_fork3();

        EVCOMM_SYS_INFO.PpVoltage = TotalTmpVolt;

        if (EVCOMM_SYS_INFO.PpVoltage_pre != EVCOMM_SYS_INFO.PpVoltage)
        {
            if ((EVCOMM_SYS_INFO.PpVoltage_pre < 0.5 && EVCOMM_SYS_INFO.PpVoltage >= 1.0) ||
                 (EVCOMM_SYS_INFO.PpVoltage_pre >= 1.0 && EVCOMM_SYS_INFO.PpVoltage < 0.5))
            {
                sprintf((char*)buf_log_evcomm_fork3,
                        "[fork3]PP(%.2f >> %.2fV)",
                        EVCOMM_SYS_INFO.PpVoltage_pre,
                        EVCOMM_SYS_INFO.PpVoltage
                        );
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork3);
                EVCOMM_SYS_INFO.PpVoltage_pre = EVCOMM_SYS_INFO.PpVoltage;
            }
        }

        #if 0
        sleep(5);
        printf("V_pp = %.02f\n", TotalTmpVolt);
        #endif
        usleep(1000);
    }//while
}

/*===========================================================================
FUNCTION: Error_Monitor
DESCRIPTION:
    1. This function only works in SeccComm fork2.
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Error_Monitor()
{
    pid_t tmp = 0;
    double time_diff = 0;
    unsigned char status = 0;
    struct ChargingInfoData *ccs;
    ccs = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    if(Error_Monitor_Pid == 0)
    {
        tmp = fork();   //SeccComm fork2
        if(tmp > 0)
        {
            Error_Monitor_Pid = tmp;

            #if 0
            unsigned char buf[64];
            memset(buf, 0, sizeof(buf));
            sprintf((char*)buf, "renice -20 -p %d", tmp);
            system(buf);
            #endif

            return;
        }
    }

    while(1)
    {
        //Step 0
        if (EVCOMM_SYS_INFO.End_Process_inused == TRUE)
        {
            //If the End_Process is in processing, disable Error_Monitor.
            continue;
        }

        //Step1 1: Check and Response to Plugin Status
        if(CheckConnectorPlugIn() == FALSE)
        {
            status = Check_V2G_Flow_Status();
            if (status > IDLE &&
                status < Performance_Timeout &&
                status != CM_SET_KEY_REQ &&
                status != CM_SET_KEY_CNF &&
                EVCOMM_SYS_INFO.End_Process_inused == FALSE)
            {
                #if (CP_PROTECTION_MECHANISM == ENABLE)
                //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[fork2] Emergency Stop (due to Connector is plugged out during communication.)");
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[fork2]Plug out Error => End_Process");
                //Update_ShmStatusCode(); //[To-Do] to be implemented
                //CCS_SECC_CP_State_Error (023889)
                ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                ShmStatusCodeData->PresentStatusCode[0][4] = 8;
                ShmStatusCodeData->PresentStatusCode[0][5] = 9;
                CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;
                End_Process();
                #else
                //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "CP_PROTECTION_MECHANISM is disabled. Emergency Stop: skipped" );
                #endif
            }
        }


        //Step 2: Check for V2G_SECC_Sequence_Timeout
        //#if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
        #if 1
        status = Check_V2G_Flow_Status();
        if (status >= SupportedAppProtocolRequest &&
            status < SessionStopRequest)
        {
            ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_End);
            time_diff = DiffTimeb_fork2_Error_Monitor(EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start, EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_End);
            if(time_diff > V2G_SECC_Sequence_Timeout)   //60s
            {
                sprintf((char*)buf_log_evcomm_fork2,
                        "[fork2]V2G_SECC_Sequence_Timeout in state %d - (%.02lf of %d ms)\n",
                        status,
                        time_diff,
                        V2G_SECC_Sequence_Timeout);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork2);
                Update_V2G_Flow_Status(Sequence_Timeout);
                //Update_ShmStatusCode(); //[To-Do] to be implemented
                //CCS_SECC_TIMEOUT_V2G_Sequence_Time (023844)
                ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                ShmStatusCodeData->PresentStatusCode[0][4] = 4;
                ShmStatusCodeData->PresentStatusCode[0][5] = 4;
                End_Process();
                break;
            }
            else if (time_diff > 4000) //4s
            {
                //Check for CSU command of "Stop by EVSE"
                if (EVCOMM_SYS_INFO.DC_EVSEStatus == EVSE_Shutdown)
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error_Monitor]EVSE_Shutdown");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                else if (EVCOMM_SYS_INFO.DC_EVSEStatus == EVSE_EmergencyShutdown)
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error_Monitor]EVSE_EmergencyShutdown");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                else if (ShmInternalComm->ChargingPermission == FALSE)
                {
                    if (status >= ChargeParameterDiscoveryRequest)  //&& status < SessionStopRequest
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error_Monitor]ChargingPermission = FALSE");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                }
                else
                {
                    //null
                }
            }
            else
            {
                //null
            }
        }
        #endif


        //Step 3: Check and Response to Error V2gFlowStatus
        status = Check_V2G_Flow_Status();
        if (status == Performance_Timeout ||
            status == Sequence_Timeout ||
            status == Other_Fault)
        {
            sprintf((char*)buf_log_evcomm_fork2,
                    "[fork2]Timeout or Fault State(%d) => End_Process",
                    status);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork2);
            //Normal Stop
            //alarm and duty to 100%
            //OutputCpPwmDuty(100);
            //SwitchCpStateE(ENABLE); //Set CP duty as 100% and set CP state as E (0V).
            //[Joseph/ To-Do] Set State E (0V) via GPIO setting
            End_Process();
        }


        //Step 4: Check and Response to CP State Error
        if(ccs->CpState_err == TRUE)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[fork2]CP Error => End_Process");
            Update_V2G_Flow_Status(Other_Fault);
            //Update_ShmStatusCode(); //[To-Do] to be implemented
            //CCS_SECC_CP_State_Error (023889)
            ShmStatusCodeData->PresentStatusCode[0][0] = 0;
            ShmStatusCodeData->PresentStatusCode[0][1] = 2;
            ShmStatusCodeData->PresentStatusCode[0][2] = 3;
            ShmStatusCodeData->PresentStatusCode[0][3] = 8;
            ShmStatusCodeData->PresentStatusCode[0][4] = 8;
            ShmStatusCodeData->PresentStatusCode[0][5] = 9;
            CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;
            End_Process();
        }


        //Step 5: Check and Response to Shutdown Commnad from CSU
        if (EVCOMM_SYS_INFO.DC_EVSEStatus == EVSE_Shutdown ||
            EVCOMM_SYS_INFO.DC_EVSEStatus == EVSE_EmergencyShutdown)
        {
            if (Check_V2G_Flow_Status() <= SLACC_SDP_TCP_Connection)
            {
                sprintf((char*)buf_log_evcomm_fork2,
                        "[fork2]EVSE Shutdown(%d) => End_Process",
                        EVCOMM_SYS_INFO.DC_EVSEStatus);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork2);
                Update_V2G_Flow_Status(Other_Fault);
                End_Process();
            }
        }


        //Step 6: Check and Response to SessionStop
        status = Check_V2G_Flow_Status();
        if (status == SessionStopResponse)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[fork2]SessionStopResponse => End_Process");
            End_Process();
        }

        //Step 7: Check for ChargingPermission from TRUE to FALSE before V2G Messages
        /*+++ 20200808, vern, sync with Tesla CHAdeMO adaptor, 2 for start communication(not yet auth),  1 for star charging (authorized)  ---*/
        if ((ShmInternalComm->ChargingPermission == FALSE) &&
            (ShmInternalComm->ChargingPermission_pre >= 1) &&
            (ccs->CpState >= 3) && (ccs->CpState <=5))
        {
            if (status >= CM_SLAC_PARM_REQ &&
                status != CM_SET_KEY_REQ &&
                status != CM_SET_KEY_CNF &&
                status <= SLACC_SDP_TCP_Connection)
            {
                sprintf((char*)buf_log_evcomm_fork2,
                        "[fork2]Permission OFF before V2G msg(%d) => End_Process",
                        ShmInternalComm->ChargingPermission);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork2);
                Update_V2G_Flow_Status(Other_Fault);
                End_Process();
            }
        }

        //Step 8: DC OVP Protection
        if (CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED &&
            status > CableCheckResponse &&
            status <= SessionStopRequest &&
            status != ChargingStatusRequest &&
            status != ChargingStatusResponse &&
            EVCOMM_SYS_INFO.EvBatteryMaxVoltage != 0)
        {
            //Part A: OVP Protection
            if (EVCOMM_SYS_INFO.PresentChargingVoltage >= (EVCOMM_SYS_INFO.EvBatteryMaxVoltage * 1.02)) // 2%
            {
                sprintf((char*)buf_log_evcomm_fork2,
                        "[fork2][Error]OVP => End_Process (%.02f > %.02f)",
                        EVCOMM_SYS_INFO.PresentChargingVoltage,
                        (EVCOMM_SYS_INFO.EvBatteryMaxVoltage * 1.02));
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork2);

                Update_V2G_Flow_Status(Other_Fault);
                //Update_ShmStatusCode(); //[To-Do] to be implemented
                //System CCS output OVP (012219)
                ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                ShmStatusCodeData->PresentStatusCode[0][1] = 1;
                ShmStatusCodeData->PresentStatusCode[0][2] = 2;
                ShmStatusCodeData->PresentStatusCode[0][3] = 2;
                ShmStatusCodeData->PresentStatusCode[0][4] = 1;
                ShmStatusCodeData->PresentStatusCode[0][5] = 9;
                CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;
                Proc_EVStopRes(ShmInternalComm->FD_CAN_Socket);
                End_Process();
            }

            //Part B: Over Voltage Request Protection
            if (EVCOMM_SYS_INFO.EvBatterytargetVoltage >= (EVCOMM_SYS_INFO.EvBatteryMaxVoltage * 1.02))
            {
                sprintf((char*)buf_log_evcomm_fork2,
                        "[fork2]Over V Req => End_Process (%.02f > %.02f)",
                        EVCOMM_SYS_INFO.EvBatterytargetVoltage,
                        (EVCOMM_SYS_INFO.EvBatteryMaxVoltage * 1.02)
                        );
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm_fork2);

                Update_V2G_Flow_Status(Other_Fault);
                //Update_ShmStatusCode(); //[To-Do] to be implemented
                //System CCS output OVP (012219)
                ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                ShmStatusCodeData->PresentStatusCode[0][1] = 1;
                ShmStatusCodeData->PresentStatusCode[0][2] = 2;
                ShmStatusCodeData->PresentStatusCode[0][3] = 2;
                ShmStatusCodeData->PresentStatusCode[0][4] = 1;
                ShmStatusCodeData->PresentStatusCode[0][5] = 9;
                CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;
                Proc_EVStopRes(ShmInternalComm->FD_CAN_Socket);
                End_Process();
            }
        }

        //Step 9: Check 60V
        /*+++ 20200808, vern, sync with Tesla CHAdeMO adaptor, 2 for start communication(not yet auth), 1 for star charging (authorized)  ---*/
        if (CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED &&
            ShmInternalComm->ChargingPermission >= 1 &&
            status < CableCheckRequest)
        {
            if (EVCOMM_SYS_INFO.PresentChargingVoltage >= 60)  //60V
            {
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[fork2]DC Output Voltage is over 60V => End_Process");
                Update_V2G_Flow_Status(Other_Fault);
                //Update_ShmStatusCode(); //[To-Do] to be implemented
                //CCS_SECC_Unexpected_60V_Before_Charing_Error (023890)
                ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                ShmStatusCodeData->PresentStatusCode[0][4] = 9;
                ShmStatusCodeData->PresentStatusCode[0][5] = 0;
                CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;
                //Proc_EVStopRes(ShmInternalComm->FD_CAN_Socket);
                End_Process();
            }
        }

        //Step 10: Check if the connector is unplug from plugin
        if (EVCOMM_SYS_INFO.ConnectorPlugIn_pre == TRUE && EVCOMM_SYS_INFO.ConnectorPlugIn == FALSE)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[fork2]Unplug Reset => End_Process");
            Update_V2G_Flow_Status(Other_Fault);
            End_Process();
        }
        usleep(1000);
    }//while
}


/*===========================================================================
FUNCTION: SendSetKey
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int SendSetKey()
{
    int i = 0;
    unsigned char nRandValue = 0x0;
    unsigned char ConstString[16] = "PhihongKey000000";

    memset(&SendMmePacket,0,sizeof(struct MmeHeader));
    memcpy(SendMmePacket.ODA,QcaMac,6);
    memcpy(SendMmePacket.OSA,CsuMac,6);
    SendMmePacket.MTYPE = htons(EtherType_HomePlug);
    SendMmePacket.MMV = 0x01;
    SendMmePacket.MMTYPE = MMTYPE_CM_SET_KEY_REQ;
    SendMmePacket.FMI[0] = SendMmePacket.FMI[1] = 0;
    SendMmePacketSize = 0;
    SendMmePacket.MMENTRY[SendMmePacketSize++] = 0x01;//Fixed value (0x01) to indicate ��NMK��
    memset(SendMmePacket.MMENTRY+SendMmePacketSize,0,4);//My Nonce, Fixed value(0x00000000), encrypted payload not used
    SendMmePacketSize+=4;
    memset(SendMmePacket.MMENTRY+SendMmePacketSize,0,4);//Your Nonce, Fixed value(0x00000000), encrypted payload not used
    SendMmePacketSize+=4;
    SendMmePacket.MMENTRY[SendMmePacketSize++] = 0x04;//PID, Fixed value (0x04) to indicate ��HLE protocol��
    memset(SendMmePacket.MMENTRY+SendMmePacketSize,0,2);//PRN, Fixed value(0x00), encrypted payload not used
    SendMmePacketSize+=2;
    SendMmePacket.MMENTRY[SendMmePacketSize++] = 0x00;//PMN, Fixed value(0x00) encrypted payload not used
    SendMmePacket.MMENTRY[SendMmePacketSize++] = 0x01;//CCo Capablility
    srand(time(NULL));
    for (i = 10; i < 16; i++)
    {
        nRandValue = (rand()%62) + 1;
        if((nRandValue>=0)&&(nRandValue<=9))  // 0 ~ 9
        {
            ConstString[i]= nRandValue + 0x30;
        }
        else if((nRandValue>=10)&&(nRandValue<=35)) // A ~ Z
        {
            ConstString[i]= nRandValue -10 + 0x41;
        }
        else if((nRandValue>=36)&&(nRandValue<=61)) // a ~ z
        {
            ConstString[i]= nRandValue -37 + 0x61;
        }
        else
        {
            ConstString[i]= 0x30;
        }
    }
    memset(NewNmkKey,0,sizeof(NewNmkKey));
    memset(Nid,0,sizeof(Nid));
    HPAVKeyNMK(NewNmkKey, (char*)ConstString);
    HPAVKeyNID(Nid,NewNmkKey,DEFAULT_LEVEL);
    memcpy(SendMmePacket.MMENTRY+SendMmePacketSize,Nid,sizeof(Nid));    //NID, 54 LSBs contain the NID 2 MSBs = 0b00
    SendMmePacketSize+=sizeof(Nid);
    SendMmePacket.MMENTRY[SendMmePacketSize++]=0x01;//NewEKS,Fixed value (0x01)to indicate ��NMK��
    memcpy(SendMmePacket.MMENTRY+SendMmePacketSize,NewNmkKey,sizeof(NewNmkKey));//NewKey
    SendMmePacketSize += sizeof(NewNmkKey);
    SendMmePacketSize += 19;  //the size before MMENTRY

    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[QCA7K][Tx]CM_SET_KEY_REQ");
    i = sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));
    Update_V2G_Flow_Status(CM_SET_KEY_REQ);
    DEBUG_PRINTF_EVCOMM_DETAIL("SendSetKey: send size =%d\n",i);

    return 0;
}


/*===========================================================================
FUNCTION: GetQca7kMac
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int GetQca7kMac()
{
    struct QcaVendorMmeHeader SendPacket;

    memset(&SendPacket, 0, sizeof(struct QcaVendorMmeHeader));
    memset(SendPacket.ODA, 0xFF, 6);    //broadcast
    memcpy(SendPacket.OSA, CsuMac, 6);
    SendPacket.MTYPE = htons(EtherType_HomePlug);
    SendPacket.MMV = 0x00;
    SendPacket.MMTYPE = MMTYPE_VENDOR_VS_NW_INFO;
    SendPacket.OUI[0] = 0x00;
    SendPacket.OUI[1] = 0xB0;
    SendPacket.OUI[2] = 0x52;

    DEBUG_PRINTF_EVCOMM_DETAIL("GetQca7kMac: send size =%d\n", sendto(RawSock, &SendPacket, 20, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll)));
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "Req for QCA7K MacAddr");

    return 0;
}



/*===========================================================================
FUNCTION: Array_Check_All_Zero
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
    result:
    (1) TRUE: all zero
    (2) FALSE: not all zero
GLOBAL VARIABLES:
=============================================================================*/
int Array_Check_All_Zero(unsigned char *ptr, int size)
{
    int result = TRUE;
    int i = 0;

    for (i = 0; i < size; i++)
    {
        if (ptr[i] != 0)
        {
            result = FALSE;
            break;
        }
    }
    return result;
}

/*===========================================================================
FUNCTION: Array_Compare_Identity
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
    result = FALSE (not identical)
    result = TRUE  (identical)
GLOBAL VARIABLES:
=============================================================================*/
int Array_Compare_Identity(unsigned char *ptrA, unsigned char *ptrB, int size)
{
    int result = TRUE;
    int i = 0;

    for (i = 0; i < size; i++)
    {
        if (ptrA[i] != ptrB[i])
        {
            result = FALSE;

            #if 0
            sprintf((char*)buf_log_evcomm,
                    "[Array_Compare_Identity]%02X%02X%02X%02X%02X%02X,%02X%02X%02X%02X%02X%02X(%d)\n",
                    ptrA[0], ptrA[1], ptrA[2], ptrA[3], ptrA[4], ptrA[5],
                    ptrB[0], ptrB[1], ptrB[2], ptrB[3], ptrB[4], ptrB[5],
                    result);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            #endif
            break;
        }
    }
    return result;
}


/*===========================================================================
FUNCTION: SLAC_DB_Search_EvMac_idx
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
    idx = -1 (not found)
GLOBAL VARIABLES:
=============================================================================*/
int SLAC_DB_Search_EvMac_idx(struct EVCC_SLAC_DATA_TYPE *evcc, unsigned char *EvMac_in)
{
    int idx = -1;
    int i = 0;

    if (evcc->arrayLen == 0)
    {
        //printf("[SLAC_DB_Search_EvMac_idx]arrayLen is empty (%d)\n", evcc->arrayLen);
        //no need to search
    }
    else if (evcc->arrayLen > EVCC_SLAC_DATA_ARRAY_TYPE_ARRAY_SIZE)
    {
        //error
        sprintf((char*)buf_log_evcomm,
                "[ERROR][SLAC_DB_Search_EvMac_idx]DB length(%d) > %d",
                evcc->arrayLen,
                EVCC_SLAC_DATA_ARRAY_TYPE_ARRAY_SIZE);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        evcc->arrayLen = 0; //reset
    }
    else
    {
        //start searching
        for (i = 0; i < evcc->arrayLen; i++)
        {
            //printf("[SLAC_DB_Search_EvMac_idx]checking DB[%d]...\n", i);
            if (Array_Compare_Identity(evcc->array[i].EvMac, EvMac_in, SLAC_EVMAC_LENGTH) == TRUE)
            {
                //printf("[SLAC_DB_Search_EvMac_idx]identical at DB[%d]...\n", i);
                idx = i;
                break;
            }
        }
    }

    //printf("[SLAC_DB_Search_EvMac_idx]return = %d\n", idx);
    return idx;
}

/*===========================================================================
FUNCTION: SLAC_DB_Check_EvMac_RunID_Matching
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
    res = FALSE (unmatched)
    res = TRUE  (matched)
GLOBAL VARIABLES:
=============================================================================*/
int SLAC_DB_Check_EvMac_RunID_Matching(struct EVCC_SLAC_DATA_TYPE *evcc, unsigned char *EvMac_in, unsigned char *RunID_in)
{
    int res = FALSE;
    int idx = -1;

    idx = SLAC_DB_Search_EvMac_idx(evcc, EvMac_in);

    if (idx >= 0)
    {
        res = Array_Compare_Identity(evcc->array[idx].RunID, RunID_in, SLAC_RUNID_LENGTH);
    }
    else
    {
        //not found the EvMac data in DB
        res = FALSE;
    }

    return res;
}

/*===========================================================================
FUNCTION: SLAC_DB_Add
DESCRIPTION:
    1. Saving each CM_SLAC_PARM_REQ data into EVCC database if its
       EvMac and RunID data are different, respectively.

PRE-CONDITION:
INPUT:
OUTPUT:
    idx = saved index (must be a positive value)
GLOBAL VARIABLES:
=============================================================================*/
int SLAC_DB_Add(unsigned char *EvMac_in, unsigned char *RunID_in)
{
    int idx = -1;

    //Search if this EvMac and RunID already exists
    idx = SLAC_DB_Search_EvMac_idx(&SLAC_INFO, EvMac_in);

    if (idx < 0)   //not exist, yet.
    {
        if (SLAC_INFO.arrayLen < EVCC_SLAC_DATA_ARRAY_TYPE_ARRAY_SIZE)  //20
        {
            sprintf((char*)buf_log_evcomm,
                    "[SLAC_DB_Add]data does not exist => added to %d-th",
                    SLAC_INFO.arrayLen);
            DEBUG_PRINTF_EVCOMM_DETAIL("%s\n", buf_log_evcomm);

            if (SLAC_INFO.arrayLen >= 0)
            {
                memset(&SLAC_INFO.array[SLAC_INFO.arrayLen], 0, sizeof(struct EVCC_SLAC_DATA_ARRAY_TYPE));
                memcpy(SLAC_INFO.array[SLAC_INFO.arrayLen].EvMac, EvMac_in, SLAC_EVMAC_LENGTH);
                memcpy(SLAC_INFO.array[SLAC_INFO.arrayLen].RunID, RunID_in, SLAC_RUNID_LENGTH);
                idx = SLAC_INFO.arrayLen;
                SLAC_INFO.arrayLen++;
            }
            else
            {
                sprintf((char*)buf_log_evcomm,
                        "[ERROR][SLAC_DB_Add]arrayLen: unexpected(%d)",
                        SLAC_INFO.arrayLen);
                DEBUG_PRINTF_EVCOMM_DETAIL("%s\n", buf_log_evcomm);

                SLAC_INFO.arrayLen = 0;
            }
        }
        else
        {
            //DB is full
            sprintf((char*)buf_log_evcomm,
                    "[SLAC_DB_Add]DB is full(%d) => bypass",
                    SLAC_INFO.arrayLen);
            DEBUG_PRINTF_EVCOMM_DETAIL("%s\n", buf_log_evcomm);
        }
    }
    else
    {
        #if 0
        sprintf((char*)buf_log_evcomm,
                "[SLAC_DB_Add]EvMac: existed (%d)",
                idx);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #endif

        //Check RunID
        if (Array_Compare_Identity(SLAC_INFO.array[idx].RunID, RunID_in, SLAC_RUNID_LENGTH) == TRUE)
        {
            //RunID is the same
            //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[SLAC_DB_Add]RunID: same");
        }
        else
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[SLAC_DB_Add]RunID: diff");
        }

        //Reset all corresponding parameters
        #if 0
        sprintf((char*)buf_log_evcomm,
                "[SLAC_DB_Add]EvMac: reset para(%d)",
                idx);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #endif

        memset(&SLAC_INFO.array[idx], 0, sizeof(struct EVCC_SLAC_DATA_ARRAY_TYPE));
        memcpy(SLAC_INFO.array[idx].EvMac, EvMac_in, SLAC_EVMAC_LENGTH);
        memcpy(SLAC_INFO.array[idx].RunID, RunID_in, SLAC_RUNID_LENGTH);
    }
    return idx;
}

/*===========================================================================
FUNCTION: SLAC_DB_Reset
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int SLAC_DB_Reset()
{
    memset(&SLAC_INFO, 0, sizeof(struct EVCC_SLAC_DATA_TYPE));
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[SLAC_DB_Reset]DONE");

    return 0;
}


/*===========================================================================
FUNCTION: MmeProcess
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int MmeProcess(unsigned char *Buffer, int DataLength)
{
    //struct ethhdr	*EthPacket;
    struct MmeHeader *MmePacket;
    static unsigned char counter;
    unsigned char state = 0;
#if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
    unsigned char tmpBuf[2048]={0};
#endif
    int Rtn = 0;
#if(NEW_SLAC_ARCHITECTURE_SWITCH == ENABLE)
    int idx = 0;
    unsigned char *EvMac_in;
    unsigned char *RunID_in;
#endif

    MmePacket = (struct MmeHeader *)Buffer;
    state = Check_V2G_Flow_Status();

    #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
    {
        DEBUG_PRINTF_EVCOMM_DETAIL("***********************************\n");
        DEBUG_PRINTF_EVCOMM_DETAIL("******* Received MME Packet *******\n");
        DEBUG_PRINTF_EVCOMM_DETAIL("***********************************\n");
        DEBUG_PRINTF_EVCOMM_DETAIL("DataLength=%d\n",DataLength);
        DEBUG_PRINTF_EVCOMM_DETAIL("ODA: %02x:%02x:%02x:%02x:%02x:%02x\n", //Destination MAC Address
            MmePacket->ODA[0], MmePacket->ODA[1],
            MmePacket->ODA[2], MmePacket->ODA[3],
            MmePacket->ODA[4], MmePacket->ODA[5]);
        DEBUG_PRINTF_EVCOMM_DETAIL("OSA: %02x:%02x:%02x:%02x:%02x:%02x\n", //Source MAC Address (EV MAC)
            MmePacket->OSA[0], MmePacket->OSA[1],
            MmePacket->OSA[2], MmePacket->OSA[3],
            MmePacket->OSA[4], MmePacket->OSA[5]);
        DEBUG_PRINTF_EVCOMM_DETAIL("MTYPE: 0x%x\n", htons(MmePacket->MTYPE));
        DEBUG_PRINTF_EVCOMM_DETAIL("MMV: 0x%x\n", MmePacket->MMV);
        DEBUG_PRINTF_EVCOMM_DETAIL("MMTYPE: 0x%x\n", MmePacket->MMTYPE);
        DEBUG_PRINTF_EVCOMM_DETAIL("FMI 0x%x, 0x%x\n",
            MmePacket->FMI[0],MmePacket->FMI[1]);
    }
    #endif

    #if (SLAC_FIRST_RESPONSE_METHOD == SET_NO_PWM_IF_NOT_GET_PERMISSION)
    {
        //Check CP as 5%
        if (EVCOMM_SYS_INFO.CpState != 3 &&
            EVCOMM_SYS_INFO.CpState != 4 &&
            MmePacket->MMTYPE != MMTYPE_CM_SET_KEY_CNF &&
            MmePacket->MMTYPE != MMTYPE_VENDOR_VS_HOST_ACTION &&
            MmePacket->MMTYPE != MMTYPE_VENDOR_ATTEN_CHAR &&
            MmePacket->MMTYPE != MMTYPE_VENDOR_VS_NW_INFO_CNF
           )
        {
            //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[SLAC]ignored(wrong CP state)");
            return 0;
        }
    }
    #endif

    //[To-Do] Adding a pre-check filter mechanism for Source and Destination MAC Address

    //check if the destination address is broadcast or EVSE itself, it can be ignore if not belong to itself.
    switch(MmePacket->MMTYPE)
    {
	    case MMTYPE_CM_SET_KEY_CNF:
		{
	        DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_SET_KEY_CNF ---\n");
	        DEBUG_PRINTF_EVCOMM_DETAIL("Result: 0x%x\n", MmePacket->MMENTRY[0]);

            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[QCA7K][Rx]CM_SET_KEY_CNF (SetKey: DONE)");
            Update_V2G_Flow_Status(CM_SET_KEY_CNF);
	        break;
		}

	    case MMTYPE_CM_SLAC_PARM_REQ:
		{
            //Check QCA7000 status
            if (EVCOMM_SYS_INFO.QCA7K_SetKeyDone == FALSE)
            {
                //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[SLAC][Rx]CM_SLAC_PARM_REQ: ignored(QCA7K init...)");
                break;
            }

            //Check error state
            state = Check_V2G_Flow_Status();
            if (state == Performance_Timeout ||     //253
                state == Sequence_Timeout ||        //254
                state == Other_Fault)               //255
            {
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[SLAC][Rx]CM_SLAC_PARM_REQ: ignored(in error state)");
				break;
            }

            //Printing EV MAC Address
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[SLAC][Rx]CM_SLAC_PARM_REQ");

            //Avoid Coupled SLAC_PARM_REQ
            if (CheckConnectorPlugIn() == FALSE)  //12V(State 1)
            {
                #if 0
                sprintf((char*)buf_log_evcomm,
                        "[WARNING][SLAC][Rx]CM_SLAC_PARM_REQ: ignored(coupled SLAC,%d)",
                        CheckConnectorPlugIn());
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                #endif
                break;
            }

            //[TC_SECC_VTB_CmSlacParm_003] SECURITY_TYPE needs to be 0x00 (no security)
            if (MmePacket->MMENTRY[1] != 0)
            {
                sprintf((char*)buf_log_evcomm,
                        "[WARNING][SLAC][Rx]CM_SLAC_PARM_REQ: ignored(invalid SECURITY_TYPE,%d)", //Source MAC Address (EV MAC)
                        MmePacket->MMENTRY[1]);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                break;
            }

            //=================== Legal CM_SLAC_PARM_REQ Zone =================

            Update_V2G_Flow_Status(CM_SLAC_PARM_REQ);

            #if (SLAC_FIRST_RESPONSE_METHOD == SET_5_PWM_ONCE_RX_CM_SLAC_PARM_REQ)
            {
                //Once receiving CM_SLAC_PARM_REQ, set PWM as 5%
                SwitchCpStateE(DISABLE);
                OutputCpPwmDuty(5);
            }
            #endif

            //Checking if this SLAC Req comes before 5% PWM (for 15118)
            if(ShmInternalComm->ChargingPermission == FALSE)
            {
                //Sniffer_Tcpdump(ENABLE);
                sprintf((char*)buf_log_evcomm, "Check Permission: %d (SLAC first => START)", ShmInternalComm->ChargingPermission);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            }

            #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
            {
                DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_SLAC_PARM_REQ ---\n");
                DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", MmePacket->MMENTRY[0]);
                DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", MmePacket->MMENTRY[1]);
                DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n",
                    MmePacket->MMENTRY[2], MmePacket->MMENTRY[3],
                    MmePacket->MMENTRY[4], MmePacket->MMENTRY[5],
                    MmePacket->MMENTRY[6], MmePacket->MMENTRY[7],
                    MmePacket->MMENTRY[8], MmePacket->MMENTRY[9]);
                DEBUG_PRINTF_EVCOMM_DETAIL("CipherSuiteSetSize: 0x%x\n", MmePacket->MMENTRY[10]);
                DEBUG_PRINTF_EVCOMM_DETAIL("CipherSuite [1]: 0x%x,0x%x\n",
                    MmePacket->MMENTRY[11], MmePacket->MMENTRY[12]);
            }
            #endif

            #if (NEW_SLAC_ARCHITECTURE_SWITCH == ENABLE)
            {
                //Saving each CM_SLAC_PARM_REQ data into EVCC database
                EvMac_in = &MmePacket->OSA[0];
                RunID_in = &MmePacket->MMENTRY[2];
                idx = SLAC_DB_Add(EvMac_in, RunID_in); //(EvMac, RunID)

                if (idx < 0)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[WARNING][CM_SLAC_PARM_REQ]DB is full or errors occour(%d) => ignore",
                            idx);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    break;
                }

                //Select the 1st EV MAC address
                if (SLAC_INFO.arrayLen == 1)   //1st Req
                {
                    #if 1
                    sprintf((char*)buf_log_evcomm,
                            "[SLAC][Rx]CM_SLAC_PARM_REQ[%d](%02X:%02X:%02X:%02X:%02X:%02X,%02X%02X%02X%02X%02X%02X%02X%02X):selected",
                            (idx + 1),
                            MmePacket->OSA[0], MmePacket->OSA[1], MmePacket->OSA[2], MmePacket->OSA[3], MmePacket->OSA[4], MmePacket->OSA[5],
                            MmePacket->MMENTRY[2], MmePacket->MMENTRY[3], MmePacket->MMENTRY[4], MmePacket->MMENTRY[5],
                            MmePacket->MMENTRY[6], MmePacket->MMENTRY[7], MmePacket->MMENTRY[8], MmePacket->MMENTRY[9]);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    #endif
                    /*
                    sprintf((char*)buf_log_evcomm,
                            "[SLAC][EVMAC][%d-th]%02X:%02X:%02X:%02X:%02X:%02X (selected)", //Source MAC Address (EV MAC)
                            SLAC_INFO.arrayLen,
                            MmePacket->OSA[0], MmePacket->OSA[1],
                            MmePacket->OSA[2], MmePacket->OSA[3],
                            MmePacket->OSA[4], MmePacket->OSA[5]);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                    sprintf((char*)buf_log_evcomm,
                            "[SLAC][RunID][%d-th]%02X%02X%02X%02X%02X%02X%02X%02X (selected)", //RunID (from EVCC)
                            SLAC_INFO.arrayLen,
                            MmePacket->MMENTRY[2], MmePacket->MMENTRY[3],
                            MmePacket->MMENTRY[4], MmePacket->MMENTRY[5],
                            MmePacket->MMENTRY[6], MmePacket->MMENTRY[7],
                            MmePacket->MMENTRY[8], MmePacket->MMENTRY[9]);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    */
                }
                else    //2nd Req
                {
                    #if 1
                    sprintf((char*)buf_log_evcomm,
                            "[SLAC][Rx]CM_SLAC_PARM_REQ[%d](%02X:%02X:%02X:%02X:%02X:%02X,%02X%02X%02X%02X%02X%02X%02X%02X):not selected",
                            (idx + 1),
                            MmePacket->OSA[0], MmePacket->OSA[1], MmePacket->OSA[2], MmePacket->OSA[3], MmePacket->OSA[4], MmePacket->OSA[5],
                            MmePacket->MMENTRY[2], MmePacket->MMENTRY[3], MmePacket->MMENTRY[4], MmePacket->MMENTRY[5],
                            MmePacket->MMENTRY[6], MmePacket->MMENTRY[7], MmePacket->MMENTRY[8], MmePacket->MMENTRY[9]);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    #endif
                    /*
                    sprintf((char*)buf_log_evcomm,
                            "[SLAC][EVMAC][%d-th]%02X:%02X:%02X:%02X:%02X:%02X (not selected)", //Source MAC Address (EV MAC)
                            SLAC_INFO.arrayLen,
                            MmePacket->OSA[0], MmePacket->OSA[1],
                            MmePacket->OSA[2], MmePacket->OSA[3],
                            MmePacket->OSA[4], MmePacket->OSA[5]);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                    sprintf((char*)buf_log_evcomm,
                            "[SLAC][RunID][%d-th]%02X%02X%02X%02X%02X%02X%02X%02X (not selected)", //RunID (from EVCC)
                            SLAC_INFO.arrayLen,
                            MmePacket->MMENTRY[2], MmePacket->MMENTRY[3],
                            MmePacket->MMENTRY[4], MmePacket->MMENTRY[5],
                            MmePacket->MMENTRY[6], MmePacket->MMENTRY[7],
                            MmePacket->MMENTRY[8], MmePacket->MMENTRY[9]);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    */
                }
                memcpy(EvMac, MmePacket->OSA, sizeof(EvMac));
                memcpy(DestSocketAddress.sll_addr, MmePacket->OSA, SLAC_EVMAC_LENGTH);
                memcpy(SlacRunId, MmePacket->MMENTRY + 2, SLAC_RUNID_LENGTH);
                memset(&SendMmePacket, 0, sizeof(struct MmeHeader));
                memcpy(SendMmePacket.ODA, MmePacket->OSA, 6);
                memcpy(SendMmePacket.OSA, CsuMac, 6);
                SendMmePacket.MTYPE = htons(EtherType_HomePlug);
                SendMmePacket.MMV = MmePacket->MMV;
                SendMmePacket.MMTYPE = MMTYPE_CM_SLAC_PARM_CNF;
                SendMmePacket.FMI[0] = SendMmePacket.FMI[1] = 0;
                SendMmePacketSize = 0;
                memset(SendMmePacket.MMENTRY, 0xFF, 6); //M-SOUND_TARGET(6-byte:0xFFFFFFFFFFFF): Fixed value indicating that M-Sounds to be sent as Ethernet broadcast
                SendMmePacketSize += 6;
                SendMmePacket.MMENTRY[SendMmePacketSize++] = C_EV_match_MNBC; //NUM_SOUNDS(0x0A): Number of M-Sounds to be transmitted by the EV GP Station during the SLAC process
                SendMmePacket.MMENTRY[SendMmePacketSize++] = 6; //Time_Out(0x06): unit = 100ms
                SendMmePacket.MMENTRY[SendMmePacketSize++] = 0x01; //RESP_TYPE(0x01): Fixed value indicating ��Other GP station��, 0x00 �V HLE of the STA, 0x01 �V Another GP STA, 0x02 �V 0xFF �V Reserved
                memcpy(SendMmePacket.MMENTRY + SendMmePacketSize, SLAC_INFO.array[idx].EvMac, 6); //FORWARDING_STA(MAC Address of the EV HLE)
                SendMmePacketSize += 6;
                SendMmePacket.MMENTRY[SendMmePacketSize++] = 0; //APPLICATION_TYPE(0x00): 0x00(PEV-EVSE Association), 0x01-0xFF(Reserved)
                SendMmePacket.MMENTRY[SendMmePacketSize++] = 0; //SECURITY_TYPE(0x00): 0x00(No Security), 0x01(Public Key Signature), 0x02-0xFF(Reserved)
                memcpy(SendMmePacket.MMENTRY + SendMmePacketSize, SlacRunId, SLAC_RUNID_LENGTH); //RunID (8-byte)
                SendMmePacketSize += SLAC_RUNID_LENGTH;
                SendMmePacketSize += 19;      //the size before MMENTRY

                #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
                {
                    DEBUG_PRINTF_EVCOMM_DETAIL("***** Response MME Packet *****\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                           SendMmePacket.ODA[0],SendMmePacket.ODA[1],SendMmePacket.ODA[2],SendMmePacket.ODA[3],SendMmePacket.ODA[4],SendMmePacket.ODA[5]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                           SendMmePacket.OSA[0],SendMmePacket.OSA[1],SendMmePacket.OSA[2],SendMmePacket.OSA[3],SendMmePacket.OSA[4],SendMmePacket.OSA[5]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("MTYPE: 0x%x\n", htons(SendMmePacket.MTYPE));
                    DEBUG_PRINTF_EVCOMM_DETAIL("MMV: 0x%x\n", SendMmePacket.MMV);
                    DEBUG_PRINTF_EVCOMM_DETAIL("MMTYPE: 0x%x\n", SendMmePacket.MMTYPE);
                    DEBUG_PRINTF_EVCOMM_DETAIL("FMI 0x%x, 0x%x\n", SendMmePacket.FMI[0],SendMmePacket.FMI[1]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("--- CM_SLAC_PARM_CNF ---\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("M-SOUND_TARGET: %02x:%02x:%02x:%02x:%02x:%02x\n",
                           SendMmePacket.MMENTRY[0],SendMmePacket.MMENTRY[1],SendMmePacket.MMENTRY[2],SendMmePacket.MMENTRY[3],
                           SendMmePacket.MMENTRY[4],SendMmePacket.MMENTRY[5]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("NUM_SOUNDS: 0x%x\n", SendMmePacket.MMENTRY[6]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("Time_Out: 0x%x\n", SendMmePacket.MMENTRY[7]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("RESP_TYPE: 0x%x\n", SendMmePacket.MMENTRY[8]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("M-FORWARDING_STA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                           SendMmePacket.MMENTRY[9],SendMmePacket.MMENTRY[10],SendMmePacket.MMENTRY[11],SendMmePacket.MMENTRY[12],
                           SendMmePacket.MMENTRY[13],SendMmePacket.MMENTRY[14]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", SendMmePacket.MMENTRY[15]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", SendMmePacket.MMENTRY[16]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n",
                           SendMmePacket.MMENTRY[17],SendMmePacket.MMENTRY[18],SendMmePacket.MMENTRY[19],SendMmePacket.MMENTRY[20],
                           SendMmePacket.MMENTRY[21],SendMmePacket.MMENTRY[22],SendMmePacket.MMENTRY[23],SendMmePacket.MMENTRY[24]);
                }
                #endif

                Update_V2G_Flow_Status(CM_SLAC_PARM_CONF);
                Rtn = sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));

                DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacketSize=%d,Rtn=%d\n",SendMmePacketSize,Rtn);

                ftime(&SeqStartTime);
                counter = 0;
                break;
            }
            #else
            {
                memcpy(EvMac, MmePacket->OSA, sizeof(EvMac));
                memcpy(DestSocketAddress.sll_addr, MmePacket->OSA, sizeof(EvMac));
                memcpy(SlacRunId,MmePacket->MMENTRY + 2, sizeof(SlacRunId));
                memset(&SendMmePacket, 0, sizeof(struct MmeHeader));
                memcpy(SendMmePacket.ODA, MmePacket->OSA, 6);
                memcpy(SendMmePacket.OSA, CsuMac, 6);
                SendMmePacket.MTYPE = htons(EtherType_HomePlug);
                SendMmePacket.MMV = MmePacket->MMV;
                SendMmePacket.MMTYPE = MMTYPE_CM_SLAC_PARM_CNF;
                SendMmePacket.FMI[0] = SendMmePacket.FMI[1] = 0;
                SendMmePacketSize = 0;
                memset(SendMmePacket.MMENTRY, 0xFF, 6); //M-SOUND_TARGET(6-byte:0xFFFFFFFFFFFF): Fixed value indicating that M-Sounds to be sent as Ethernet broadcast
                SendMmePacketSize += 6;
                SendMmePacket.MMENTRY[SendMmePacketSize++] = C_EV_match_MNBC; //NUM_SOUNDS(0x0A): Number of M-Sounds to be transmitted by the EV GP Station during the SLAC process
                SendMmePacket.MMENTRY[SendMmePacketSize++] = 6; //Time_Out(0x06): unit = 100ms
                SendMmePacket.MMENTRY[SendMmePacketSize++] = 0x01; //RESP_TYPE(0x01): Fixed value indicating ��Other GP station��, 0x00 �V HLE of the STA, 0x01 �V Another GP STA, 0x02 �V 0xFF �V Reserved
                memcpy(SendMmePacket.MMENTRY + SendMmePacketSize, EvMac, 6); //FORWARDING_STA(MAC Address of the EV HLE)
                SendMmePacketSize += 6;
                SendMmePacket.MMENTRY[SendMmePacketSize++] = 0; //APPLICATION_TYPE(0x00): 0x00(PEV-EVSE Association), 0x01-0xFF(Reserved)
                SendMmePacket.MMENTRY[SendMmePacketSize++] = 0; //SECURITY_TYPE(0x00): 0x00(No Security), 0x01(Public Key Signature), 0x02-0xFF(Reserved)
                memcpy(SendMmePacket.MMENTRY + SendMmePacketSize, SlacRunId, sizeof(SlacRunId)); //RunID (8-byte)
                SendMmePacketSize += sizeof(SlacRunId);
                SendMmePacketSize += 19;      //the size before MMENTRY

                #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
                {
                    DEBUG_PRINTF_EVCOMM_DETAIL("\n\n***** Response MME Packet *****\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                           SendMmePacket.ODA[0],SendMmePacket.ODA[1],SendMmePacket.ODA[2],SendMmePacket.ODA[3],SendMmePacket.ODA[4],SendMmePacket.ODA[5]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                           SendMmePacket.OSA[0],SendMmePacket.OSA[1],SendMmePacket.OSA[2],SendMmePacket.OSA[3],SendMmePacket.OSA[4],SendMmePacket.OSA[5]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("MTYPE: 0x%x\n", htons(SendMmePacket.MTYPE));
                    DEBUG_PRINTF_EVCOMM_DETAIL("MMV: 0x%x\n", SendMmePacket.MMV);
                    DEBUG_PRINTF_EVCOMM_DETAIL("MMTYPE: 0x%x\n", SendMmePacket.MMTYPE);
                    DEBUG_PRINTF_EVCOMM_DETAIL("FMI 0x%x, 0x%x\n", SendMmePacket.FMI[0],SendMmePacket.FMI[1]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("--- CM_SLAC_PARM_CNF ---\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("M-SOUND_TARGET: %02x:%02x:%02x:%02x:%02x:%02x\n",
                           SendMmePacket.MMENTRY[0],SendMmePacket.MMENTRY[1],SendMmePacket.MMENTRY[2],SendMmePacket.MMENTRY[3],
                           SendMmePacket.MMENTRY[4],SendMmePacket.MMENTRY[5]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("NUM_SOUNDS: 0x%x\n", SendMmePacket.MMENTRY[6]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("Time_Out: 0x%x\n", SendMmePacket.MMENTRY[7]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("RESP_TYPE: 0x%x\n", SendMmePacket.MMENTRY[8]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("M-FORWARDING_STA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                           SendMmePacket.MMENTRY[9],SendMmePacket.MMENTRY[10],SendMmePacket.MMENTRY[11],SendMmePacket.MMENTRY[12],
                           SendMmePacket.MMENTRY[13],SendMmePacket.MMENTRY[14]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", SendMmePacket.MMENTRY[15]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", SendMmePacket.MMENTRY[16]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n",
                           SendMmePacket.MMENTRY[17],SendMmePacket.MMENTRY[18],SendMmePacket.MMENTRY[19],SendMmePacket.MMENTRY[20],
                           SendMmePacket.MMENTRY[21],SendMmePacket.MMENTRY[22],SendMmePacket.MMENTRY[23],SendMmePacket.MMENTRY[24]);
                }
                #endif

                Rtn = sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));
                Update_V2G_Flow_Status(CM_SLAC_PARM_CONF);

                DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacketSize=%d,Rtn=%d\n",SendMmePacketSize,Rtn);

                ftime(&SeqStartTime);
                counter = 0;
                break;
            }
            #endif
		}

	    case MMTYPE_CM_START_ATTEN_CHAR_IND:
		{
            if(V2gFlowStatus >= CM_ATTEN_CHAR_IND)
            {
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[WARNING][SLAC][Rx]CM_START_ATTEN_CHAR_IND: ignored(timeup)");
                break;
            }

            //Avoid Coupled CM_START_ATTEN_CHAR_IND
            if (CheckConnectorPlugIn() == FALSE)  //12V(State 1)
            {
                sprintf((char*)buf_log_evcomm,
                        "[WARNING][SLAC][Rx]CM_START_ATTEN_CHAR_IND: ignored(coupled SLAC,%d)",
                        CheckConnectorPlugIn());
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                break;
            }

            #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
            {
                DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_START_ATTEN_CHAR_IND (counter : %d/3 ) ---\n", counter);
                DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", MmePacket->MMENTRY[0]);
                DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", MmePacket->MMENTRY[1]);
                DEBUG_PRINTF_EVCOMM_DETAIL("NUM_SOUNDS: 0x%x\n", MmePacket->MMENTRY[2]);
                DEBUG_PRINTF_EVCOMM_DETAIL("Time_Out 0x%x\n", MmePacket->MMENTRY[3]);
                DEBUG_PRINTF_EVCOMM_DETAIL("RESP_TYPE 0x%x\n", MmePacket->MMENTRY[4]);    //Fixed value (0x01) indicating ��other Green PHY station��
                DEBUG_PRINTF_EVCOMM_DETAIL("FORWARDING_STA: %02x:%02x:%02x:%02x:%02x:%02x\n",
                       MmePacket->MMENTRY[5],MmePacket->MMENTRY[6],MmePacket->MMENTRY[7],MmePacket->MMENTRY[8],
                       MmePacket->MMENTRY[9],MmePacket->MMENTRY[10]);
                DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n",
                       MmePacket->MMENTRY[11],MmePacket->MMENTRY[12],MmePacket->MMENTRY[13],MmePacket->MMENTRY[14],
                       MmePacket->MMENTRY[15],MmePacket->MMENTRY[16],MmePacket->MMENTRY[17],MmePacket->MMENTRY[18]);
            }
            #endif

            //New SLAC architecture designed by Joseph
            #if (NEW_SLAC_ARCHITECTURE_SWITCH == ENABLE)
            {
                EvMac_in = &MmePacket->OSA[0];
                RunID_in = &MmePacket->MMENTRY[11];
                idx = SLAC_DB_Search_EvMac_idx(&SLAC_INFO, EvMac_in);

                if (idx >= 0)
                {
                    Update_V2G_Flow_Status(CM_START_ATTEN_CHAR_IND);
                    counter++;
                    //[TC_SECC_VTB_AttenuationCharacterization_013]
                    if (MmePacket->MMENTRY[0] != 0) //APPLICATION_TYPE must be 0x00(EV-EVSE Matching)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[WARNING][SLAC][Rx][CM_START_ATTEN_CHAR_IND]APPLICATION_TYPE(%d): invalid => ignore Req",
                                MmePacket->MMENTRY[0]);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        break;
                    }

                    //[TC_SECC_VTB_AttenuationCharacterization_014]
                    if (MmePacket->MMENTRY[1] != 0) //SECURITY_TYPE must be 0x00(No Security)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[WARNING][SLAC][Rx][CM_START_ATTEN_CHAR_IND]SECURITY_TYPE(%d): invalid => ignore Req",
                                MmePacket->MMENTRY[1]);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        break;
                    }

                    //[TC_SECC_VTB_AttenuationCharacterization_017]
                    if (MmePacket->MMENTRY[4] != 0x01) //RESP_TYPE must be 0x01(Send to another GP STA(EV))
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[WARNING][SLAC][Rx][CM_START_ATTEN_CHAR_IND]RESP_TYPE(%d): invalid => ignore Req",
                                MmePacket->MMENTRY[4]);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        break;
                    }

                    //[TC_SECC_VTB_AttenuationCharacterization_021]
                    //FORWARDING_STA: MAC Address of the EV HLE (station which the measurement results shall be sent to)
                    if (Array_Compare_Identity(EvMac_in, &MmePacket->MMENTRY[5], SLAC_EVMAC_LENGTH) == FALSE)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[WARNING][SLAC][Rx][CM_START_ATTEN_CHAR_IND]FORWARDING_STA(%02X:%02X:%02X:%02X:%02X:%02X): invalid => ignore Req",
                                MmePacket->MMENTRY[5], MmePacket->MMENTRY[6],
                                MmePacket->MMENTRY[7], MmePacket->MMENTRY[8],
                                MmePacket->MMENTRY[9], MmePacket->MMENTRY[10]);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                        SLAC_INFO.array[idx].StartAttenCharErr = TRUE;
                        break;
                    }

                    //Check RunID
                    if (SLAC_DB_Check_EvMac_RunID_Matching(&SLAC_INFO, EvMac_in, RunID_in) == TRUE)
                    {
                        SLAC_INFO.array[idx].MnbcSoundNum = MmePacket->MMENTRY[2];
                        SLAC_INFO.array[idx].StartAttenCharCnt++;

                        #if 0
                        sprintf((char*)buf_log_evcomm,
                                "[SLAC][Rx]CM_START_ATTEN_CHAR_IND[%d]:%d-th",
                                (idx + 1),
                                SLAC_INFO.array[idx].StartAttenCharCnt);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        #endif

                        if (SLAC_INFO.array[idx].StartAttenCharCnt == 1)
                        {
                            memset(SLAC_INFO.array[idx].AAG, 0, sizeof(SLAC_INFO.array[idx].AAG));
                            SLAC_INFO.array[idx].AttenProfileCnt = 0;
                            ftime(&SeqStartTime);       //start TT_EVSE_match_MNBC
                        }
                        else if (SLAC_INFO.array[idx].StartAttenCharCnt >= 3)
                        {
                            sprintf((char*)buf_log_evcomm,
                                    "[WARNING][SLAC][Rx][CM_START_ATTEN_CHAR_IND]counter(%d): unexpected",
                                    SLAC_INFO.array[idx].StartAttenCharCnt);
                        }
                        else
                        {
                            //null
                        }
                    }
                    else
                    {
                        //This RunID is not matched with this EvMac,
                        //or this RunID is not found in DB.
                        sprintf((char*)buf_log_evcomm,
                                "[WARNING][SLAC][Rx][CM_START_ATTEN_CHAR_IND]EvMac-RunID: unmatched => ignore Req");
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                        //Response: ignore
                    }
                }
                else
                {
                    //this msg source is not in database
                    //ignore
                }
                break;
            }
            #else   //Old SLAC architecture designed by Vern
            {
                MnbcSoundNum = MmePacket->MMENTRY[2];
                Update_V2G_Flow_Status(CM_START_ATTEN_CHAR_IND);
                counter++;
                if(counter == 1)
                {
                    memset(Aag, 0, sizeof(Aag));
                    AttenProfileCnt = 0;
                    ftime(&SeqStartTime);       //start TT_EVSE_match_MNBC
                }
                else if(counter >= 3)
                {
                    counter = 0;
                }
                break;
            }
            #endif
		}

	    case MMTYPE_CM_MNBC_SOUND_IND:
		{
	        if(V2gFlowStatus >= CM_ATTEN_CHAR_IND)
	        {
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[WARNING][SLAC][Rx]CM_MNBC_SOUND_IND: ignored(timeup)");
                break;
            }

            //Avoid Coupled CM_MNBC_SOUND_IND
            if (CheckConnectorPlugIn() == FALSE)  //12V(State 1)
            {
                sprintf((char*)buf_log_evcomm,
                        "[WARNING][SLAC][Rx]CM_MNBC_SOUND_IND: ignored(coupled SLAC,%d)",
                        CheckConnectorPlugIn());
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                break;
            }

            if(V2gFlowStatus == CM_START_ATTEN_CHAR_IND)
            {
            	counter = 0;
            }

            #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
            {
                DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_MNBC_SOUND_IND (counter : %d/%d) ---\n", counter, SLAC_INFO.array[idx].MnbcSoundNum);
                DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", MmePacket->MMENTRY[0]);
                DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", MmePacket->MMENTRY[1]);
                DEBUG_PRINTF_EVCOMM_DETAIL("SenderID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n",
                       MmePacket->MMENTRY[2],MmePacket->MMENTRY[3],MmePacket->MMENTRY[4],MmePacket->MMENTRY[5],
                       MmePacket->MMENTRY[6],MmePacket->MMENTRY[7],MmePacket->MMENTRY[8],MmePacket->MMENTRY[9],
                       MmePacket->MMENTRY[10],MmePacket->MMENTRY[11],MmePacket->MMENTRY[12],MmePacket->MMENTRY[13],
                       MmePacket->MMENTRY[14],MmePacket->MMENTRY[15],MmePacket->MMENTRY[16],MmePacket->MMENTRY[17],
                       MmePacket->MMENTRY[18]);
                DEBUG_PRINTF_EVCOMM_DETAIL("Cnt: 0x%x\n", MmePacket->MMENTRY[19]);
                DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n",
                       MmePacket->MMENTRY[20],MmePacket->MMENTRY[21],MmePacket->MMENTRY[22],MmePacket->MMENTRY[23],
                       MmePacket->MMENTRY[24],MmePacket->MMENTRY[25],MmePacket->MMENTRY[26],MmePacket->MMENTRY[27]);
                DEBUG_PRINTF_EVCOMM_DETAIL("RSVD: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n",
                       MmePacket->MMENTRY[28],MmePacket->MMENTRY[29],MmePacket->MMENTRY[30],MmePacket->MMENTRY[31],
                       MmePacket->MMENTRY[32],MmePacket->MMENTRY[33],MmePacket->MMENTRY[34],MmePacket->MMENTRY[35]);
                DEBUG_PRINTF_EVCOMM_DETAIL("Rnd: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n",
                       MmePacket->MMENTRY[36],MmePacket->MMENTRY[37],MmePacket->MMENTRY[38],MmePacket->MMENTRY[39],
                       MmePacket->MMENTRY[40],MmePacket->MMENTRY[41],MmePacket->MMENTRY[42],MmePacket->MMENTRY[43],
                       MmePacket->MMENTRY[44],MmePacket->MMENTRY[45],MmePacket->MMENTRY[46],MmePacket->MMENTRY[47],
                       MmePacket->MMENTRY[48],MmePacket->MMENTRY[49],MmePacket->MMENTRY[50],MmePacket->MMENTRY[51]);
            }
            #endif


            //New SLAC architecture designed by Joseph
            #if (NEW_SLAC_ARCHITECTURE_SWITCH == ENABLE)
            {
                EvMac_in = &MmePacket->OSA[0];
                RunID_in = &MmePacket->MMENTRY[20];
                idx = SLAC_DB_Search_EvMac_idx(&SLAC_INFO, EvMac_in);

                if (idx >= 0)
                {
                    Update_V2G_Flow_Status(CM_MNBC_SOUND_IND);
                    counter++;

                    //Check for RunID
                    if (SLAC_DB_Check_EvMac_RunID_Matching(&SLAC_INFO, EvMac_in, RunID_in) == TRUE)
                    {
                        SLAC_INFO.array[idx].MnbcSoundCnt++;

                        /*
                        sprintf((char*)buf_log_evcomm,
                                "[SLAC][Rx]CM_MNBC_SOUND_IND[%d]:%d-th",
                                (idx + 1),
                                SLAC_INFO.array[idx].MnbcSoundCnt);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        */
                    }
                    else
                    {
                        //RunID is not matched or does not exist.
                        sprintf((char*)buf_log_evcomm,
                                "[WARNING][SLAC][Rx]CM_MNBC_SOUND_IND]EvMac-RunID: unmatched");
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    }
                }
                else
                {
                    //ignore
                    sprintf((char*)buf_log_evcomm,
                            "[WARNING][SLAC][Rx]CM_MNBC_SOUND_IND]EvMac does not exist");
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                }
                break;
            }
            #else   //Old SLAC architecture designed by Vern
            {
                Update_V2G_Flow_Status(CM_MNBC_SOUND_IND);
                counter++;
                break;
            }
            #endif
		}

	    case MMTYPE_CM_ATTEN_PROFILE_IND:
		{
	        if(V2gFlowStatus >= CM_ATTEN_CHAR_IND)
	        {
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[WARNING][SLAC][Rx]CM_ATTEN_PROFILE_IND: ignore(timeup)");
				break;
			}

            #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
            {
                DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_ATTEN_PROFILE_IND (counter : %d/%d) ---\n", counter, SLAC_INFO.array[idx].MnbcSoundNum);
                DEBUG_PRINTF_EVCOMM_DETAIL("EV MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
                       MmePacket->MMENTRY[0], MmePacket->MMENTRY[1], MmePacket->MMENTRY[2], MmePacket->MMENTRY[3],
                       MmePacket->MMENTRY[4], MmePacket->MMENTRY[5]);
                DEBUG_PRINTF_EVCOMM_DETAIL("NumGroups: 0x%x\n", MmePacket->MMENTRY[6]);  //NumGroups, Number of AAG Groups (ex: 0x3A = 58)
                //NumGroups: Number of OFDM carrier groups used for the SLAC signal characterization.
                //AAG[i]: Average Attenuation of Group i (i = 1 ~ 58)
                DEBUG_PRINTF_EVCOMM_DETAIL("RSVD: 0x%x\n", MmePacket->MMENTRY[7]);

                memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf));
                for(Rtn = 0; Rtn < MmePacket->MMENTRY[6]; Rtn++)
                {
                	sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, MmePacket->MMENTRY[8 + Rtn]);
                }
                DEBUG_PRINTF_EVCOMM_DETAIL("AAG: %s\n", tmpBuf);
            }
            #endif

            //New SLAC architecture designed by Joseph
            #if (NEW_SLAC_ARCHITECTURE_SWITCH == ENABLE)
            {
                EvMac_in = &MmePacket->MMENTRY[0]; //[CAUTION] The EvMac address is not &MmePacket->OSA[0]
                //[CAUTION] There is no RunID information of CM_ATTEN_PROFILE_IND
                //          packet, which means SECC cannot use the RunID to
                //          distinguish those SLAC request with identical EvMac
                //          but with different RunID.
                idx = SLAC_DB_Search_EvMac_idx(&SLAC_INFO, EvMac_in);

                /*
                printf("%d, %d, %d, %d\n",
                        idx,
                        SLAC_INFO.array[idx].AagGroupsNum,
                        MmePacket->MMENTRY[6],
                        SLAC_INFO.array[idx].AttenProfileCnt);
                */

                if (idx >= 0)
                {
                    SLAC_INFO.array[idx].AttenProfileCnt++;

                    /*
                    sprintf((char*)buf_log_evcomm,
                            "[SLAC][Rx]CM_ATTEN_PROFILE_IND[%d]:%d-th",
                            (idx + 1),
                            SLAC_INFO.array[idx].AttenProfileCnt);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    */

                    //printf("%d, %d\n", SLAC_INFO.array[idx].AagGroupsNum, MmePacket->MMENTRY[6]);

                    SLAC_INFO.array[idx].AagGroupsNum = MmePacket->MMENTRY[6];
                    ////NumGroups, Number of AAG Groups (ex: 0x3A = 58)

                    for(Rtn = 0; Rtn < SLAC_INFO.array[idx].AagGroupsNum; Rtn++) //ex:58
                    {
                        SLAC_INFO.array[idx].AAG[Rtn] += MmePacket->MMENTRY[8 + Rtn];
                    }

                    Update_V2G_Flow_Status(CM_MNBC_SOUND_IND);
                    break;
                }
                else
                {
                    //The EvMac is not in the database
                    //ignore
                    sprintf((char*)buf_log_evcomm,
                            "[SLAC][Rx][CM_ATTEN_PROFILE_IND]EvMac(%02X%02X%02X%02X%02X%02X): not exist => ignore",
                            EvMac_in[0], EvMac_in[1], EvMac_in[2], EvMac_in[3], EvMac_in[4], EvMac_in[5]);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    break;
                }
            }
            #else   //Old SLAC architecture designed by Vern
            {
                AagGroupsNum = MmePacket->MMENTRY[6];
                for(Rtn = 0; Rtn < MmePacket->MMENTRY[6]; Rtn++)
                {
                    Aag[Rtn] += MmePacket->MMENTRY[8 + Rtn];
                }
                AttenProfileCnt++;
                Update_V2G_Flow_Status(CM_MNBC_SOUND_IND);
                break;
            }
            #endif
		}

	    case MMTYPE_CM_ATTEN_CHAR_RSP:
		{
            #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
            {
                DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_ATTEN_CHAR_RSP ---\n");
                DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", MmePacket->MMENTRY[0]);
                DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", MmePacket->MMENTRY[1]);
                DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x\n",
                       MmePacket->MMENTRY[2],MmePacket->MMENTRY[3],MmePacket->MMENTRY[4],MmePacket->MMENTRY[5],
                       MmePacket->MMENTRY[6],MmePacket->MMENTRY[7]);
                DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n",
                       MmePacket->MMENTRY[8],MmePacket->MMENTRY[9],MmePacket->MMENTRY[10],MmePacket->MMENTRY[11],
                       MmePacket->MMENTRY[12],MmePacket->MMENTRY[13],MmePacket->MMENTRY[14],MmePacket->MMENTRY[15]);

                memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf));
                for(Rtn = 0; Rtn < 17; Rtn++)
                {
                	sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, MmePacket->MMENTRY[16 + Rtn]);
                }
                DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ID: %s\n", tmpBuf);
                                ;
                memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf));
                for(Rtn = 0; Rtn < 17; Rtn++)
                {
                	sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, MmePacket->MMENTRY[33 + Rtn]);
                }
                DEBUG_PRINTF_EVCOMM_DETAIL("RESP_ID: %s\n", tmpBuf);
                DEBUG_PRINTF_EVCOMM_DETAIL("Result: 0x%x\n", MmePacket->MMENTRY[50]);    //Fixed value of 0x00 indicates a successful SLAC process
            }
            #endif

            #if (NEW_SLAC_ARCHITECTURE_SWITCH == ENABLE)
            {
                //Check ODA (Destination Address)
                if (Array_Compare_Identity(CsuMac, MmePacket->ODA, SLAC_EVSE_MAC_LENGTH) == FALSE)
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[SLAC][Rx][CM_ATTEN_CHAR_RSP]wrong ODA: ignore");
                    break;
                }

                EvMac_in = &MmePacket->OSA[0];
                RunID_in = &MmePacket->MMENTRY[8];
                idx = SLAC_DB_Search_EvMac_idx(&SLAC_INFO, EvMac_in);

                //Check Parameters
                if ((MmePacket->MMENTRY[0] != 0) ||   //[TC_SECC_VTB_AttenuationCharacterization_005] applicationType must be 0x00
                    (MmePacket->MMENTRY[1] != 0) ||   //[TC_SECC_VTB_AttenuationCharacterization_006] securityType must be 0x00
                    (SLAC_DB_Search_EvMac_idx(&SLAC_INFO, EvMac_in) < 0) || //[TC_SECC_VTB_AttenuationCharacterization_007] sourceAddress cannot not be all zero
                    (SLAC_DB_Check_EvMac_RunID_Matching(&SLAC_INFO, EvMac_in, RunID_in) == FALSE) ||    //[TC_SECC_VTB_AttenuationCharacterization_008] check for invalid runID
                    (Array_Check_All_Zero(&MmePacket->MMENTRY[16], 17) == FALSE) ||  //[TC_SECC_VTB_AttenuationCharacterization_009] SourceID(17 bytes) must be all zero.
                    (Array_Check_All_Zero(&MmePacket->MMENTRY[33], 17) == FALSE) ||  //[TC_SECC_VTB_AttenuationCharacterization_009] RESP_ID (17 bytes) must be all zero.
                    (MmePacket->MMENTRY[50] != 0)   //Result:  must be 0x00(Success)
                    )
                {
                    EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry++;

                    sprintf((char*)buf_log_evcomm,
                            "[WARNING][SLAC][Rx]CM_ATTEN_CHAR_RSP:invalid para(%d,%d,%d,%d,%d) => %d-th retry",
                            MmePacket->MMENTRY[0],  //applicationType must be 0x00
                            MmePacket->MMENTRY[1],  //securityType must be 0x00
                            SLAC_DB_Search_EvMac_idx(&SLAC_INFO, EvMac_in),
                            SLAC_DB_Check_EvMac_RunID_Matching(&SLAC_INFO, EvMac_in, RunID_in),
                            MmePacket->MMENTRY[50],
                            EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry
                            );
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                    if (EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry <= 2)   //limited to 2 retries
                    {
                        Update_V2G_Flow_Status(CM_MNBC_SOUND_IND);
                        ftime(&SeqStartTime);
                        break;
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR][SLAC][Rx]CM_ATTEN_CHAR_RSP:invalid para => 2-retry fail => End_Process");
                        Update_V2G_Flow_Status(Other_Fault);
                        break;
                    }
                }
                else
                {
                    //The CM_ATTEN_CHAR_IND is legal
                    SLAC_INFO.array[idx].AttenCharRspCnt++;

                    sprintf((char*)buf_log_evcomm,
                            "[SLAC][Rx]CM_ATTEN_CHAR_RSP[%d]:%d-th",
                            (idx + 1),
                            SLAC_INFO.array[idx].AttenCharRspCnt);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                    EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry = 0;
                    Update_V2G_Flow_Status(CM_ATTEN_CHAR_RSP);
                    ftime(&SeqStartTime);
                    break;
                }
            }
            #else
            {
                //Check Parameters
                if ((MmePacket->MMENTRY[0] != 0) ||   //[TC_SECC_VTB_AttenuationCharacterization_005] applicationType must be 0x00
                    (MmePacket->MMENTRY[1] != 0) ||   //[TC_SECC_VTB_AttenuationCharacterization_006] securityType must be 0x00
                    (Array_Compare_Identity(SLAC_INFO.array[0].EvMac, &MmePacket->MMENTRY[2], 6) == TRUE) || //[TC_SECC_VTB_AttenuationCharacterization_007] sourceAddress cannot not be all zero
                    (Array_Compare_Identity(SLAC_INFO.array[0].RunID, &MmePacket->MMENTRY[8], 8) == TRUE)    //[TC_SECC_VTB_AttenuationCharacterization_008] check for invalid runID
                    )
                {
                    EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry++;

                    sprintf((char*)buf_log_evcomm,
                            "[WARNING][SLAC][Rx]CM_ATTEN_CHAR_RSP: invalid parameters(%d-th)",
                            EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                    if (EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry <= 2)   //limited to 2 retries
                    {
                        Update_V2G_Flow_Status(CM_MNBC_SOUND_IND);
                        ftime(&SeqStartTime);
                        break;
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]CM_ATTEN_CHAR_RSP: invalid parameters => End_Process");
                        Update_V2G_Flow_Status(Other_Fault);
                        ftime(&SeqStartTime);
                        break;
                    }
                }
                else
                {
                    EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry = 0;
                    Update_V2G_Flow_Status(CM_ATTEN_CHAR_RSP);
                    ftime(&SeqStartTime);
                    break;
                }
            }
            #endif
		}

	    case MMTYPE_CM_VALIDATE_REQ:   //BCB Toggle
		{
            #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
            {
                DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_VALIDATE_REQ ---\n");
                DEBUG_PRINTF_EVCOMM_DETAIL("Signal Type: 0x%x\n", MmePacket->MMENTRY[0]);    //Fixed value (0x00) to indicate ��PEV S2 toggles on control pilot line��
                DEBUG_PRINTF_EVCOMM_DETAIL("Timer: 0x%x\n", MmePacket->MMENTRY[1]);    //Fixed value In the first VALIDATE Request-Response exchange, the Timer field shall be set to zero.
                DEBUG_PRINTF_EVCOMM_DETAIL("Result: 0x%x\n", MmePacket->MMENTRY[2]);    //Fixed value In the first VALIDATE Request-Response exchange, the Result field shall be set to 0x01 = ��ready��.
            }
            #endif

            #if (NEW_SLAC_ARCHITECTURE_SWITCH == ENABLE)
            {
                counter = 0;

                EvMac_in = &MmePacket->OSA[0];
                idx = SLAC_DB_Search_EvMac_idx(&SLAC_INFO, EvMac_in);

                if (idx >= 0)
                {
                    Update_V2G_Flow_Status(CM_VALIDATE_CNF);
                    SLAC_INFO.array[idx].ValidateReqCnt++;

                    sprintf((char*)buf_log_evcomm,
                            "[SLAC][Rx]CM_VALIDATE_REQ[%d]:%d-th",
                            (idx + 1),
                            SLAC_INFO.array[idx].ValidateReqCnt);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);


                    //[To-Do] Protection


                    memset(&SendMmePacket, 0, sizeof(struct MmeHeader));
                    memcpy(SendMmePacket.ODA, EvMac_in, SLAC_EVMAC_LENGTH);
                    memcpy(SendMmePacket.OSA, CsuMac, 6);
                    SendMmePacket.MTYPE = htons(EtherType_HomePlug);
                    SendMmePacket.MMV = 0x01;
                    SendMmePacket.MMTYPE = MMTYPE_CM_VALIDATE_CNF;
                    SendMmePacket.FMI[0] = SendMmePacket.FMI[1] = 0;
                    SendMmePacketSize = 0;

                    if(counter == 0)
                    {
                        //The First MMTYPE_CM_VALIDATE_REQ because Unicast
                        SendMmePacket.MMENTRY[SendMmePacketSize++] = 0;    //SignalType(0x00): Fixed value to indicate "EV S2 toggles on control pilot line"
                        SendMmePacket.MMENTRY[SendMmePacketSize++] = 0;    //ToggleNum(0x00): Fixed value. In the first VALIDATE Request-Response exchange, the ToggleNum field shall be set to zero.

                        #if (SUPPORT_BCB_TOGGLE_FUNCTION == ENABLE)
                            SendMmePacket.MMENTRY[SendMmePacketSize++] = 1;    //0x01 = Ready
                        #else
                            SendMmePacket.MMENTRY[SendMmePacketSize++] = 4;    //0x04 = Not Required
                        #endif
                    }
                    else
                    {
                        //The Second MMTYPE_CM_VALIDATE_REQ because Broadcast
                        unsigned char PreStatus = 3;
                        unsigned char ToggleNum = 0;
                        ftime(&SeqStartTime);
                        while(1)
                        {
                            if((EVCOMM_SYS_INFO.CpState == 4) && (PreStatus == 3))
                            {
                                ToggleNum++;
                                PreStatus = 4;
                            }
                            else
                            {
                                PreStatus = 3;
                            }

                            ftime(&SeqEndTime);
                            if(DiffTimeb(SeqStartTime, SeqEndTime) >= (SendMmePacket.MMENTRY[1]*100 + 100))
                            {
                                SendMmePacket.MMENTRY[SendMmePacketSize++] = 0;    //Fixed value to indicate "PEV S2 toggles on control pilot line"
                                SendMmePacket.MMENTRY[SendMmePacketSize++] = ToggleNum;

                                #if (SUPPORT_BCB_TOGGLE_FUNCTION == ENABLE)
                                    SendMmePacket.MMENTRY[SendMmePacketSize++] = 2;    //0x02 = Success
                                #else
                                    SendMmePacket.MMENTRY[SendMmePacketSize++] = 4;    //0x04 = Not Required
                                #endif

                                break;
                            }
                        }
                    }
                    SendMmePacketSize += 19;      //the size before MMENTRY
                    Rtn = sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));
                    ftime(&SeqStartTime);
                }
                else
                {
                    //EvMac does not exist.
                    //ignore
                }
                break;
            }
            #else
            {
                counter = 0;

                for(Rtn = 0; Rtn < 6; Rtn++)
                {
                    if(MmePacket->ODA[Rtn] != CsuMac[Rtn])
                    {
                        counter = 1;
                        break;
                    }
                }

                memset(&SendMmePacket, 0, sizeof(struct MmeHeader));
                memcpy(SendMmePacket.ODA, EvMac,6);
                memcpy(SendMmePacket.OSA, CsuMac,6);
                SendMmePacket.MTYPE = htons(EtherType_HomePlug);
                SendMmePacket.MMV = 0x01;
                SendMmePacket.MMTYPE = MMTYPE_CM_VALIDATE_CNF;
                SendMmePacket.FMI[0] = SendMmePacket.FMI[1] = 0;
                SendMmePacketSize = 0;
                if(counter == 0)
                {
                    //The First MMTYPE_CM_VALIDATE_REQ because Unicast
                    SendMmePacket.MMENTRY[SendMmePacketSize++] = 0;    //Fixed value to indicate ��PEV S2 toggles on control pilot line��
                    SendMmePacket.MMENTRY[SendMmePacketSize++] = 0;    //Fixed value In the first VALIDATE Request-Response exchange, the ToggleNum field shall be set to zero.
                    #if (SUPPORT_BCB_TOGGLE_FUNCTION == ENABLE)
                    SendMmePacket.MMENTRY[SendMmePacketSize++] = 1;    //0x01 = Ready
                    #else
                    SendMmePacket.MMENTRY[SendMmePacketSize++] = 4;    //0x04 = Not Required
                    #endif
                }
                else
                {
                    //The Second MMTYPE_CM_VALIDATE_REQ because Broadcast
                    unsigned char PreStatus = 3, ToggleNum = 0;
                    ftime(&SeqStartTime);
                    while(1)
                    {
                        ftime(&SeqEndTime);
                        if((EVCOMM_SYS_INFO.CpState == 4) && (PreStatus == 3))
                        {
                            ToggleNum++;
                            PreStatus = 4;
                        }
                        else
                        {
                            PreStatus = 3;
                        }
                        if(DiffTimeb(SeqStartTime, SeqEndTime) >= (SendMmePacket.MMENTRY[1]*100 + 100))
                        {
                            SendMmePacket.MMENTRY[SendMmePacketSize++] = 0;    //Fixed value to indicate ��PEV S2 toggles on control pilot line��
                            SendMmePacket.MMENTRY[SendMmePacketSize++] = ToggleNum;
                            #if (SUPPORT_BCB_TOGGLE_FUNCTION == ENABLE)
                            SendMmePacket.MMENTRY[SendMmePacketSize++] = 2;    //0x02 = Success
                            #else
                            SendMmePacket.MMENTRY[SendMmePacketSize++] = 4;    //0x04 = Not Required
                            #endif
                            break;
                        }
                    }
                }
                SendMmePacketSize += 19;      //the size before MMENTRY
                Rtn = sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));
                Update_V2G_Flow_Status(CM_VALIDATE_CNF);
                ftime(&SeqStartTime);
                break;
            }
            #endif
		}

	    case MMTYPE_CM_SLAC_MATCH_REQ:
		{
            #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
            {
                DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_SLAC_MATCH_REQ ---\n");
                DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", MmePacket->MMENTRY[0]);
                DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", MmePacket->MMENTRY[1]);
                DEBUG_PRINTF_EVCOMM_DETAIL("MVFLength: 0x%x, 0x%x\n", MmePacket->MMENTRY[2],MmePacket->MMENTRY[3]);    //Fixed value (0x3E) for matching
                DEBUG_PRINTF_EVCOMM_DETAIL("PEV ID: \n");
                for(Rtn=0; Rtn<17; Rtn++)
                {
                    DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",MmePacket->MMENTRY[4+Rtn]);
                }
                DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                DEBUG_PRINTF_EVCOMM_DETAIL("PEV MAC: \n");
                for(Rtn=0; Rtn<6; Rtn++)
                {
                    DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",MmePacket->MMENTRY[21+Rtn]);
                }
                DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                DEBUG_PRINTF_EVCOMM_DETAIL("EVSE ID: \n");
                for(Rtn=0; Rtn<17; Rtn++)
                {
                    DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",MmePacket->MMENTRY[27+Rtn]);
                }
                DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                DEBUG_PRINTF_EVCOMM_DETAIL("EVSE MAC: \n");
                for(Rtn=0; Rtn<6; Rtn++)
                {
                    DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",MmePacket->MMENTRY[44+Rtn]);
                }
                DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                DEBUG_PRINTF_EVCOMM_DETAIL("RunID: \n");
                for(Rtn=0; Rtn<8; Rtn++)
                {
                    DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",MmePacket->MMENTRY[50+Rtn]);
                }
                DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                DEBUG_PRINTF_EVCOMM_DETAIL("RSVD: \n");
                for(Rtn=0; Rtn<8; Rtn++)
                {
                    DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",MmePacket->MMENTRY[58+Rtn]);
                }
                DEBUG_PRINTF_EVCOMM_DETAIL("\n");
            }
            #endif

            #if (NEW_SLAC_ARCHITECTURE_SWITCH == ENABLE)
            {
                //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[SLAC][Rx]CM_SLAC_MATCH_REQ");

                //Check ODA (Destination Address)
                if (Array_Compare_Identity(CsuMac, MmePacket->ODA, SLAC_EVSE_MAC_LENGTH) == FALSE)
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[SLAC][Rx][CM_SLAC_MATCH_REQ]wrong ODA: ignore");
                    //break; //patch for DEKRA I2SE EVCC (another EVSE MAC Address protection comes as below.)
                }

                EvMac_in = &MmePacket->OSA[0];
                RunID_in = &MmePacket->MMENTRY[50];
                idx = SLAC_DB_Search_EvMac_idx(&SLAC_INFO, EvMac_in);

                if (idx >= 0)
                {
                    Update_V2G_Flow_Status(CM_SLAC_MATCH_REQ);

                    SLAC_INFO.array[idx].MatchReqNum++;

                    sprintf((char*)buf_log_evcomm,
                            "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]:%d-th",
                            (idx + 1),
                            SLAC_INFO.array[idx].MatchReqNum);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                    //[TC_SECC_VTB_CmSlacMatch_007] APPLICATION_TYPE must be 0x00(EV-EVSE Matching)
                    //[TC_SECC_VTB_CmSlacMatch_008]
                    if (MmePacket->MMENTRY[0] != 0)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]:wrong APPLICATION_TYPE(%d)",
                                (idx + 1),
                                MmePacket->MMENTRY[0]);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        break;
                    }

                    //[TC_SECC_VTB_CmSlacMatch_009] SECURITY_TYPE must be 0x00(No Security)
                    //[TC_SECC_VTB_CmSlacMatch_010]
                    if (MmePacket->MMENTRY[1] != 0)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]:wrong SECURITY_TYPE(%d)",
                                (idx + 1),
                                MmePacket->MMENTRY[1]);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        break;
                    }

                    //[TC_SECC_VTB_CmSlacMatch_011] MVFLength must be 0x3E(MatchVarField Length)
                    //[TC_SECC_VTB_CmSlacMatch_012]
                    if (MmePacket->MMENTRY[2] != 0x3E || MmePacket->MMENTRY[3] != 0x00)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]:wrong MVFLength(%d,%d)",
                                (idx + 1),
                                MmePacket->MMENTRY[2],
                                MmePacket->MMENTRY[3]);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        break;
                    }

                    //[TC_SECC_VTB_CmSlacMatch_013] EV ID (muxt be all zero)
                    //[TC_SECC_VTB_CmSlacMatch_014]
                    if (Array_Check_All_Zero(&MmePacket->MMENTRY[4], 17) == FALSE)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]: wrong EV ID",
                                (idx + 1));
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        break;
                    }

                    //[TC_SECC_VTB_CmSlacMatch_015] EV MAC
                    //[TC_SECC_VTB_CmSlacMatch_016]
                    if (Array_Compare_Identity(EvMac_in, &MmePacket->MMENTRY[21], SLAC_EVMAC_LENGTH) == FALSE)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]: wrong EV MAC(%02X:%02X:%02X:%02X:%02X:%02X)",
                                (idx + 1),
                                MmePacket->MMENTRY[21], MmePacket->MMENTRY[22], MmePacket->MMENTRY[23],
                                MmePacket->MMENTRY[24], MmePacket->MMENTRY[25], MmePacket->MMENTRY[26]);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        break;
                    }

                    //[TC_SECC_VTB_CmSlacMatch_017] EVSE ID should be all zero
                    //[TC_SECC_VTB_CmSlacMatch_018]
                    if (Array_Check_All_Zero(&MmePacket->MMENTRY[27], 17) == FALSE)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]: wrong EVSE ID",
                                (idx + 1));
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        break;
                    }

                    //[TC_SECC_VTB_CmSlacMatch_019] EVSE MAC
                    //[TC_SECC_VTB_CmSlacMatch_020]
                    if (Array_Compare_Identity(CsuMac, &MmePacket->MMENTRY[44], SLAC_EVSE_MAC_LENGTH) == FALSE)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]: wrong EVSE MAC(%02X:%02X:%02X:%02X:%02X:%02X)",
                                (idx + 1),
                                MmePacket->MMENTRY[44], MmePacket->MMENTRY[45], MmePacket->MMENTRY[46],
                                MmePacket->MMENTRY[47], MmePacket->MMENTRY[48], MmePacket->MMENTRY[49]);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        break;
                    }

                    //[TC_SECC_VTB_CmSlacMatch_021]runID: Check RunID
                    //[TC_SECC_VTB_CmSlacMatch_022]
                    if (SLAC_DB_Check_EvMac_RunID_Matching(&SLAC_INFO, EvMac_in, RunID_in) == TRUE &&
                       (idx == 0)) //only setup a successful link establishment with the first SLAC Req instance
                    {
                        memset(&SendMmePacket, 0, sizeof(struct MmeHeader));
            	        memcpy(SendMmePacket.ODA, MmePacket->OSA, 6);
            	        memcpy(SendMmePacket.OSA, CsuMac, 6);
            	        SendMmePacket.MTYPE = htons(EtherType_HomePlug);
            	        SendMmePacket.MMV = MmePacket->MMV;
            	        SendMmePacket.MMTYPE = MMTYPE_CM_SLAC_MATCH_CNF;
            	        SendMmePacket.FMI[0] = SendMmePacket.FMI[1] = 0;
            	        SendMmePacketSize = 0;
            	        SendMmePacket.MMENTRY[SendMmePacketSize++] = 0x00;    //APPLICATION_TYPE: Fixed value (0x00: EV-EVSE matching)
            	        SendMmePacket.MMENTRY[SendMmePacketSize++] = 0x00;    //SECURITY_TYPE: Fixed value (0x00: No Security)
            	        SendMmePacket.MMENTRY[SendMmePacketSize++] = 0x56;    //MVFLength: MatchVarField Length (Fixed value: 0x0056)
            	        SendMmePacket.MMENTRY[SendMmePacketSize++] = 0x00;    //MVFLength: MatchVarField Length (Fixed value: 0x0056)
            	        memset(SendMmePacket.MMENTRY + SendMmePacketSize, 0, 17);         //EV ID
            	        SendMmePacketSize += 17;
            	        memcpy(SendMmePacket.MMENTRY + SendMmePacketSize, EvMac_in, SLAC_EVMAC_LENGTH); //EV MAC
            	        SendMmePacketSize += 6;
            	        memset(SendMmePacket.MMENTRY + SendMmePacketSize, 0, 17);         //EVSE ID
            	        SendMmePacketSize += 17;
            	        memcpy(SendMmePacket.MMENTRY + SendMmePacketSize, CsuMac, 6);     //EVSE MAC
            	        SendMmePacketSize += 6;
            	        memcpy(SendMmePacket.MMENTRY + SendMmePacketSize, RunID_in, SLAC_RUNID_LENGTH);
            	        SendMmePacketSize += SLAC_RUNID_LENGTH;
            	        memset(SendMmePacket.MMENTRY + SendMmePacketSize, 0, 8);    //RSVD
            	        SendMmePacketSize += 8;
            	        memcpy(SendMmePacket.MMENTRY + SendMmePacketSize, Nid, sizeof(Nid));   //NID: Network ID given by the CCo(EVSE)
            	        SendMmePacketSize += sizeof(Nid);                                      //NID caculated from the random NMK that will be set.
            	        SendMmePacket.MMENTRY[SendMmePacketSize++] = 0x00;          //RSVD
            	        memcpy(SendMmePacket.MMENTRY + SendMmePacketSize, NewNmkKey, sizeof(NewNmkKey)); //NMK: Random value
            	        SendMmePacketSize += sizeof(NewNmkKey);                                          //NMK: Private NMK of the EVSE (random value)
            	        SendMmePacketSize += 19;      //the size before MMENTRY

                        #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
                        {
                            DEBUG_PRINTF_EVCOMM_DETAIL("\n\n***** Response MME Packet *****\n");
                            DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                                   SendMmePacket.ODA[0],SendMmePacket.ODA[1],SendMmePacket.ODA[2],SendMmePacket.ODA[3],SendMmePacket.ODA[4],SendMmePacket.ODA[5]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                                   SendMmePacket.OSA[0],SendMmePacket.OSA[1],SendMmePacket.OSA[2],SendMmePacket.OSA[3],SendMmePacket.OSA[4],SendMmePacket.OSA[5]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("MTYPE: 0x%x\n", htons(SendMmePacket.MTYPE));
                            DEBUG_PRINTF_EVCOMM_DETAIL("MMV: 0x%x\n", SendMmePacket.MMV);
                            DEBUG_PRINTF_EVCOMM_DETAIL("MMTYPE: 0x%x\n", SendMmePacket.MMTYPE);
                            DEBUG_PRINTF_EVCOMM_DETAIL("FMI 0x%x, 0x%x\n", SendMmePacket.FMI[0],SendMmePacket.FMI[1]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("--- CM_SLAC_MATCH_CNF ---\n");
                            DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", SendMmePacket.MMENTRY[0]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", SendMmePacket.MMENTRY[1]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("MVFLength: 0x%x, 0x%x\n", SendMmePacket.MMENTRY[2],SendMmePacket.MMENTRY[3]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("PEV ID: \n");
                            for(Rtn=0; Rtn<17; Rtn++)
                            {
                                DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[4+Rtn]);
                            }
                            DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                            DEBUG_PRINTF_EVCOMM_DETAIL("PEV MAC: \n");
                            for(Rtn=0; Rtn<6; Rtn++)
                            {
                                DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[21+Rtn]);
                            }
                            DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                            DEBUG_PRINTF_EVCOMM_DETAIL("EVSE ID: \n");
                            for(Rtn=0; Rtn<17; Rtn++)
                            {
                                DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[27+Rtn]);
                            }
                            DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                            DEBUG_PRINTF_EVCOMM_DETAIL("EVSE MAC: \n");
                            for(Rtn=0; Rtn<6; Rtn++)
                            {
                                DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[44+Rtn]);
                            }
                            DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                            DEBUG_PRINTF_EVCOMM_DETAIL("RunID: \n");
                            for(Rtn=0; Rtn<8; Rtn++)
                            {
                                DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[50+Rtn]);
                            }
                            DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                            DEBUG_PRINTF_EVCOMM_DETAIL("RSVD: \n");
                            for(Rtn=0; Rtn<8; Rtn++)
                            {
                                DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[58+Rtn]);
                            }
                            DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                            DEBUG_PRINTF_EVCOMM_DETAIL("NID: \n");
                            for(Rtn=0; Rtn<7; Rtn++)
                            {
                                DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[66+Rtn]);
                            }
                            DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                            DEBUG_PRINTF_EVCOMM_DETAIL("RSVD: 0x%x\n", SendMmePacket.MMENTRY[73]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("NMK: \n");
                            for(Rtn=0; Rtn<16; Rtn++)
                            {
                                DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[74+Rtn]);
                            }
                            DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                        }
                        #endif

                        Update_V2G_Flow_Status(CM_SLAC_MATCH_CNF);
            	        Rtn = sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));


            	        DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacketSize=%d,Rtn=%d\n",SendMmePacketSize,Rtn);
                        sprintf((char*)buf_log_evcomm,
                                "[SLAC][Tx]CM_SLAC_MATCH_CNF[%d]",
                                (idx + 1));
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                        ftime(&SeqStartTime);
                    }
                    else
                    {
                        //RunID does not match and it's not the first SLAC request
                        //Reset the SLAC database to embrace SLAC retry
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[CM_SLAC_MATCH_REQ]No Real MATCH_REQ");
                        SLAC_DB_Reset();
                    }
                }
                else
                {
                    //OSA(EvMac) does not exist
                }
                break;
            }
            #else
            {
                Update_V2G_Flow_Status(CM_SLAC_MATCH_REQ);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[SLAC][Rx]CM_SLAC_MATCH_REQ");

                memset(&SendMmePacket,0,sizeof(struct MmeHeader));
                memcpy(SendMmePacket.ODA,MmePacket->OSA,6);
                memcpy(SendMmePacket.OSA,CsuMac,6);
                SendMmePacket.MTYPE=htons(EtherType_HomePlug);
                SendMmePacket.MMV=MmePacket->MMV;
                SendMmePacket.MMTYPE=MMTYPE_CM_SLAC_MATCH_CNF;
                SendMmePacket.FMI[0]=SendMmePacket.FMI[1]=0;
                SendMmePacketSize=0;
                SendMmePacket.MMENTRY[SendMmePacketSize++]=0x00;    //Fixed value (0x00) indicating ��PEV-EVSE matching��
                SendMmePacket.MMENTRY[SendMmePacketSize++]=0x00;    //Fixed value (0x00) indicating ��No Security��
                SendMmePacket.MMENTRY[SendMmePacketSize++]=0x56;    //Fixed value (0x0056) for matching
                SendMmePacket.MMENTRY[SendMmePacketSize++]=0x00;    //Fixed value (0x0056) for matching
                memset(SendMmePacket.MMENTRY+SendMmePacketSize,0,17);    //PEV ID
                SendMmePacketSize+=17;
                memcpy(SendMmePacket.MMENTRY+SendMmePacketSize,EvMac,6);
                SendMmePacketSize+=6;
                memset(SendMmePacket.MMENTRY+SendMmePacketSize,0,17);    //EVSE ID
                SendMmePacketSize+=17;
                memcpy(SendMmePacket.MMENTRY+SendMmePacketSize,CsuMac,6);
                SendMmePacketSize+=6;
                memcpy(SendMmePacket.MMENTRY+SendMmePacketSize,SlacRunId,sizeof(SlacRunId));
                SendMmePacketSize+=sizeof(SlacRunId);
                memset(SendMmePacket.MMENTRY+SendMmePacketSize,0,8);    //RSVD
                SendMmePacketSize+=8;
                memcpy(SendMmePacket.MMENTRY+SendMmePacketSize,Nid,sizeof(Nid));
                SendMmePacketSize+=sizeof(Nid);
                SendMmePacket.MMENTRY[SendMmePacketSize++]=0x00;    //RSVD
                memcpy(SendMmePacket.MMENTRY+SendMmePacketSize,NewNmkKey,sizeof(NewNmkKey));
                SendMmePacketSize+=sizeof(NewNmkKey);
                SendMmePacketSize+=19;      //the size before MMENTRY

                #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
                    DEBUG_PRINTF_EVCOMM_DETAIL("\n\n***** Response MME Packet *****\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                           SendMmePacket.ODA[0],SendMmePacket.ODA[1],SendMmePacket.ODA[2],SendMmePacket.ODA[3],SendMmePacket.ODA[4],SendMmePacket.ODA[5]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                           SendMmePacket.OSA[0],SendMmePacket.OSA[1],SendMmePacket.OSA[2],SendMmePacket.OSA[3],SendMmePacket.OSA[4],SendMmePacket.OSA[5]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("MTYPE: 0x%x\n", htons(SendMmePacket.MTYPE));
                    DEBUG_PRINTF_EVCOMM_DETAIL("MMV: 0x%x\n", SendMmePacket.MMV);
                    DEBUG_PRINTF_EVCOMM_DETAIL("MMTYPE: 0x%x\n", SendMmePacket.MMTYPE);
                    DEBUG_PRINTF_EVCOMM_DETAIL("FMI 0x%x, 0x%x\n", SendMmePacket.FMI[0],SendMmePacket.FMI[1]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("--- CM_SLAC_MATCH_CNF ---\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", SendMmePacket.MMENTRY[0]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", SendMmePacket.MMENTRY[1]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("MVFLength: 0x%x, 0x%x\n", SendMmePacket.MMENTRY[2],SendMmePacket.MMENTRY[3]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("PEV ID: \n");
                    for(Rtn=0; Rtn<17; Rtn++)
                    {
                        DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[4+Rtn]);
                    }
                    DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("PEV MAC: \n");
                    for(Rtn=0; Rtn<6; Rtn++)
                    {
                        DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[21+Rtn]);
                    }
                    DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("EVSE ID: \n");
                    for(Rtn=0; Rtn<17; Rtn++)
                    {
                        DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[27+Rtn]);
                    }
                    DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("EVSE MAC: \n");
                    for(Rtn=0; Rtn<6; Rtn++)
                    {
                        DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[44+Rtn]);
                    }
                    DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("RunID: \n");
                    for(Rtn=0; Rtn<8; Rtn++)
                    {
                        DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[50+Rtn]);
                    }
                    DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("RSVD: \n");
                    for(Rtn=0; Rtn<8; Rtn++)
                    {
                        DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[58+Rtn]);
                    }
                    DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("NID: \n");
                    for(Rtn=0; Rtn<7; Rtn++)
                    {
                        DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[66+Rtn]);
                    }
                    DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                    DEBUG_PRINTF_EVCOMM_DETAIL("RSVD: 0x%x\n", SendMmePacket.MMENTRY[73]);
                    DEBUG_PRINTF_EVCOMM_DETAIL("NMK: \n");
                    for(Rtn=0; Rtn<16; Rtn++)
                    {
                        DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[74+Rtn]);
                    }
                    DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                #endif

                Update_V2G_Flow_Status(CM_SLAC_MATCH_CNF);
                Rtn = sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));


                DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacketSize=%d,Rtn=%d\n",SendMmePacketSize,Rtn);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[SLAC][Tx]CM_SLAC_MATCH_CNF");

                ftime(&SeqStartTime);
                break;
            }
            #endif
		}

	    case MMTYPE_VENDOR_VS_HOST_ACTION:
	    {
	        struct QcaVendorMmeHeader *RecvPacket;
	        RecvPacket = (struct QcaVendorMmeHeader *)Buffer;

	        DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_VENDOR_VS_HOST_ACTION ---\n");

	        switch (RecvPacket->MBODY[0])
	        {
		        case 0x00:
		            //Loader (Device Softloader or Bootloader) ready
		            DEBUG_PRINTF_EVCOMM_DETAIL("QCA7K: Loader Ready\n");
		            break;

		        case 0x01:
		            //Firmware Upgrade Ready
		            DEBUG_PRINTF_EVCOMM_DETAIL("QCA7K: Firmware Upgrade Ready\n");
		            break;

		        case 0x02:
		            //PIB Update Ready
		            DEBUG_PRINTF_EVCOMM_DETAIL("QCA7K: PIB Update Ready\n");
		            break;

		        case 0x03:
		            //Firmware Upgrade and PIB Update ready
		            DEBUG_PRINTF_EVCOMM_DETAIL("QCA7K: Firmware Upgrade and PIB Update ready\n");
		            break;

		        case 0x04:
		            //Loader (Bootloader) ready to receive SDRAM configuration.
		            DEBUG_PRINTF_EVCOMM_DETAIL("QCA7K: Loader ready to receive SDRAM configuration\n");
		            break;

		        case 0x05:
		            //Reset to Factory Defaults.
		            DEBUG_PRINTF_EVCOMM_DETAIL("QCA7K: Reset to Factory Defaults\n");
		            break;

		        default:
		            //Reserved
		            DEBUG_PRINTF_EVCOMM_DETAIL("QCA7K: Reserved\n");
		            break;
	        }
			break;
	    }

	    case MMTYPE_VENDOR_ATTEN_CHAR:
		{
	        DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_VENDOR_ATTEN_CHAR ---\n");
	        break;
		}

	    case MMTYPE_VENDOR_VS_NW_INFO_CNF:
		{
            memcpy(QcaMac, MmePacket->OSA, 6);

            sprintf((char*)buf_log_evcomm,
                    "[QCA7K][Rx][VENDOR_VS_NW_INFO_CNF]Got QCA7K MacAddr:%02X:%02X:%02X:%02X:%02X:%02X (comm:OK)",
                     QcaMac[0],  QcaMac[1],  QcaMac[2],  QcaMac[3],  QcaMac[4],  QcaMac[5]);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

	        DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_VENDOR_VS_NW_INFO_CNF ---\n");
	        DEBUG_PRINTF_EVCOMM_DETAIL("QcaMac: %02x:%02x:%02x:%02x:%02x:%02x\n",
	                QcaMac[0],
                    QcaMac[1],
                    QcaMac[2],
                    QcaMac[3],
                    QcaMac[4],
                    QcaMac[5]);

	        Update_V2G_Flow_Status(CM_SET_KEY_REQ);
            ftime(&SeqStartTime);
            break;
		}

	    case MMTYPE_VENDOR_VS_PL_LNK_STATUS_CNF:
		{
			struct QcaVendorMmeHeader *RecvPacket;
			RecvPacket = (struct QcaVendorMmeHeader *)Buffer;

			if(RecvPacket->MBODY[1]==0)
			{
				//PLC disconnected
				sprintf((char*)buf_log_evcomm,
					"[QCA7K][Rx][MMTYPE_VENDOR_VS_PL_LNK_STATUS_CNF]Got PLC Link Status:%d",
					RecvPacket->MBODY[1]);
				SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
				Update_V2G_Flow_Status(Other_Fault);
			}
			else
				Update_V2G_Flow_Status(CM_SET_KEY_REQ);
		ftime(&SeqStartTime);
			break;
		}

	    default:
		{
	        break;
		}
    }

    return 0;
}


/*===========================================================================
FUNCTION: SlacComm
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int SlacComm()
{
    static unsigned char qca7k_comm_retry = 0;
    double t_diff = 0;
    int packet_size = 0;
    int count = 0;
    //int idx = 0;
#if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
    unsigned char tmpBuf[2048]={0};
#endif

#if (NEW_SLAC_ARCHITECTURE_SWITCH == ENABLE)
    unsigned char *EvMac_in;
    unsigned char *RunID_in;
    int i = 0;
#endif
    if(RawSock >= 0)
    {
        memset(V2gtpMsgRxBuf, 0, V2GTP_MSG_RX_BUFFER_SIZE);
        packet_size = recvfrom(RawSock, V2gtpMsgRxBuf, V2GTP_MSG_RX_BUFFER_SIZE, 0, NULL, NULL);
        if(packet_size > 0)
        {
            /*#ifdef Debug
               DEBUG_PRINTF_EVCOMM_DETAIL("Raw Data: ");
               for(count=0;count<packet_size;count++)
                DEBUG_PRINTF_EVCOMM_DETAIL("0x%x, ",V2gtpMsgRxBuf[count]);
               DEBUG_PRINTF_EVCOMM_DETAIL("\n");
             #endif*/
            MmeProcess(V2gtpMsgRxBuf, packet_size);
        }
    }

    switch(Check_V2G_Flow_Status())
    {
	    case IDLE:
		{
	        if(RawSock < 0)
	        {
	            RawSock = socket(PF_PACKET, SOCK_RAW, htons(EtherType_HomePlug));

	            sprintf((char*)buf_log_evcomm, "[RawSock]opened(%d)", RawSock);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

	            if(RawSock == -1)
	            {
	                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "SlacComm:Failed to create socket");
	                Update_V2G_Flow_Status(Other_Fault);
	                return -1;
	            }

	            if (setsockopt(RawSock, SOL_SOCKET, SO_BINDTODEVICE, QcaInterface, 4) < 0)
	            {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "SlacComm:Set SO_BINDTODEVICE NG");
                    Update_V2G_Flow_Status(Other_Fault);
                    return -1;
                }

                struct timeval tv;
	            tv.tv_sec = 0;
		        tv.tv_usec = 100000;  //100ms (Rx timeout)
	            if (setsockopt(RawSock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct	timeval)) < 0)
	            {
	                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "SlacComm:Set SO_RCVTIMEO NG");
	                Update_V2G_Flow_Status(Other_Fault);
	                return -1;
	            }

                tv.tv_usec = 100000;  //100ms (Tx timeout)
                if (setsockopt(RawSock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(struct	timeval)) < 0)
	            {
	                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "SlacComm:Set SO_SNDTIMEO NG");
	                Update_V2G_Flow_Status(Other_Fault);
	                return -1;
	            }

	            memset(&Req, 0, sizeof(struct ifreq));
	            strcpy( (char*)Req.ifr_name, QcaInterface);

	            if (ioctl(RawSock, SIOCGIFINDEX, &Req) < 0)
	            {
	                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "SlacComm: ioctl NG");
	                Update_V2G_Flow_Status(Other_Fault);
	                return -1;
	            }

	            memset( &DestSocketAddress, 0, sizeof(struct sockaddr_ll));
	            DestSocketAddress.sll_ifindex = Req.ifr_ifindex;
	            DestSocketAddress.sll_halen = ETH_ALEN;

                PwmStartTime = 0;

                EVCOMM_SYS_INFO.QCA7K_SetKeyDone = FALSE;
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[QCA7K]connecting...");
                //Get QCA7K MAC address
                GetQca7kMac();
                ftime(&SeqStartTime);
                break;
	        }
	        else   //RawSock: opened
	        {
                if(EVCOMM_SYS_INFO.QCA7K_SetKeyDone == FALSE)
                {
                    ftime(&SeqEndTime);
                    t_diff = DiffTimeb(SeqStartTime, SeqEndTime);

                    if (t_diff > V2G_SECC_QCA7000_GET_MAC_ADDR_REQ_RETRY_PERIOD)   //3 secs
                    {
                        qca7k_comm_retry++;
                        sprintf((char*)buf_log_evcomm,
                                "Re-try connecting...(%.02lf/%dms)",
                                t_diff,
                                V2G_SECC_QCA7000_GET_MAC_ADDR_REQ_RETRY_PERIOD);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                        GetQca7kMac(); //re-send req
                        ftime(&SeqStartTime);
                        break;
                    }
                    else
                    {
                        //null
                    }

                    //Retry by 3 times
                    if (qca7k_comm_retry >= 3)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[Error]Comm: fail (retry by %d times)",
                                qca7k_comm_retry);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                        //Update_ShmStatusCode(); //[To-Do] to be implemented
                        //CCS_SECCC_TIMEOUT_QCA7000_COMM (023892): The firmware code of QCA7000 may not be installed, yet
                        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                        ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                        ShmStatusCodeData->PresentStatusCode[0][4] = 9;
                        ShmStatusCodeData->PresentStatusCode[0][5] = 2;
                        CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE;
                        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
                        Proc_EVStopRes(ShmInternalComm->FD_CAN_Socket);

                        Update_V2G_Flow_Status(Sequence_Timeout);
                        qca7k_comm_retry = 0;
                        break;
                    }
                }
                else    //RawSock: opened; Set Key: DONE
                {
                	/*+++ 20200808, vern, sync with Tesla CHAdeMO adaptor, 2 for start communication(not yet auth), 1 for star charging (authorized)  ---*/
                    if((CheckConnectorPlugIn() == TRUE) && (ShmInternalComm->ChargingPermission >= 1))
                    {
                        if(PwmStartTime <= 0)
                        {
                            //Sniffer_Tcpdump(ENABLE);
                            //#if (TCPDUMP_PACKETS_SNIFFER_SWITCH == ENABLE)
                            //sleep(1);   //wait for tcpdump to be ready.
                            //#endif
                            SwitchCpStateE(DISABLE);
                            OutputCpPwmDuty(5);
                            PwmStartTime = time(NULL);
                        }
                        else
                        {
                            if((time(NULL) - PwmStartTime) > TT_EVSE_SLAC_init)
                            {
                                sprintf((char*)buf_log_evcomm,
                                        "SlacComm: Wait CM_SLAC_PARM_REQ Timeout - TT_EVSE_SLAC_init, NowTime(%ld)-PwmStartTime(%d)>%d (sec)",
                                        time(NULL),
                                        PwmStartTime,
                                        TT_EVSE_SLAC_init);
                                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                                //Update_ShmStatusCode(); //[To-Do] to be implemented
                                //CCS_SECC_TIMEOUT_SLAC_TT_EVSE_SLAC_init (023809)
                                ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                                ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                                ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                                ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                                ShmStatusCodeData->PresentStatusCode[0][4] = 0;
                                ShmStatusCodeData->PresentStatusCode[0][5] = 9;
                                CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;
                                Update_V2G_Flow_Status(Sequence_Timeout);
                                PwmStartTime = 0;
                                return -1;
                            }
                            else
                            {
                                //waiting for CM_SLAC_PARM_REQ
                            }
                        }
                    }
                    else
                    {
                        PwmStartTime = 0;
                    }
                }
	        }
	        break;
		}

	    case CM_SET_KEY_REQ:   //13
		{
	        //CM_SET_KEY_REQ
            //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[QCA7K][Rx]CM_SET_KEY_REQ");
            ftime(&SeqEndTime);
            t_diff = DiffTimeb(SeqStartTime, SeqEndTime);
            if (t_diff > V2G_SECC_QCA7000_COMM_TIMEOUT)   //10 seconds
            {
                sprintf((char*)buf_log_evcomm,
                        "[QCA7K]Failed on SetKey => End_Process (%.02lf/%dms)",
                        t_diff,
                        V2G_SECC_QCA7000_COMM_TIMEOUT);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                //Update_ShmStatusCode(); //[To-Do] to be implemented
                //CCS_SECCC_TIMEOUT_QCA7000_COMM (023892): The firmware code of QCA7000 may not be installed, yet
                ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                ShmStatusCodeData->PresentStatusCode[0][4] = 9;
                ShmStatusCodeData->PresentStatusCode[0][5] = 2;
                CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE;
                CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;

                Update_V2G_Flow_Status(Sequence_Timeout);
            }
            else if (t_diff > V2G_SECC_QCA7000_SEND_SET_KEY_PERIOD)  //2 seconds
            {
                sprintf((char*)buf_log_evcomm,
                        "[QCA7K]SetKey: proceed (%.02lf/%dms)",
                        t_diff,
                        V2G_SECC_QCA7000_SEND_SET_KEY_PERIOD);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                SendSetKey();
                ftime(&SeqStartTime);
            }
            else
            {
                //null
            }
	        break;
		}

	    case CM_SET_KEY_CNF:   //14
		{
            sprintf((char*)buf_log_evcomm,
                    "[SECCReady]Wait: plugin(%d), matached(%d), permission(%d)...",
                    CheckConnectorPlugIn(),
                    CSUCOMMDC_TASK_FLAG.matched,
                    ShmInternalComm->ChargingPermission
                    );
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

            EVCOMM_SYS_INFO.QCA7K_SetKeyDone = TRUE;
            PwmStartTime = 0;
            Update_V2G_Flow_Status(IDLE);
	        break;
		}

	    case CM_SLAC_PARM_CONF:
		{
	        ftime(&SeqEndTime);
	        if(DiffTimeb(SeqStartTime, SeqEndTime) > TT_match_sequence)
	        {
	            sprintf((char*)buf_log_evcomm,
                        "SlacComm: Wait CM_START_ATTEN_CHAR_IND Timeout - TT_match_sequence (%.02lf of %dms)",
                        DiffTimeb(SeqStartTime, SeqEndTime),
                        TT_match_sequence);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                //Update_ShmStatusCode(); //[To-Do] to be implemented
                //CCS_SECC_TIMEOUT_CM_START_ATTEN_CHAR_IND (023811):
                //[Possible Reason] CCS Board image might not be updated properly. The 2nd reboot process is not finished.
                //[Verification Method] By tying reboot command to the terminal and see if it could be executed immediately.
                ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                ShmStatusCodeData->PresentStatusCode[0][4] = 1;
                ShmStatusCodeData->PresentStatusCode[0][5] = 1;
                CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE;
                CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;

	            Update_V2G_Flow_Status(Sequence_Timeout);
	            return -1;
	        }
	        break;
		}

	    case CM_START_ATTEN_CHAR_IND:
		{
	        ftime(&SeqEndTime);
	        if(DiffTimeb(SeqStartTime, SeqEndTime) > (TP_EV_batch_msg_interval))    //one more time interval for tolerance
	        {
	            sprintf((char*)buf_log_evcomm,
                        "SlacComm: Wait CM_MNBC_SOUND_IND Timeout - TP_EV_batch_msg_interval (%.02lf of %dms)",
                        DiffTimeb(SeqStartTime, SeqEndTime),
                        TP_EV_batch_msg_interval);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                //Update_ShmStatusCode(); //[To-Do] to be implemented
                //CCS_SECC_TIMEOUT_SLAC_CM_MNBC_SOUND_IND (023818):
                //[Possible Reason] CCS Board image might not be updated properly. The 2nd reboot process is not finished.
                //[Verification Method] By tying reboot command to the terminal and see if it could be executed immediately.
                ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                ShmStatusCodeData->PresentStatusCode[0][4] = 1;
                ShmStatusCodeData->PresentStatusCode[0][5] = 8;
                CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE;
                CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;

	            Update_V2G_Flow_Status(Sequence_Timeout);
	            return -1;
	        }
	        break;
		}

	    case CM_MNBC_SOUND_IND:
		{
            #if (NEW_SLAC_ARCHITECTURE_SWITCH == ENABLE)
            {
                ftime(&SeqEndTime);
                t_diff = DiffTimeb(SeqStartTime, SeqEndTime);
                //printf("time:%.02lf, profilNum:%d\n",DiffTimeb(SeqStartTime, SeqEndTime),AttenProfileCnt);  //added by Vern
    	        if(t_diff > TT_EVSE_match_MNBC ||
                  (SLAC_INFO.array[0].AttenProfileCnt >= SLAC_INFO.array[0].MnbcSoundNum) ||
                  (EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry > 0)) //TC_SECC_VTB_AttenuationCharacterization_003
                {
                    //Wait for other SLAC Req sets
                    if ((SLAC_INFO.arrayLen >= 2) &&
                        (t_diff < TT_EVSE_match_MNBC) &&
                        (EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry == 0)) //not a retry
                    {
                        break;
                    }

                    //Check if it is a timeup response
                    if (t_diff > TT_EVSE_match_MNBC)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[WARNING][SLAC][Tx]CM_ATTEN_CHAR_IND[%d]: timeup(%.2f/%dms) => send",
                                (i + 1),
                                t_diff,
                                TT_EVSE_match_MNBC);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    }

                    //Sending all CM_ATTEN_CHAR_IND according to all corresponding SLAC Req sets
                    for (i = 0; i < SLAC_INFO.arrayLen; i++)
                    {
                        if ((SLAC_INFO.array[i].AttenProfileCnt == 0) ||
                            (SLAC_INFO.array[i].AagGroupsNum == 0) ||
                            (SLAC_INFO.array[i].StartAttenCharCnt == 0) ||
                            (SLAC_INFO.array[i].MnbcSoundNum != 10) || //received in CM_START_ATTEN_CHAR_IND
                            (SLAC_INFO.array[i].StartAttenCharErr == TRUE)
                           )
                        {
                            //Ignoring those SLAC request sets without sending CM_MNBC_SOUND_IND(CM_ATTEN_PROFILE_IND)
                            sprintf((char*)buf_log_evcomm,
                                    "[WARNING][SLAC][Tx]CM_ATTEN_CHAR_IND[%d]: para err(%d,%d,%d,%d,%d) => canceled",
                                    (i + 1),
                                    SLAC_INFO.array[i].AttenProfileCnt,
                                    SLAC_INFO.array[i].AagGroupsNum,
                                    SLAC_INFO.array[i].StartAttenCharCnt,
                                    SLAC_INFO.array[i].MnbcSoundNum,
                                    SLAC_INFO.array[i].StartAttenCharErr);
                            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                            continue;
                        }

                        //In CM_ATTEN_CHAR_IND retry process, here only re-send this message according to the 1st coming SLAC request
                        if ((EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry > 0) && (i != 0))
                        {
                            sprintf((char*)buf_log_evcomm,
                                    "[NOTE][SLAC][Tx]CM_ATTEN_CHAR_IND[%d]: canceled",
                                    (i + 1));
                            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                            break;
                        }

                        EvMac_in = SLAC_INFO.array[i].EvMac;
                        RunID_in = SLAC_INFO.array[i].RunID;

                        memset(&SendMmePacket, 0, sizeof(struct MmeHeader));
                        memcpy(SendMmePacket.ODA, EvMac_in, SLAC_EVMAC_LENGTH);
                        memcpy(SendMmePacket.OSA, CsuMac, 6);
                        SendMmePacket.MTYPE = htons(EtherType_HomePlug);
                        SendMmePacket.MMV = 0x01;
                        SendMmePacket.MMTYPE = MMTYPE_CM_ATTEN_CHAR_IND;
                        SendMmePacket.FMI[0] = SendMmePacket.FMI[1] = 0;
                        SendMmePacketSize = 0;
                        SendMmePacket.MMENTRY[SendMmePacketSize++] = 0;    //APPLICATION_TYPE(0x00: EV-EVSE Matching)
                        SendMmePacket.MMENTRY[SendMmePacketSize++] = 0;    //SECURITY_TYPE(0x00: No Security)
                        memcpy(SendMmePacket.MMENTRY + SendMmePacketSize, EvMac_in, SLAC_EVMAC_LENGTH); //SOURCE_ADDRESS, MAC address of the EV Host
                        SendMmePacketSize += SLAC_EVMAC_LENGTH;
                        memcpy(SendMmePacket.MMENTRY + SendMmePacketSize, RunID_in, SLAC_RUNID_LENGTH);
                        SendMmePacketSize += SLAC_RUNID_LENGTH;
                        memset(SendMmePacket.MMENTRY + SendMmePacketSize, 0, 17); //SOURCE_ID(0x00)
                        SendMmePacketSize += 17;
                        memset(SendMmePacket.MMENTRY + SendMmePacketSize, 0, 17); //RESP_ID(0x00)
                        SendMmePacketSize += 17;
                        SendMmePacket.MMENTRY[SendMmePacketSize++] = SLAC_INFO.array[i].AttenProfileCnt; //NumSounds: Number of M-Sounds used for generation of the ATTEN_PROFILE
                        SendMmePacket.MMENTRY[SendMmePacketSize++] = SLAC_INFO.array[i].AagGroupsNum;    //NumGroups

                        for(count = 0; count < SLAC_INFO.array[i].AagGroupsNum; count++)
                        {
                            unsigned char TmpAag;
                            TmpAag = ((SLAC_INFO.array[i].AAG[count] / SLAC_INFO.array[i].AttenProfileCnt) & 0xFF);
                            SLAC_INFO.array[i].AAG_quality_ori += (float) TmpAag;   //original signal quality

                            #if (SUDO_PSD_PARAMETER_MECHANISM == ENABLE)    //default: ENABLE
                                #if 1
                                //TC_SECC_VTB_AttenuationCharacterization_019
                                TmpAag = TmpAag >> 1;   //new method proposed by Joseph (divided by 2)
                                #else
                                if(TmpAag >= 39)        //original method proposed by Vern
                                {
                                    TmpAag = 37;
                                }
                                #endif
                            #endif
                            SendMmePacket.MMENTRY[SendMmePacketSize++] = TmpAag;
                            SLAC_INFO.array[i].AAG_quality_refined += (float) TmpAag;   //refined signal quality
                        }
                        SendMmePacketSize += 19;      //the size before MMENTRY

                        #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
                        {
                            DEBUG_PRINTF_EVCOMM_DETAIL("\n\n***** Send MME Packet *****\n");
                            DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                                   SendMmePacket.ODA[0],SendMmePacket.ODA[1],SendMmePacket.ODA[2],SendMmePacket.ODA[3],SendMmePacket.ODA[4],SendMmePacket.ODA[5]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                                   SendMmePacket.OSA[0],SendMmePacket.OSA[1],SendMmePacket.OSA[2],SendMmePacket.OSA[3],SendMmePacket.OSA[4],SendMmePacket.OSA[5]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("MTYPE: 0x%x\n", htons(SendMmePacket.MTYPE));
                            DEBUG_PRINTF_EVCOMM_DETAIL("MMV: 0x%x\n", SendMmePacket.MMV);
                            DEBUG_PRINTF_EVCOMM_DETAIL("MMTYPE: 0x%x\n", SendMmePacket.MMTYPE);
                            DEBUG_PRINTF_EVCOMM_DETAIL("FMI 0x%x, 0x%x\n", SendMmePacket.FMI[0],SendMmePacket.FMI[1]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("--- CM_ATTEN_CHAR_IND ---\n");
                            DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", SendMmePacket.MMENTRY[0]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", SendMmePacket.MMENTRY[1]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x\n",
                                   SendMmePacket.MMENTRY[2],SendMmePacket.MMENTRY[3],SendMmePacket.MMENTRY[4],SendMmePacket.MMENTRY[5],
                                   SendMmePacket.MMENTRY[6],SendMmePacket.MMENTRY[7]);
                            DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n",
                                   SendMmePacket.MMENTRY[8],SendMmePacket.MMENTRY[9],SendMmePacket.MMENTRY[10],SendMmePacket.MMENTRY[11],
                                   SendMmePacket.MMENTRY[12],SendMmePacket.MMENTRY[13],SendMmePacket.MMENTRY[14],SendMmePacket.MMENTRY[15]);

                            memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf));
                            for(count=0; count<17; count++)
                            {
                            	sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, SendMmePacket.MMENTRY[16+count]);
                            }
                            DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ID: %s\n", tmpBuf);

                            memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf));
                            for(count=0; count<17; count++)
                            {
                            	sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, SendMmePacket.MMENTRY[33+count]);
                            }
                            DEBUG_PRINTF_EVCOMM_DETAIL("RESP_ID: %s\n", tmpBuf);

                            DEBUG_PRINTF_EVCOMM_DETAIL("NumSounds: 0x%x\n", SendMmePacket.MMENTRY[50]);

                            memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf));
                            for(count=0; count<AagGroupsNum; count++)
                            {
                            	sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, SendMmePacket.MMENTRY[51+count]);
                            }
                            DEBUG_PRINTF_EVCOMM_DETAIL("ATTEN_PROFILE: %s\n", tmpBuf);
                        }
                        #endif

                        count = sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));

                        SLAC_INFO.array[i].AAG_quality_ori /= SLAC_INFO.array[i].AagGroupsNum;
                        SLAC_INFO.array[i].AAG_quality_refined /= SLAC_INFO.array[i].AagGroupsNum;

                        //Print log if this CM_ATTEN_CHAR_IND belongs to RETRY Tx message.
                        if (EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry > 0)
                        {
                            sprintf((char*)buf_log_evcomm,
                                    "[SLAC][Tx]CM_ATTEN_CHAR_IND[%d]: %d-th resend (Q=%.2f/%.2f)(%d/%d)",
                                    (i + 1),
                                    EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry,
                                    SLAC_INFO.array[i].AAG_quality_refined,
                                    SLAC_INFO.array[i].AAG_quality_ori,
                                    SLAC_INFO.array[i].AttenProfileCnt,
                                    SLAC_INFO.array[i].MnbcSoundNum);
                            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        }
                        else if (EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry == 0)
                        {
                            sprintf((char*)buf_log_evcomm,
                                    "[SLAC][Tx]CM_ATTEN_CHAR_IND[%d]: Q=%.2f/%.2f(%d/%d)",
                                    (i + 1),
                                    SLAC_INFO.array[i].AAG_quality_refined,
                                    SLAC_INFO.array[i].AAG_quality_ori,
                                    SLAC_INFO.array[i].AttenProfileCnt,
                                    SLAC_INFO.array[i].MnbcSoundNum);
                            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        }
                        else
                        {
                            sprintf((char*)buf_log_evcomm,
                                    "[SLAC][Tx]CM_ATTEN_CHAR_IND[%d]: unexpected CM_ATTEN_CHAR_IND_retry(%d))",
                                    i,
                                    EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry);
                            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        }

                        DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacketSize=%d,Rtn=%d\n", SendMmePacketSize,count);
                    } //end of for loop

                    Update_V2G_Flow_Status(CM_ATTEN_CHAR_IND);
                    ftime(&SeqStartTime);
    	        }
    	        break;
            }
            #else
            {
                ftime(&SeqEndTime);
                //printf("time:%.02lf, profilNum:%d\n",DiffTimeb(SeqStartTime, SeqEndTime),AttenProfileCnt);  //added by Vern

    	        if(DiffTimeb(SeqStartTime, SeqEndTime) > TT_EVSE_match_MNBC || (AttenProfileCnt >= MnbcSoundNum) || (EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry > 0))
                {
                    memset(&SendMmePacket, 0, sizeof(struct MmeHeader));
                    memcpy(SendMmePacket.ODA, EvMac, 6);
                    memcpy(SendMmePacket.OSA, CsuMac, 6);
                    SendMmePacket.MTYPE = htons(EtherType_HomePlug);
                    SendMmePacket.MMV = 0x01;
                    SendMmePacket.MMTYPE = MMTYPE_CM_ATTEN_CHAR_IND;
                    SendMmePacket.FMI[0] = SendMmePacket.FMI[1] = 0;
                    SendMmePacketSize = 0;
                    SendMmePacket.MMENTRY[SendMmePacketSize++] = 0;    //APPLICATION_TYPE(0x00: EV-EVSE Matching)
                    SendMmePacket.MMENTRY[SendMmePacketSize++] = 0;    //SECURITY_TYPE(0x00: No Security)
                    memcpy(SendMmePacket.MMENTRY + SendMmePacketSize, EvMac, 6); //SOURCE_ADDRESS, MAC address of the EV Host
                    SendMmePacketSize += 6;
                    memcpy(SendMmePacket.MMENTRY+SendMmePacketSize, SlacRunId, sizeof(SlacRunId));
                    SendMmePacketSize += sizeof(SlacRunId);
                    memset(SendMmePacket.MMENTRY+SendMmePacketSize, 0, 17);    //SOURCE_ID
                    SendMmePacketSize += 17;
                    memset(SendMmePacket.MMENTRY+SendMmePacketSize, 0, 17);    //RESP_ID
                    SendMmePacketSize += 17;
                    SendMmePacket.MMENTRY[SendMmePacketSize++] = AttenProfileCnt;    //NumSounds
                    SendMmePacket.MMENTRY[SendMmePacketSize++] = AagGroupsNum;    //NumGroups
                    for(count=0; count < AagGroupsNum; count++)
                    {
                        unsigned char TmpAag;
                        TmpAag = ((Aag[count] / AttenProfileCnt) & 0xFF);
                        #if (SUDO_PSD_PARAMETER_MECHANISM == ENABLE)    //default: ENABLE
                            #if 1
                            //TC_SECC_VTB_AttenuationCharacterization_019
                            TmpAag = TmpAag >> 1;   //new method proposed by Joseph (divided by 2)
                            #else
                            if(TmpAag >= 39)        //original method proposed by Vern
                            {
                                /*
                                // [To-do] If this statement is enabled, SLAC will fail due to timeout.
                                {
                                    unsigned char TmpBuf[64];
                                    memset(TmpBuf,0,sizeof(TmpBuf));
                                    sprintf((char*)TmpBuf,"SlacComm: bad Aag[%d]=%d",count,TmpAag);
                                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", TmpBuf);
                                }
                                */
                                printf("%d,", TmpAag);
                                TmpAag = 37;
                            }
                            #endif
                        #endif
                        SendMmePacket.MMENTRY[SendMmePacketSize++] = TmpAag;
                    }
                    SendMmePacketSize += 19;      //the size before MMENTRY

                    #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
                    {
                        DEBUG_PRINTF_EVCOMM_DETAIL("\n\n***** Send MME Packet *****\n");
                        DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                               SendMmePacket.ODA[0],SendMmePacket.ODA[1],SendMmePacket.ODA[2],SendMmePacket.ODA[3],SendMmePacket.ODA[4],SendMmePacket.ODA[5]);
                        DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                               SendMmePacket.OSA[0],SendMmePacket.OSA[1],SendMmePacket.OSA[2],SendMmePacket.OSA[3],SendMmePacket.OSA[4],SendMmePacket.OSA[5]);
                        DEBUG_PRINTF_EVCOMM_DETAIL("MTYPE: 0x%x\n", htons(SendMmePacket.MTYPE));
                        DEBUG_PRINTF_EVCOMM_DETAIL("MMV: 0x%x\n", SendMmePacket.MMV);
                        DEBUG_PRINTF_EVCOMM_DETAIL("MMTYPE: 0x%x\n", SendMmePacket.MMTYPE);
                        DEBUG_PRINTF_EVCOMM_DETAIL("FMI 0x%x, 0x%x\n", SendMmePacket.FMI[0],SendMmePacket.FMI[1]);
                        DEBUG_PRINTF_EVCOMM_DETAIL("--- CM_ATTEN_CHAR_IND ---\n");
                        DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", SendMmePacket.MMENTRY[0]);
                        DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", SendMmePacket.MMENTRY[1]);
                        DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x\n",
                               SendMmePacket.MMENTRY[2],SendMmePacket.MMENTRY[3],SendMmePacket.MMENTRY[4],SendMmePacket.MMENTRY[5],
                               SendMmePacket.MMENTRY[6],SendMmePacket.MMENTRY[7]);
                        DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n",
                               SendMmePacket.MMENTRY[8],SendMmePacket.MMENTRY[9],SendMmePacket.MMENTRY[10],SendMmePacket.MMENTRY[11],
                               SendMmePacket.MMENTRY[12],SendMmePacket.MMENTRY[13],SendMmePacket.MMENTRY[14],SendMmePacket.MMENTRY[15]);

                        memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf));
                        for(count=0; count<17; count++)
                        {
                        	sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, SendMmePacket.MMENTRY[16+count]);
                        }
                        DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ID: %s\n", tmpBuf);

                        memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf));;
                        for(count=0; count<17; count++)
                        {
                        	sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, SendMmePacket.MMENTRY[33+count]);
                        }
                        DEBUG_PRINTF_EVCOMM_DETAIL("RESP_ID: %s\n", tmpBuf);

                        DEBUG_PRINTF_EVCOMM_DETAIL("NumSounds: 0x%x\n", SendMmePacket.MMENTRY[50]);

                        memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf));
                        for(count=0; count<AagGroupsNum; count++)
                        {
                            sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, SendMmePacket.MMENTRY[51+count]);
                        }
                        DEBUG_PRINTF_EVCOMM_DETAIL("ATTEN_PROFILE: %s\n", tmpBuf);
                    }
                    #endif

                    Update_V2G_Flow_Status(CM_ATTEN_CHAR_IND);
                    count = sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));

                    //Print log if this CM_ATTEN_CHAR_IND belongs to RETRY Tx message.
                    if (EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry > 0)
                    {
                        sprintf((char*)buf_log_evcomm,
                                "[SLAC][Tx]CM_ATTEN_CHAR_IND: resend(%d-th)",
                                EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    }

                    DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacketSize=%d,Rtn=%d\n", SendMmePacketSize,count);

                    ftime(&SeqStartTime);
    	        }
    	        break;
            }
            #endif
		}

	    case CM_ATTEN_CHAR_IND:
		{
	        ftime(&SeqEndTime);
	        //if(DiffTimeb(SeqStartTime, SeqEndTime)>TT_match_response)
	        if(DiffTimeb(SeqStartTime, SeqEndTime) > TT_match_response)     //extended to 400ms due to the response of CM_ATTEN_CHAR.RSP of some EVCC is slower than 200ms.
	        {
	            sprintf((char*)buf_log_evcomm,
                        "SlacComm: Wait CM_ATTEN_CHAR_RSP Timeout - TT_match_response (%.02lf of %dms)",
                        DiffTimeb(SeqStartTime, SeqEndTime),
                        TT_match_response);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                //Update_ShmStatusCode(); //[To-Do] to be implemented
                //CCS_SECC_TIMEOUT_SLAC_CM_ATTEN_CHAR_RSP (023814):
                //[Possible Reason] Frequent on BMW i3, need to drive the EV a bit.
                ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                ShmStatusCodeData->PresentStatusCode[0][4] = 1;
                ShmStatusCodeData->PresentStatusCode[0][5] = 4;
                CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE;
                CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;

	            Update_V2G_Flow_Status(Sequence_Timeout);
	            return -1;
	        }
	        break;
		}

	    case CM_ATTEN_CHAR_RSP:
		{
	        ftime(&SeqEndTime);
	        if(DiffTimeb(SeqStartTime, SeqEndTime) > TT_EVSE_match_session)
	        {
	            sprintf((char*)buf_log_evcomm,
                        "SlacComm: Wait CM_VALIDATE_REQ_1ST or CM_SLAC_MATCH_REQ Timeout - TT_EVSE_match_session (%.02lf of %dms)",
                        DiffTimeb(SeqStartTime, SeqEndTime),
                        TT_EVSE_match_session);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                //Update_ShmStatusCode(); //[To-Do] to be implemented
                //CCS_SECC_TIMEOUT_SLAC_CM_VALIDATE_REQ_1ST__CM_SLAC_MATCH_REQ (023815):
                //[Possible Reason] Frequent on BMW i3, need to drive the EV a bit.
                ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                ShmStatusCodeData->PresentStatusCode[0][4] = 1;
                ShmStatusCodeData->PresentStatusCode[0][5] = 5;
                CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE;
                CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;

	            Update_V2G_Flow_Status(Sequence_Timeout);
	            return -1;
	        }
	        break;
		}

	    case CM_VALIDATE_CNF:
		{
	        ftime(&SeqEndTime);
	        if(DiffTimeb(SeqStartTime, SeqEndTime) > TT_match_sequence)
	        {
	            sprintf((char*)buf_log_evcomm,
                        "SlacComm: Wait CM_VALIDATE_REQ_2ND or CM_SLAC_MATCH_REQ Timeout - TT_match_sequence (%.02lf of %dms)",
                        DiffTimeb(SeqStartTime, SeqEndTime),
                        TT_match_sequence);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                //Update_ShmStatusCode(); //[To-Do] to be implemented
                //CCS_SECC_TIMEOUT_SLAC_CM_VALIDATE_REQ_2ND__CM_SLAC_MATCH_REQ (023819):
                //[Possible Reason] Frequent on BMW i3, need to drive the EV a bit.
                ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                ShmStatusCodeData->PresentStatusCode[0][4] = 1;
                ShmStatusCodeData->PresentStatusCode[0][5] = 9;
                CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE;
                CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;

	            Update_V2G_Flow_Status(Sequence_Timeout);
	            return -1;
	        }
	        break;
		}

	    case CM_SLAC_MATCH_CNF:
		{
	        if(UdpSock > 0)
	        {
	            close(UdpSock);
	            UdpSock = -1;
	        }
	        if(TcpSock > 0)
	        {
	            close(TcpSock);
	            TcpSock = -1;
	        }
	        ftime(&SeqStartTime);
            V2gTcpConnected();
            Update_V2G_Flow_Status(SLACC_SDP_UDP_Connection);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "SLAAC,SDP,UDP: connecting...");
	        break;
		}

		default:
		{
		    break;
		}
    }
    return 0;
}


/*===========================================================================
FUNCTION: V2gMsgDecoder
DESCRIPTION:
        1. Decode the V2GTP messages inside "msg" and save the decoded
           messages in ccs_exi_doc_DIN, ccs_exi_doc_ISO1, and ccs_exi_doc_ISO2,
           respectively.

        2. After decoding, V2gMsg_Process() could then use
           ccs_exi_doc_DIN, ccs_exi_doc_ISO1, or ccs_exi_doc_ISO2
           to deal with the corresponding Response messages, respectively.

PRE-CONDITION:
        1. msg_length > 0

INPUT:
        1. msg
        2. msg_length

OUTPUT:
        1. ccs_exi_doc_DIN     //global variable
           ccs_exi_doc_ISO1
           ccs_exi_doc_ISO2

        2. v2g_state            //Status Flag
                                //indicating the V2gMsg_Process_din to proceed
                                  the next process.
        3. return value         // < 0: ERROR
                                // > 0: Message Type

GLOBAL VARIABLES:
=============================================================================*/
int V2gMsgDecoder(unsigned char *msg, unsigned int msg_length, unsigned int v2g_state)
{
    int errn = 0;

    //Checking the minimum Header size requirement
    if(msg_length < V2GTP_MSG_HEADER_LENGTH)   //The minimum requirement should be 8-byte header.
    {
        errn = -1;
        return errn;
    }

    //Decode the 1st V2GMSG: AppProtocol
    if(v2g_state == SupportedAppProtocolRequest)   //17
    {
        if ((errn = API_V2GMSG_EXI_Decoder_AppProtocol(msg, msg_length, &ccs_handshake)) < 0)
        {
            DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR = %d (DEC)]V2gMsgDecoder: SupportedAppProtocolRequest()\n", errn);
        }
        else    //decoded successfully.
        {
            //PRINT_XML_DOC_supportedAppProtocolReq(&ccs_handshake);
        }
    }
    //Decode the subsequent V2GMSG (DIN 70121, ISO 15118-2, ISO 15118-20)
    else if(v2g_state > SupportedAppProtocolRequest && v2g_state <= SessionStopResponse)
    {
        //Decoding according to its own protocol
        switch (ShmCcsData->CommProtocol)
        {
            case V2GT_MSG_PROTOCOL_DIN70121:        //0
            {
                //DIN
                if((errn = API_V2GMSG_EXI_Decoder_DIN(msg, msg_length, &ccs_exi_doc_DIN)) < 0)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR = %d (DEC)]V2gMsgDecoder: API_V2GMSG_EXI_Decoder_DIN()",
                            errn);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                }
                break;
            }

            case V2GT_MSG_PROTOCOL_ISO15118_2014:   //1
            {
                //ISO1
                if((errn = API_V2GMSG_EXI_Decoder_ISO1(msg, msg_length, &ccs_exi_doc_ISO1)) < 0)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR = %d (DEC)]V2gMsgDecoder: API_V2GMSG_EXI_Decoder_ISO1()",
                            errn);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                }
                break;
            }

            case V2GT_MSG_PROTOCOL_ISO15118_2018:   //2
            {
                //ISO2
                if((errn = API_V2GMSG_EXI_Decoder_ISO2(msg, msg_length, &ccs_exi_doc_ISO2)) < 0)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR = %d (DEC)]V2gMsgDecoder: API_V2GMSG_EXI_Decoder_ISO2()",
                            errn);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                }
                break;
            }

            default:
                break;
        }
    }
    else
    {
        DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR = %d (DEC)]V2gMsgDecoder: Unexpected v2g_state\n", errn);
        errn = -1;
    }
    return errn;
}


/*===========================================================================
FUNCTION: encode_din_V2GTP_stream
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int encode_din_V2GTP_stream(bitstream_t *v2g_tx_stream, struct dinEXIDocument *ccs_exi_doc_DIN)
{
    int errn = 0;
    *v2g_tx_stream->pos = V2GTP_HEADER_LENGTH;

    errn = encode_dinExiDocument(v2g_tx_stream, ccs_exi_doc_DIN);
    if (errn == 0)
    {
        //successfully encoded
        errn = write_v2gtpHeader(v2g_tx_stream->data, (*v2g_tx_stream->pos) - V2GTP_HEADER_LENGTH, V2GTP_EXI_TYPE);
        v2g_tx_stream->size = *v2g_tx_stream->pos;	//total length of the encoded V2GMSG.

        if (errn != 0)
        {
            DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][SeccComm][encode_din_V2GTP_stream]write_v2gtpHeader(): %d (DEC)\n", errn);
        }
    }
    else
    {
        DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][SeccComm][encode_din_V2GTP_stream]encode_dinExiDocument(): %d (DEC)\n", errn);
    }
    return errn;
}

/*===========================================================================
FUNCTION: encode_iso1_V2GTP_stream
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int encode_iso1_V2GTP_stream(bitstream_t *v2g_tx_stream, struct iso1EXIDocument *ccs_exi_doc_ISO1)
{
    int errn = 0;
    *v2g_tx_stream->pos = V2GTP_HEADER_LENGTH;

    errn = encode_iso1ExiDocument(v2g_tx_stream, ccs_exi_doc_ISO1);
    if (errn == 0)
    {
        //successfully encoded
        errn = write_v2gtpHeader(v2g_tx_stream->data, (*v2g_tx_stream->pos) - V2GTP_HEADER_LENGTH, V2GTP_EXI_TYPE);
        v2g_tx_stream->size = *v2g_tx_stream->pos;	//total length of the encoded V2GMSG.

        if (errn != 0)
        {
            DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][SeccComm][encode_iso1_V2GTP_stream]write_v2gtpHeader(): %d (DEC)\n", errn);
        }
    }
    else
    {
        DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][SeccComm][encode_iso1_V2GTP_stream]encode_iso1ExiDocument(): %d (DEC)\n", errn);
    }
    return errn;
}

/*===========================================================================
FUNCTION: encode_iso2_V2GTP_stream
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int encode_iso2_V2GTP_stream(bitstream_t *v2g_tx_stream, struct iso2EXIDocument *ccs_exi_doc_ISO2)
{
    int errn = 0;
    *v2g_tx_stream->pos = V2GTP_HEADER_LENGTH;

    errn = encode_iso2ExiDocument(v2g_tx_stream, ccs_exi_doc_ISO2);
    if (errn == 0)
    {
        //successfully encoded
        errn = write_v2gtpHeader(v2g_tx_stream->data, (*v2g_tx_stream->pos) - V2GTP_HEADER_LENGTH, V2GTP_EXI_TYPE);
        v2g_tx_stream->size = *v2g_tx_stream->pos;	//total length of the encoded V2GMSG.

        if (errn != 0)
        {
            DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][SeccComm][encode_iso2_V2GTP_stream]write_v2gtpHeader(): %d (DEC)\n", errn);
        }
    }
    else
    {
        DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][SeccComm][encode_iso2_V2GTP_stream]encode_iso2ExiDocument(): %d (DEC)\n", errn);
    }
    return errn;
}


/*===========================================================================
FUNCTION: send_encoded_din_V2GTP_Stream
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int send_encoded_din_V2GTP_Stream(int AcceptFd, bitstream_t *v2g_tx_stream, struct dinEXIDocument *ccs_exi_doc_DIN)
{
    int errn = 0;

    // STEP 1: =========== Encoding into EXI and Composing into V2GTP Stream ==========
    errn = encode_din_V2GTP_stream(v2g_tx_stream, ccs_exi_doc_DIN);

    // STEP 2: =========== Send Response Packet  ===========
    int rtn = 0;
    rtn = send(AcceptFd, v2g_tx_stream->data, v2g_tx_stream->size, 0);

	if (rtn == v2g_tx_stream->size)
    {
        /*
        DEBUG_PRINTF_EVCOMM_DETAIL("[SeccComm][send_encoded_din_V2GTP_Stream] Response Message is sent ( %d / %d ). (Bytes, DEC): OK\n",
                rtn, v2g_tx_stream->size);
        */

        //Reset all EXI doc Req/Res _isUsed Flags after each Res Tx

    }
    else if (rtn >= 0)
    {
        DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][SeccComm][send_encoded_din_V2GTP_Stream]Imcomplete Tx ( %d / %d ). (Bytes, DEC): FAIL\n", rtn, v2g_tx_stream->size);
    }
    else
    {
        errn = rtn;
        DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][send_encoded_din_V2GTP_Stream]send(): %d (DEC)\n", errn);
    }

    //STEP 3: ========= Reset V2G MSG Flags ==========
    init_dinBodyType(&ccs_exi_doc_DIN->V2G_Message.Body);
    return errn;
}

/*===========================================================================
FUNCTION: send_encoded_iso1_V2GTP_Stream
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int send_encoded_iso1_V2GTP_Stream(int AcceptFd, bitstream_t *v2g_tx_stream, struct iso1EXIDocument *ccs_exi_doc_ISO1)
{
    int errn = 0;

    // STEP 1: =========== Encoding into EXI and Composing into V2GTP Stream ==========
    errn = encode_iso1_V2GTP_stream(v2g_tx_stream, ccs_exi_doc_ISO1);

    // STEP 2: =========== Send Response Packet  ===========
    int rtn = 0;
    rtn = send(AcceptFd, v2g_tx_stream->data, v2g_tx_stream->size, 0);

	if (rtn == v2g_tx_stream->size)
    {
        /*
        DEBUG_PRINTF_EVCOMM_DETAIL("[SeccComm][send_encoded_iso1_V2GTP_Stream] Response Message is sent ( %d / %d ). (Bytes, DEC): OK\n",
                rtn, v2g_tx_stream->size);
        */

        //Reset all EXI doc Req/Res _isUsed Flags after each Res Tx

    }
    else if (rtn >= 0)
    {
        DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][SeccComm][send_encoded_iso1_V2GTP_Stream]Imcomplete Tx ( %d / %d ). (Bytes, DEC): FAIL\n", rtn, v2g_tx_stream->size);
    }
    else
    {
        errn = rtn;
        DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][send_encoded_iso1_V2GTP_Stream]send(): %d (DEC)\n", errn);
    }

    //STEP 3: ========= Reset V2G MSG Flags ==========
    init_iso1BodyType(&ccs_exi_doc_ISO1->V2G_Message.Body);
    return errn;
}

/*===========================================================================
FUNCTION: send_encoded_iso2_V2GTP_Stream
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int send_encoded_iso2_V2GTP_Stream(int AcceptFd, bitstream_t *v2g_tx_stream, struct iso2EXIDocument *ccs_exi_doc_ISO2)
{
    int errn = 0;

    // STEP 1: =========== Encoding into EXI and Composing into V2GTP Stream ==========
    errn = encode_iso2_V2GTP_stream(v2g_tx_stream, ccs_exi_doc_ISO2);

    // STEP 2: =========== Send Response Packet  ===========
    int rtn = 0;
    rtn = send(AcceptFd, v2g_tx_stream->data, v2g_tx_stream->size, 0);

	if (rtn == v2g_tx_stream->size)
    {
        /*
        DEBUG_PRINTF_EVCOMM_DETAIL("[SeccComm][send_encoded_iso2_V2GTP_Stream] Response Message is sent ( %d / %d ). (Bytes, DEC): OK\n",
                rtn, v2g_tx_stream->size);
        */

        //Reset all EXI doc Req/Res _isUsed Flags after each Res Tx

    }
    else if (rtn >= 0)
    {
        DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][SeccComm][send_encoded_iso2_V2GTP_Stream]Imcomplete Tx ( %d / %d ). (Bytes, DEC): FAIL\n",
                                    rtn, v2g_tx_stream->size);
    }
    else
    {
        errn = rtn;
        DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][send_encoded_iso2_V2GTP_Stream]send(): %d (DEC)\n", errn);
    }

    //STEP 3: ========= Reset V2G MSG Flags ==========
    init_iso2BodyType(&ccs_exi_doc_ISO2->V2G_Message.Body);
    return errn;
}


/*===========================================================================
FUNCTION: Check_din_V2G_Rx_MSG_SessionID
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Check_din_V2G_Rx_MSG_SessionID(struct dinEXIDocument *exi_doc_DIN)
{
    int i = 0;
    int leng = 0;
    int errn = 0;
    leng = exi_doc_DIN->V2G_Message.Header.SessionID.bytesLen;

    //Step 1: Check SessionID Length
    if (leng != 8)  //8-byte
    {
        sprintf((char*)buf_log_evcomm, "[ERROR]SessionID: incorrect length(%d)", leng);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        errn = -1;
    }
    else
    {
        //Step 2-1: Check SessionID content
        for (i = 0; i < leng; i++)
        {
            if (exi_doc_DIN->V2G_Message.Header.SessionID.bytes[i] != EVCOMM_SYS_INFO.SessionID[i])
            {
                errn = -2;
                break;
            }
        }
    }

    //Step 2-2: Print Incorrect ID
    if (errn == -2) //incorrect ID
    {
        sprintf((char*)buf_log_evcomm,
                "[ERROR]SessionID: incorrect ID(RX:%02X%02X%02X%02X%02X%02X%02X%02X, ORI:%02X%02X%02X%02X%02X%02X%02X%02X)",
                exi_doc_DIN->V2G_Message.Header.SessionID.bytes[0],
                exi_doc_DIN->V2G_Message.Header.SessionID.bytes[1],
                exi_doc_DIN->V2G_Message.Header.SessionID.bytes[2],
                exi_doc_DIN->V2G_Message.Header.SessionID.bytes[3],
                exi_doc_DIN->V2G_Message.Header.SessionID.bytes[4],
                exi_doc_DIN->V2G_Message.Header.SessionID.bytes[5],
                exi_doc_DIN->V2G_Message.Header.SessionID.bytes[6],
                exi_doc_DIN->V2G_Message.Header.SessionID.bytes[7],
                EVCOMM_SYS_INFO.SessionID[0],
                EVCOMM_SYS_INFO.SessionID[1],
                EVCOMM_SYS_INFO.SessionID[2],
                EVCOMM_SYS_INFO.SessionID[3],
                EVCOMM_SYS_INFO.SessionID[4],
                EVCOMM_SYS_INFO.SessionID[5],
                EVCOMM_SYS_INFO.SessionID[6],
                EVCOMM_SYS_INFO.SessionID[7]
            );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }

    //Step 3: Correct SessionID for Res Message
    if (errn != 0)
    {
        exi_doc_DIN->V2G_Message.Header.SessionID.bytesLen = 8;
        memset(exi_doc_DIN->V2G_Message.Header.SessionID.bytes, 0, 8);
        memcpy(exi_doc_DIN->V2G_Message.Header.SessionID.bytes, EVCOMM_SYS_INFO.SessionID, 8);
    }

    return errn;
}

/*===========================================================================
FUNCTION: Check_iso1_V2G_Rx_MSG_SessionID
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Check_iso1_V2G_Rx_MSG_SessionID(struct iso1EXIDocument *exi_doc_ISO1)
{
    int i = 0;
    int leng = 0;
    int errn = 0;
    leng = exi_doc_ISO1->V2G_Message.Header.SessionID.bytesLen;

    //Step 1: Check SessionID Length
    if (leng != 8)  //8-byte
    {
        sprintf((char*)buf_log_evcomm, "[ERROR]SessionID: incorrect length(%d)", leng);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        errn = -1;
    }
    else
    {
        //Step 2-1: Check SessionID content
        for (i = 0; i < leng; i++)
        {
            if (exi_doc_ISO1->V2G_Message.Header.SessionID.bytes[i] != EVCOMM_SYS_INFO.SessionID[i])
            {
                errn = -2;
                break;
            }
        }
    }

    //Step 2-2: Print Incorrect ID
    if (errn == -2) //incorrect ID
    {
        sprintf((char*)buf_log_evcomm,
                "[ERROR]SessionID: incorrect ID(RX:%02X%02X%02X%02X%02X%02X%02X%02X, ORI:%02X%02X%02X%02X%02X%02X%02X%02X)",
                exi_doc_ISO1->V2G_Message.Header.SessionID.bytes[0],
                exi_doc_ISO1->V2G_Message.Header.SessionID.bytes[1],
                exi_doc_ISO1->V2G_Message.Header.SessionID.bytes[2],
                exi_doc_ISO1->V2G_Message.Header.SessionID.bytes[3],
                exi_doc_ISO1->V2G_Message.Header.SessionID.bytes[4],
                exi_doc_ISO1->V2G_Message.Header.SessionID.bytes[5],
                exi_doc_ISO1->V2G_Message.Header.SessionID.bytes[6],
                exi_doc_ISO1->V2G_Message.Header.SessionID.bytes[7],
                EVCOMM_SYS_INFO.SessionID[0],
                EVCOMM_SYS_INFO.SessionID[1],
                EVCOMM_SYS_INFO.SessionID[2],
                EVCOMM_SYS_INFO.SessionID[3],
                EVCOMM_SYS_INFO.SessionID[4],
                EVCOMM_SYS_INFO.SessionID[5],
                EVCOMM_SYS_INFO.SessionID[6],
                EVCOMM_SYS_INFO.SessionID[7]
            );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }

    //Step 3: Correct SessionID for Res Message
    if (errn != 0)
    {
        exi_doc_ISO1->V2G_Message.Header.SessionID.bytesLen = 8;
        memset(exi_doc_ISO1->V2G_Message.Header.SessionID.bytes, 0, 8);
        memcpy(exi_doc_ISO1->V2G_Message.Header.SessionID.bytes, EVCOMM_SYS_INFO.SessionID, 8);
    }

    return errn;
}

/*===========================================================================
FUNCTION: Check_iso2_V2G_Rx_MSG_SessionID
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Check_iso2_V2G_Rx_MSG_SessionID(struct iso2EXIDocument *exi_doc_ISO2)
{
    int i = 0;
    int leng = 0;
    int errn = 0;
    leng = exi_doc_ISO2->V2G_Message.Header.SessionID.bytesLen;

    //Step 1: Check SessionID Length
    if (leng != 8)  //8-byte
    {
        sprintf((char*)buf_log_evcomm, "[ERROR]SessionID: incorrect length(%d)", leng);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        errn = -1;
    }
    else
    {
        //Step 2-1: Check SessionID content
        for (i = 0; i < leng; i++)
        {
            if (exi_doc_ISO2->V2G_Message.Header.SessionID.bytes[i] != EVCOMM_SYS_INFO.SessionID[i])
            {
                errn = -2;
                break;
            }
        }
    }

    //Step 2-2: Print Incorrect ID
    if (errn == -2) //incorrect ID
    {
        sprintf((char*)buf_log_evcomm,
                "[ERROR]SessionID: incorrect ID(RX:%02X%02X%02X%02X%02X%02X%02X%02X, ORI:%02X%02X%02X%02X%02X%02X%02X%02X)",
                exi_doc_ISO2->V2G_Message.Header.SessionID.bytes[0],
                exi_doc_ISO2->V2G_Message.Header.SessionID.bytes[1],
                exi_doc_ISO2->V2G_Message.Header.SessionID.bytes[2],
                exi_doc_ISO2->V2G_Message.Header.SessionID.bytes[3],
                exi_doc_ISO2->V2G_Message.Header.SessionID.bytes[4],
                exi_doc_ISO2->V2G_Message.Header.SessionID.bytes[5],
                exi_doc_ISO2->V2G_Message.Header.SessionID.bytes[6],
                exi_doc_ISO2->V2G_Message.Header.SessionID.bytes[7],
                EVCOMM_SYS_INFO.SessionID[0],
                EVCOMM_SYS_INFO.SessionID[1],
                EVCOMM_SYS_INFO.SessionID[2],
                EVCOMM_SYS_INFO.SessionID[3],
                EVCOMM_SYS_INFO.SessionID[4],
                EVCOMM_SYS_INFO.SessionID[5],
                EVCOMM_SYS_INFO.SessionID[6],
                EVCOMM_SYS_INFO.SessionID[7]
            );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }

    //Step 3: Correct SessionID for Res Message
    if (errn != 0)
    {
        exi_doc_ISO2->V2G_Message.Header.SessionID.bytesLen = 8;
        memset(exi_doc_ISO2->V2G_Message.Header.SessionID.bytes, 0, 8);
        memcpy(exi_doc_ISO2->V2G_Message.Header.SessionID.bytes, EVCOMM_SYS_INFO.SessionID, 8);
    }

    return errn;
}


/*===========================================================================
FUNCTION: GetSchemaID_of_Protocol
DESCRIPTION:
    1. Get the SchemaID accroding to the input target
        *V2GT_MSG_PROTOCOL_DIN70121: choose DIN 70121
        *V2GT_MSG_PROTOCOL_ISO15118_2014: choose ISO 15118-2 (ed1)
        *V2GT_MSG_PROTOCOL_ISO15118_2018: choose ISO 15118-20 (ed2)
        *V2GT_MSG_PROTOCOL_HIGHEST_PRIORITY: choose the one with the highest priority

    2. [To-do] Checking Major and Minor version
    3. The parsing method will not support those private protocols,
       such as "usr:tesla...," since "tesla" is 5 bytes but "din" and "iso" are 3 bytes.

    4. [To-do] If the target is selected as DIN," but there is no DIN.
               However, if EV and EVSE all support ISO, how to use ISO instead?

PRE-CONDITION:
INPUT:
    1. target: target protocol

OUTPUT:
    1. id: SchemaID of selected protocol by EVSE
    2. ShmCcsData->CommProtocol  (selected protocol)
    3. SupportedAppProtocol_result
        (1) appHandresponseCodeType_OK_SuccessfulNegotiation = 0,
        (2) appHandresponseCodeType_OK_SuccessfulNegotiationWithMinorDeviation = 1,
        (3) appHandresponseCodeType_Failed_NoNegotiation = 2

GLOBAL VARIABLES:
    1. ccs_handshake
    2. ShmCcsData
=============================================================================*/
int GetSchemaID_of_Protocol(unsigned char target)
{
    int i = 0;
    int ii = 0;
    int id = 0;
    //unsigned char tmp = 0;
    unsigned char pri = 20; //priority = 1(highest)~20(lowerest)
    char num[10];

    //struct CCS_ProtocolNamespacestructCharacters pro;

    //Choose the 1st protocol as default.
    //id = CCS_HANDSHAKE_PROTOCOLS.array[0].SchemaID;
    id = -1;
    ShmCcsData->CommProtocol = V2GT_MSG_PROTOCOL_DIN70121;

    for(i = 0; i < CCS_HANDSHAKE_PROTOCOLS.arrayLen; i++)
    {
        //Checking for <ProtocolNamespace>urn:din:70121:2012:MsgDef</ProtocolNamespace>
        //[To-Do] Ignoring the priority from EV and force DIN 70121 as our only option. (for temp)

        //[CAUTION] The parsing method will not support those private protocols, such as "usr:tesla..."
        num[0] = CCS_HANDSHAKE_PROTOCOLS.array[i].ProtocolNamespace.characters[8];
        num[1] = CCS_HANDSHAKE_PROTOCOLS.array[i].ProtocolNamespace.characters[9];
        num[2] = CCS_HANDSHAKE_PROTOCOLS.array[i].ProtocolNamespace.characters[10];
        num[3] = CCS_HANDSHAKE_PROTOCOLS.array[i].ProtocolNamespace.characters[11];
        num[4] = CCS_HANDSHAKE_PROTOCOLS.array[i].ProtocolNamespace.characters[12];
        num[5] = '\0';

        if (atoi(num) == 70121)
        {
            sprintf((char*)buf_log_evcomm,
                    "[GetSchemaID_of_Protocol]supported(%d-th/%d): DIN 70121(%d:v%d.%d;id=%d,pri=%d)",
                    (i+1),
                    CCS_HANDSHAKE_PROTOCOLS.arrayLen,
                    atoi(num),
                    CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMajor,
                    CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMinor,
                    CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID,
                    CCS_HANDSHAKE_PROTOCOLS.array[i].Priority);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

            if (target == V2GT_MSG_PROTOCOL_DIN70121)
            {
                sprintf((char*)buf_log_evcomm,
                        "[GetSchemaID_of_Protocol]selected(%d-th/%d): DIN 70121(%d:v%d.%d;id=%d,pri=%d)",
                        (i+1),
                        CCS_HANDSHAKE_PROTOCOLS.arrayLen,
                        atoi(num),
                        CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMajor,
                        CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMinor,
                        CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID,
                        CCS_HANDSHAKE_PROTOCOLS.array[i].Priority);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                if (CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMajor == DIN_SPEC_70121_2012_VersionNumberMajor)
                {
                    if (CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMinor == DIN_SPEC_70121_2012_VersionNumberMinor)
                    {
                        EVCOMM_SYS_INFO.SupportedAppProtocol_result = appHandresponseCodeType_OK_SuccessfulNegotiation;
                    }
                    else
                    {   //[TC_SECC_VTB_SupportedAppProtocol_005]
                        EVCOMM_SYS_INFO.SupportedAppProtocol_result = appHandresponseCodeType_OK_SuccessfulNegotiationWithMinorDeviation;
                    }
                    id = CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID;
                    ShmCcsData->CommProtocol = V2GT_MSG_PROTOCOL_DIN70121;
                    return id;
                }
                else
                {
                    //keep looking for the suitable protocol
                }
            }
            else if (target == V2GT_MSG_PROTOCOL_HIGHEST_PRIORITY)
            {
                if (pri > CCS_HANDSHAKE_PROTOCOLS.array[i].Priority)
                {
                    ii = i;
                    id = CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID;
                    pri = CCS_HANDSHAKE_PROTOCOLS.array[i].Priority;
                    ShmCcsData->CommProtocol = V2GT_MSG_PROTOCOL_DIN70121;
                }
                else
                {
                    //not using this SchemaID, and keep looking for that SchemaID with higer priority
                }
            }
            else
            {
                //null
            }
        }
        else if (atoi(num) == 15118)
        {
            //urn:din:70121:2012:MsgDef
            //urn:iso:15118:2:2013:MsgDef
            memset(num, 0, sizeof(num));
            num[0] = CCS_HANDSHAKE_PROTOCOLS.array[i].ProtocolNamespace.characters[16];
            num[1] = CCS_HANDSHAKE_PROTOCOLS.array[i].ProtocolNamespace.characters[17];
            num[2] = CCS_HANDSHAKE_PROTOCOLS.array[i].ProtocolNamespace.characters[18];
            num[3] = CCS_HANDSHAKE_PROTOCOLS.array[i].ProtocolNamespace.characters[19];
            num[4] = '\0';

            if (atoi(num) < 2018 && atoi(num) >= 2010)
            {
                sprintf((char*)buf_log_evcomm,
                        "[GetSchemaID_of_Protocol]supported(%d-th/%d): ISO 15118-2(ed1,%d:v%d.%d;id=%d,pri=%d)",
                        (i+1),
                        CCS_HANDSHAKE_PROTOCOLS.arrayLen,
                        atoi(num),
                        CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMajor,
                        CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMinor,
                        CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID,
                        CCS_HANDSHAKE_PROTOCOLS.array[i].Priority);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                if (target == V2GT_MSG_PROTOCOL_ISO15118_2014)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[GetSchemaID_of_Protocol]selected(%d-th/%d): ISO 15118-2,ed1(%d:v%d.%d;id=%d,pri=%d)",
                            (i+1),
                            CCS_HANDSHAKE_PROTOCOLS.arrayLen,
                            atoi(num),
                            CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMajor,
                            CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMinor,
                            CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID,
                            CCS_HANDSHAKE_PROTOCOLS.array[i].Priority);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                    if (CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMajor == ISO1_15118_2013_VersionNumberMajor)
                    {
                        if (CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMinor == ISO1_15118_2013_VersionNumberMinor)
                        {
                            EVCOMM_SYS_INFO.SupportedAppProtocol_result = appHandresponseCodeType_OK_SuccessfulNegotiation;
                        }
                        else
                        {
                            EVCOMM_SYS_INFO.SupportedAppProtocol_result = appHandresponseCodeType_OK_SuccessfulNegotiationWithMinorDeviation;
                        }
                        id = CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID;
                        ShmCcsData->CommProtocol = V2GT_MSG_PROTOCOL_ISO15118_2014;
                        return id;
                    }
                    else
                    {
                        //keep looking for the suitable protocol
                    }
                }
                else if (target == V2GT_MSG_PROTOCOL_HIGHEST_PRIORITY)
                {
                    if (pri > CCS_HANDSHAKE_PROTOCOLS.array[i].Priority)
                    {
                        ii = i;
                        id = CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID;
                        pri = CCS_HANDSHAKE_PROTOCOLS.array[i].Priority;
                        ShmCcsData->CommProtocol = V2GT_MSG_PROTOCOL_ISO15118_2014;
                    }
                    else
                    {
                        //not using this SchemaID, and keep looking for that SchemaID with higer priority
                    }
                }
                else
                {
                    //null
                }
            }
            else if (atoi(num) >= 2018 && atoi(num) <= 2100)    // >= 2018
            {
                sprintf((char*)buf_log_evcomm,
                        "[GetSchemaID_of_Protocol]supported(%d-th/%d): ISO 15118-20(ed2,%d:v%d.%d;id=%d,pri=%d)",
                        (i+1),
                        CCS_HANDSHAKE_PROTOCOLS.arrayLen,
                        atoi(num),
                        CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMajor,
                        CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMinor,
                        CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID,
                        CCS_HANDSHAKE_PROTOCOLS.array[i].Priority);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                if (target == V2GT_MSG_PROTOCOL_ISO15118_2018)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[GetSchemaID_of_Protocol]selected(%d-th/%d): ISO 15118-20,ed2(%d:v%d.%d;id=%d,pri=%d)",
                            (i+1),
                            CCS_HANDSHAKE_PROTOCOLS.arrayLen,
                            atoi(num),
                            CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMajor,
                            CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMinor,
                            CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID,
                            CCS_HANDSHAKE_PROTOCOLS.array[i].Priority);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                    if (CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMajor == ISO2_15118_2018_VersionNumberMajor)
                    {
                        if (CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMinor == ISO2_15118_2018_VersionNumberMinor)
                        {
                            EVCOMM_SYS_INFO.SupportedAppProtocol_result = appHandresponseCodeType_OK_SuccessfulNegotiation;
                        }
                        else
                        {
                            EVCOMM_SYS_INFO.SupportedAppProtocol_result = appHandresponseCodeType_OK_SuccessfulNegotiationWithMinorDeviation;
                        }
                        id = CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID;
                        ShmCcsData->CommProtocol = V2GT_MSG_PROTOCOL_ISO15118_2018;
                        return id;
                    }
                    else
                    {
                        //keep looking for the suitable protocol
                    }
                }
                else if (target == V2GT_MSG_PROTOCOL_HIGHEST_PRIORITY)
                {
                    if (pri > CCS_HANDSHAKE_PROTOCOLS.array[i].Priority)
                    {
                        ii = i;
                        id = CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID;
                        pri = CCS_HANDSHAKE_PROTOCOLS.array[i].Priority;
                        ShmCcsData->CommProtocol = V2GT_MSG_PROTOCOL_ISO15118_2018;
                    }
                    else
                    {
                        //not using this SchemaID, and keep looking for that SchemaID with higer priority
                    }
                }
                else
                {
                    //null
                }
            }
            else
            {
                //Unexpected Year
                sprintf((char*)buf_log_evcomm,
                        "[GetSchemaID_of_Protocol]unsupported(%d-th/%d): ISO 15118-X(unexpected year:%d,v%d.%d),id=%d,pri=%d",
                        (i+1),
                        CCS_HANDSHAKE_PROTOCOLS.arrayLen,
                        atoi(num),
                        CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMajor,
                        CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMinor,
                        CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID,
                        CCS_HANDSHAKE_PROTOCOLS.array[i].Priority);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                //return -1;
            }
        }
        else
        {
            sprintf((char*)buf_log_evcomm,
                    "[GetSchemaID_of_Protocol]unsupported protocol(%d-th/%d)(%d:v%d.%d;id=%d,pri=%d)",
                    (i+1),
                    CCS_HANDSHAKE_PROTOCOLS.arrayLen,
                    atoi(num),
                    CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMajor,
                    CCS_HANDSHAKE_PROTOCOLS.array[i].VersionNumberMinor,
                    CCS_HANDSHAKE_PROTOCOLS.array[i].SchemaID,
                    CCS_HANDSHAKE_PROTOCOLS.array[i].Priority);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            //return -1;
        }
    }

    //The final result of highest priority protocol
    sprintf((char*)buf_log_evcomm,
            "[GetSchemaID_of_Protocol]selected(%d-th/%d): pro=%d(0:DIN,1:ISO1,2:ISO2);id=%d,pri=%d",
            (ii+1),
            CCS_HANDSHAKE_PROTOCOLS.arrayLen,
            ShmCcsData->CommProtocol,
            id,
            pri);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

    if (id < 0)
    {
        EVCOMM_SYS_INFO.SupportedAppProtocol_result = appHandresponseCodeType_Failed_NoNegotiation;
    }

    return id;
}


/*===========================================================================
FUNCTION: Proc_supportedAppProtocolRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_supportedAppProtocolRes(int AcceptFd)
{
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct ChargingInfoData *sys;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    //STEP 1: =========== Setting the Response Message ===========
	init_appHandEXIDocument(&ccs_handshake);
    ccs_handshake.supportedAppProtocolRes.ResponseCode = appHandresponseCodeType_OK_SuccessfulNegotiation;
	ccs_handshake.supportedAppProtocolRes_isUsed = 1u;

    //select the 1st one as the default
    ccs_handshake.supportedAppProtocolRes.SchemaID = CCS_HANDSHAKE_PROTOCOLS.array[0].SchemaID;
    ccs_handshake.supportedAppProtocolRes.SchemaID_isUsed = 1u;
    int id = 0;
    /*+++ 20200808, vern, support both DIN and ISO +++*/
    //id = GetSchemaID_of_Protocol(V2GT_MSG_PROTOCOL_PREFERENCE); //output: EVCOMM_SYS_INFO.SupportedAppProtocol_result
    id = GetSchemaID_of_Protocol(V2GT_MSG_PROTOCOL_HIGHEST_PRIORITY); //output: EVCOMM_SYS_INFO.SupportedAppProtocol_result
    /*--- 20200808, vern, support both DIN and ISO ---*/
    ccs_handshake.supportedAppProtocolRes.ResponseCode = EVCOMM_SYS_INFO.SupportedAppProtocol_result;   //updating the response code
    if (id < 0)
    {
        sprintf((char*)buf_log_evcomm,
                "[Error]No avalible CCS protocol (id = %d, preference = %d)",
                id,
                V2GT_MSG_PROTOCOL_PREFERENCE);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    else
    {
        //selected SchemaID
        ccs_handshake.supportedAppProtocolRes.SchemaID = (unsigned char) id;
    }


    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_supportedAppProtocolRes]EVSE_Shutdown => End_Process");
        ccs_handshake.supportedAppProtocolRes.ResponseCode = appHandresponseCodeType_Failed_NoNegotiation;
        errn = -1;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_supportedAppProtocolRes]EVSE_EmergencyShutdown => End_Process");
        ccs_handshake.supportedAppProtocolRes.ResponseCode = appHandresponseCodeType_Failed_NoNegotiation;
        errn = -1;
    }
    else
    {
        //null
    }

    //Check for Permission Changing from TRUE to FALSE
    /*+++ 20200808, vern, sync with Tesla CHAdeMO adaptor, 2 for start communication(not yet auth), 1 for star charging (authorized)  ---*/
    if (ShmInternalComm->ChargingPermission_pre >= 1 &&
        ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][DIN][supportedAppProtocolRes]Permission OFF");
        ccs_handshake.supportedAppProtocolRes.ResponseCode = appHandresponseCodeType_Failed_NoNegotiation;
        //errn = -1;
    }

    #if (CP_PROTECTION_MECHANISM == ENABLE)
    {
        #if (SLAC_FIRST_RESPONSE_METHOD == SET_5_PWM_ONCE_GET_PERMISSION_IN_AUTHORIZATIONRES)
        {
            //Detect for CP State should be 9V with 5% PWM or 100%PWM (State B1, B2)
            if (sys->CpState != 2 && sys->CpState != 3)  //State B1, B2
            {
                ccs_handshake.supportedAppProtocolRes.ResponseCode = appHandresponseCodeType_Failed_NoNegotiation;
                CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
                Update_V2G_Flow_Status(Other_Fault);
                sprintf((char*)buf_log_evcomm,
                        "[Proc_supportedAppProtocolRes]Emergency Stop by CP Error (%d, %.02f V)\n",
                        sys->CpState,
                        sys->CpVoltage);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            }
        }
        #else
        {
            //Detect for CP State should be 9V (State B)
            if (sys->CpState != 3)  //B2
            {
                ccs_handshake.supportedAppProtocolRes.ResponseCode = appHandresponseCodeType_Failed_NoNegotiation;
                CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
                Update_V2G_Flow_Status(Other_Fault);
                sprintf((char*)buf_log_evcomm,
                        "[Proc_supportedAppProtocolRes]Emergency Stop by CP Error (%d, %.02f V)\n",
                        sys->CpState,
                        sys->CpVoltage);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            }
        }
        #endif
    }
    #endif


    //STEP 2: =========== Encode into EXI ===========
    if ((errn = API_V2GMSG_EXI_Encoder_AppProtocol(&ccs_handshake, &v2g_tx_stream)) !=0)
    {
        DEBUG_PRINTF_EVCOMM_DETAIL("\n[Error]API_V2GMSG_EXI_Encoder_AppProtocol\n");
        return errn;
    }

    //STEP 3: =========== Send Response Packet ===========
    int Rtn = 0;
	Rtn = send(AcceptFd, v2g_tx_stream.data, v2g_tx_stream.size, 0);
    //Rtn = send(6, v2g_tx_stream.data, v2g_tx_stream.size, 0);

    DEBUG_PRINTF_EVCOMM_DETAIL("Send V2GTP Packet Size = %d, Rtn = %d (Bytes, DEC)\n", v2g_tx_stream.size, Rtn);

    if (Rtn < 0)
    {
        return Rtn;
    }

    //STEP 4: =========== Save into Share Memory =========
	//[Joseph, To-Do] Adding a mechanism to choose DIN 70121 as our 1st priority. (for multiple protocols)

    //STEP 5: =========== Updating the Flow State Flag =========
    if (id < 0)
    {
        errn = -1;
    }

    //STEP 6: ===========  Reset Flags ============
    //Reset all EXI doc Req/Res _isUsed Flags after each Res Tx
    init_appHandEXIDocument(&ccs_handshake);

    return errn;
}

/*===========================================================================
FUNCTION: Proc_supportedAppProtocolReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_supportedAppProtocolReq(int AcceptFd)
{
    //[Joseph, To-Do] analysis on Req message and choose the prefered protocol
    //Default: DIN 70121 (find SchemaID)
    int errn = 0;

    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]supportedAppProtocolReq");
    SHM_Save_din_supportedAppProtocolReq(ShmCcsData, &ccs_handshake, ShmSysConfigAndInfo);

    errn = Proc_supportedAppProtocolRes(AcceptFd);
    if (errn == 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Tx]supportedAppProtocolRes");
    }
    else
    {
        DEBUG_PRINTF_EVCOMM_DETAIL("[Error]Proc_supportedAppProtocolRes(): %d (DEC)\n", errn);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_din_SessionSetupRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_SessionSetupRes(int AcceptFd)
{
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct ChargingInfoData *sys;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;

    init_dinBodyType(&ccs_exi_doc_DIN.V2G_Message.Body);
    init_dinSessionSetupResType(&ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes);


    // ====== [BODY (1/2) ResponseCode ======
    ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes_isUsed = 1u;
    ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = dinresponseCodeType_OK_NewSessionEstablished;


    //[HEADER] Assign Res SessionID
    ccs_exi_doc_DIN.V2G_Message.Header.SessionID.bytesLen = 8;
    memset(ccs_exi_doc_DIN.V2G_Message.Header.SessionID.bytes, 0, 8);
    memcpy(ccs_exi_doc_DIN.V2G_Message.Header.SessionID.bytes, EVCOMM_SYS_INFO.SessionID, 8);


    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = dinresponseCodeType_FAILED_SequenceError;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //#if PARAMETER_NORMAL_MODE == ENABLE
    //SHM_Read_din_V2GMSG_Header(&ccs_exi_doc_DIN, ShmCcsData);
    //#endif


    //Detect for CP State should be 9V (State B)
    if ((sys->CpState != 2) && (sys->CpState != 3))  //State B1, B2
    {
	    #if CP_PROTECTION_MECHANISM == ENABLE
        ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = dinresponseCodeType_FAILED;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;

        sprintf((char*)buf_log_evcomm,
                "[Proc_din_SessionSetupRes]Emergency Stop by CP Error (%d)\n",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #else
        sprintf((char*)buf_log_evcomm,
                "[Proc_din_SessionSetupRes]Emergency Stop by CP Error (%d): ignored\n",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #endif
    }

    //Check for shutdown commands from EVSE(DC Main Board)
    if (sys->DC_EVSEStatus == EVSE_Shutdown ||
        sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = dinresponseCodeType_FAILED;
        sprintf((char*)buf_log_evcomm, "[Proc_din_SessionSetupRes]Stop by EVSE(%d:normal, %d:emergency): (%d)\n",
                EVSE_Shutdown,
                EVSE_EmergencyShutdown,
                sys->DC_EVSEStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        errn = -1;
    }

    //Check for Permission Changing from TRUE to FALSE
    /*+++ 20200808, vern, sync with Tesla CHAdeMO adaptor, 2 for start communication(not yet auth), 1 for star charging (authorized)  ---*/
    if (ShmInternalComm->ChargingPermission_pre >= 1 &&
        ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][DIN][SessionSetupRes]Permission OFF");
        ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = dinresponseCodeType_FAILED;
        errn = -1;
    }

    // ====== [BODY (2/3) EVSEID ======
    //EVSEID = all zero
    memset(ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.EVSEID.bytes, 0, sizeof(ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.EVSEID.bytes));
    //vern, should be encode  by SN
    ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.EVSEID.bytesLen = 1;  //max: DIN = 32, ISO1/ISO2 = 37 bytes

    // ====== [BODY (3/3) DateTimeNow ======
    ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.DateTimeNow_isUsed = 1u;
    ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.DateTimeNow = (int64_t)time(NULL);   //[Joseph] Format: Unix Time Stamp

    #if PARAMETER_NORMAL_MODE == ENABLE
    ///////////SHM_Read_din_SessionSetupRes(&ccs_exi_doc_DIN, ShmCcsData);
    #endif

    // ============ Encode and Send Response Message ===========
    if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_DIN) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_SessionSetupRes][Error]Tx encoded msg error");
        errn = -1;
    }

    return errn;

}

/*===========================================================================
FUNCTION: Proc_iso1_SessionSetupRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_SessionSetupRes(int AcceptFd)
{
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct ChargingInfoData *sys;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;

    init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body);
    init_iso1SessionSetupResType(&ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes);

    // ====== [BODY (1/2) ResponseCode ======
    ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes_isUsed = 1u;
    ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_OK_NewSessionEstablished;


    //[HEADER] Assign Res SessionID
    ccs_exi_doc_ISO1.V2G_Message.Header.SessionID.bytesLen = 8;
    memset(ccs_exi_doc_ISO1.V2G_Message.Header.SessionID.bytes, 0, 8);
    memcpy(ccs_exi_doc_ISO1.V2G_Message.Header.SessionID.bytes, EVCOMM_SYS_INFO.SessionID, 8);

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //#if PARAMETER_NORMAL_MODE == ENABLE
    //SHM_Read_iso1_V2GMSG_Header(&ccs_exi_doc_ISO1, ShmCcsData);
    //#endif

    //Detect for CP State should be 9V (State B)
    if ((sys->CpState != 2) && (sys->CpState != 3))  //State B1, B2
    {
        #if CP_PROTECTION_MECHANISM == ENABLE
        ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_FAILED;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;

        sprintf((char*)buf_log_evcomm,
                "[Proc_iso1_SessionSetupRes]Emergency Stop by CP Error (%d)\n",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #else
        sprintf((char*)buf_log_evcomm,
                "[Proc_iso1_SessionSetupRes]Emergency Stop by CP Error (%d): ignored\n",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #endif
    }

    //Check for shutdown commands from EVSE(DC Main Board)
    if (sys->DC_EVSEStatus == EVSE_Shutdown ||
        sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_FAILED;
        sprintf((char*)buf_log_evcomm, "[Proc_iso1_SessionSetupRes]Stop by EVSE(%d:normal, %d:emergency): (%d)\n",
                EVSE_Shutdown,
                EVSE_EmergencyShutdown,
                sys->DC_EVSEStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        errn = -1;
    }

    //Check for Permission Changing from TRUE to FALSE
    if (ShmInternalComm->ChargingPermission_pre == TRUE &&
        ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][ISO1][SessionSetupRes]Permission OFF");
        ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_FAILED;
        errn = -1;
    }

    // ====== [BODY (2/3) EVSEID ======
    //EVSEID = all zero
    memset(ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters, 0, sizeof(ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters));
    /*+++ 20200808, vern, set default EVSEID +++*/
    //vern, should be encoded  by SN
    ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[0]='Z';
    ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[1]='Z';
    ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[2]='0';
    ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[3]='0';
    ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[4]='0';
    ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[5]='0';
    ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[6]='0';
    ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.charactersLen = 7;  //max: DIN = 32, ISO1/ISO2 = 37 bytes
    /*--- 20200808, vern, set default EVSEID ---*/

    // ====== [BODY (3/3) DateTimeNow ======
    ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.EVSETimeStamp_isUsed = 1u;
    ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.EVSETimeStamp = (int64_t)time(NULL);   //[Joseph] Format: Unix Time Stamp

    #if PARAMETER_NORMAL_MODE == ENABLE
    ///////////SHM_Read_iso1_SessionSetupRes(&ccs_exi_doc_ISO1, ShmCcsData);
    #endif


    // ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_SessionSetupRes][Error]Tx encoded msg error");
        errn = -1;
    }

    return errn;

}

/*===========================================================================
FUNCTION: Proc_iso2_SessionSetupRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso2_SessionSetupRes(int AcceptFd)
{
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct ChargingInfoData *sys;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;

    init_iso2BodyType(&ccs_exi_doc_ISO2.V2G_Message.Body);
    init_iso2SessionSetupResType(&ccs_exi_doc_ISO2.V2G_Message.Body.SessionSetupRes);

    // ====== [BODY (1/2) ResponseCode ======
    ccs_exi_doc_ISO2.V2G_Message.Body.SessionSetupRes_isUsed = 1u;
    ccs_exi_doc_ISO2.V2G_Message.Body.SessionSetupRes.ResponseCode = iso2responseCodeType_OK_NewSessionEstablished;


    //[HEADER] Assign Res SessionID
    ccs_exi_doc_ISO2.V2G_Message.Header.SessionID.bytesLen = 8;
    memset(ccs_exi_doc_ISO2.V2G_Message.Header.SessionID.bytes, 0, 8);
    memcpy(ccs_exi_doc_ISO2.V2G_Message.Header.SessionID.bytes, EVCOMM_SYS_INFO.SessionID, 8);

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //#if PARAMETER_NORMAL_MODE == ENABLE
    //SHM_Read_iso2_V2GMSG_Header(&ccs_exi_doc_ISO2, ShmCcsData);
    //#endif

    //Detect for CP State should be 9V (State B)
    if ((sys->CpState != 2) && (sys->CpState != 3))  //State B1, B2
    {
        #if CP_PROTECTION_MECHANISM == ENABLE
        ccs_exi_doc_ISO2.V2G_Message.Body.SessionSetupRes.ResponseCode = iso2responseCodeType_FAILED;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;

        sprintf((char*)buf_log_evcomm,
                "[Proc_iso2_SessionSetupRes]Emergency Stop by CP Error (%d)",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #else
        sprintf((char*)buf_log_evcomm,
                "[Proc_iso2_SessionSetupRes]Emergency Stop by CP Error (%d): ignored",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #endif
    }

    //Check for shutdown commands from EVSE(DC Main Board)
    if (sys->DC_EVSEStatus == EVSE_Shutdown ||
        sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        ccs_exi_doc_ISO2.V2G_Message.Body.SessionSetupRes.ResponseCode = iso2responseCodeType_FAILED;
        sprintf((char*)buf_log_evcomm, "[Proc_iso2_SessionSetupRes]Stop by EVSE(%d:normal, %d:emergency): (%d)\n",
                EVSE_Shutdown,
                EVSE_EmergencyShutdown,
                sys->DC_EVSEStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        errn = -1;
    }

    //Check for Permission Changing from TRUE to FALSE
    /*+++ 20200808, vern, sync with Tesla CHAdeMO adaptor, 2 for start communication(not yet auth), 1 for star charging (authorized)  ---*/
    if (ShmInternalComm->ChargingPermission_pre >= 1 &&
        ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][ISO2][SessionSetupRes]Permission OFF");
        ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = iso2responseCodeType_FAILED;
        errn = -1;
    }

    // ====== [BODY (2/3) EVSEID ======
    //EVSEID = all zero
    memset(ccs_exi_doc_ISO2.V2G_Message.Body.SessionSetupRes.EVSEID.characters, 0, sizeof(ccs_exi_doc_ISO2.V2G_Message.Body.SessionSetupRes.EVSEID.characters));
    ccs_exi_doc_ISO2.V2G_Message.Body.SessionSetupRes.EVSEID.charactersLen = 15;  //max: DIN = 32, ISO1/ISO2 = 37 bytes

    // ====== [BODY (3/3) DateTimeNow ======
    ccs_exi_doc_ISO2.V2G_Message.Body.SessionSetupRes.EVSETimeStamp_isUsed = 1u;
    ccs_exi_doc_ISO2.V2G_Message.Body.SessionSetupRes.EVSETimeStamp = (int64_t)time(NULL);   //[Joseph] Format: Unix Time Stamp

    #if PARAMETER_NORMAL_MODE == ENABLE
    ///////////SHM_Read_iso2_SessionSetupRes(&ccs_exi_doc_ISO2, ShmCcsData);
    #endif


    // ============ Encode and Send Response Message ===========
    if (send_encoded_iso2_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO2) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso2_SessionSetupRes][Error]Tx encoded msg error");
        errn = -1;
    }

    return errn;

}

/*===========================================================================
FUNCTION: Proc_din_SessionSetupReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
        2. ccs_exi_doc_DIN
=============================================================================*/
int Proc_din_SessionSetupReq(int AcceptFd)
{
    int errn = 0;

    DEBUG_PRINTF_EVCOMM_DETAIL("\n[Proc_din_SessionSetupReq]Got SessionSetupReq\n");

    //Print the decoded XML Document
    PRINT_XML_DOC_DIN_SessionSetupReq(&ccs_exi_doc_DIN);

    //Save into Share Memory
    SHM_Save_din_SessionSetupReq(ShmCcsData, &ccs_exi_doc_DIN, ShmSysConfigAndInfo);

    errn = Proc_din_SessionSetupRes(AcceptFd);
    if (errn == 0)
    {
    	//successfully send response.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][V2G][Tx]SessionSetupRes");
    }
    else
    {
    	sprintf((char*)buf_log_evcomm,
                "[Error]Proc_din_SessionSetupRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }

    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_SessionSetupReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
        2. ccs_exi_doc_ISO1
=============================================================================*/
int Proc_iso1_SessionSetupReq(int AcceptFd)
{
    int errn = 0;
    DEBUG_PRINTF_EVCOMM_DETAIL("\n[Proc_iso1_SessionSetupReq]Got SessionSetupReq\n");

    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_SessionSetupReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_SessionSetupReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    errn = Proc_iso1_SessionSetupRes(AcceptFd);
    if (errn == 0)
    {
        //successfully send response.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][V2G][Tx]SessionSetupRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error]Proc_iso1_SessionSetupRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso2_SessionSetupReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
        2. ccs_exi_doc_ISO2
=============================================================================*/
int Proc_iso2_SessionSetupReq(int AcceptFd)
{
    int errn = 0;
    DEBUG_PRINTF_EVCOMM_DETAIL("\n[Proc_iso2_SessionSetupReq]Got SessionSetupReq\n");

    //Print the decoded XML Document
    PRINT_XML_DOC_ISO2_SessionSetupReq(&ccs_exi_doc_ISO2);

    //Save into Share Memory
    SHM_Save_iso2_SessionSetupReq(ShmCcsData, &ccs_exi_doc_ISO2, ShmSysConfigAndInfo);

    errn = Proc_iso2_SessionSetupRes(AcceptFd);
    if (errn == 0)
    {
        //successfully send response.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO2][V2G][Tx]SessionSetupRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error]Proc_iso2_SessionSetupRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}


/*===========================================================================
FUNCTION: Proc_din_ServiceDiscoveryRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_ServiceDiscoveryRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    struct ChargingInfoData *sys;
    //struct ServiceDiscoveryRequest_DIN70121 *req;
    struct ServiceDiscoveryResponse_DIN70121 *res;


    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];
    //req = &ShmCcsData->V2GMessage_DIN70121.ServiceDiscoveryRequest;
    res = &ShmCcsData->V2GMessage_DIN70121.ServiceDiscoveryResponse;


    init_dinBodyType(&ccs_exi_doc_DIN.V2G_Message.Body);
    init_dinServiceDiscoveryResType(&ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes);

    //[1/4] Response Code
    ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes_isUsed = 1u;
    ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = dinresponseCodeType_OK;

    //[HEADER] Check Req SessionID
    if (Check_din_V2G_Rx_MSG_SessionID(&ccs_exi_doc_DIN) < 0)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }


    //Detect for CP State should be 9V (State B)
    if ((sys->CpState != 2) && (sys->CpState != 3))  //State B1, B2
    {
        #if CP_PROTECTION_MECHANISM == ENABLE
        ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode =  dinresponseCodeType_FAILED;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
	    errn = -1;
        sprintf((char*)buf_log_evcomm, "[Proc_din_ServiceDiscoveryRes]Emergency Stop by CP Error (%d)", sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #else
        sprintf((char*)buf_log_evcomm,
                "[Proc_din_ServiceDiscoveryRes]Emergency Stop by CP Error (%d): ignored",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #endif
    }

    if (sys->DC_EVSEStatus == EVSE_Shutdown ||
        sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = dinresponseCodeType_FAILED;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_ServiceDiscoveryRes]shutdown by EVSE");
        errn = -1;
    }

    //Check for Permission Changing from TRUE to FALSE
    /*+++ 20200808, vern, sync with Tesla CHAdeMO adaptor, 2 for start communication(not yet auth), 1 for star charging (authorized)  ---*/
    if (ShmInternalComm->ChargingPermission_pre >= 1 &&
        ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][DIN][ServiceDiscoveryRes]Permission OFF");
        ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = dinresponseCodeType_FAILED;
        errn = -1;
    }

    //[2/4] PaymentOptions
    ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.PaymentOptions.PaymentOption.arrayLen = 1u;
    ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.PaymentOptions.PaymentOption.array[0] = dinpaymentOptionType_ExternalPayment; //1

    //[3/4] Charge Service
    res->ChargeService_DIN70121.Services.ServiceTag.ServiceID = 1;
    ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceTag.ServiceID = (unsigned short) res->ChargeService_DIN70121.Services.ServiceTag.ServiceID;
    ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceTag.ServiceCategory = dinserviceCategoryType_EVCharging;
    ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.FreeService = 1; //[Joseph] for test
    ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.EnergyTransferType = dinEVSESupportedEnergyTransferType_DC_extended;

    //[4/4] Service List (null, not be uesed for now.)
    //#if PARAMETER_NORMAL_MODE == ENABLE
    ///////////////SHM_Read_din_ServiceDiscoveryRes(&ccs_exi_doc_DIN, ShmCcsData);
    //#endif

    // ============ Encode and Send Response Message ===========
    if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_DIN) != 0)
    {
        errn = -1;
    }

    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_ServiceDiscoveryRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_ServiceDiscoveryRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    struct ChargingInfoData *sys;
    //struct ServiceDiscoveryRequest_ISO15118_2014 *req;
    struct ServiceDiscoveryResponse_ISO15118_2014 *res;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];
    //req = &ShmCcsData->V2GMessage_ISO15118_2014.ServiceDiscoveryRequest;
    res = &ShmCcsData->V2GMessage_ISO15118_2014.ServiceDiscoveryResponse;

    init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body);
    init_iso1ServiceDiscoveryResType(&ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes);

    //[1/4] Response Code
    ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes_isUsed = 1u;
    ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso1responseCodeType_OK;


    //[HEADER] Check Req SessionID
    if (Check_iso1_V2G_Rx_MSG_SessionID(&ccs_exi_doc_ISO1) < 0)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }


    //Detect for CP State should be 9V (State B)
    if ((sys->CpState != 2) && (sys->CpState != 3))  //State B1, B2
    {
        #if CP_PROTECTION_MECHANISM == ENABLE
        ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso1responseCodeType_FAILED;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
        sprintf((char*)buf_log_evcomm,
                "[Proc_iso1_ServiceDiscoveryRes]Emergency Stop by CP Error (%d)",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #else
        sprintf((char*)buf_log_evcomm,
                "[Proc_iso1_ServiceDiscoveryRes]Emergency Stop by CP Error (%d): ignored",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #endif
    }

    if (sys->DC_EVSEStatus == EVSE_Shutdown ||
        sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso1responseCodeType_FAILED;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_ServiceDiscoveryRes]shutdown by EVSE");
        errn = -1;
    }

    //Check for Permission Changing from TRUE to FALSE
    /*+++ 20200808, vern, sync with Tesla CHAdeMO adaptor, 2 for start communication(not yet auth), 1 for star charging (authorized)  ---*/
    if (ShmInternalComm->ChargingPermission_pre >= 1 &&
        ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][ISO1][ServiceDiscoveryRes]Permission OFF");
        ccs_exi_doc_DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso1responseCodeType_FAILED;
        errn = -1;
    }

    //[2/4] PaymentOptionList
    ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.PaymentOptionList.PaymentOption.arrayLen = 1u;
    ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.PaymentOptionList.PaymentOption.array[0] = iso1paymentOptionType_ExternalPayment; //1

    //[3/4] Charge Service
    res->ChargeService.Services.ServiceID = 1;
    ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceID = (unsigned short) res->ChargeService.Services.ServiceID;
    //ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceName_isUsed = 1;   //new in ISO1, not be used, yet.
    //ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceName.charactersLen = xxx;
    //ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceName.characters[i] = xxx;
    ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceCategory = iso1serviceCategoryType_EVCharging;
    ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.FreeService = 1; //[Joseph] for test
    ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.arrayLen = 1u;    //[ISO1] max = 6

    switch (ShmCcsData->EnergyTransferMode)
    {
        case DC_extended:
        {
            ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.array[0] = iso1EnergyTransferModeType_DC_extended;
            break;
        }

        case AC_single_phase_core:
        {
            ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.array[0] = iso1EnergyTransferModeType_AC_single_phase_core;
            break;
        }

        case AC_three_phase_core:
        {
            ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.array[0] = iso1EnergyTransferModeType_AC_three_phase_core;
            break;
        }

        default:
        {
            sprintf((char*)buf_log_evcomm,
                    "[ISO1][ServiceDiscoveryRes][Warning]unexpected EnergyTransferMode(%d)",
                    ShmCcsData->EnergyTransferMode);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            break;
        }
    }


    //[4/4] Service List (null, not be uesed for now.)
    //#if PARAMETER_NORMAL_MODE == ENABLE
    ///////////////SHM_Read_iso1_ServiceDiscoveryRes(&ccs_exi_doc_ISO1, ShmCcsData);
    //#endif


    // ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        errn = -1;
    }

    return errn;
}

/*===========================================================================
FUNCTION: Proc_din_ServiceDiscoveryReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_ServiceDiscoveryReq(int AcceptFd)
{
    int errn = 0;
    DEBUG_PRINTF_EVCOMM_DETAIL("\n[SeccComm][Proc_din_ServiceDiscoveryReq]Got ServiceDiscoveryReq\n");

    //Print the decoded XML Document
    PRINT_XML_DOC_DIN_ServiceDiscoveryReq(&ccs_exi_doc_DIN);

    //Save into Share Memory
    SHM_Save_din_ServiceDiscoveryReq(ShmCcsData, &ccs_exi_doc_DIN, ShmSysConfigAndInfo);

    errn = Proc_din_ServiceDiscoveryRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][V2G][Tx]ServiceDiscoveryRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_din_ServiceDiscoveryReq]Proc_din_ServiceDiscoveryRes(): %d (DEC)",
                errn
                );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_ServiceDiscoveryReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_ServiceDiscoveryReq(int AcceptFd)
{
    int errn = 0;
    DEBUG_PRINTF_EVCOMM_DETAIL("[SeccComm][Proc_iso1_ServiceDiscoveryReq]Got ServiceDiscoveryReq\n");

    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_ServiceDiscoveryReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_ServiceDiscoveryReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    errn = Proc_iso1_ServiceDiscoveryRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][V2G][Tx]ServiceDiscoveryRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_iso1_ServiceDiscoveryReq]Proc_iso1_ServiceDiscoveryRes(): %d (DEC)",
                errn
                );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_din_ServiceAndPaymentSelectionRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_ServiceAndPaymentSelectionRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    struct ServiceAndPaymentSelectionRequest_DIN70121 *req;
    //struct ServiceAndPaymentSelectionResponse_DIN70121 *res;
    struct ServiceDiscoveryResponse_DIN70121 *sd_res;
    struct ChargingInfoData *sys;


    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    req = &ShmCcsData->V2GMessage_DIN70121.ServiceAndPaymentSelectionRequest;
    //res = &ShmCcsData->V2GMessage_DIN70121.ServiceAndPaymentSelectionResponse;
    sd_res = &ShmCcsData->V2GMessage_DIN70121.ServiceDiscoveryResponse;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];


    init_dinBodyType(&ccs_exi_doc_DIN.V2G_Message.Body);
    init_dinServicePaymentSelectionResType(&ccs_exi_doc_DIN.V2G_Message.Body.ServicePaymentSelectionRes);

    //[1/1] Response Code
    ccs_exi_doc_DIN.V2G_Message.Body.ServicePaymentSelectionRes_isUsed = 1u;
    ccs_exi_doc_DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_OK;


    //[HEADER] Check Req SessionID
    if (Check_din_V2G_Rx_MSG_SessionID(&ccs_exi_doc_DIN) < 0)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //Check for SelectedPaymentOption (TC_SECC_VTB_ServicePaymentSelection_007)
    if (req->SelectedPaymentOption != ExternalPayment)  //1
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED_PaymentSelectionInvalid;
        sprintf((char*)buf_log_evcomm,
                "[ERROR]unexpected SelectedPaymentOption(%d) => End_Process (EIM only, no PnC, yet.)",
                req->SelectedPaymentOption);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_Payment SelectionInvalid (023762)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 6;
        ShmStatusCodeData->PresentStatusCode[0][5] = 2;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
    }

    //Check for ServiceID (TC_SECC_VTB_ServicePaymentSelection_004)
    if (req->SelectedServiceList.SelectedService[0].ServiceID != sd_res->ChargeService_DIN70121.Services.ServiceTag.ServiceID)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED_ServiceSelectionInvalid;  //8
        sprintf((char*)buf_log_evcomm,
                "[ERROR]Wrong selected ServiceID(%d) => End_Process",
                req->SelectedServiceList.SelectedService[0].ServiceID);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_ServiceSelectionInvalid (023764)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 6;
        ShmStatusCodeData->PresentStatusCode[0][5] = 4;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
    }


    //Detect for CP State should be 9V (State B)
    if ((sys->CpState != 2) && (sys->CpState != 3))  //State B1, B2
    {
        #if CP_PROTECTION_MECHANISM == ENABLE
        ccs_exi_doc_DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
        sprintf((char*)buf_log_evcomm,
                "[Proc_din_ServiceAndPaymentSelectionRes]Emergency Stop by CP Error (%d)",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #else
        sprintf((char*)buf_log_evcomm,
                "[Proc_din_ServiceAndPaymentSelectionRes]Emergency Stop by CP Error (%d): ignored due to function is disabled",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #endif
    }

    if (sys->DC_EVSEStatus == EVSE_Shutdown ||
        sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_ServiceAndPaymentSelectionRes]shutdown by EVSE");
        ccs_exi_doc_DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED;
        errn = -1;
    }

    //Check for Permission Changing from TRUE to FALSE
    /*+++ 20200808, vern, sync with Tesla CHAdeMO adaptor, 2 for start communication(not yet auth), 1 for star charging (authorized)  ---*/
    if (ShmInternalComm->ChargingPermission_pre >= 1 &&
        ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][DIN][ServicePaymentSelectionRes]Permission OFF");
        ccs_exi_doc_DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED;
        errn = -1;
    }

    // ============ Encode and Send Response Message ===========
    if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_DIN) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_ServiceAndPaymentSelectionRes]Tx encoded msg error");
        errn = -1;
    }

    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_ServiceAndPaymentSelectionRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_ServiceAndPaymentSelectionRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    struct ServiceAndPaymentSelectionRequest_ISO15118_2014 *req;
    //struct ServiceAndPaymentSelectionResponse_ISO15118_2014 *res;
    struct ServiceDiscoveryResponse_ISO15118_2014 *sd_res;
    static struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    req = &ShmCcsData->V2GMessage_ISO15118_2014.ServiceAndPaymentSelectionRequest;
    //res = &ShmCcsData->V2GMessage_ISO15118_2014.ServiceAndPaymentSelectionResponse;
    sd_res = &ShmCcsData->V2GMessage_ISO15118_2014.ServiceDiscoveryResponse;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body);
    init_iso1PaymentServiceSelectionResType(&ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes);

    //[1/1] Response Code
    ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes_isUsed = 1u;
    ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_OK;


    //[HEADER] Check Req SessionID
    if (Check_iso1_V2G_Rx_MSG_SessionID(&ccs_exi_doc_ISO1) < 0)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //Check for SelectedPaymentOption (TC_SECC_VTB_ServicePaymentSelection_007)
    if (req->SelectedPaymentOption != ExternalPayment)  //1
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_PaymentSelectionInvalid;
        sprintf((char*)buf_log_evcomm,
                "[ERROR]unexpected SelectedPaymentOption(%d) => End_Process (EIM only, no PnC, yet.)",
                req->SelectedPaymentOption);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_Payment SelectionInvalid (023762)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 6;
        ShmStatusCodeData->PresentStatusCode[0][5] = 2;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
    }


    //Check for ServiceID (TC_SECC_VTB_ServicePaymentSelection_004)
    if (req->SelectedServiceList.SelectedService[0].ServiceID != sd_res->ChargeService.Services.ServiceID)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_ServiceSelectionInvalid;  //8
        sprintf((char*)buf_log_evcomm,
                "[ERROR]Wrong selected ServiceID(%d) => End_Process",
                req->SelectedServiceList.SelectedService[0].ServiceID);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_ServiceSelectionInvalid (023764)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 6;
        ShmStatusCodeData->PresentStatusCode[0][5] = 4;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
    }


    //Detect for CP State should be 9V (State B)
    if ((sys->CpState != 2) && (sys->CpState != 3))  //State B1, B2
    {
        #if CP_PROTECTION_MECHANISM == ENABLE
        ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
        sprintf((char*)buf_log_evcomm,
                "[Proc_iso1_ServiceAndPaymentSelectionRes]Emergency Stop by CP Error (%d)",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #else
        sprintf((char*)buf_log_evcomm,
                "[Proc_iso1_ServiceAndPaymentSelectionRes]Emergency Stop by CP Error (%d): ignored due to function is disabled",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        #endif
    }

    if (sys->DC_EVSEStatus == EVSE_Shutdown ||
        sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_ServiceAndPaymentSelectionRes]shutdown by EVSE");
        ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED;
        errn = -1;
    }

    //Check for Permission Changing from TRUE to FALSE
    /*+++ 20200808, vern, sync with Tesla CHAdeMO adaptor, 2 for start communication(not yet auth), 1 for star charging (authorized)  ---*/
    if (ShmInternalComm->ChargingPermission_pre >= 1 &&
        ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][ISO1][PaymentServiceSelectionRes]Permission OFF");
        ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED;
        errn = -1;
    }

    // ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_ServiceAndPaymentSelectionRes]Tx encoded msg error");
        errn = -1;
    }

    return errn;
}

/*===========================================================================
FUNCTION: Proc_din_ServiceAndPaymentSelectionReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_ServiceAndPaymentSelectionReq(int AcceptFd)
{
    int errn = 0;
    DEBUG_PRINTF_EVCOMM_DETAIL("[SeccComm][Proc_din_ServiceAndPaymentSelectionReq]Got ServiceAndPaymentSelectionReq");
    //Print the decoded XML Document
    PRINT_XML_DOC_DIN_ServiceAndPaymentSelectionReq(&ccs_exi_doc_DIN);

    //Save into Share Memory
    SHM_Save_din_ServiceAndPaymentSelectionReq(ShmCcsData, &ccs_exi_doc_DIN, ShmSysConfigAndInfo);

    errn = Proc_din_ServiceAndPaymentSelectionRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][V2G][Tx]ServiceAndPaymentSelectionRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
        "[Error][Proc_iso1_ServiceAndPaymentSelectionReq]Proc_iso1_ServiceAndPaymentSelectionRes(): %d (DEC)",
        errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}


/*===========================================================================
FUNCTION: Proc_iso1_ServiceAndPaymentSelectionReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_ServiceAndPaymentSelectionReq(int AcceptFd)
{
    int errn = 0;
    DEBUG_PRINTF_EVCOMM_DETAIL("[SeccComm][Proc_iso1_ServiceAndPaymentSelectionReq]Got ServiceAndPaymentSelectionReq");


    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_ServiceAndPaymentSelectionReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_ServiceAndPaymentSelectionReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    errn = Proc_iso1_ServiceAndPaymentSelectionRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][V2G][Tx]ServiceAndPaymentSelectionRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][Proc_iso1_ServiceAndPaymentSelectionReq]Proc_iso1_ServiceAndPaymentSelectionRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}


/*===========================================================================
FUNCTION: Proc_din_ContractAuthenticationRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_ContractAuthenticationRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct ChargingInfoData *sys;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;

    init_dinBodyType(&ccs_exi_doc_DIN.V2G_Message.Body);
    init_dinContractAuthenticationResType(&ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes);

    ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes_isUsed = 1u;

    //[BODY (1/2)] ResponseCode
    ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_OK;
    ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.EVSEProcessing = dinEVSEProcessingType_Ongoing; //0


    //[HEADER] Check Req SessionID
    if (Check_din_V2G_Rx_MSG_SessionID(&ccs_exi_doc_DIN) < 0)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //Detect for CP State should be 9V (State B)
    #if CP_PROTECTION_MECHANISM == ENABLE
    if ((sys->CpState != 2) && (sys->CpState != 3))  //State B1, B2
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_FAILED;
        ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.EVSEProcessing =  dinEVSEProcessingType_Finished;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
        sprintf((char*)buf_log_evcomm,
                "[Proc_din_ContractAuthenticationRes]Emergency Stop by CP Error (%d)",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    #endif

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_FAILED;
        ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.EVSEProcessing =  dinEVSEProcessingType_Finished;
        errn = -1;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_FAILED;
        ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.EVSEProcessing =  dinEVSEProcessingType_Finished;
        errn = -1;
    }

    //[BODY (2/2)] EVSEProcessing
    if(ShmInternalComm->ChargingPermission == TRUE)
    {
        ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.EVSEProcessing = dinEVSEProcessingType_Finished; //0
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "CSU Permission: OK");

        #if (SLAC_FIRST_RESPONSE_METHOD == SET_5_PWM_ONCE_GET_PERMISSION_IN_AUTHORIZATIONRES)
        {
            //Set PWM as 5% (for SLAC first case)
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "Set PWM as 5%%");
            SwitchCpStateE(DISABLE);
            OutputCpPwmDuty(5);
        }
        #endif
    }

    //Check for Permission Changing from TRUE to FALSE
    if (ShmInternalComm->ChargingPermission_pre == TRUE &&
        ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][DIN][ContractAuthenticationRes]Permission OFF");
        ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_FAILED;
        ccs_exi_doc_DIN.V2G_Message.Body.ContractAuthenticationRes.EVSEProcessing =  dinEVSEProcessingType_Finished;
        errn = -1;
    }

    #if PARAMETER_NORMAL_MODE == ENABLE
    ////////////SHM_Read_din_ContractAuthenticationRes(&ccs_exi_doc_DIN, ShmCcsData);
    #endif


    // ============ Encode and Send Response Message ===========
    if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_DIN) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_ChargeParameterDiscoveryRes][Error]Tx encoded msg error");
        errn = -1;
    }

    return errn;
}


/*===========================================================================
FUNCTION: Proc_iso1_AuthorizationRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_AuthorizationRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct ChargingInfoData *sys;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;

    init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body);
    init_iso1AuthorizationResType(&ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes);

    ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes_isUsed = 1u;

    //[BODY (1/2)] ResponseCode
    ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = iso1responseCodeType_OK;
    /*+++ 20200808, vern, EVSEProcessing should be waiting for Customer during authrization +++*/
    ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.EVSEProcessing = iso1EVSEProcessingType_Ongoing_WaitingForCustomerInteraction; //0
    /*--- 20200808, vern, should be waiting for Customer during authrization ---*/

    //[HEADER] Check Req SessionID
    if (Check_iso1_V2G_Rx_MSG_SessionID(&ccs_exi_doc_ISO1) < 0)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }


    //Detect for CP State should be 9V (State B)
    #if CP_PROTECTION_MECHANISM == ENABLE
    if ((sys->CpState != 2) && (sys->CpState != 3))  //State B1, B2
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = iso1responseCodeType_FAILED;
        ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.EVSEProcessing =  iso1EVSEProcessingType_Finished;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;

        sprintf((char*)buf_log_evcomm,
                "[Proc_iso1_AuthorizationRes]Emergency Stop by CP Error (%d)",
                sys->CpState);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    #endif

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = FAILED_ISO15118_2014;
        ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.EVSEProcessing =  iso1EVSEProcessingType_Finished;
        errn = -1;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = FAILED_ISO15118_2014;
        ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.EVSEProcessing =  iso1EVSEProcessingType_Finished;
        errn = -1;
    }
    //[BODY (2/2)] EVSEProcessing
    //Check for Permission from CSU
    if(ShmInternalComm->ChargingPermission == TRUE)
    {
        ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.EVSEProcessing = iso1EVSEProcessingType_Finished; //0
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "CSU Permission: OK");

        #if (SLAC_FIRST_RESPONSE_METHOD == SET_5_PWM_ONCE_GET_PERMISSION_IN_AUTHORIZATIONRES)
        {
            //Set PWM as 5% (for SLAC first case)
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "Set PWM as 5%");
            SwitchCpStateE(DISABLE);
            OutputCpPwmDuty(5);
        }
        #endif
    }

    //Check for Permission Changing from TRUE to FALSE
    /*+++ 20200808, vern, sync with Tesla CHAdeMO adaptor, 2 for start communication(not yet auth), 1 for star charging (authorized)  ---*/
    if (ShmInternalComm->ChargingPermission_pre >= 1 &&
        ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][ISO1][AuthorizationRes]Permission OFF");
        ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = FAILED_ISO15118_2014;
        ccs_exi_doc_ISO1.V2G_Message.Body.AuthorizationRes.EVSEProcessing =  iso1EVSEProcessingType_Finished;
        errn = -1;
    }

    #if PARAMETER_NORMAL_MODE == ENABLE
    ////////////SHM_Read_iso1_AuthorizationRes(&ccs_exi_doc_ISO1, ShmCcsData);
    #endif


    // ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_ChargeParameterDiscoveryRes][Error]Tx encoded msg error");
        errn = -1;
    }

    return errn;
}


/*===========================================================================
FUNCTION: Proc_din_ContractAuthenticationReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_ContractAuthenticationReq(int AcceptFd)
{
    int errn = 0;

        DEBUG_PRINTF_EVCOMM_DETAIL("\n[SeccComm][Proc_din_ContractAuthenticationReq]Got Proc_din_ContractAuthenticationReq\n");


        //Print the decoded XML Document
        PRINT_XML_DOC_DIN_ContractAuthenticationReq(&ccs_exi_doc_DIN);

        //Save into Share Memory
        SHM_Save_din_ContractAuthenticationReq(ShmCcsData, &ccs_exi_doc_DIN, ShmSysConfigAndInfo);

        errn = Proc_din_ContractAuthenticationRes(AcceptFd);
        if (errn == 0)
        {
            //send response successfully.
            //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][V2G][Tx]ContractAuthenticationRes");
        }
        else
        {
            sprintf((char*)buf_log_evcomm,
                    "[Error][SeccComm][Proc_din_ContractAuthenticationReq]Proc_iso1_AuthenticationRes(): %d (DEC)",
                    errn);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        }

    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_AuthenticationReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_AuthenticationReq(int AcceptFd)
{
    int errn = 0;
    DEBUG_PRINTF_EVCOMM_DETAIL("[SeccComm][Proc_iso1_AuthenticationReq]Got AuthorizationReq\n");


    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_AuthorizationReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_AuthorizationReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    errn = Proc_iso1_AuthorizationRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][V2G][Tx]AuthorizationRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_iso1_AuthenticationReq]Proc_iso1_AuthenticationRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}



/*===========================================================================
FUNCTION: SHM_Init_dinDC_EVSEStatusType
DESCRIPTION:
PRE-CONDITION:
INPUT:
		1. in
OUTPUT:
		2. out

GLOBAL VARIABLES:
=============================================================================*/
void SHM_Init_dinDC_EVSEStatusType(struct DC_EVSEStatusType_DIN70121 *in)
{
	in->EVSEIsolationStatus = dinisolationLevelType_Valid;
	//	dinisolationLevelType_Invalid = 0,
	//	dinisolationLevelType_Valid = 1, (default)
	//	dinisolationLevelType_Warning = 2,
	//	dinisolationLevelType_Fault = 3

	in->EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;
	// dinDC_EVSEStatusCodeType_EVSE_NotReady = 0,
	// dinDC_EVSEStatusCodeType_EVSE_Ready = 1, (default)
	// dinDC_EVSEStatusCodeType_EVSE_Shutdown = 2,
	// dinDC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
	// dinDC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
	// dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
	// dinDC_EVSEStatusCodeType_EVSE_Malfunction = 6,
	// dinDC_EVSEStatusCodeType_Reserved_8 = 7,
	// dinDC_EVSEStatusCodeType_Reserved_9 = 8,
	// dinDC_EVSEStatusCodeType_Reserved_A = 9,
	// dinDC_EVSEStatusCodeType_Reserved_B = 10,
	// dinDC_EVSEStatusCodeType_Reserved_C = 11

	in->EVSENotification = dinEVSENotificationType_None;
	// dinEVSENotificationType_None = 0, (default)
	// dinEVSENotificationType_StopCharging = 1,
	// dinEVSENotificationType_ReNegotiation = 2
}

/*===========================================================================
FUNCTION: SHM_Save_dinPhysicalValueType
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void SHM_Save_dinPhysicalValueType(struct PhysicalValueType_DIN70121 *obj, short value, int multiplier, unsigned char unit)
{
    obj->Value = value;
    obj->Multiplier = multiplier;
    obj->Unit =unit;
}

/*===========================================================================
FUNCTION: SHM_Init_din_ChargeParameterDiscoveryRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
		1. shm_ccs
OUTPUT:
		2. shm_ccs

GLOBAL VARIABLES:
=============================================================================*/
void SHM_Init_din_ChargeParameterDiscoveryRes(struct CcsData *shm_ccs)
{
	struct ChargeParameterDiscoveryResponse_DIN70121 *in;

	in = &shm_ccs->V2GMessage_DIN70121.ChargeParameterDiscoveryResponse;

	//----- [BODY (1/5)] ResponseCode -----
    in->ResponseCode = dinresponseCodeType_OK;

    //----- [BODY (2/5)] EVSEProcessing -----
    in->EVSEProcessing = dinEVSEProcessingType_Ongoing;    //0
    // 	dinEVSEProcessingType_Finished = 0,
    //	dinEVSEProcessingType_Ongoing = 1

    //----- [BODY (3/5)] SAScheduleList of SASchedules -----
	//be fixed in another function.

    //-----  [BODY (4/5)] AC_EVSEChargeParameter of EVSEChargeParameter -----
    //ignore, since DIN doesn't support AC

    //----- [BODY (5/5)] DC_EVSEChargeParameter of EVSEChargeParameter -----
	struct DC_EVSEChargeParameterType_DIN70121 *in_para;
	in_para = &in->DC_EVSEChargeParameter;

    //DC_EVSEStatus
	SHM_Init_dinDC_EVSEStatusType(&in_para->DC_EVSEStatus);
    in_para->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid;

    short value = 0; int multiplier = 0; unsigned char unit = 0;

    //EVSEMaximumCurrentLimit
    value = 600; multiplier = -1; unit = A_DIN70121;    //60A
	SHM_Save_dinPhysicalValueType(&in_para->EVSEMaximumCurrentLimit, value, multiplier, unit);

    //EVSEMaximumPowerLimit
    value = 3000; multiplier = 1; unit = W_DIN70121;    //30KW
	SHM_Save_dinPhysicalValueType(&in_para->EVSEMaximumPowerLimit, value, multiplier, unit);

    //EVSEMaximumVoltageLimit
    value = 7500; multiplier = -1; unit = V_DIN70121;   //750V
	SHM_Save_dinPhysicalValueType(&in_para->EVSEMaximumVoltageLimit, value, multiplier, unit);

    //EVSEMinimumVoltageLimit
    value = 1500; multiplier = -1; unit = V_DIN70121;   //150V
	SHM_Save_dinPhysicalValueType(&in_para->EVSEMinimumVoltageLimit, value, multiplier, unit);


    //EVSEMinimumCurrentLimit
    value = 10; multiplier = -1; unit = A_DIN70121;     //1A
	SHM_Save_dinPhysicalValueType(&in_para->EVSEMinimumCurrentLimit, value, multiplier, unit);

    //EVSECurrentRegulationTolerance
    value = 10; multiplier = -1; unit = A_DIN70121;      //1A
	SHM_Save_dinPhysicalValueType(&in_para->EVSECurrentRegulationTolerance, value, multiplier, unit);

    //EVSEPeakCurrentRipple
    value = 2; multiplier = -1; unit = A_DIN70121;      //0.2A
	SHM_Save_dinPhysicalValueType(&in_para->EVSEPeakCurrentRipple, value, multiplier, unit);

    //EVSEEnergyToBeDelivered (optional)
    //SHM_Save_dinPhysicalValueType(&out_para->EVSEEnergyToBeDelivered, &in_para->EVSEEnergyToBeDelivered);
}

/*===========================================================================
FUNCTION: Sudo_Parameter_din_ChargeParameterDiscoveryRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_din_ChargeParameterDiscoveryRes()
{
    init_dinBodyType(&ccs_exi_doc_DIN.V2G_Message.Body);
    init_dinChargeParameterDiscoveryResType(&ccs_exi_doc_DIN.V2G_Message.Body.ChargeParameterDiscoveryRes);

    ccs_exi_doc_DIN.V2G_Message.Body.ChargeParameterDiscoveryRes_isUsed = 1u;

    //----- [BODY (1/5)] ResponseCode -----
    struct dinChargeParameterDiscoveryResType *res;
    res = &ccs_exi_doc_DIN.V2G_Message.Body.ChargeParameterDiscoveryRes;
    res->ResponseCode = dinresponseCodeType_OK;

    //----- [BODY (2/5)] EVSEProcessing -----
    res->EVSEProcessing = dinEVSEProcessingType_Finished; //0
    // 	dinEVSEProcessingType_Finished = 0,
    //	dinEVSEProcessingType_Ongoing = 1

    //----- [BODY (3/5)] SAScheduleList of SASchedules -----
    res->SAScheduleList_isUsed = 1u;
    struct dinSAScheduleListType *list;
    list = &res->SAScheduleList;
    //
    list->SAScheduleTuple.arrayLen = 1;
    list->SAScheduleTuple.array[0].SAScheduleTupleID = 0;
    list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleID = 0;
    list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.arrayLen = 1;
    list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.array[0].RelativeTimeInterval_isUsed = 1u;
    list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.array[0].RelativeTimeInterval.start = 0;
    //list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.array[0].RelativeTimeInterval.duration = xxx
    //list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.array[0].RelativeTimeInterval.duration_isUsed = 1u;
    //list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.array[0].TimeInterval_isUsed = 0u;
    //list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.array[0].TimeInterval.xxx
    //list->SAScheduleTuple.array[0].SalesTariff.xxx
    //list->SAScheduleTuple.array[0].SalesTariff_isUsed = 0u;


    //-----  [BODY (4/5)] AC_EVSEChargeParameter of EVSEChargeParameter -----
    //ignore, since DIN doesn't support AC

    //----- [BODY (5/5)] DC_EVSEChargeParameter of EVSEChargeParameter -----
    res->DC_EVSEChargeParameter_isUsed = 1u;
    struct dinDC_EVSEChargeParameterType *para;
    para = &res->DC_EVSEChargeParameter;

    //DC_EVSEStatus
    para->DC_EVSEStatus.EVSEIsolationStatus_isUsed = 1u;
    para->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid;
    //	dinisolationLevelType_Invalid = 0,
    //	dinisolationLevelType_Valid = 1,
    //	dinisolationLevelType_Warning = 2,
    //	dinisolationLevelType_Fault = 3

    para->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;
    // dinDC_EVSEStatusCodeType_EVSE_NotReady = 0,
    // dinDC_EVSEStatusCodeType_EVSE_Ready = 1,
    // dinDC_EVSEStatusCodeType_EVSE_Shutdown = 2,
    // dinDC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
    // dinDC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
    // dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
    // dinDC_EVSEStatusCodeType_EVSE_Malfunction = 6,
    // dinDC_EVSEStatusCodeType_Reserved_8 = 7,
    // dinDC_EVSEStatusCodeType_Reserved_9 = 8,
    // dinDC_EVSEStatusCodeType_Reserved_A = 9,
    // dinDC_EVSEStatusCodeType_Reserved_B = 10,
    // dinDC_EVSEStatusCodeType_Reserved_C = 11

    para->DC_EVSEStatus.NotificationMaxDelay = 0u;

    para->DC_EVSEStatus.EVSENotification = dinEVSENotificationType_None;
    // dinEVSENotificationType_None = 0,
    // dinEVSENotificationType_StopCharging = 1,
    // dinEVSENotificationType_ReNegotiation = 2

    //EVSEMaximumCurrentLimit
    para->EVSEMaximumCurrentLimit.Value = 2400;
    para->EVSEMaximumCurrentLimit.Multiplier = -1;
    para->EVSEMaximumCurrentLimit.Unit_isUsed = 1u;
    para->EVSEMaximumCurrentLimit.Unit = dinunitSymbolType_A;
    //	dinunitSymbolType_h = 0,
    //	dinunitSymbolType_m = 1,
    //	dinunitSymbolType_s = 2,
    //	dinunitSymbolType_A = 3,
    //	dinunitSymbolType_Ah = 4,
    //	dinunitSymbolType_V = 5,
    //	dinunitSymbolType_VA = 6,
    //	dinunitSymbolType_W = 7,
    //	dinunitSymbolType_W_s = 8,
    //	dinunitSymbolType_Wh = 9

    //EVSEMaximumPowerLimit
    para->EVSEMaximumPowerLimit.Value = 6000;
    para->EVSEMaximumPowerLimit.Multiplier = 1;
    para->EVSEMaximumPowerLimit.Unit_isUsed = 1u;
    para->EVSEMaximumPowerLimit.Unit = dinunitSymbolType_W;


    //EVSEMaximumVoltageLimit
    para->EVSEMaximumVoltageLimit.Value = 7500;
    para->EVSEMaximumVoltageLimit.Multiplier = -1;
    para->EVSEMaximumVoltageLimit.Unit_isUsed = 1u;
    para->EVSEMaximumVoltageLimit.Unit = dinunitSymbolType_V;

    //EVSEMinimumVoltageLimit
    para->EVSEMinimumVoltageLimit.Value = 1500;
    para->EVSEMinimumVoltageLimit.Multiplier = -1;
    para->EVSEMinimumVoltageLimit.Unit_isUsed = 1u;
    para->EVSEMinimumVoltageLimit.Unit = dinunitSymbolType_V;


    //EVSEMinimumCurrentLimit
    para->EVSEMinimumCurrentLimit.Value = 20;
    para->EVSEMinimumCurrentLimit.Multiplier = -1;
    para->EVSEMinimumCurrentLimit.Unit_isUsed = 1u;
    para->EVSEMinimumCurrentLimit.Unit = dinunitSymbolType_A;

    //EVSECurrentRegulationTolerance_isUsed
    para->EVSECurrentRegulationTolerance_isUsed = 1u;
    //EVSECurrentRegulationTolerance
    para->EVSECurrentRegulationTolerance.Value = 10;
    para->EVSECurrentRegulationTolerance.Multiplier = -1;
    para->EVSECurrentRegulationTolerance.Unit_isUsed = 1u;
    para->EVSECurrentRegulationTolerance.Unit = dinunitSymbolType_A;


    //EVSEEnergyToBeDelivered_isUsed
    para->EVSEEnergyToBeDelivered_isUsed = 1u;
    //EVSEPeakCurrentRipple
    para->EVSEPeakCurrentRipple.Value = 2;
    para->EVSEPeakCurrentRipple.Multiplier = -1;
    para->EVSEPeakCurrentRipple.Unit_isUsed = 1u;
    para->EVSEPeakCurrentRipple.Unit = dinunitSymbolType_A;


    //EVSEEnergyToBeDelivered (optional)
    /*
    para->EVSEEnergyToBeDelivered.Value = 360;
    para->EVSEEnergyToBeDelivered.Multiplier = 3;
    para->EVSEEnergyToBeDelivered.Unit_isUsed = 1u;
    para->EVSEEnergyToBeDelivered.Unit = dinunitSymbolType_Wh;
    */
}

/*===========================================================================
FUNCTION: Sudo_Parameter_iso1_ChargeParameterDiscoveryRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_iso1_ChargeParameterDiscoveryRes()
{
    init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body);
    init_iso1ChargeParameterDiscoveryResType(&ccs_exi_doc_ISO1.V2G_Message.Body.ChargeParameterDiscoveryRes);

    ccs_exi_doc_ISO1.V2G_Message.Body.ChargeParameterDiscoveryRes_isUsed = 1u;

    //----- [BODY (1/5)] ResponseCode -----
    struct iso1ChargeParameterDiscoveryResType *res;
    res = &ccs_exi_doc_ISO1.V2G_Message.Body.ChargeParameterDiscoveryRes;
    res->ResponseCode = iso1responseCodeType_OK;

    //----- [BODY (2/5)] EVSEProcessing -----
    res->EVSEProcessing = iso1EVSEProcessingType_Finished; //0
    // 	iso1EVSEProcessingType_Finished = 0,
    //	iso1EVSEProcessingType_Ongoing = 1

    //----- [BODY (3/5)] SAScheduleList of SASchedules -----
    res->SAScheduleList_isUsed = 1u;
    struct iso1SAScheduleListType *list;
    list = &res->SAScheduleList;
    //
    list->SAScheduleTuple.arrayLen = 1;
    list->SAScheduleTuple.array[0].SAScheduleTupleID = 0;
    list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.arrayLen = 1;
    list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.array[0].RelativeTimeInterval_isUsed = 1u;
    list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.array[0].RelativeTimeInterval.start = 0;
    //list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.array[0].RelativeTimeInterval.duration = xxx
    //list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.array[0].RelativeTimeInterval.duration_isUsed = 1u;
    //list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.array[0].TimeInterval_isUsed = 0u;
    //list->SAScheduleTuple.array[0].PMaxSchedule.PMaxScheduleEntry.array[0].TimeInterval.xxx
    //list->SAScheduleTuple.array[0].SalesTariff.xxx
    //list->SAScheduleTuple.array[0].SalesTariff_isUsed = 0u;


    //-----  [BODY (4/5)] AC_EVSEChargeParameter of EVSEChargeParameter -----
    //ignore, since our ISO1 doesn't support AC, yet

    //----- [BODY (5/5)] DC_EVSEChargeParameter of EVSEChargeParameter -----
    res->DC_EVSEChargeParameter_isUsed = 1u;
    struct iso1DC_EVSEChargeParameterType *para;
    para = &res->DC_EVSEChargeParameter;

    //DC_EVSEStatus
    para->DC_EVSEStatus.EVSEIsolationStatus_isUsed = 1u;
    para->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Invalid;
    //	iso1isolationLevelType_Invalid = 0,
    //	iso1isolationLevelType_Valid = 1,
    //	iso1isolationLevelType_Warning = 2,
    //	iso1isolationLevelType_Fault = 3

    para->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;
    // iso1DC_EVSEStatusCodeType_EVSE_NotReady = 0,
    // iso1DC_EVSEStatusCodeType_EVSE_Ready = 1,
    // iso1DC_EVSEStatusCodeType_EVSE_Shutdown = 2,
    // iso1DC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
    // iso1DC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
    // iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
    // iso1DC_EVSEStatusCodeType_EVSE_Malfunction = 6,
    // iso1DC_EVSEStatusCodeType_Reserved_8 = 7,
    // iso1DC_EVSEStatusCodeType_Reserved_9 = 8,
    // iso1DC_EVSEStatusCodeType_Reserved_A = 9,
    // iso1DC_EVSEStatusCodeType_Reserved_B = 10,
    // iso1DC_EVSEStatusCodeType_Reserved_C = 11

    para->DC_EVSEStatus.NotificationMaxDelay = 0u;

    para->DC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None;
    // iso1EVSENotificationType_None = 0,
    // iso1EVSENotificationType_StopCharging = 1,
    // iso1EVSENotificationType_ReNegotiation = 2

    //EVSEMaximumCurrentLimit
    para->EVSEMaximumCurrentLimit.Value = 2400;
    para->EVSEMaximumCurrentLimit.Multiplier = -1;
    //para->EVSEMaximumCurrentLimit.Unit_isUsed = 1u;
    para->EVSEMaximumCurrentLimit.Unit = iso1unitSymbolType_A;
    //iso1unitSymbolType_h = 0,
	//iso1unitSymbolType_m = 1,
	//iso1unitSymbolType_s = 2,
	//iso1unitSymbolType_A = 3,
	//iso1unitSymbolType_V = 4,
	//iso1unitSymbolType_W = 5,
	//iso1unitSymbolType_Wh = 6

    //EVSEMaximumPowerLimit
    para->EVSEMaximumPowerLimit.Value = 6000;
    para->EVSEMaximumPowerLimit.Multiplier = 1;
    //para->EVSEMaximumPowerLimit.Unit_isUsed = 1u;
    para->EVSEMaximumPowerLimit.Unit = iso1unitSymbolType_W;


    //EVSEMaximumVoltageLimit
    para->EVSEMaximumVoltageLimit.Value = 7500;
    para->EVSEMaximumVoltageLimit.Multiplier = -1;
    //para->EVSEMaximumVoltageLimit.Unit_isUsed = 1u;
    para->EVSEMaximumVoltageLimit.Unit = iso1unitSymbolType_V;

    //EVSEMinimumVoltageLimit
    para->EVSEMinimumVoltageLimit.Value = 1500;
    para->EVSEMinimumVoltageLimit.Multiplier = -1;
    //para->EVSEMinimumVoltageLimit.Unit_isUsed = 1u;
    para->EVSEMinimumVoltageLimit.Unit = iso1unitSymbolType_V;


    //EVSEMinimumCurrentLimit
    para->EVSEMinimumCurrentLimit.Value = 20;
    para->EVSEMinimumCurrentLimit.Multiplier = -1;
    //para->EVSEMinimumCurrentLimit.Unit_isUsed = 1u;
    para->EVSEMinimumCurrentLimit.Unit = iso1unitSymbolType_A;

    //EVSECurrentRegulationTolerance_isUsed
    para->EVSECurrentRegulationTolerance_isUsed = 1u;
    //EVSECurrentRegulationTolerance
    para->EVSECurrentRegulationTolerance.Value = 10;
    para->EVSECurrentRegulationTolerance.Multiplier = -1;
    //para->EVSECurrentRegulationTolerance.Unit_isUsed = 1u;
    para->EVSECurrentRegulationTolerance.Unit = iso1unitSymbolType_A;


    //EVSEEnergyToBeDelivered_isUsed
    para->EVSEEnergyToBeDelivered_isUsed = 1u;
    //EVSEPeakCurrentRipple
    para->EVSEPeakCurrentRipple.Value = 2;
    para->EVSEPeakCurrentRipple.Multiplier = -1;
    //para->EVSEPeakCurrentRipple.Unit_isUsed = 1u;
    para->EVSEPeakCurrentRipple.Unit = iso1unitSymbolType_A;


    //EVSEEnergyToBeDelivered (optional)
    /*
    para->EVSEEnergyToBeDelivered.Value = 360;
    para->EVSEEnergyToBeDelivered.Multiplier = 3;
    para->EVSEEnergyToBeDelivered.Unit_isUsed = 1u;
    para->EVSEEnergyToBeDelivered.Unit = iso1unitSymbolType_Wh;
    */
}


/*===========================================================================
FUNCTION: Proc_din_ChargeParameterDiscoveryRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_ChargeParameterDiscoveryRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    int errn = 0;
    bitstream_t v2g_tx_stream;
    struct ChargeParameterDiscoveryResponse_DIN70121 *res;
    struct ChargeParameterDiscoveryRequest_DIN70121 *req;
    struct DC_EVSEChargeParameterType_DIN70121 *dc_para;
    struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    res = &ShmCcsData->V2GMessage_DIN70121.ChargeParameterDiscoveryResponse;
    req = &ShmCcsData->V2GMessage_DIN70121.ChargeParameterDiscoveryRequest;
    dc_para = &ShmCcsData->V2GMessage_DIN70121.ChargeParameterDiscoveryResponse.DC_EVSEChargeParameter;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    res->ResponseCode = OK_DIN70121;
    res->EVSEProcessing =  Ongoing_DIN70121;
    dc_para->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;    //1


    //[HEADER] Check Req SessionID
    if (Check_din_V2G_Rx_MSG_SessionID(&ccs_exi_doc_DIN) < 0)
    {
        res->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        res->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }


    //[TC_SECC_VTB_ChargeParameterDiscovery_005]
    if (sys->EvBatteryMaxCurrent < 0)
    {
        sprintf((char*)buf_log_evcomm,
                "[ERROR]EvBatteryMaxCurrent is negative(%.02f) => End_Process",
                sys->EvBatteryMaxCurrent);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

        res->ResponseCode = dinresponseCodeType_FAILED_WrongChargeParameter;    //16
        res->EVSEProcessing = Finished_DIN70121;
        dc_para->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
        errn = -1;
        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_WrongChargeParameter (023775)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 7;
        ShmStatusCodeData->PresentStatusCode[0][5] = 5;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
    }


    //STEP 2: ============ Modify Parameters of ShmCcsData ============
    SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMaximumPowerLimit, (int) (sys->AvailableChargingPower * 10), W_DIN70121);
    SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMaximumCurrentLimit, (int) (sys->AvailableChargingCurrent * 10), A_DIN70121);
    SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMaximumVoltageLimit, (int) (sys->MaximumChargingVoltage * 10), V_DIN70121);

    SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMinimumVoltageLimit, 1500, V_DIN70121); //150V
    SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMinimumCurrentLimit, 10, A_DIN70121); //1A
    SAVE_PhysicalValueType_DIN70121(&dc_para->EVSECurrentRegulationTolerance, 10, A_DIN70121); //1A
    SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEPeakCurrentRipple, 2, A_DIN70121);   //0.2A
    //SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEEnergyToBeDelivered, 0, WH_DIN70121); //optional

    #if PATCH_FOR_BMW_I3_BUG_EVSEMAXIMUMVOLTAGELIMIT_599V == ENABLE
    if (sys->EvBatteryMaxVoltage <= 500)
    {
        SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMaximumVoltageLimit, (int) (500 * 10), V_DIN70121);  //500V
    }
    #endif

    //for test with Tesla Model 3, 10A
    //SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMaximumCurrentLimit, (int) (10 * 10), A_DIN70121);   //10A, for testing with Tesla Model 3


    //Check for EnergyTransferMode [TC_SECC_VTB_ChargeParameterDiscovery_004]
    if (req->EVRequestedEnergyTransferType != DC_extended)
    {
        sprintf((char*)buf_log_evcomm,
                "[ERROR]Wrong EVRequestedEnergyTransferType(%d,%d)",
                req->EVRequestedEnergyTransferType,
                dinEVSESupportedEnergyTransferType_DC_extended);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        res->ResponseCode = FAILED_WrongEnergyTransferType_DIN70121;
        res->EVSEProcessing = Finished_DIN70121;
        dc_para->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
        errn = -1;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_WrongEnergyTransferMode (023774)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 7;
        ShmStatusCodeData->PresentStatusCode[0][5] = 4;
    }


    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_ChargeParameterDiscoveryRes]EVSE_Shutdown");
        res->ResponseCode = FAILED_DIN70121;
        res->EVSEProcessing = Finished_DIN70121;
        dc_para->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
        errn = -1;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_ChargeParameterDiscoveryRes]EVSE_EmergencyShutdown");
        res->ResponseCode = FAILED_DIN70121;
        res->EVSEProcessing = Finished_DIN70121;
        dc_para->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        errn = -1;
    }

    //Detect for CP State should be 9V (State B)
    #if CP_PROTECTION_MECHANISM == ENABLE
    if (sys->CpState != 3)  //State B1, B2
    {
        res->ResponseCode = FAILED_DIN70121;
        dc_para->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        res->EVSEProcessing = Finished_DIN70121;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;

        sprintf((char*)buf_log_evcomm,
                "[Proc_din_ChargeParameterDiscoveryRes]Emergency Stop by CP Error (%d, %.02f V)\n",
                sys->CpState,
                sys->CpVoltage);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    #endif

    //Check for Permission from CSU
    if (ShmInternalComm->ChargingPermission == TRUE)
    {
        res->EVSEProcessing = Finished_DIN70121;
    }

    //Check for Permission Off
    if (ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][DIN][ChargeParameterDiscoveryRes]Permission OFF");
        res->ResponseCode = FAILED_DIN70121;
        res->EVSEProcessing = Finished_DIN70121;
        dc_para->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
        errn = -1;
    }

    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_din_ChargeParameterDiscoveryRes(&ccs_exi_doc_DIN, ShmCcsData);
    #else
    Sudo_Parameter_din_ChargeParameterDiscoveryRes();
    #endif

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_DIN) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_ChargeParameterDiscoveryRes][Error]Tx encoded msg error");
        errn = -1;
    }

    //STPE 5: ============ Update Flags ============

    return errn;
}


/*===========================================================================
FUNCTION: Proc_iso1_ChargeParameterDiscoveryRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_ChargeParameterDiscoveryRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    int errn = 0;
    bitstream_t v2g_tx_stream;
    struct ChargeParameterDiscoveryResponse_ISO15118_2014 *res;
    struct ChargeParameterDiscoveryRequest_ISO15118_2014 *req;
    struct DC_EVSEChargeParameterType_ISO15118_2014 *dc_para;
    struct AC_EVSEChargeParameterType_ISO15118_2014 *ac_para;
    struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    res = &ShmCcsData->V2GMessage_ISO15118_2014.ChargeParameterDiscoveryResponse;
    req = &ShmCcsData->V2GMessage_ISO15118_2014.ChargeParameterDiscoveryRequest;
    dc_para = &ShmCcsData->V2GMessage_ISO15118_2014.ChargeParameterDiscoveryResponse.DC_EVSEChargeParameter;
    ac_para = &ShmCcsData->V2GMessage_ISO15118_2014.ChargeParameterDiscoveryResponse.AC_EVSEChargeParameter;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    res->ResponseCode = OK_ISO15118_2014;
    /*+++ 20200808, vern, EVSEProcessing should be on-going during ChargeParameterDiscovery +++*/
    res->EVSEProcessing =  iso1EVSEProcessingType_Ongoing;
    /*--- 20200808, vern, EVSEProcessing should be on-going during ChargeParameterDiscovery ---*/
    dc_para->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;    //1
    ac_para->AC_EVSEStatus.RCD = ShmInternalComm->AC_RcdStatus; //0:no error, 1:error
    ac_para->AC_EVSEStatus.NotificationMaxDelay = 0;  //unit: 1s
    ac_para->AC_EVSEStatus.EVSENotification = ShmInternalComm->AC_EVSENotification; //0:none, 1:StopCharging, 2:RenNgotiation


    //[HEADER] Check Req SessionID
    if (Check_iso1_V2G_Rx_MSG_SessionID(&ccs_exi_doc_ISO1) < 0)
    {
        res->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        res->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }


    //[TC_SECC_VTB_ChargeParameterDiscovery_005]
    /*+++ 20200808, vern, should check the voltage and current to see if the range of battery parameter is accepted by charger ---*/
    if ((sys->EvBatteryMaxCurrent < 0) ||(sys->EvBatteryMaxVoltage<150))
    {
        sprintf((char*)buf_log_evcomm,
                "[ERROR]EvBatteryMaxCurrent is negative(%.02f) => End_Process",
                sys->EvBatteryMaxCurrent);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

        res->ResponseCode = iso1responseCodeType_FAILED_WrongChargeParameter;   //16
        res->EVSEProcessing = Finished_ISO15118_2014;
        dc_para->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
        ac_para->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging;
        errn = -1;
        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_WrongChargeParameter (023775)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 7;
        ShmStatusCodeData->PresentStatusCode[0][5] = 5;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
    }


    //STEP 2: ============ Modify Parameters of ShmCcsData ============
    //DC
    SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMaximumPowerLimit, (int) (sys->AvailableChargingPower * 10), W_ISO15118_2014);
    SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMaximumCurrentLimit, (int) (sys->AvailableChargingCurrent * 10), A_ISO15118_2014);
    SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMaximumVoltageLimit, (int) (sys->MaximumChargingVoltage * 10), V_ISO15118_2014);

    SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMinimumVoltageLimit, 1500, V_ISO15118_2014); //150V
    SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMinimumCurrentLimit, 10, A_ISO15118_2014); //1A
    SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSECurrentRegulationTolerance, 10, A_ISO15118_2014); //1A
    SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEPeakCurrentRipple, 2, A_ISO15118_2014);   //0.2A
    //SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEEnergyToBeDelivered, 0, Wh_ISO15118_2014); //optional

    //AC
    SAVE_PhysicalValueType_ISO15118_2014(&ac_para->EVSENominalVoltage, (int) (sys->AC_EVSENominalVoltage * 10), V_ISO15118_2014);
    SAVE_PhysicalValueType_ISO15118_2014(&ac_para->EVSEMaxCurrent, (int) (sys->AvailableChargingCurrent * 10), A_ISO15118_2014);


    #if PATCH_FOR_BMW_I3_BUG_EVSEMAXIMUMVOLTAGELIMIT_599V == ENABLE
    if (sys->EvBatteryMaxVoltage <= 500)
    {
        SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMaximumVoltageLimit, (int) (500 * 10), V_ISO15118_2014);  //500V
    }
    #endif

    //for test with Tesla Model 3, 10A
    //SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMaximumCurrentLimit, (int) (10 * 10), A_ISO15118_2014);   //10A, for testing with Tesla Model 3

    //Check for EnergyTransferMode
    if (req->RequestedEnergyTransferMode != ShmCcsData->EnergyTransferMode) //[CAUTION] Their table should be kept as the same.
    {
        sprintf((char*)buf_log_evcomm,
                "[ERROR]Unmatched RequestedEnergyTransferMode(%d,%d)",
                req->RequestedEnergyTransferMode,
                ShmCcsData->EnergyTransferMode);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        res->ResponseCode = FAILED_WrongEnergyTransferMode_ISO15118_2014;
        res->EVSEProcessing = iso1EVSEProcessingType_Finished;
        dc_para->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
        ac_para->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging;
        errn = -1;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_WrongEnergyTransferMode (023774)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 7;
        ShmStatusCodeData->PresentStatusCode[0][5] = 4;
    }

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_ChargeParameterDiscoveryRes]EVSE_Shutdown");
        res->ResponseCode = FAILED_ISO15118_2014;
        res->EVSEProcessing = iso1EVSEProcessingType_Finished;
        dc_para->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
        ac_para->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging;
        errn = -1;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_ChargeParameterDiscoveryRes]EVSE_EmergencyShutdown");
        res->ResponseCode = FAILED_ISO15118_2014;
        res->EVSEProcessing =  iso1EVSEProcessingType_Finished;
        dc_para->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        ac_para->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging;
        errn = -1;
    }

    //Detect for CP State should be 9V (State B)
    #if CP_PROTECTION_MECHANISM == ENABLE
    if (sys->CpState != 3)  //State B1, B2
    {
        res->ResponseCode = FAILED_ISO15118_2014;
        dc_para->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        ac_para->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging;
        res->EVSEProcessing = iso1EVSEProcessingType_Finished;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;

        sprintf((char*)buf_log_evcomm,
                "[Proc_iso1_ChargeParameterDiscoveryRes]Emergency Stop by CP Error (%d, %.02f V)\n",
                sys->CpState,
                sys->CpVoltage);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    #endif

    //Check for Permission from CSU
    if(ShmInternalComm->ChargingPermission == TRUE)
    {
        res->EVSEProcessing = iso1EVSEProcessingType_Finished;
    }

    //Check for Permission Off
    if (ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][ISO1][ChargeParameterDiscoveryRes]Permission OFF");
        res->ResponseCode = FAILED_ISO15118_2014;
        res->EVSEProcessing = iso1EVSEProcessingType_Finished;
        dc_para->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
        ac_para->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging;
        errn = -1;
    }

    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_iso1_ChargeParameterDiscoveryRes(&ccs_exi_doc_ISO1, ShmCcsData);
    #else
    Sudo_Parameter_iso1_ChargeParameterDiscoveryRes();
    #endif

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_ChargeParameterDiscoveryRes][Error]Tx encoded msg error");
        errn = -1;
    }

    //STPE 5: ============ Update Flags ============

    return errn;
}


/*===========================================================================
FUNCTION: Proc_din_ChargeParameterDiscoveryReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_ChargeParameterDiscoveryReq(int AcceptFd)
{
    int errn = 0;

        //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_ChargeParameterDiscoveryReq] Got ChargeParameterDiscoveryReq");

        //ftime(&SeqStartTime);
        //Print the decoded XML Document
        PRINT_XML_DOC_DIN_ChargeParameterDiscoveryReq(&ccs_exi_doc_DIN);

        //Save into Share Memory
        SHM_Save_din_ChargeParameterDiscoveryReq(ShmCcsData, &ccs_exi_doc_DIN, ShmSysConfigAndInfo);

        //Check for EV Error Code
        Check_EVErrorCode(ShmCcsData->V2GMessage_DIN70121.ChargeParameterDiscoveryRequest.DC_EVChargeParameter.DC_EVStatus.EVErrorCode);

        errn = Proc_din_ChargeParameterDiscoveryRes(AcceptFd);
        //ftime(&SeqEndTime);
        //DEBUG_PRINTF_EVCOMM_DETAIL("\ndelta = %.02lf ms\n", DiffTimeb(SeqStartTime, SeqEndTime));
        if ( errn == 0)
        {
            //send response successfully.
            //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][V2G][Tx]ChargeParameterDiscoveryRes");

        }
        else
        {
            sprintf((char*)buf_log_evcomm,
                    "[Error][DIN][ChargeParameterDiscoveryRes]%d (DEC)",
                    errn);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        }
    return errn;
}


/*===========================================================================
FUNCTION: Proc_iso1_ChargeParameterDiscoveryReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_ChargeParameterDiscoveryReq(int AcceptFd)
{
    int errn = 0;
    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_ChargeParameterDiscoveryReq] Got ChargeParameterDiscoveryReq");

    //ftime(&SeqStartTime);
    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_ChargeParameterDiscoveryReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_ChargeParameterDiscoveryReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_ISO15118_2014.ChargeParameterDiscoveryRequest.DC_EVChargeParameter.DC_EVStatus.EVErrorCode);

    errn = Proc_iso1_ChargeParameterDiscoveryRes(AcceptFd);
    //ftime(&SeqEndTime);
    //DEBUG_PRINTF_EVCOMM_DETAIL("\ndelta = %.02lf ms\n", DiffTimeb(SeqStartTime, SeqEndTime));
    if (errn == 0)
    {
        //send response successfully.
        //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][V2G][Tx]ChargeParameterDiscoveryRes");

    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][ISO1][ChargeParameterDiscoveryRes]%d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}


/*===========================================================================
FUNCTION: SHM_Init_din_CableCheckRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
    1. shm_ccs

OUTPUT:
    1. shm_ccs

GLOBAL VARIABLES:
=============================================================================*/
void SHM_Init_din_CableCheckRes(struct CcsData *shm_ccs)
{
	struct CableCheckResponse_DIN70121 *in;

	in = &shm_ccs->V2GMessage_DIN70121.CableCheckResponse;

	//----- [BODY (1/3)] ResponseCode -----
    in->ResponseCode = dinresponseCodeType_OK;

    //----- [BODY (2/3)] EVSEProcessing -----
	//in->EVSEProcessing = dinEVSEProcessingType_Finished; //for test
    in->EVSEProcessing = dinEVSEProcessingType_Ongoing; //default
    // 	dinEVSEProcessingType_Finished = 0,
    //	dinEVSEProcessingType_Ongoing = 1

    //----- [BODY (3/3)] DC_EVSEStatus -----
	SHM_Init_dinDC_EVSEStatusType(&in->DC_EVSEStatus);
    in->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid;    //0 (default)
    //	dinisolationLevelType_Invalid = 0,
    //	dinisolationLevelType_Valid = 1, (default)
    //	dinisolationLevelType_Warning = 2,
    //	dinisolationLevelType_Fault = 3
}

/*===========================================================================
FUNCTION: Sudo_Parameter_din_CableCheckRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_din_CableCheckRes()
{
    init_dinBodyType(&ccs_exi_doc_DIN.V2G_Message.Body);
    init_dinCableCheckResType(&ccs_exi_doc_DIN.V2G_Message.Body.CableCheckRes);

    ccs_exi_doc_DIN.V2G_Message.Body.CableCheckRes_isUsed = 1u;

    //----- [BODY (1/3)] ResponseCode -----
    struct dinCableCheckResType *res;
    res = &ccs_exi_doc_DIN.V2G_Message.Body.CableCheckRes;
    res->ResponseCode = dinresponseCodeType_OK;

    //----- [BODY (2/3)] EVSEProcessing -----
    res->EVSEProcessing = dinEVSEProcessingType_Finished; //0
    // 	dinEVSEProcessingType_Finished = 0,
    //	dinEVSEProcessingType_Ongoing = 1

    //----- [BODY (3/3)] DC_EVSEStatus -----
    res->DC_EVSEStatus.EVSEIsolationStatus_isUsed = 1u;
    res->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid;
    //	dinisolationLevelType_Invalid = 0,
    //	dinisolationLevelType_Valid = 1,
    //	dinisolationLevelType_Warning = 2,
    //	dinisolationLevelType_Fault = 3

    res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;
    // dinDC_EVSEStatusCodeType_EVSE_NotReady = 0,
    // dinDC_EVSEStatusCodeType_EVSE_Ready = 1,
    // dinDC_EVSEStatusCodeType_EVSE_Shutdown = 2,
    // dinDC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
    // dinDC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
    // dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
    // dinDC_EVSEStatusCodeType_EVSE_Malfunction = 6,
    // dinDC_EVSEStatusCodeType_Reserved_8 = 7,
    // dinDC_EVSEStatusCodeType_Reserved_9 = 8,
    // dinDC_EVSEStatusCodeType_Reserved_A = 9,
    // dinDC_EVSEStatusCodeType_Reserved_B = 10,
    // dinDC_EVSEStatusCodeType_Reserved_C = 11

    res->DC_EVSEStatus.NotificationMaxDelay = 0u;

    res->DC_EVSEStatus.EVSENotification = dinEVSENotificationType_None;
    // dinEVSENotificationType_None = 0,
    // dinEVSENotificationType_StopCharging = 1,
    // dinEVSENotificationType_ReNegotiation = 2
}

/*===========================================================================
FUNCTION: Sudo_Parameter_iso1_CableCheckRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_iso1_CableCheckRes()
{
    init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body);
    init_iso1CableCheckResType(&ccs_exi_doc_ISO1.V2G_Message.Body.CableCheckRes);

    ccs_exi_doc_ISO1.V2G_Message.Body.CableCheckRes_isUsed = 1u;

    //----- [BODY (1/3)] ResponseCode -----
    struct iso1CableCheckResType *res;
    res = &ccs_exi_doc_ISO1.V2G_Message.Body.CableCheckRes;
    res->ResponseCode = iso1responseCodeType_OK;

    //----- [BODY (2/3)] EVSEProcessing -----
    res->EVSEProcessing = iso1EVSEProcessingType_Finished; //0
    //iso1EVSEProcessingType_Finished = 0,
	//iso1EVSEProcessingType_Ongoing = 1,
	//iso1EVSEProcessingType_Ongoing_WaitingForCustomerInteraction = 2

    //----- [BODY (3/3)] DC_EVSEStatus -----
    res->DC_EVSEStatus.EVSEIsolationStatus_isUsed = 1u;
    res->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid;
    //iso1isolationLevelType_Invalid = 0,
	//iso1isolationLevelType_Valid = 1,
	//iso1isolationLevelType_Warning = 2,
	//iso1isolationLevelType_Fault = 3,
	//iso1isolationLevelType_No_IMD = 4

    res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;
    //iso1DC_EVSEStatusCodeType_EVSE_NotReady = 0,
	//iso1DC_EVSEStatusCodeType_EVSE_Ready = 1,
	//iso1DC_EVSEStatusCodeType_EVSE_Shutdown = 2,
	//iso1DC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
	//iso1DC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
	//iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
	//iso1DC_EVSEStatusCodeType_EVSE_Malfunction = 6,
	//iso1DC_EVSEStatusCodeType_Reserved_8 = 7,
	//iso1DC_EVSEStatusCodeType_Reserved_9 = 8,
	//iso1DC_EVSEStatusCodeType_Reserved_A = 9,
	//iso1DC_EVSEStatusCodeType_Reserved_B = 10,
	//iso1DC_EVSEStatusCodeType_Reserved_C = 11

    res->DC_EVSEStatus.NotificationMaxDelay = 0u;

    res->DC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None;
    //iso1EVSENotificationType_None = 0,
	//iso1EVSENotificationType_StopCharging = 1,
	//iso1EVSENotificationType_ReNegotiation = 2
}


/*===========================================================================
FUNCTION: Proc_din_CableCheckRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_CableCheckRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct CableCheckResponse_DIN70121 *cab;
    static struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    cab = &ShmCcsData->V2GMessage_DIN70121.CableCheckResponse;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    cab->ResponseCode = OK_DIN70121;
    cab->cnt++;

    DEBUG_PRINTF_EVCOMM_DETAIL("CP_State = %d (%.02f V), V_now = %.02f, Isolation Status = %d, EVSEProcessing = %d\n",
            sys->CpState,
            sys->CpVoltage,
            sys->PresentChargingVoltage,
            sys->IsolationStatus,
            cab->EVSEProcessing);

    //[HEADER] Check Req SessionID
    if (Check_din_V2G_Rx_MSG_SessionID(&ccs_exi_doc_DIN) < 0)
    {
        cab->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        cab->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============
    if (sys->IsolationStatus == GFD_Invalid)  //0: on going
    {
        //For PSU
        sys->EvBatterytargetVoltage = CABLECHECK_TARGET_VOLTAGE;	//500V	//[To-Do] this should be modified to auto decision.
        sys->EvBatterytargetCurrent = CABLECHECK_TARGET_CURRENT;	//2A(default), unit: 1A

        cab->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid;
        cab->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive;    //4
        cab->EVSEProcessing = dinEVSEProcessingType_Ongoing;
    }
    else if ((sys->IsolationStatus == GFD_Valid) || (sys->IsolationStatus == GFD_Warning)) //1: valid, 2: warning
    {
        //For PSU
        sys->EvBatterytargetVoltage = 0;	//0V, asking PSU to discharge to 0V
        sys->EvBatterytargetCurrent = 0;	//0A, unit: 1A

        if (sys->PresentChargingVoltage < 60)  // < 60V
        {
            //memset(buf_log_evcomm, 0, sizeof(buf_log_evcomm));
            sprintf((char*)buf_log_evcomm, "[V2G][CableCheck]Pass (V_now = %.02f, Isolated = %d)",
                    sys->PresentChargingVoltage,
                    sys->IsolationStatus);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

            //IsolationStatus
            if (sys->IsolationStatus == GFD_Valid)
            {
                cab->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid;
            }
            else if (sys->IsolationStatus == GFD_Warning)
            {
                cab->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Warning;
            }
            else
            {
                sprintf((char*)buf_log_evcomm,
                        "[WARNING]unexpected IsolationStatus(%d)",
                        sys->IsolationStatus);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            }
            cab->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;
            cab->EVSEProcessing = dinEVSEProcessingType_Finished;
        }
        else
        {
            cab->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid;
            cab->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive;
            cab->EVSEProcessing = dinEVSEProcessingType_Ongoing;
        }
    }
    else if (sys->IsolationStatus == GFD_Fault) //3: fault
    {
        //For PSU
        sys->EvBatterytargetVoltage = 0;	//0V, asking PSU to discharge to 0V
        sys->EvBatterytargetCurrent = 0;	//0A, unit: 1A

        cab->ResponseCode = FAILED_DIN70121;
        cab->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;
        cab->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_NotReady;
        cab->EVSEProcessing = dinEVSEProcessingType_Finished;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_CableCheckRes]IsolationStatus = 3 (fault)");
        errn = -1;
    }
    else
    {
        //For PSU
        sys->EvBatterytargetVoltage = 0;	//0V, asking PSU to discharge to 0V
        sys->EvBatterytargetCurrent = 0;	//0A, unit: 1A

        cab->ResponseCode = FAILED_DIN70121;
        cab->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid;
        cab->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_NotReady;
        cab->EVSEProcessing = dinEVSEProcessingType_Finished;
        sprintf((char*)buf_log_evcomm,
                "[Proc_din_CableCheckRes]Undefined Isolation Status(%d)",
                sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        cab->ResponseCode = FAILED_DIN70121;
        cab->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
        cab->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;
        cab->EVSEProcessing = dinEVSEProcessingType_Finished;
	    errn = -1;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_CableCheckRes]EVSE_Shutdown");
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        cab->ResponseCode = FAILED_DIN70121;
        cab->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        cab->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;
        cab->EVSEProcessing = dinEVSEProcessingType_Finished;
	    errn = -1;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_CableCheckRes]EVSE_EmergencyShutdown");
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        cab->ResponseCode = FAILED_DIN70121;
        cab->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
        cab->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;
        cab->EVSEProcessing = dinEVSEProcessingType_Finished;
	    errn = -1;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_din_CableCheckRes]ChargingPermission = FALSE");
    }
    else
    {
        //null
    }

    //Response to CP Error
    #if CP_PROTECTION_MECHANISM == ENABLE
    //#if 1
    if (sys->CableCheckPreCountDownDone == TRUE)   //[To-Do] Here should be modified to 2 seconds
    {
        if ((sys->CpState != 4) && (sys->CpState != 5))  //State C (6V), D (3V)
        {
            cab->ResponseCode = FAILED_DIN70121;
            cab->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
            CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
            Update_V2G_Flow_Status(Other_Fault);
            errn = -1;

            //Update_ShmStatusCode(); //[To-Do] to be implemented
            //CCS_SECC_CP_State_Error (023889)
            ShmStatusCodeData->PresentStatusCode[0][0] = 0;
            ShmStatusCodeData->PresentStatusCode[0][1] = 2;
            ShmStatusCodeData->PresentStatusCode[0][2] = 3;
            ShmStatusCodeData->PresentStatusCode[0][3] = 8;
            ShmStatusCodeData->PresentStatusCode[0][4] = 8;
            ShmStatusCodeData->PresentStatusCode[0][5] = 9;
            CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;

            sprintf((char*)buf_log_evcomm,
                    "[CableCheck]Emergency Stop by CP Error (%d, %.02f V, %d)\n",
                    sys->CpState,
                    sys->CpVoltage,
                    cab->cnt
                    );
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            //cab->cnt = 0;
        }
    }
    #endif

    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_din_CableCheckRes(&ccs_exi_doc_DIN, ShmCcsData);
    #else
    Sudo_Parameter_din_CableCheckRes();
    #endif


    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_DIN) != 0)
    {
      errn = -1;
    }

    //STEP 5: ============ Update Flags ===========
    sys->ConnectorLocked = TRUE;    //Inicating EVSE that the CCS Connector is Locked.

    return errn;
}


/*===========================================================================
FUNCTION: Proc_iso1_CableCheckRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_CableCheckRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct CableCheckResponse_ISO15118_2014 *cab;
    static struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    cab = &ShmCcsData->V2GMessage_ISO15118_2014.CableCheckResponse;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    cab->ResponseCode = OK_ISO15118_2014;
    cab->cnt++;

    DEBUG_PRINTF_EVCOMM_DETAIL("CP_State = %d (%.02f V), V_now = %.02f, Isolation Status = %d, EVSEProcessing = %d\n",
            sys->CpState,
            sys->CpVoltage,
            sys->PresentChargingVoltage,
            sys->IsolationStatus,
            cab->EVSEProcessing);


    //[HEADER] Check Req SessionID
    if (Check_iso1_V2G_Rx_MSG_SessionID(&ccs_exi_doc_ISO1) < 0)
    {
        cab->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        cab->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============
    if (sys->IsolationStatus == GFD_Invalid)  //0: invalid (on going)
    {
        //For PSU
        sys->EvBatterytargetVoltage = CABLECHECK_TARGET_VOLTAGE;	//500V	//[To-Do] this should be modified to auto decision.
        sys->EvBatterytargetCurrent = CABLECHECK_TARGET_CURRENT;	//2A(default), unit: 1A

        cab->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Invalid;
        cab->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive;
        cab->EVSEProcessing = iso1EVSEProcessingType_Ongoing;
    }
    else if ((sys->IsolationStatus == GFD_Valid) || (sys->IsolationStatus == GFD_Warning)) //1: valid, 2:waring
    {
        //For PSU
        sys->EvBatterytargetVoltage = 0;	//0V, asking PSU to discharge to 0V
        sys->EvBatterytargetCurrent = 0;	//0A, unit: 1A

        if (sys->PresentChargingVoltage < 60)  // < 60V
        {
            //memset(buf_log_evcomm, 0, sizeof(buf_log_evcomm));
            sprintf((char*)buf_log_evcomm, "[V2G][CableCheck]Pass (V_now = %.02f, Isolated = %d)",
                    sys->PresentChargingVoltage,
                    sys->IsolationStatus);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

            //IsolationStatus
            if (sys->IsolationStatus == GFD_Valid)
            {
                cab->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid;
            }
            else if (sys->IsolationStatus == GFD_Warning)
            {
                cab->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Warning;
            }
            else
            {
                sprintf((char*)buf_log_evcomm,
                        "[WARNING]unexpected IsolationStatus(%d)",
                        sys->IsolationStatus);
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            }

            cab->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;
            cab->EVSEProcessing = iso1EVSEProcessingType_Finished;
        }
        else
        {
            cab->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Invalid;
            cab->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive;
            cab->EVSEProcessing = iso1EVSEProcessingType_Ongoing;
        }
    }
    else if (sys->IsolationStatus == GFD_Fault) //3: fault
    {
        //For PSU
        sys->EvBatterytargetVoltage = 0;	//0V, asking PSU to discharge to 0V
        sys->EvBatterytargetCurrent = 0;	//0A, unit: 1A

        cab->ResponseCode = FAILED_ISO15118_2014;
        cab->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;
        cab->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_NotReady;
        cab->EVSEProcessing = iso1EVSEProcessingType_Finished;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_CableCheckRes]IsolationStatus = 3 (fault)");
        errn = -1;
    }
    //else if (sys->IsolationStatus == GFD_No_IMD){}    //only for ISO15118
    else
    {
        //For PSU
        sys->EvBatterytargetVoltage = 0;	//0V, asking PSU to discharge to 0V
        sys->EvBatterytargetCurrent = 0;	//0A, unit: 1A

        cab->ResponseCode = FAILED_ISO15118_2014;
        cab->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;
        cab->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_NotReady;
        cab->EVSEProcessing = iso1EVSEProcessingType_Finished;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_CableCheckRes]Undefined Isolation Status.");
    }

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        cab->ResponseCode = FAILED_ISO15118_2014;
        cab->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
        cab->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;
        cab->EVSEProcessing = iso1EVSEProcessingType_Finished;
        errn = -1;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_CableCheckRes]EVSE_Shutdown");
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        cab->ResponseCode = FAILED_ISO15118_2014;
        cab->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        cab->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;
        cab->EVSEProcessing = iso1EVSEProcessingType_Finished;
        errn = -1;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_CableCheckRes]EVSE_EmergencyShutdown");
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        cab->ResponseCode = FAILED_ISO15118_2014;
        cab->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
        cab->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;
        cab->EVSEProcessing = iso1EVSEProcessingType_Finished;
        errn = -1;
	    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_iso1_CableCheckRes]ChargingPermission = FALSE");
    }
    else
    {
        //null
    }

    //Response to CP Error
    #if CP_PROTECTION_MECHANISM == ENABLE
    if (sys->CableCheckPreCountDownDone == TRUE)   //[To-Do] Here should be modified to 2 seconds
    {
        if ((sys->CpState != 4) && (sys->CpState != 5))  //State C (6V), D (3V)
        {
            cab->ResponseCode = FAILED_ISO15118_2014;
            cab->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
            CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
            Update_V2G_Flow_Status(Other_Fault);
            errn = -1;

            //Update_ShmStatusCode(); //[To-Do] to be implemented
            //CCS_SECC_CP_State_Error (023889)
            ShmStatusCodeData->PresentStatusCode[0][0] = 0;
            ShmStatusCodeData->PresentStatusCode[0][1] = 2;
            ShmStatusCodeData->PresentStatusCode[0][2] = 3;
            ShmStatusCodeData->PresentStatusCode[0][3] = 8;
            ShmStatusCodeData->PresentStatusCode[0][4] = 8;
            ShmStatusCodeData->PresentStatusCode[0][5] = 9;
            CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;

            sprintf((char*)buf_log_evcomm,
                    "[CableCheck]Emergency Stop by CP Error (%d, %.02f V, %d)\n",
                    sys->CpState,
                    sys->CpVoltage,
                    cab->cnt
                    );
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            //cab->cnt = 0;
        }
    }
    #endif

    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_iso1_CableCheckRes(&ccs_exi_doc_ISO1, ShmCcsData);
    #else
    Sudo_Parameter_iso1_CableCheckRes();
    #endif


    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        errn = -1;
    }

    //STEP 5: ============ Update Flags ===========
    sys->ConnectorLocked = TRUE;    //Inicating EVSE that the CCS Connector is Locked.

    return errn;
}


/*===========================================================================
FUNCTION: Proc_din_CableCheckReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_CableCheckReq(int AcceptFd)
{
    int errn = 0;
    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_CableCheckReq] Got CableCheckReq\n");


    //Print the decoded XML Document
    PRINT_XML_DOC_DIN_CableCheckReq(&ccs_exi_doc_DIN);

    //Save into Share Memory
    SHM_Save_din_CableCheckReq(ShmCcsData, &ccs_exi_doc_DIN, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_DIN70121.CableCheckRequest.DC_EVStatus.EVErrorCode);

    errn = Proc_din_CableCheckRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][V2G][Tx]CableCheckRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_din_CableCheckReq]Proc_iso1_CableCheckRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_CableCheckReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_CableCheckReq(int AcceptFd)
{
    int errn = 0;
    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_CableCheckReq] Got CableCheckReq");

    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_CableCheckReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_CableCheckReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_ISO15118_2014.CableCheckRequest.DC_EVStatus.EVErrorCode);

    errn = Proc_iso1_CableCheckRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][V2G][Tx]CableCheckRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_iso1_CableCheckReq]Proc_iso1_CableCheckRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}



/*===========================================================================
FUNCTION: SHM_Init_din_PreChargeRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
    1. shm_ccs

OUTPUT:
    1. shm_ccs

GLOBAL VARIABLES:
=============================================================================*/
void SHM_Init_din_PreChargeRes(struct CcsData *shm_ccs)
{
	struct PreChargeResponse_DIN70121 *in;

	in = &shm_ccs->V2GMessage_DIN70121.PreChargeResponse;

	//----- [BODY (1/3)] ResponseCode -----
    in->ResponseCode = dinresponseCodeType_OK;


    //----- [BODY (2/3)] EVSEPresentVoltage -----
    short value = 0; int multiplier = 0; unsigned char unit = 0;
    //value = 3820; multiplier = -1; unit = V_DIN70121;    //382V, for Test
    value = 0; multiplier = 0; unit = V_DIN70121; //waiting for CsuComm to update V to fit EV Target
	SHM_Save_dinPhysicalValueType(&in->EVSEPresentVoltage, value, multiplier, unit);

    //----- [BODY (3/3)] DC_EVSEStatus -----
	SHM_Init_dinDC_EVSEStatusType(&in->DC_EVSEStatus);
}

/*===========================================================================
FUNCTION: Sudo_Parameter_din_PreChargeRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_din_PreChargeRes()
{
    init_dinBodyType(&ccs_exi_doc_DIN.V2G_Message.Body);
    init_dinPreChargeResType(&ccs_exi_doc_DIN.V2G_Message.Body.PreChargeRes);

    ccs_exi_doc_DIN.V2G_Message.Body.PreChargeRes_isUsed = 1u;

    //----- [BODY (1/3)] ResponseCode -----
    struct dinPreChargeResType *res;
    res = &ccs_exi_doc_DIN.V2G_Message.Body.PreChargeRes;
    res->ResponseCode = dinresponseCodeType_OK;


    //----- [BODY (2/3)] EVSEPresentVoltage -----
    res->EVSEPresentVoltage.Value = 3820;
    res->EVSEPresentVoltage.Multiplier = -1;
    res->EVSEPresentVoltage.Unit_isUsed = 1u;
    res->EVSEPresentVoltage.Unit = dinunitSymbolType_V;
    //	dinunitSymbolType_h = 0,
    //	dinunitSymbolType_m = 1,
    //	dinunitSymbolType_s = 2,
    //	dinunitSymbolType_A = 3,
    //	dinunitSymbolType_Ah = 4,
    //	dinunitSymbolType_V = 5,
    //	dinunitSymbolType_VA = 6,
    //	dinunitSymbolType_W = 7,
    //	dinunitSymbolType_W_s = 8,
    //	dinunitSymbolType_Wh = 9


    //----- [BODY (3/3)] DC_EVSEStatus -----
    res->DC_EVSEStatus.EVSEIsolationStatus_isUsed = 1u;
    res->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid;
    //	dinisolationLevelType_Invalid = 0,
    //	dinisolationLevelType_Valid = 1,
    //	dinisolationLevelType_Warning = 2,
    //	dinisolationLevelType_Fault = 3

    res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;
    // dinDC_EVSEStatusCodeType_EVSE_NotReady = 0,
    // dinDC_EVSEStatusCodeType_EVSE_Ready = 1,
    // dinDC_EVSEStatusCodeType_EVSE_Shutdown = 2,
    // dinDC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
    // dinDC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
    // dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
    // dinDC_EVSEStatusCodeType_EVSE_Malfunction = 6,
    // dinDC_EVSEStatusCodeType_Reserved_8 = 7,
    // dinDC_EVSEStatusCodeType_Reserved_9 = 8,
    // dinDC_EVSEStatusCodeType_Reserved_A = 9,
    // dinDC_EVSEStatusCodeType_Reserved_B = 10,
    // dinDC_EVSEStatusCodeType_Reserved_C = 11

    res->DC_EVSEStatus.NotificationMaxDelay = 0u;

    res->DC_EVSEStatus.EVSENotification = dinEVSENotificationType_None;
    // dinEVSENotificationType_None = 0,
    // dinEVSENotificationType_StopCharging = 1,
    // dinEVSENotificationType_ReNegotiation = 2
}

/*===========================================================================
FUNCTION: Sudo_Parameter_iso1_PreChargeRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_iso1_PreChargeRes()
{
    init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body);
    init_iso1PreChargeResType(&ccs_exi_doc_ISO1.V2G_Message.Body.PreChargeRes);

    ccs_exi_doc_ISO1.V2G_Message.Body.PreChargeRes_isUsed = 1u;

    //----- [BODY (1/3)] ResponseCode -----
    struct iso1PreChargeResType *res;
    res = &ccs_exi_doc_ISO1.V2G_Message.Body.PreChargeRes;
    res->ResponseCode = iso1responseCodeType_OK;


    //----- [BODY (2/3)] EVSEPresentVoltage -----
    res->EVSEPresentVoltage.Value = 3820;
    res->EVSEPresentVoltage.Multiplier = -1;
    //res->EVSEPresentVoltage.Unit_isUsed = 1u;
    res->EVSEPresentVoltage.Unit = iso1unitSymbolType_V;
    //iso1unitSymbolType_h = 0,
	//iso1unitSymbolType_m = 1,
	//iso1unitSymbolType_s = 2,
	//iso1unitSymbolType_A = 3,
	//iso1unitSymbolType_V = 4,
	//iso1unitSymbolType_W = 5,
	//iso1unitSymbolType_Wh = 6


    //----- [BODY (3/3)] DC_EVSEStatus -----
    res->DC_EVSEStatus.EVSEIsolationStatus_isUsed = 1u;
    res->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid;
    //iso1isolationLevelType_Invalid = 0,
	//iso1isolationLevelType_Valid = 1,
	//iso1isolationLevelType_Warning = 2,
	//iso1isolationLevelType_Fault = 3,
	//iso1isolationLevelType_No_IMD = 4

    res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;
    //iso1DC_EVSEStatusCodeType_EVSE_NotReady = 0,
	//iso1DC_EVSEStatusCodeType_EVSE_Ready = 1,
	//iso1DC_EVSEStatusCodeType_EVSE_Shutdown = 2,
	//iso1DC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
	//iso1DC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
	//iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
	//iso1DC_EVSEStatusCodeType_EVSE_Malfunction = 6,
	//iso1DC_EVSEStatusCodeType_Reserved_8 = 7,
	//iso1DC_EVSEStatusCodeType_Reserved_9 = 8,
	//iso1DC_EVSEStatusCodeType_Reserved_A = 9,
	//iso1DC_EVSEStatusCodeType_Reserved_B = 10,
	//iso1DC_EVSEStatusCodeType_Reserved_C = 11

    res->DC_EVSEStatus.NotificationMaxDelay = 0u;

    res->DC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None;
    //iso1EVSENotificationType_None = 0,
	//iso1EVSENotificationType_StopCharging = 1,
	//iso1EVSENotificationType_ReNegotiation = 2
}


/*===========================================================================
FUNCTION: Proc_din_PreChargeRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_PreChargeRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct PreChargeResponse_DIN70121 *pre;
    static struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    pre = &ShmCcsData->V2GMessage_DIN70121.PreChargeResponse;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    pre->ResponseCode = OK_DIN70121;

    //EVSE Status Code
    pre->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;

    //[HEADER] Check Req SessionID
    if (Check_din_V2G_Rx_MSG_SessionID(&ccs_exi_doc_DIN) < 0)
    {
        pre->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        pre->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============
    SAVE_PhysicalValueType_DIN70121(&pre->EVSEPresentVoltage, (int) (sys->PresentChargingVoltage * 10), V_DIN70121);

    //Isolation Status
    if (sys->IsolationStatus == GFD_Invalid)  //0: invalid
    {
        pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid; //0
        pre->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
        sprintf((char*)buf_log_evcomm, "[Error][Proc_din_PreChargeRes]IsolationStatus = %d", sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    else if (sys->IsolationStatus == GFD_Valid) //1: valid
    {
        pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid;  //1
    }
    else if (sys->IsolationStatus == GFD_Warning) //2: warning
    {
        pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Warning;  //2
    }
    else if (sys->IsolationStatus == GFD_Fault) //3: fault
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_din_PreChargeRes]GFD_Fault => Emergency Shutdown");
        pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;  //3
        pre->ResponseCode = FAILED_DIN70121;
        pre->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        errn = -1;
    }
    else    //GFD_No_IMD or other unexpected status
    {
        pre->ResponseCode = FAILED_DIN70121;
        pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;  //3
        pre->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
        sprintf((char*)buf_log_evcomm,
                "[Error][Proc_din_PreChargeRes]IsolationStatus = %d (undefined)",
                sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        //Check for Alarm Code: CCS GFD trip (012235)
        if (ShmInternalComm->EVSEStopChargingReq.alarmcode[0] == 0 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[1] == 1 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[2] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[3] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[4] == 3 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[5] == 5)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_din_PreChargeRes]CCS GFD trip => EVSE_Shutdown");
            pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;
        }
        else
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_din_PreChargeRes]EVSE_Shutdown");
            pre->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus;
        }

        pre->ResponseCode = FAILED_DIN70121;
        pre->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
        errn = -1;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        //Check for Alarm Code: CCS GFD trip (012235)
        if (ShmInternalComm->EVSEStopChargingReq.alarmcode[0] == 0 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[1] == 1 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[2] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[3] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[4] == 3 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[5] == 5)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_din_PreChargeRes]CCS GFD trip => EVSE_EmergencyShutdown");
            pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;
        }
        else
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_din_PreChargeRes]EVSE_EmergencyShutdown");
            pre->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus;
        }

        pre->ResponseCode = FAILED_DIN70121;
        pre->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        errn = -1;
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_din_PreChargeRes]ChargingPermission = FALSE");
        pre->ResponseCode = FAILED_DIN70121;
        pre->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus;
        pre->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
        errn = -1;
    }
    else
    {
        //null
    }

    //Response to CP Error
    #if CP_PROTECTION_MECHANISM == ENABLE
    if ((sys->CpState != 4) && (sys->CpState != 5))  //State C (6V), D (3V)
    {
        pre->ResponseCode = FAILED_DIN70121;
        pre->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_CP_State_Error (023889)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 8;
        ShmStatusCodeData->PresentStatusCode[0][4] = 8;
        ShmStatusCodeData->PresentStatusCode[0][5] = 9;
        CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;

        sprintf((char*)buf_log_evcomm,
                "[Error][Proc_din_PreChargeRes]Emergency Stop by CP Error (%d, %.02f V)\n",
                sys->CpState,
                sys->CpVoltage
                );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    #endif

    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_din_PreChargeRes(&ccs_exi_doc_DIN, ShmCcsData);
    #else
    Sudo_Parameter_din_PreChargeRes();
    #endif

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_DIN) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][send_encoded_din_V2GTP_Stream]:Tx encoded msg error");
        errn = -1;
    }

    //STEP 5: ============ Update Flags ===========

    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_PreChargeRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_PreChargeRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct PreChargeResponse_ISO15118_2014 *pre;
    static struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    pre = &ShmCcsData->V2GMessage_ISO15118_2014.PreChargeResponse;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    pre->ResponseCode = OK_ISO15118_2014;

    //EVSE Status Code
    pre->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;

    //[HEADER] Check Req SessionID
    if (Check_iso1_V2G_Rx_MSG_SessionID(&ccs_exi_doc_ISO1) < 0)
    {
        pre->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        pre->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============
    SAVE_PhysicalValueType_ISO15118_2014(&pre->EVSEPresentVoltage, (int) (sys->PresentChargingVoltage * 10), V_ISO15118_2014);


    //Isolation Status
    if (sys->IsolationStatus == GFD_Invalid)    //0: invalid(on going)
    {
        pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Invalid; //0
        pre->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;

        sprintf((char*)buf_log_evcomm, "[Error][Proc_iso1_PreChargeRes]IsolationStatus = %d", sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    else if (sys->IsolationStatus == GFD_Valid) //1: valid
    {
        pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid;  //1
    }
    else if (sys->IsolationStatus == GFD_Warning) //2: waring
    {
        pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Warning;  //1
    }
    else if (sys->IsolationStatus == GFD_Fault) //3: fault
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_iso1_PreChargeRes]GFD_Fault => Emergency Shutdown");
        pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;  //3
        pre->ResponseCode = FAILED_ISO15118_2014;
        pre->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        errn = -1;
    }
    else
    {
        pre->ResponseCode = FAILED_ISO15118_2014;
        pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;  //3
        pre->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;

        sprintf((char*)buf_log_evcomm,
                "[Error][Proc_iso1_PreChargeRes]IsolationStatus = %d (undefined)",
                sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        //Check for Alarm Code: CCS GFD trip (012235)
        if (ShmInternalComm->EVSEStopChargingReq.alarmcode[0] == 0 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[1] == 1 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[2] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[3] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[4] == 3 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[5] == 5)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_iso1_PreChargeRes]CCS GFD trip => EVSE_Shutdown");
            pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;
        }
        else
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_iso1_PreChargeRes]EVSE_Shutdown");
            pre->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus;
        }

        pre->ResponseCode = FAILED_ISO15118_2014;
        pre->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
        errn = -1;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        //Check for Alarm Code: CCS GFD trip (012235)
        if (ShmInternalComm->EVSEStopChargingReq.alarmcode[0] == 0 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[1] == 1 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[2] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[3] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[4] == 3 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[5] == 5)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_iso1_PreChargeRes]CCS GFD trip => EVSE_EmergencyShutdown");
            pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;
        }
        else
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_iso1_PreChargeRes]EVSE_EmergencyShutdown");
            pre->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus;
        }

        pre->ResponseCode = FAILED_ISO15118_2014;
        pre->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        errn = -1;
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_iso1_PreChargeRes]ChargingPermission = FALSE");
        pre->ResponseCode = FAILED_ISO15118_2014;
        pre->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus;
        pre->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
        errn = -1;
    }
    else
    {
        //null
    }

    //Response to CP Error
    #if CP_PROTECTION_MECHANISM == ENABLE
    if ((sys->CpState != 4) && (sys->CpState != 5))  //State C (6V), D (3V)
    {
        pre->ResponseCode = FAILED_ISO15118_2014;
        pre->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_CP_State_Error (023889)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 8;
        ShmStatusCodeData->PresentStatusCode[0][4] = 8;
        ShmStatusCodeData->PresentStatusCode[0][5] = 9;
        CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;

        sprintf((char*)buf_log_evcomm,
                "[Error][Proc_iso1_PreChargeRes]Emergency Stop by CP Error (%d, %.02f V)\n",
                sys->CpState,
                sys->CpVoltage
                );
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    #endif

    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_iso1_PreChargeRes(&ccs_exi_doc_ISO1, ShmCcsData);
    #else
    Sudo_Parameter_iso1_PreChargeRes();
    #endif

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][send_encoded_iso1_V2GTP_Stream]:Tx encoded msg error");
        errn = -1;
    }

    //STEP 5: ============ Update Flags ===========

    return errn;
}


/*===========================================================================
FUNCTION: Proc_din_PreChargeReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_PreChargeReq(int AcceptFd)
{
    int errn = 0;
    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_PreChargeReq] Got PreChargeReq");

    //Print the decoded XML Document
    PRINT_XML_DOC_DIN_PreChargeReq(&ccs_exi_doc_DIN);

    //Save into Share Memory
    SHM_Save_din_PreChargeReq(ShmCcsData, &ccs_exi_doc_DIN, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_DIN70121.PreChargeRequest.DC_EVStatus.EVErrorCode);

    errn = Proc_din_PreChargeRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][V2G][Tx]PreChargeRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_din_PreChargeReq]Proc_iso1_PreChargeRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_PreChargeReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_PreChargeReq(int AcceptFd)
{
    int errn = 0;
    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_PreChargeReq] Got PreChargeReq");

    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_PreChargeReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_PreChargeReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_ISO15118_2014.PreChargeRequest.DC_EVStatus.EVErrorCode);

    errn = Proc_iso1_PreChargeRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][V2G][Tx]PreChargeRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_iso1_PreChargeReq]Proc_iso1_PreChargeRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}


/*===========================================================================
FUNCTION: SHM_Init_din_PowerDeliveryRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
    1. shm_ccs

OUTPUT:
    1. shm_ccs

GLOBAL VARIABLES:
=============================================================================*/
void SHM_Init_din_PowerDeliveryRes(struct CcsData *shm_ccs)
{
	struct PowerDeliveryResponse_DIN70121 *in;

	in = &shm_ccs->V2GMessage_DIN70121.PowerDeliveryResponse;


	//----- [BODY (1/3)] ResponseCode -----
    in->ResponseCode = dinresponseCodeType_OK;


    //----- [BODY (2/3)] AC_EVSEStatus -----
    //ignore, since DIN 70121 doesn't support AC, yet.


    //----- [BODY (2/3)] DC_EVSEStatus -----
	SHM_Init_dinDC_EVSEStatusType(&in->DC_EVSEStatus);
}

/*===========================================================================
FUNCTION: Sudo_Parameter_din_PowerDeliveryRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_din_PowerDeliveryRes()
{
    init_dinBodyType(&ccs_exi_doc_DIN.V2G_Message.Body);
    init_dinPowerDeliveryResType(&ccs_exi_doc_DIN.V2G_Message.Body.PowerDeliveryRes);

    ccs_exi_doc_DIN.V2G_Message.Body.PowerDeliveryRes_isUsed = 1u;

    //----- [BODY (1/3)] ResponseCode -----
    struct dinPowerDeliveryResType *res;
    res = &ccs_exi_doc_DIN.V2G_Message.Body.PowerDeliveryRes;
    res->ResponseCode = dinresponseCodeType_OK;


    //----- [BODY (2/3)] AC_EVSEStatus -----
    //ignore, since DIN 70121 doesn't support AC, yet.


    //----- [BODY (2/3)] DC_EVSEStatus -----
    res->DC_EVSEStatus_isUsed = 1u;
    res->DC_EVSEStatus.EVSEIsolationStatus_isUsed = 1u;
    res->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid;
    //	dinisolationLevelType_Invalid = 0,
    //	dinisolationLevelType_Valid = 1,
    //	dinisolationLevelType_Warning = 2,
    //	dinisolationLevelType_Fault = 3

    res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;
    // dinDC_EVSEStatusCodeType_EVSE_NotReady = 0,
    // dinDC_EVSEStatusCodeType_EVSE_Ready = 1,
    // dinDC_EVSEStatusCodeType_EVSE_Shutdown = 2,
    // dinDC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
    // dinDC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
    // dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
    // dinDC_EVSEStatusCodeType_EVSE_Malfunction = 6,
    // dinDC_EVSEStatusCodeType_Reserved_8 = 7,
    // dinDC_EVSEStatusCodeType_Reserved_9 = 8,
    // dinDC_EVSEStatusCodeType_Reserved_A = 9,
    // dinDC_EVSEStatusCodeType_Reserved_B = 10,
    // dinDC_EVSEStatusCodeType_Reserved_C = 11

    res->DC_EVSEStatus.NotificationMaxDelay = 0u;

    res->DC_EVSEStatus.EVSENotification = dinEVSENotificationType_None;
    // dinEVSENotificationType_None = 0,
    // dinEVSENotificationType_StopCharging = 1,
    // dinEVSENotificationType_ReNegotiation = 2
}

/*===========================================================================
FUNCTION: Sudo_Parameter_iso1_PowerDeliveryRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_iso1_PowerDeliveryRes()
{
    init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body);
    init_iso1PowerDeliveryResType(&ccs_exi_doc_ISO1.V2G_Message.Body.PowerDeliveryRes);

    ccs_exi_doc_ISO1.V2G_Message.Body.PowerDeliveryRes_isUsed = 1u;

    //----- [BODY (1/3)] ResponseCode -----
    struct iso1PowerDeliveryResType *res;
    res = &ccs_exi_doc_ISO1.V2G_Message.Body.PowerDeliveryRes;
    res->ResponseCode = iso1responseCodeType_OK;


    //----- [BODY (2/3)] AC_EVSEStatus -----
    //ignore, since our ISO1 70121 doesn't support AC, yet.


    //----- [BODY (2/3)] DC_EVSEStatus -----
    res->DC_EVSEStatus_isUsed = 1u;
    res->DC_EVSEStatus.EVSEIsolationStatus_isUsed = 1u;
    res->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid;
    //iso1isolationLevelType_Invalid = 0,
	//iso1isolationLevelType_Valid = 1,
	//iso1isolationLevelType_Warning = 2,
	//iso1isolationLevelType_Fault = 3,
	//iso1isolationLevelType_No_IMD = 4

    res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;
    //iso1DC_EVSEStatusCodeType_EVSE_NotReady = 0,
	//iso1DC_EVSEStatusCodeType_EVSE_Ready = 1,
	//iso1DC_EVSEStatusCodeType_EVSE_Shutdown = 2,
	//iso1DC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
	//iso1DC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
	//iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
	//iso1DC_EVSEStatusCodeType_EVSE_Malfunction = 6,
	//iso1DC_EVSEStatusCodeType_Reserved_8 = 7,
	//iso1DC_EVSEStatusCodeType_Reserved_9 = 8,
	//iso1DC_EVSEStatusCodeType_Reserved_A = 9,
	//iso1DC_EVSEStatusCodeType_Reserved_B = 10,
	//iso1DC_EVSEStatusCodeType_Reserved_C = 11

    res->DC_EVSEStatus.NotificationMaxDelay = 0u;

    res->DC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None;
    //iso1EVSENotificationType_None = 0,
	//iso1EVSENotificationType_StopCharging = 1,
	//iso1EVSENotificationType_ReNegotiation = 2
}


/*===========================================================================
FUNCTION: Proc_din_PowerDeliveryStartRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_PowerDeliveryStartRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    struct dinPowerDeliveryResType *res;
    struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    res = &ccs_exi_doc_DIN.V2G_Message.Body.PowerDeliveryRes;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    res->ResponseCode = OK_DIN70121;

    //[HEADER] Check Req SessionID
    if (Check_din_V2G_Rx_MSG_SessionID(&ccs_exi_doc_DIN) < 0)
    {
        res->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        res->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }


    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============

    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_din_PowerDeliveryRes(&ccs_exi_doc_DIN, ShmCcsData);
    #else
    Sudo_Parameter_din_PowerDeliveryRes();
    #endif

    //EVSE Status Code
    res->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid;  //1
    res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        //res->ResponseCode = FAILED_DIN70121;
        res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        //res->ResponseCode = FAILED_DIN70121;
        res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        //res->ResponseCode = FAILED_DIN70121;
        res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
    }

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_DIN) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_PowerDeliveryStartRes][Error]Tx encoded msg error");
        errn = -1;
    }

    //STEP 5: ============ Update Flags ===========

    return errn;
}


/*===========================================================================
FUNCTION: Proc_iso1_PowerDeliveryStartRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_PowerDeliveryStartRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    struct iso1PowerDeliveryResType *res;
    struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    res = &ccs_exi_doc_ISO1.V2G_Message.Body.PowerDeliveryRes;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    res->ResponseCode = OK_ISO15118_2014;

    //[HEADER] Check Req SessionID
    if (Check_iso1_V2G_Rx_MSG_SessionID(&ccs_exi_doc_ISO1) < 0)
    {
        res->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }


    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============

    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_iso1_PowerDeliveryRes(&ccs_exi_doc_ISO1, ShmCcsData);
    #else
    Sudo_Parameter_iso1_PowerDeliveryRes();
    #endif

    //EVSE Status Code
    res->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid;  //1
    res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        //res->ResponseCode = FAILED_ISO15118_2014;
        res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        //res->ResponseCode = FAILED_ISO15118_2014;
        res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        //res->ResponseCode = FAILED_ISO15118_2014;
        res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
    }

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_PowerDeliveryStartRes][Error]Tx encoded msg error");
        errn = -1;
    }

    //STEP 5: ============ Update Flags ===========

    return errn;
}


/*===========================================================================
FUNCTION: Proc_din_PowerDeliveryStartReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_PowerDeliveryStartReq(int AcceptFd)
{
    int errn = 0;
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]PowerDeliveryStartReq");


    //Print the decoded XML Document
    PRINT_XML_DOC_DIN_PowerDeliveryReq(&ccs_exi_doc_DIN);

    //Save into Share Memory
    SHM_Save_din_PowerDeliveryReq(ShmCcsData, &ccs_exi_doc_DIN, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_DIN70121.PowerDeliveryRequest.DC_EVPowerDeliveryParameter.DC_EVStatus.EVErrorCode);

    errn = Proc_din_PowerDeliveryStartRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][V2G][Tx]PowerDeliveryStartRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][Proc_din_PowerDeliveryStartReq]Proc_iso1_PowerDeliveryStartRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_PowerDeliveryStartReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_PowerDeliveryStartReq(int AcceptFd)
{
    int errn = 0;
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]PowerDeliveryStartReq");

    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_PowerDeliveryReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_PowerDeliveryReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryRequest.DC_EVPowerDeliveryParameter.DC_EVStatus.EVErrorCode);

    errn = Proc_iso1_PowerDeliveryStartRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][V2G][Tx]PowerDeliveryStartRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][Proc_iso1_PowerDeliveryStartReq]Proc_iso1_PowerDeliveryStartRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}


/*===========================================================================
FUNCTION: SHM_Init_din_CurrentDemandRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
    1. shm_ccs

OUTPUT:
    1. shm_ccs

GLOBAL VARIABLES:
=============================================================================*/
void SHM_Init_din_CurrentDemandRes(struct CcsData *shm_ccs)
{
	struct CurrentDemandResponse_DIN70121 *in;

	in = &shm_ccs->V2GMessage_DIN70121.CurrentDemandResponse;


	//----- [BODY (1/10)] ResponseCode -----
    in->ResponseCode = dinresponseCodeType_OK;

    //----- [BODY (2/10)] DC_EVSEStatus -----
    SHM_Init_dinDC_EVSEStatusType(&in->DC_EVSEStatus);


    //----- [BODY (3/10)] EVSEPresentVoltage -----
    short value = 0; int multiplier = 0; unsigned char unit = 0;

    //value = 3820; multiplier = -1; unit = V_DIN70121;    //382V, for test only.
    value = 0; multiplier = 0; unit = V_DIN70121;
	SHM_Save_dinPhysicalValueType(&in->EVSEPresentVoltage, value, multiplier, unit);


    //----- [BODY (4/10)] EVSEPresentCurrent -----
    //value = 600; multiplier = -1; unit = A_DIN70121;    //60A, for test only.
    value = 0; multiplier = 0; unit = A_DIN70121;
    SHM_Save_dinPhysicalValueType(&in->EVSEPresentCurrent, value, multiplier, unit);


    //----- [BODY (5/10)] EVSECurrentLimitAchieved -----
    in->EVSECurrentLimitAchieved = FALSE;

    //----- [BODY (6/10)] EVSEVoltageLimitAchieved -----
    in->EVSEVoltageLimitAchieved = FALSE;

    //----- [BODY (7/10)] EVSEPowerLimitAchieved -----
    in->EVSEPowerLimitAchieved = FALSE;

    //----- [BODY (8/10)] EVSEMaximumVoltageLimit -----
    //value = 7500; multiplier = -1; unit = V_DIN70121;    //750V
    value = 5000; multiplier = -1; unit = V_DIN70121;    //500V
    SHM_Save_dinPhysicalValueType(&in->EVSEMaximumVoltageLimit, value, multiplier, unit);

    //----- [BODY (9/10)] EVSEMaximumCurrentLimit -----
    value = 600; multiplier = -1; unit = A_DIN70121;    //60A
    SHM_Save_dinPhysicalValueType(&in->EVSEMaximumCurrentLimit, value, multiplier, unit);

    //----- [BODY (10/10)] EVSEMaximumPowerLimit -----
    value = 3000; multiplier = 1; unit = W_DIN70121;    //30KW
    SHM_Save_dinPhysicalValueType(&in->EVSEMaximumPowerLimit, value, multiplier, unit);
}


/*===========================================================================
FUNCTION: Sudo_Parameter_din_CurrentDemandRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_din_CurrentDemandRes()
{
    init_dinBodyType(&ccs_exi_doc_DIN.V2G_Message.Body);
    init_dinCurrentDemandResType(&ccs_exi_doc_DIN.V2G_Message.Body.CurrentDemandRes);

    ccs_exi_doc_DIN.V2G_Message.Body.CurrentDemandRes_isUsed = 1u;

    //----- [BODY (1/10)] ResponseCode -----
    struct dinCurrentDemandResType *res;
    res = &ccs_exi_doc_DIN.V2G_Message.Body.CurrentDemandRes;
    res->ResponseCode = dinresponseCodeType_OK;

    //----- [BODY (2/10)] DC_EVSEStatus -----
    res->DC_EVSEStatus.EVSEIsolationStatus_isUsed = 1u;
    res->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid;
    //	dinisolationLevelType_Invalid = 0,
    //	dinisolationLevelType_Valid = 1,
    //	dinisolationLevelType_Warning = 2,
    //	dinisolationLevelType_Fault = 3

    res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;
    // dinDC_EVSEStatusCodeType_EVSE_NotReady = 0,
    // dinDC_EVSEStatusCodeType_EVSE_Ready = 1,
    // dinDC_EVSEStatusCodeType_EVSE_Shutdown = 2,
    // dinDC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
    // dinDC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
    // dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
    // dinDC_EVSEStatusCodeType_EVSE_Malfunction = 6,
    // dinDC_EVSEStatusCodeType_Reserved_8 = 7,
    // dinDC_EVSEStatusCodeType_Reserved_9 = 8,
    // dinDC_EVSEStatusCodeType_Reserved_A = 9,
    // dinDC_EVSEStatusCodeType_Reserved_B = 10,
    // dinDC_EVSEStatusCodeType_Reserved_C = 11

    res->DC_EVSEStatus.NotificationMaxDelay = 0u;
    res->DC_EVSEStatus.EVSENotification = dinEVSENotificationType_None;
    // dinEVSENotificationType_None = 0,
    // dinEVSENotificationType_StopCharging = 1,
    // dinEVSENotificationType_ReNegotiation = 2



    //----- [BODY (3/10)] EVSEPresentVoltage -----
    res->EVSEPresentVoltage.Value = 3820;
    res->EVSEPresentVoltage.Multiplier = -1;
    res->EVSEPresentVoltage.Unit_isUsed = 1u;
    res->EVSEPresentVoltage.Unit = dinunitSymbolType_V;


    //----- [BODY (4/10)] EVSEPresentCurrent -----
    res->EVSEPresentCurrent.Value = 1200;
    res->EVSEPresentCurrent.Multiplier = -1;
    res->EVSEPresentCurrent.Unit_isUsed = 1u;
    res->EVSEPresentCurrent.Unit = dinunitSymbolType_A;


    //----- [BODY (5/10)] EVSECurrentLimitAchieved -----
    res->EVSECurrentLimitAchieved = 0;

    //----- [BODY (6/10)] EVSEVoltageLimitAchieved -----
    res->EVSEVoltageLimitAchieved = 0;

    //----- [BODY (7/10)] EVSEPowerLimitAchieved -----
    res->EVSEPowerLimitAchieved = 0;

    //----- [BODY (8/10)] EVSEMaximumVoltageLimit -----
    res->EVSEMaximumVoltageLimit_isUsed = 1u;
    res->EVSEMaximumVoltageLimit.Value = 7500;
    res->EVSEMaximumVoltageLimit.Multiplier = -1;
    res->EVSEMaximumVoltageLimit.Unit_isUsed = 1u;
    res->EVSEMaximumVoltageLimit.Unit = dinunitSymbolType_V;

    //----- [BODY (9/10)] EVSEMaximumCurrentLimit -----
    res->EVSEMaximumCurrentLimit_isUsed = 1u;
    res->EVSEMaximumCurrentLimit.Value = 1200;
    res->EVSEMaximumCurrentLimit.Multiplier = -1;
    res->EVSEMaximumCurrentLimit.Unit_isUsed = 1u;
    res->EVSEMaximumCurrentLimit.Unit = dinunitSymbolType_A;

    //----- [BODY (10/10)] EVSEMaximumPowerLimit -----
    res->EVSEMaximumPowerLimit_isUsed = 1u;
    res->EVSEMaximumPowerLimit.Value = 6000;
    res->EVSEMaximumPowerLimit.Multiplier = 1;
    res->EVSEMaximumPowerLimit.Unit_isUsed = 1u;
    res->EVSEMaximumPowerLimit.Unit = dinunitSymbolType_W;
}

/*===========================================================================
FUNCTION: Sudo_Parameter_iso1_CurrentDemandRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_iso1_CurrentDemandRes()
{
    init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body);
    init_iso1CurrentDemandResType(&ccs_exi_doc_ISO1.V2G_Message.Body.CurrentDemandRes);

    ccs_exi_doc_ISO1.V2G_Message.Body.CurrentDemandRes_isUsed = 1u;

    //----- [BODY (1/10)] ResponseCode -----
    struct iso1CurrentDemandResType *res;
    res = &ccs_exi_doc_ISO1.V2G_Message.Body.CurrentDemandRes;
    res->ResponseCode = iso1responseCodeType_OK;

    //----- [BODY (2/10)] DC_EVSEStatus -----
    res->DC_EVSEStatus.EVSEIsolationStatus_isUsed = 1u;
    res->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Invalid;
    //iso1isolationLevelType_Invalid = 0,
	//iso1isolationLevelType_Valid = 1,
	//iso1isolationLevelType_Warning = 2,
	//iso1isolationLevelType_Fault = 3,
	//iso1isolationLevelType_No_IMD = 4

    res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;
    //iso1DC_EVSEStatusCodeType_EVSE_NotReady = 0,
	//iso1DC_EVSEStatusCodeType_EVSE_Ready = 1,
	//iso1DC_EVSEStatusCodeType_EVSE_Shutdown = 2,
	//iso1DC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
	//iso1DC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
	//iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
	//iso1DC_EVSEStatusCodeType_EVSE_Malfunction = 6,
	//iso1DC_EVSEStatusCodeType_Reserved_8 = 7,
	//iso1DC_EVSEStatusCodeType_Reserved_9 = 8,
	//iso1DC_EVSEStatusCodeType_Reserved_A = 9,
	//iso1DC_EVSEStatusCodeType_Reserved_B = 10,
	//iso1DC_EVSEStatusCodeType_Reserved_C = 11

    res->DC_EVSEStatus.NotificationMaxDelay = 0u;
    res->DC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None;
    //iso1EVSENotificationType_None = 0,
	//iso1EVSENotificationType_StopCharging = 1,
	//iso1EVSENotificationType_ReNegotiation = 2



    //----- [BODY (3/10)] EVSEPresentVoltage -----
    res->EVSEPresentVoltage.Value = 3820;
    res->EVSEPresentVoltage.Multiplier = -1;
    //res->EVSEPresentVoltage.Unit_isUsed = 1u;
    res->EVSEPresentVoltage.Unit = iso1unitSymbolType_V;


    //----- [BODY (4/10)] EVSEPresentCurrent -----
    res->EVSEPresentCurrent.Value = 1200;
    res->EVSEPresentCurrent.Multiplier = -1;
    //res->EVSEPresentCurrent.Unit_isUsed = 1u;
    res->EVSEPresentCurrent.Unit = iso1unitSymbolType_A;


    //----- [BODY (5/10)] EVSECurrentLimitAchieved -----
    res->EVSECurrentLimitAchieved = 0;

    //----- [BODY (6/10)] EVSEVoltageLimitAchieved -----
    res->EVSEVoltageLimitAchieved = 0;

    //----- [BODY (7/10)] EVSEPowerLimitAchieved -----
    res->EVSEPowerLimitAchieved = 0;

    //----- [BODY (8/10)] EVSEMaximumVoltageLimit -----
    res->EVSEMaximumVoltageLimit_isUsed = 1u;
    res->EVSEMaximumVoltageLimit.Value = 7500;
    res->EVSEMaximumVoltageLimit.Multiplier = -1;
    //res->EVSEMaximumVoltageLimit.Unit_isUsed = 1u;
    res->EVSEMaximumVoltageLimit.Unit = iso1unitSymbolType_V;

    //----- [BODY (9/10)] EVSEMaximumCurrentLimit -----
    res->EVSEMaximumCurrentLimit_isUsed = 1u;
    res->EVSEMaximumCurrentLimit.Value = 1200;
    res->EVSEMaximumCurrentLimit.Multiplier = -1;
    //res->EVSEMaximumCurrentLimit.Unit_isUsed = 1u;
    res->EVSEMaximumCurrentLimit.Unit = iso1unitSymbolType_A;

    //----- [BODY (10/10)] EVSEMaximumPowerLimit -----
    res->EVSEMaximumPowerLimit_isUsed = 1u;
    res->EVSEMaximumPowerLimit.Value = 6000;
    res->EVSEMaximumPowerLimit.Multiplier = 1;
    //res->EVSEMaximumPowerLimit.Unit_isUsed = 1u;
    res->EVSEMaximumPowerLimit.Unit = iso1unitSymbolType_W;
}

/*===========================================================================
FUNCTION: Sudo_Parameter_iso1_ChargingStatusRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_iso1_ChargingStatusRes()
{
    //int i = 0;
	struct iso1ChargingStatusResType *res;
	init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body);
	init_iso1ChargingStatusResType(&ccs_exi_doc_ISO1.V2G_Message.Body.ChargingStatusRes);

	res = &ccs_exi_doc_ISO1.V2G_Message.Body.ChargingStatusRes;
	ccs_exi_doc_ISO1.V2G_Message.Body.ChargingStatusRes_isUsed = 1u;


	//----- [BODY (1/10)] ResponseCode -----
    res->ResponseCode = OK_ISO15118_2014;

    //----- [BODY (2/10)] AC_EVSEStatus -----
    res->AC_EVSEStatus.RCD = FALSE;     //FALSE(no error), TRUE(error is detected)
    res->AC_EVSEStatus.NotificationMaxDelay = 0;
    res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None;
    //	iso1EVSENotificationType_None = 0,
    //	iso1EVSENotificationType_StopCharging = 1,
    //	iso1EVSENotificationType_ReNegotiation = 2

    //----- [BODY (3/10)] EVSEMaxCurrent -----
	res->EVSEMaxCurrent_isUsed = 1u;
	res->EVSEMaxCurrent.Value = 32;
	res->EVSEMaxCurrent.Multiplier = 0;
	res->EVSEMaxCurrent.Unit = iso1unitSymbolType_A;

    //----- [BODY (4/10)] SAScheduleTupleID -----
	res->SAScheduleTupleID = 0;

    //----- [BODY (5/10)] EVSEID -----
    res->EVSEID.charactersLen = 37;
    memset(res->EVSEID.characters, 0, sizeof(res->EVSEID.characters));
    //sprintf((char*)res->EVSEID.characters, CCS_AC_EVSEID);

    //----- [BODY (6/10)] MeterInfo -----
    res->MeterInfo_isUsed = 1u;
    memset(res->MeterInfo.MeterID.characters, 0, sizeof(res->MeterInfo.MeterID.characters));
    memset(res->MeterInfo.SigMeterReading.bytes, 0, sizeof(res->MeterInfo.SigMeterReading.bytes));

    //[MeterInfo][1/5] MeterID
    //sprintf((char*)res->MeterInfo.MeterID , CCS_AC_METER_ID);

    //[MeterInfo][2/5] SigMeterReading (optional)
    //sprintf((char*)res->MeterInfo.SigMeterReading , CCS_AC_SIG_METER_READING);

    //[MeterInfo][3/5] MeterStatus (optional)
    res->MeterInfo.MeterStatus = 0;

    //[MeterInfo][4/5] MeterReading (optional)
    res->MeterInfo.MeterReading = 12345;

    //[MeterInfo][5/5] TMeter (optional)
    res->MeterInfo.TMeter = 1586243587; //Unix Time Stamp format


    //----- [BODY (7/10)] ReceiptRequired -----
    res->ReceiptRequired_isUsed = 1u;
    res->ReceiptRequired = FALSE;       //optional
}

/*===========================================================================
FUNCTION: Check_EVErrorCode
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Check_EVErrorCode(int code)
{
    if (code != NO_ERROR)	//NO_ERROR = 0
    {
        //Asking CSU to Stop
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        //Update_V2G_Flow_Status(Other_Fault);

        //memset(buf_log_evcomm, 0, sizeof(buf_log_evcomm));
        sprintf((char*)buf_log_evcomm,
                "Stop by EV (EVErrorCode = %d (DEC))",
                code);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
}

/*===========================================================================
FUNCTION: Proc_din_CurrentDemandRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_CurrentDemandRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct CurrentDemandResponse_DIN70121 *cur;
    static struct ChargingInfoData *sys;

//    int i = 0;
//    static int EVSE_max_current;
//    int tmp = 0;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    cur = &ShmCcsData->V2GMessage_DIN70121.CurrentDemandResponse;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    cur->ResponseCode = OK_DIN70121;

    //EVSE Status Code
    cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;

    //[HEADER] Check Req SessionID
    if (Check_din_V2G_Rx_MSG_SessionID(&ccs_exi_doc_DIN) < 0)
    {
        cur->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        cur->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //Check for negative EvBatteryMaxCurrent
    if (sys->EvBatteryMaxCurrent < 0)
    {
        sprintf((char*)buf_log_evcomm,
                "[ERROR]EvBatteryMaxCurrent is negative(%.02f) => End_Process",
                sys->EvBatteryMaxCurrent);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

        cur->DC_EVSEStatus.EVSEStatusCode = dinresponseCodeType_FAILED_WrongChargeParameter;    //16
        cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
        errn = -1;
        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_WrongChargeParameter (023775)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 7;
        ShmStatusCodeData->PresentStatusCode[0][5] = 5;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
    }

    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============
    SAVE_PhysicalValueType_DIN70121(&cur->EVSEPresentCurrent, (int) (sys->PresentChargingCurrent * 10), A_DIN70121);
    SAVE_PhysicalValueType_DIN70121(&cur->EVSEPresentVoltage, (int) (sys->PresentChargingVoltage * 10), V_DIN70121);
    #if TESLA_SLOW_INCREASE_CURRENT_FUNCTION == DISABLE
    SAVE_PhysicalValueType_DIN70121(&cur->EVSEMaximumCurrentLimit, (int) (sys->AvailableChargingCurrent * 10), A_DIN70121);
    #endif
    SAVE_PhysicalValueType_DIN70121(&cur->EVSEMaximumPowerLimit, (int) (sys->AvailableChargingPower * 10), W_DIN70121);
    SAVE_PhysicalValueType_DIN70121(&cur->EVSEMaximumVoltageLimit, (int) (sys->MaximumChargingVoltage * 10), V_DIN70121);


    #if PATCH_FOR_BMW_I3_BUG_EVSEMAXIMUMVOLTAGELIMIT_599V == ENABLE
    if (sys->EvBatteryMaxVoltage <= 500)
    {
        SAVE_PhysicalValueType_DIN70121(&cur->EVSEMaximumVoltageLimit, (int) (500 * 10), V_DIN70121);   //500V
    }
    #endif

    //Limit the EVTargetCurrent should be under EVSEMaximumCurrentLimit
    if (sys->EvBatterytargetCurrent > sys->AvailableChargingCurrent)
    {
        sys->EvBatterytargetCurrent = sys->AvailableChargingCurrent;

        //[To-Do] Limit is achieved flag
    }

    //Isolation Status
    if (sys->IsolationStatus == GFD_Invalid)  //0:invalid (on going)
    {
        cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid; //0
        cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        sprintf((char*)buf_log_evcomm, "[Error][Proc_din_CurrentDemandRes]IsolationStatus = %d", sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;

    }
    else if (sys->IsolationStatus == GFD_Valid) //1: valid
    {
        cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid;  //1
    }
    else if (sys->IsolationStatus == GFD_Warning) //2: warning
    {
        cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Warning; //2
    }
    else if (sys->IsolationStatus == GFD_Fault) //3: fault
    {
        cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;  //3
        cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_din_CurrentDemandRes]GFD_Fault => Emergency Shutdown");
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }
    else //GFD_No_IMD or other unexpected status
    {
        cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;  //3
        cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        sprintf((char*)buf_log_evcomm, "[Error][Proc_din_CurrentDemandRes]IsolationStatus = %d(undefined)", sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }

    //For testing with Tesla Model 3
    #if TESLA_SLOW_INCREASE_CURRENT_FUNCTION == ENABLE
    //[CAUTION][To-Do] Decresement of Current is not implemented.
    //SAVE_PhysicalValueType_DIN70121(&cur->EVSEMaximumCurrentLimit, 10, A_DIN70121);
    if (sys->EvBatterytargetCurrent <= 0)
    {
        EVSE_max_current =  50;   //10A
        cur->EVSEMaximumCurrentLimit.Value = 50;   //10A
        /*
          DEBUG_PRINTF_EVCOMM_DETAIL("1PresentChargingCurrent = %.02f, EvBatterytargetCurrent = %.02f, EVSE_max_current = %d, EVSEMaximumCurrentLimit = %d\n",
                    sys->PresentChargingCurrent,
                    sys->EvBatterytargetCurrent,
                    EVSE_max_current,
                    cur->EVSEMaximumCurrentLimit.Value
                );
        */
    }
    else //1A
    {
        /*
    	  DEBUG_PRINTF_EVCOMM_DETAIL("2PresentChargingCurrent = %.02f, EvBatterytargetCurrent = %.02f, EVSE_max_current = %d, EVSEMaximumCurrentLimit = %d\n",
                    sys->PresentChargingCurrent,
                    sys->EvBatterytargetCurrent,
                    EVSE_max_current,
                    cur->EVSEMaximumCurrentLimit.Value
                );
        */
        if ((abs((int)sys->PresentChargingCurrent - (int)sys->EvBatterytargetCurrent) < 3)&&(abs((int)(EVSE_max_current/10) - (int)sys->EvBatterytargetCurrent) < 3))
        {
            tmp = EVSE_max_current + 50; //10A

            if (tmp <= (int)(sys->AvailableChargingCurrent * 10))
            {
             cur->EVSEMaximumCurrentLimit.Value = (int)tmp;
                EVSE_max_current = tmp;
            }
            else
            {
                cur->EVSEMaximumCurrentLimit.Value = (int) (sys->AvailableChargingCurrent * 10);   //max is set to 40A
                 EVSE_max_current =  (int) (sys->AvailableChargingCurrent * 10);
            }
        }
    }
    #endif

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        //Check for Alarm Code: CCS GFD trip (012235)
        if (ShmInternalComm->EVSEStopChargingReq.alarmcode[0] == 0 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[1] == 1 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[2] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[3] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[4] == 3 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[5] == 5)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][Error][CurrentDemandRes]CCS GFD trip => EVSE_Shutdown");
            cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;
        }
        else
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][Error][CurrentDemandRes]EVSE_Shutdown");
            cur->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus;
        }

        //cur->ResponseCode = FAILED_DIN70121;
        cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
        //errn = -1;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        //Check for Alarm Code: CCS GFD trip (012235)
        if (ShmInternalComm->EVSEStopChargingReq.alarmcode[0] == 0 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[1] == 1 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[2] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[3] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[4] == 3 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[5] == 5)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][Error][CurrentDemandRes]CCS GFD trip => EVSE_EmergencyShutdown");
            cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;
        }
        else
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][Error][CurrentDemandRes]EVSE_EmergencyShutdown");
            cur->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus;
        }

        //cur->ResponseCode = FAILED_DIN70121;
        cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        //errn = -1;
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][Error][CurrentDemandRes]Permission OFF");
        //cur->ResponseCode = FAILED_DIN70121;
        cur->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus;
        cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
        //errn = -1;
    }
    else
    {
        //null
    }

    //Response to CP Error
    #if CP_PROTECTION_MECHANISM == ENABLE
    if ((sys->CpState != 4) && (sys->CpState != 5))  //State C (6V), D (3V)
    {
        cur->ResponseCode = FAILED_DIN70121;
        cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_CP_State_Error (023889)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 8;
        ShmStatusCodeData->PresentStatusCode[0][4] = 8;
        ShmStatusCodeData->PresentStatusCode[0][5] = 9;
        CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;

        sprintf((char*)buf_log_evcomm,
                "[CurrentDemand]Emergency Stop by CP Error (%d, %.02f V)",
                sys->CpState,
                sys->CpVoltage);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    #endif


    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_din_CurrentDemandRes(&ccs_exi_doc_DIN, ShmCcsData);
    #else
    Sudo_Parameter_din_CurrentDemandRes();
    #endif

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_DIN) != 0)
    {
        errn = -1;
    }

    //STEP 5: ============ Update Flags ===========

    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_CurrentDemandRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_CurrentDemandRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct CurrentDemandResponse_ISO15118_2014 *cur;
    static struct ChargingInfoData *sys;
//    int i = 0;
//    static int EVSE_max_current;
//    int tmp = 0;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    cur = &ShmCcsData->V2GMessage_ISO15118_2014.CurrentDemandResponse;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    cur->ResponseCode = OK_ISO15118_2014;

    //EVSE Status Code
    cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;

    //[HEADER] Check Req SessionID
    if (Check_iso1_V2G_Rx_MSG_SessionID(&ccs_exi_doc_ISO1) < 0)
    {
        cur->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        cur->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //Check for negative EvBatteryMaxCurrent
    if (sys->EvBatteryMaxCurrent < 0)
    {
        sprintf((char*)buf_log_evcomm,
                "[ERROR]EvBatteryMaxCurrent is negative(%.02f) => End_Process",
                sys->EvBatteryMaxCurrent);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

        cur->ResponseCode = iso1responseCodeType_FAILED_WrongChargeParameter;   //16
        cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
        errn = -1;
        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_WrongChargeParameter (023775)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 7;
        ShmStatusCodeData->PresentStatusCode[0][5] = 5;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
    }


    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============
    SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEPresentCurrent, (int) (sys->PresentChargingCurrent * 10), A_ISO15118_2014);
    SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEPresentVoltage, (int) (sys->PresentChargingVoltage * 10), V_ISO15118_2014);
    #if TESLA_SLOW_INCREASE_CURRENT_FUNCTION == DISABLE
    SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEMaximumCurrentLimit, (int) (sys->AvailableChargingCurrent * 10), A_ISO15118_2014);
    #endif
    SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEMaximumPowerLimit, (int) (sys->AvailableChargingPower * 10), W_ISO15118_2014);
    SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEMaximumVoltageLimit, (int) (sys->MaximumChargingVoltage * 10), V_ISO15118_2014);


    #if PATCH_FOR_BMW_I3_BUG_EVSEMAXIMUMVOLTAGELIMIT_599V == ENABLE
    if (sys->EvBatteryMaxVoltage <= 500)
    {
        SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEMaximumVoltageLimit, (int) (500 * 10), V_ISO15118_2014);   //500V
    }
    #endif

    //Limit the EVTargetCurrent should be under EVSEMaximumCurrentLimit
    if (sys->EvBatterytargetCurrent > sys->AvailableChargingCurrent)
    {
        sys->EvBatterytargetCurrent = sys->AvailableChargingCurrent;

        //[To-Do] Limit is achieved flag
    }

    //Isolation Status
    if (sys->IsolationStatus == GFD_Invalid) //0: invalid (on going)
    {
        cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Invalid; //0
        cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        sprintf((char*)buf_log_evcomm, "[Error][Proc_iso1_CurrentDemandRes]IsolationStatus = %d", sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }
    else if (sys->IsolationStatus == GFD_Valid) //1: valid
    {
        cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid;  //1
    }
    else if (sys->IsolationStatus == GFD_Warning) //2: warning
    {
        cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Warning; //2
    }
    else if (sys->IsolationStatus == GFD_Fault) //3: fault
    {
        cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;  //3
        cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_iso1_CurrentDemandRes]GFD_Fault => EmergencyShutdown");
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }
    else
    {
        cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;  //3
        cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        sprintf((char*)buf_log_evcomm, "[Error][Proc_iso1_CurrentDemandRes]IsolationStatus = %d(undefined)", sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }

    //For testing with Tesla Model 3
    #if TESLA_SLOW_INCREASE_CURRENT_FUNCTION == ENABLE
    //[CAUTION][To-Do] Decresement of Current is not implemented.
    //SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEMaximumCurrentLimit, 10, A_ISO15118_2014);
    if (sys->EvBatterytargetCurrent <= 0)
    {
        EVSE_max_current =  50;   //10A
        cur->EVSEMaximumCurrentLimit.Value = 50;   //10A
        /*
          DEBUG_PRINTF_EVCOMM_DETAIL("1PresentChargingCurrent = %.02f, EvBatterytargetCurrent = %.02f, EVSE_max_current = %d, EVSEMaximumCurrentLimit = %d\n",
                    sys->PresentChargingCurrent,
                    sys->EvBatterytargetCurrent,
                    EVSE_max_current,
                    cur->EVSEMaximumCurrentLimit.Value
                );
        */
    }
    else //1A
    {
        /*
    	  DEBUG_PRINTF_EVCOMM_DETAIL("2PresentChargingCurrent = %.02f, EvBatterytargetCurrent = %.02f, EVSE_max_current = %d, EVSEMaximumCurrentLimit = %d\n",
                    sys->PresentChargingCurrent,
                    sys->EvBatterytargetCurrent,
                    EVSE_max_current,
                    cur->EVSEMaximumCurrentLimit.Value
                );
        */
        if ((abs((int)sys->PresentChargingCurrent - (int)sys->EvBatterytargetCurrent) < 3)&&(abs((int)(EVSE_max_current/10) - (int)sys->EvBatterytargetCurrent) < 3))
        {
            tmp = EVSE_max_current + 50; //10A

            if (tmp <= (int)(sys->AvailableChargingCurrent * 10))
            {
             cur->EVSEMaximumCurrentLimit.Value = (int)tmp;
                EVSE_max_current = tmp;
            }
            else
            {
                cur->EVSEMaximumCurrentLimit.Value = (int) (sys->AvailableChargingCurrent * 10);   //max is set to 40A
                 EVSE_max_current =  (int) (sys->AvailableChargingCurrent * 10);
            }
        }
    }
    #endif

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        //Check for Alarm Code: CCS GFD trip (012235)
        if (ShmInternalComm->EVSEStopChargingReq.alarmcode[0] == 0 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[1] == 1 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[2] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[3] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[4] == 3 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[5] == 5)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][Error][CurrentDemandRes]CCS GFD trip => EVSE_Shutdown");
            cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;
        }
        else
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][Error][CurrentDemandRes]EVSE_Shutdown");
            cur->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus;
        }

        //cur->ResponseCode = FAILED_ISO15118_2014;
        cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
        //errn = -1;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        //Check for Alarm Code: CCS GFD trip (012235)
        if (ShmInternalComm->EVSEStopChargingReq.alarmcode[0] == 0 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[1] == 1 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[2] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[3] == 2 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[4] == 3 &&
            ShmInternalComm->EVSEStopChargingReq.alarmcode[5] == 5)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][Error][CurrentDemandRes]CCS GFD trip => EVSE_EmergencyShutdown");
            cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;
        }
        else
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][Error][CurrentDemandRes]EVSE_EmergencyShutdown");
            cur->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus;
        }

        //cur->ResponseCode = FAILED_ISO15118_2014;
        cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        //errn = -1;
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][Error][CurrentDemandRes]Permission OFF");
        //cur->ResponseCode = FAILED_ISO15118_2014;
        cur->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus;
        cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
        //errn = -1;
    }
    else
    {
        //null
    }

    //Response to CP Error
    #if CP_PROTECTION_MECHANISM == ENABLE
    if ((sys->CpState != 4) && (sys->CpState != 5))  //State C (6V), D (3V)
    {
        cur->ResponseCode = FAILED_ISO15118_2014;
        cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_CP_State_Error (023889)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 8;
        ShmStatusCodeData->PresentStatusCode[0][4] = 8;
        ShmStatusCodeData->PresentStatusCode[0][5] = 9;
        CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;

        sprintf((char*)buf_log_evcomm,
                "[CurrentDemand]Emergency Stop by CP Error (%d, %.02f V)",
                sys->CpState,
                sys->CpVoltage);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    #endif

    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_iso1_CurrentDemandRes(&ccs_exi_doc_ISO1, ShmCcsData);
    #else
    Sudo_Parameter_iso1_CurrentDemandRes();
    #endif

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        errn = -1;
    }

    //STEP 5: ============ Update Flags ===========

    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_ChargingStatusRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_ChargingStatusRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct ChargingStatusResponse_ISO15118_2014 *res;
    static struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    res = &ShmCcsData->V2GMessage_ISO15118_2014.ChargingStatusResponse;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    //Init
    res->ResponseCode = OK_ISO15118_2014;
    res->ReceiptRequired = FALSE;       //optional
    res->SAScheduleTupleID = 0;
    res->AC_EVSEStatus.RCD = FALSE;     //FALSE(no error), TRUE(error is detected)
    res->AC_EVSEStatus.NotificationMaxDelay = 0;
    res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None;
    //	iso1EVSENotificationType_None = 0,
    //	iso1EVSENotificationType_StopCharging = 1,
    //	iso1EVSENotificationType_ReNegotiation = 2

    //[HEADER] Check Req SessionID
    if (Check_iso1_V2G_Rx_MSG_SessionID(&ccs_exi_doc_ISO1) < 0)
    {
        res->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        res->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //EVSE ID
    memset(res->EVSEID, 0, sizeof(res->EVSEID));
    //sprintf((char*)res->EVSEID, CCS_AC_EVSEID);

    //[MeterInfo][0/5] init
    //memset(res->MeterInfo.MeterID.characters, 0, sizeof(res->MeterInfo.MeterID.characters));
    //memset(res->MeterInfo.SigMeterReading.bytes, 0, sizeof(res->MeterInfo.SigMeterReading.bytes));

    //[MeterInfo][1/5] MeterID
    //sprintf((char*)res->MeterInfo.MeterID , CCS_AC_METER_ID);

    //[MeterInfo][2/5] SigMeterReading (optional)
    //sprintf((char*)res->MeterInfo.SigMeterReading , CCS_AC_SIG_METER_READING);

    //[MeterInfo][3/5] MeterStatus (optional)
    res->MeterInfo.MeterStatus = 0;

    //[MeterInfo][4/5] MeterReading (optional)
    res->MeterInfo.MeterReading = 12345;

    //[MeterInfo][5/5] TMeter (optional)
    res->MeterInfo.TMeter = 1586243587; //Unix Time Stamp format



    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============
    SAVE_PhysicalValueType_ISO15118_2014(&res->EVSEMaxCurrent, (int)(sys->AvailableChargingCurrent * 10), A_ISO15118_2014);

    //Isolation Status (RCD)
    if (sys->IsolationStatus == 0)  //Isolation is invalid
    {
        res->AC_EVSEStatus.RCD = TRUE;     //FALSE(no error), TRUE(error is detected)
        res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        sprintf((char*)buf_log_evcomm, "[ISO1][Error][ChargingStatusRes]IsolationStatus = %d", sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }
    else if (sys->IsolationStatus == 1) //Isolation is valid
    {
        res->AC_EVSEStatus.RCD = FALSE;     //FALSE(no error), TRUE(error is detected)
        res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None;
    }
    else
    {
        res->AC_EVSEStatus.RCD = TRUE;     //FALSE(no error), TRUE(error is detected)
        res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        sprintf((char*)buf_log_evcomm, "[ISO1][Error][ChargingStatusRes]IsolationStatus = %d(undefined)", sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        //res->ResponseCode = FAILED_ISO15118_2014;
        res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging;
        //errn = -1;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        //res->ResponseCode = FAILED_ISO15118_2014;
        res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging;
        //errn = -1;
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        //res->ResponseCode = FAILED_ISO15118_2014;
        res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging;
        //errn = -1;
    }

    //Response to CP Error
    #if CP_PROTECTION_MECHANISM == ENABLE
    if ((sys->CpState != 4) && (sys->CpState != 5))  //State C (6V), D (3V)
    {
        res->ResponseCode = FAILED_ISO15118_2014;
        res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        Update_V2G_Flow_Status(Other_Fault);

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_CP_State_Error (023889)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 8;
        ShmStatusCodeData->PresentStatusCode[0][4] = 8;
        ShmStatusCodeData->PresentStatusCode[0][5] = 9;
        CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;

        sprintf((char*)buf_log_evcomm,
                "[ChargingStatus]Emergency Stop by CP Error (%d, %.02f V)",
                sys->CpState,
                sys->CpVoltage);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    #endif

    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_iso1_ChargingStatusRes(&ccs_exi_doc_ISO1, ShmCcsData);
    #else
    Sudo_Parameter_iso1_ChargingStatusRes();
    #endif

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        errn = -1;
    }

    //STEP 5: ============ Update Flags ===========

    return errn;
}

/*===========================================================================
FUNCTION: Proc_din_CurrentDemandReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_CurrentDemandReq(int AcceptFd)
{
    int errn = 0;
    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_CurrentDemandReq] Got CurrentDemandReq\n");

    //Print the decoded XML Document
    PRINT_XML_DOC_DIN_CurrentDemandReq(&ccs_exi_doc_DIN);

    //Save into Share Memory
    SHM_Save_din_CurrentDemandReq(ShmCcsData, &ccs_exi_doc_DIN, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_DIN70121.CurrentDemandRequest.DC_EVStatus.EVErrorCode);

    errn = Proc_din_CurrentDemandRes(AcceptFd);
    if (errn == 0)
    {
        //Response is sent successfully.
        //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][V2G][Tx]CurrentDemandRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[DIN][Error][CurrentDemandReq]CurrentDemandRes: fail(%d,DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_CurrentDemandReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_CurrentDemandReq(int AcceptFd)
{
    int errn = 0;
    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_CurrentDemandReq] Got CurrentDemandReq\n");

    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_CurrentDemandReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_CurrentDemandReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_ISO15118_2014.CurrentDemandRequest.DC_EVStatus.EVErrorCode);

    errn = Proc_iso1_CurrentDemandRes(AcceptFd);
    if (errn == 0)
    {
        //Response is sent successfully.
        //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][V2G][Tx]CurrentDemandRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[ISO1][Error][CurrentDemandReq]CurrentDemandRes: fail(%d,DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_ChargingStatusReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_ChargingStatusReq(int AcceptFd)
{
    int errn = 0;
    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_ChargingStatusReq] Got ChargingStatusReq\n");

    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_ChargingStatusReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_ChargingStatusReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    //Check for EV Error Code
    //no content in ISO1

    errn = Proc_iso1_ChargingStatusRes(AcceptFd);
    if (errn == 0)
    {
        //Response is sent successfully.
        //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][V2G][Tx]ChargingStatusRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[ISO1][Error][ChargingStatusReq]ChargingStatusRes: fail(%d,DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_din_PowerDeliveryStopRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_PowerDeliveryStopRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    struct dinPowerDeliveryResType *res;
    struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    res = &ccs_exi_doc_DIN.V2G_Message.Body.PowerDeliveryRes;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    res->ResponseCode = OK_DIN70121;

    //[HEADER] Check Req SessionID
    if (Check_din_V2G_Rx_MSG_SessionID(&ccs_exi_doc_DIN) < 0)
    {
        res->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        res->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============


    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    ShmCcsData->V2GMessage_DIN70121.PowerDeliveryResponse.DC_EVSEStatus.EVSEStatusCode = EVSE_NotReady;
    SHM_Read_din_PowerDeliveryRes(&ccs_exi_doc_DIN, ShmCcsData);
    #else
    Sudo_Parameter_din_PreChargeRes();
    #endif

    //EVSE Status Code
    res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        //res->ResponseCode = FAILED_DIN70121;
        res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        //res->ResponseCode = FAILED_DIN70121;
        res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        //res->ResponseCode = FAILED_DIN70121;
        res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
    }

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_DIN) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_PowerDeliveryStopRes][Error]Tx encoded msg error");
        errn = -1;
    }

    //STEP 5: ============ Update Flags ===========

    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_PowerDeliveryStopRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_PowerDeliveryStopRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    struct iso1PowerDeliveryResType *res;
    struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    res = &ccs_exi_doc_ISO1.V2G_Message.Body.PowerDeliveryRes;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    res->ResponseCode = OK_ISO15118_2014;

    //[HEADER] Check Req SessionID
    if (Check_iso1_V2G_Rx_MSG_SessionID(&ccs_exi_doc_ISO1) < 0)
    {
        res->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        res->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============


    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryResponse.DC_EVSEStatus.DC_EVSEStatusCode = EVSE_NotReady;
    SHM_Read_iso1_PowerDeliveryRes(&ccs_exi_doc_ISO1, ShmCcsData);
    #else
    Sudo_Parameter_iso1_PreChargeRes();
    #endif

    //EVSE Status Code
    res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;
    res->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid;  //1 /*+++ 20200808, vern, Isolation Status should be valid during 2nd PowerDelivert ---*/

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        //res->ResponseCode = FAILED_ISO15118_2014;
    	res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready; /*+++ 20200808, vern, Isolation Status should be valid during 2nd PowerDelivert ---*/
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        //res->ResponseCode = FAILED_ISO15118_2014;
        res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        //res->ResponseCode = FAILED_ISO15118_2014;
    	res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready; /*+++ 20200808, vern, Isolation Status should be valid during 2nd PowerDelivert ---*/
    }

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_PowerDeliveryStopRes][Error]Tx encoded msg error");
        errn = -1;
    }

    //STEP 5: ============ Update Flags ===========

    return errn;
}

/*===========================================================================
FUNCTION: Proc_din_PowerDeliveryStopReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_PowerDeliveryStopReq(int AcceptFd)
{
    int errn = 0;
    //Request CSU to STOP
    //This should be reponsed as soon as possible once this message is received.
    CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
    EVCOMM_SYS_INFO.EvBatterytargetVoltage = 0;
    EVCOMM_SYS_INFO.EvBatterytargetCurrent = 0;

    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]PowerDeliveryReq (2nd)\n");

    //Print the decoded XML Document
    PRINT_XML_DOC_DIN_PowerDeliveryReq(&ccs_exi_doc_DIN);

    //Save into Share Memory
    SHM_Save_din_PowerDeliveryReq(ShmCcsData, &ccs_exi_doc_DIN, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_DIN70121.PowerDeliveryRequest.DC_EVPowerDeliveryParameter.DC_EVStatus.EVErrorCode);

    //[To-Do] Sending response after the EVSE output voltage decreases to under 60V
    usleep(1500000);    //1.5 seconds
    //sleep(1);   //1 second

    errn = Proc_din_PowerDeliveryStopRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][V2G][Tx]PowerDeliveryRes (2nd)\n");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_din_PowerDeliveryStopReq]Proc_iso1_PowerDeliveryStopRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_PowerDeliveryStopReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_PowerDeliveryStopReq(int AcceptFd)
{
    int errn = 0;
    //Request CSU to STOP
    //This should be reponsed as soon as possible once this message is received.
    CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
    EVCOMM_SYS_INFO.EvBatterytargetVoltage = 0;
    EVCOMM_SYS_INFO.EvBatterytargetCurrent = 0;

    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]PowerDeliveryReq (2nd)\n");

    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_PowerDeliveryReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_PowerDeliveryReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryRequest.DC_EVPowerDeliveryParameter.DC_EVStatus.EVErrorCode);

    //[To-Do] Sending response after the EVSE output voltage decreases to under 60V
    usleep(1500000);    //1.5 seconds
    //sleep(1);   //1 second
    errn = Proc_iso1_PowerDeliveryStopRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][V2G][Tx]PowerDeliveryRes (2nd)");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_iso1_PowerDeliveryStopReq]Proc_iso1_PowerDeliveryStopRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}


/*===========================================================================
FUNCTION: SHM_Init_din_WeldingDetectionRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
    1. shm_ccs

OUTPUT:
    1. shm_ccs

GLOBAL VARIABLES:
=============================================================================*/
void SHM_Init_din_WeldingDetectionRes(struct CcsData *shm_ccs)
{
	struct WeldingDetectionResponse_DIN70121 *in;

	in = &shm_ccs->V2GMessage_DIN70121.WeldingDetectionResponse;


	//----- [BODY (1/3)] ResponseCode -----
    in->ResponseCode = dinresponseCodeType_OK;

    //----- [BODY (2/3)] EVSEPresentVoltage -----
    short value = 0; int multiplier = 0; unsigned char unit = 0;

    //value = 3820; multiplier = -1; unit = V_DIN70121;    //382V, for test only.
    value = 0; multiplier = 0; unit = V_DIN70121;
	SHM_Save_dinPhysicalValueType(&in->EVSEPresentVoltage, value, multiplier, unit);

    //----- [BODY (3/3)] DC_EVSEStatus -----
    SHM_Init_dinDC_EVSEStatusType(&in->DC_EVSEStatus);
}


/*===========================================================================
FUNCTION: Sudo_Parameter_din_WeldingDetectionRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_din_WeldingDetectionRes()
{
    init_dinBodyType(&ccs_exi_doc_DIN.V2G_Message.Body);
    init_dinWeldingDetectionResType(&ccs_exi_doc_DIN.V2G_Message.Body.WeldingDetectionRes);

    ccs_exi_doc_DIN.V2G_Message.Body.WeldingDetectionRes_isUsed = 1u;

    //----- [BODY (1/3)] ResponseCode -----
    struct dinWeldingDetectionResType *res;
    res = &ccs_exi_doc_DIN.V2G_Message.Body.WeldingDetectionRes;
    res->ResponseCode = dinresponseCodeType_OK;


    //----- [BODY (2/3)] EVSEPresentVoltage -----
    res->EVSEPresentVoltage.Value = 3820;
    res->EVSEPresentVoltage.Multiplier = -1;
    res->EVSEPresentVoltage.Unit_isUsed = 1u;
    res->EVSEPresentVoltage.Unit = dinunitSymbolType_V;
    //	dinunitSymbolType_h = 0,
    //	dinunitSymbolType_m = 1,
    //	dinunitSymbolType_s = 2,
    //	dinunitSymbolType_A = 3,
    //	dinunitSymbolType_Ah = 4,
    //	dinunitSymbolType_V = 5,
    //	dinunitSymbolType_VA = 6,
    //	dinunitSymbolType_W = 7,
    //	dinunitSymbolType_W_s = 8,
    //	dinunitSymbolType_Wh = 9


    //----- [BODY (3/3)] DC_EVSEStatus -----
    res->DC_EVSEStatus.EVSEIsolationStatus_isUsed = 1u;
    res->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid;
    //	dinisolationLevelType_Invalid = 0,
    //	dinisolationLevelType_Valid = 1,
    //	dinisolationLevelType_Warning = 2,
    //	dinisolationLevelType_Fault = 3

    res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;
    // dinDC_EVSEStatusCodeType_EVSE_NotReady = 0,
    // dinDC_EVSEStatusCodeType_EVSE_Ready = 1,
    // dinDC_EVSEStatusCodeType_EVSE_Shutdown = 2,
    // dinDC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
    // dinDC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
    // dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
    // dinDC_EVSEStatusCodeType_EVSE_Malfunction = 6,
    // dinDC_EVSEStatusCodeType_Reserved_8 = 7,
    // dinDC_EVSEStatusCodeType_Reserved_9 = 8,
    // dinDC_EVSEStatusCodeType_Reserved_A = 9,
    // dinDC_EVSEStatusCodeType_Reserved_B = 10,
    // dinDC_EVSEStatusCodeType_Reserved_C = 11

    res->DC_EVSEStatus.NotificationMaxDelay = 0u;

    res->DC_EVSEStatus.EVSENotification = dinEVSENotificationType_None;
    // dinEVSENotificationType_None = 0,
    // dinEVSENotificationType_StopCharging = 1,
    // dinEVSENotificationType_ReNegotiation = 2
}

/*===========================================================================
FUNCTION: Sudo_Parameter_iso1_WeldingDetectionRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_iso1_WeldingDetectionRes()
{
    init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body);
    init_iso1WeldingDetectionResType(&ccs_exi_doc_ISO1.V2G_Message.Body.WeldingDetectionRes);

    ccs_exi_doc_ISO1.V2G_Message.Body.WeldingDetectionRes_isUsed = 1u;

    //----- [BODY (1/3)] ResponseCode -----
    struct iso1WeldingDetectionResType *res;
    res = &ccs_exi_doc_ISO1.V2G_Message.Body.WeldingDetectionRes;
    res->ResponseCode = iso1responseCodeType_OK;


    //----- [BODY (2/3)] EVSEPresentVoltage -----
    res->EVSEPresentVoltage.Value = 3820;
    res->EVSEPresentVoltage.Multiplier = -1;
    //res->EVSEPresentVoltage.Unit_isUsed = 1u;
    res->EVSEPresentVoltage.Unit = iso1unitSymbolType_V;
    //iso1unitSymbolType_h = 0,
	//iso1unitSymbolType_m = 1,
	//iso1unitSymbolType_s = 2,
	//iso1unitSymbolType_A = 3,
	//iso1unitSymbolType_V = 4,
	//iso1unitSymbolType_W = 5,
	//iso1unitSymbolType_Wh = 6


    //----- [BODY (3/3)] DC_EVSEStatus -----
    res->DC_EVSEStatus.EVSEIsolationStatus_isUsed = 1u;
    res->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid;
    //iso1isolationLevelType_Invalid = 0,
	//iso1isolationLevelType_Valid = 1,
	//iso1isolationLevelType_Warning = 2,
	//iso1isolationLevelType_Fault = 3,
	//iso1isolationLevelType_No_IMD = 4

    res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;
    //iso1DC_EVSEStatusCodeType_EVSE_NotReady = 0,
	//iso1DC_EVSEStatusCodeType_EVSE_Ready = 1,
	//iso1DC_EVSEStatusCodeType_EVSE_Shutdown = 2,
	//iso1DC_EVSEStatusCodeType_EVSE_UtilityInterruptEvent = 3,
	//iso1DC_EVSEStatusCodeType_EVSE_IsolationMonitoringActive = 4,
	//iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown = 5,
	//iso1DC_EVSEStatusCodeType_EVSE_Malfunction = 6,
	//iso1DC_EVSEStatusCodeType_Reserved_8 = 7,
	//iso1DC_EVSEStatusCodeType_Reserved_9 = 8,
	//iso1DC_EVSEStatusCodeType_Reserved_A = 9,
	//iso1DC_EVSEStatusCodeType_Reserved_B = 10,
	//iso1DC_EVSEStatusCodeType_Reserved_C = 11

    res->DC_EVSEStatus.NotificationMaxDelay = 0u;

    res->DC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None;
    //iso1EVSENotificationType_None = 0,
	//iso1EVSENotificationType_StopCharging = 1,
	//iso1EVSENotificationType_ReNegotiation = 2
}


/*===========================================================================
FUNCTION: Proc_din_WeldingDetectionRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_WeldingDetectionRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct WeldingDetectionResponse_DIN70121 *wel;
    static struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    wel = &ShmCcsData->V2GMessage_DIN70121.WeldingDetectionResponse;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    wel->ResponseCode = OK_DIN70121;

    //[HEADER] Check Req SessionID
    if (Check_din_V2G_Rx_MSG_SessionID(&ccs_exi_doc_DIN) < 0)
    {
        wel->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        wel->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }


    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============
    SAVE_PhysicalValueType_DIN70121(&wel->EVSEPresentVoltage, (int) (sys->PresentChargingVoltage * 10), V_DIN70121);

    //EVSE Status Code
    wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready;

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        //wel->ResponseCode = FAILED_DIN70121;
        wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        //wel->ResponseCode = FAILED_DIN70121;
        wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        //wel->ResponseCode = FAILED_DIN70121;
        wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown;
    }

    //Isolation Status
    if (sys->IsolationStatus == GFD_Invalid)  //0:invalid (on going)
    {
        wel->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid; //0
        wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        sprintf((char*)buf_log_evcomm, "[Error][Proc_din_WeldingDetectionRes]IsolationStatus = %d", sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;

    }
    else if (sys->IsolationStatus == GFD_Valid) //1: valid
    {
        wel->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid;  //1
    }
    else if (sys->IsolationStatus == GFD_Warning) //2: warning
    {
        wel->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Warning; //2
    }
    else if (sys->IsolationStatus == GFD_Fault) //3: fault
    {
        wel->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;  //3
        wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_din_WeldingDetectionRes]GFD_Fault => Emergency Shutdown");
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }
    else //GFD_No_IMD or other unexpected status
    {
        wel->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault;  //3
        wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        sprintf((char*)buf_log_evcomm, "[Error][Proc_din_WeldingDetectionRes]IsolationStatus = %d(undefined)", sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }

    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_din_WeldingDetectionRes(&ccs_exi_doc_DIN, ShmCcsData);
    #else
    Sudo_Parameter_din_WeldingDetectionRes();
    #endif

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_DIN) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_WeldingDetectionRes][Error]Tx encoded msg error");
        errn = -1;
    }

    //STEP 5: ============ Update Flags ===========

    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_WeldingDetectionRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_WeldingDetectionRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    static struct WeldingDetectionResponse_ISO15118_2014 *wel;
    static struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    wel = &ShmCcsData->V2GMessage_ISO15118_2014.WeldingDetectionResponse;
    sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    wel->ResponseCode = OK_ISO15118_2014;

    //[HEADER] Check Req SessionID
    if (Check_iso1_V2G_Rx_MSG_SessionID(&ccs_exi_doc_ISO1) < 0)
    {
        wel->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        wel->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============
    SAVE_PhysicalValueType_ISO15118_2014(&wel->EVSEPresentVoltage, (int) (sys->PresentChargingVoltage * 10), V_ISO15118_2014);

    //EVSE Status Code
    wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready;

    //Check for CSU command of "Stop by EVSE"
    if (sys->DC_EVSEStatus == EVSE_Shutdown)
    {
        //wel->ResponseCode = FAILED_ISO15118_2014;
        wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
    }
    else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown)
    {
        //wel->ResponseCode = FAILED_ISO15118_2014;
        wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
    }
    else if (ShmInternalComm->ChargingPermission == FALSE)
    {
        //wel->ResponseCode = FAILED_ISO15118_2014;
        wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown;
    }

    //Isolation Status
    if (sys->IsolationStatus == GFD_Invalid) //0: invalid (on going)
    {
        wel->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Invalid; //0
        wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        sprintf((char*)buf_log_evcomm, "[Error][Proc_iso1_WeldingDetectionRes]IsolationStatus = %d", sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }
    else if (sys->IsolationStatus == GFD_Valid) //1: valid
    {
        wel->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid;  //1
    }
    else if (sys->IsolationStatus == GFD_Warning) //2: warning
    {
        wel->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Warning; //2
    }
    else if (sys->IsolationStatus == GFD_Fault) //3: fault
    {
        wel->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;  //3
        wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error][Proc_iso1_WeldingDetectionRes]GFD_Fault => EmergencyShutdown");
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }
    else
    {
        wel->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault;  //3
        wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown;
        CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
        sprintf((char*)buf_log_evcomm, "[Error][Proc_iso1_WeldingDetectionRes]IsolationStatus = %d(undefined)", sys->IsolationStatus);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }

    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_iso1_WeldingDetectionRes(&ccs_exi_doc_ISO1, ShmCcsData);
    #else
    Sudo_Parameter_iso1_WeldingDetectionRes();
    #endif

    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_WeldingDetectionRes][Error]Tx encoded msg error");
        errn = -1;
    }

    //STEP 5: ============ Update Flags ===========

    return errn;
}


/*===========================================================================
FUNCTION: Proc_din_WeldingDetectionReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_WeldingDetectionReq(int AcceptFd)
{
    int errn = 0;
    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_din_WeldingDetectionReq] Got WeldingDetectionReq\n");

    //Print the decoded XML Document
    PRINT_XML_DOC_DIN_WeldingDetectionReq(&ccs_exi_doc_DIN);

    //Save into Share Memory
    SHM_Save_din_WeldingDetectionReq(ShmCcsData, &ccs_exi_doc_DIN, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_DIN70121.WeldingDetectionRequest.DC_EVStatus.EVErrorCode);

    errn = Proc_din_WeldingDetectionRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[DIN][V2G][Tx]WeldingDetectionRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_din_WeldingDetectionReq]Proc_din_WeldingDetectionRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_WeldingDetectionReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_WeldingDetectionReq(int AcceptFd)
{
    int errn = 0;
    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Proc_iso1_WeldingDetectionReq] Got WeldingDetectionReq\n");


    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_WeldingDetectionReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_WeldingDetectionReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    //Check for EV Error Code
    Check_EVErrorCode(ShmCcsData->V2GMessage_ISO15118_2014.WeldingDetectionRequest.DC_EVStatus.EVErrorCode);

    errn = Proc_iso1_WeldingDetectionRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
        //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ISO1][V2G][Tx]WeldingDetectionRes");
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_iso1_WeldingDetectionReq]Proc_iso1_WeldingDetectionRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}


/*===========================================================================
FUNCTION: SHM_Init_din_SessionStopRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
    1. shm_ccs

OUTPUT:
    1. shm_ccs

GLOBAL VARIABLES:
=============================================================================*/
void SHM_Init_din_SessionStopRes(struct CcsData *shm_ccs)
{
	struct SessionStopResponse_DIN70121 *in;

	in = &shm_ccs->V2GMessage_DIN70121.SessionStopResponse;

	//----- [BODY (1/3)] ResponseCode -----
    in->ResponseCode = dinresponseCodeType_OK;
}

/*===========================================================================
FUNCTION: Sudo_Parameter_din_SessionStopRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_din_SessionStopRes()
{
    init_dinBodyType(&ccs_exi_doc_DIN.V2G_Message.Body);
    init_dinSessionStopResType(&ccs_exi_doc_DIN.V2G_Message.Body.SessionStopRes);

    ccs_exi_doc_DIN.V2G_Message.Body.SessionStopRes_isUsed = 1u;

    //----- [BODY (1/3)] ResponseCode -----
    struct dinSessionStopResType *res;
    res = &ccs_exi_doc_DIN.V2G_Message.Body.SessionStopRes;
    res->ResponseCode = dinresponseCodeType_OK;
}

/*===========================================================================
FUNCTION: Sudo_Parameter_iso1_SessionStopRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
void Sudo_Parameter_iso1_SessionStopRes()
{
    init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body);
    init_iso1SessionStopResType(&ccs_exi_doc_ISO1.V2G_Message.Body.SessionStopRes);

    ccs_exi_doc_ISO1.V2G_Message.Body.SessionStopRes_isUsed = 1u;

    //----- [BODY (1/3)] ResponseCode -----
    struct iso1SessionStopResType *res;
    res = &ccs_exi_doc_ISO1.V2G_Message.Body.SessionStopRes;
    res->ResponseCode = iso1responseCodeType_OK;
}


/*===========================================================================
FUNCTION: Proc_din_SessionStopRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_SessionStopRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    struct SessionStopResponse_DIN70121 *stp;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    stp = &ShmCcsData->V2GMessage_DIN70121.SessionStopResponse;

    stp->ResponseCode = OK_DIN70121;

    //[HEADER] Check Req SessionID
    if (Check_din_V2G_Rx_MSG_SessionID(&ccs_exi_doc_DIN) < 0)
    {
        stp->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        stp->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============


    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_din_SessionStopRes(&ccs_exi_doc_DIN, ShmCcsData);
    #else
    Sudo_Parameter_din_SessionStopRes();
    #endif


    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_DIN) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Tx]SessionStopRes: fail");
        errn = -1;
    }
    else
    {
        //send response successfully.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Tx]SessionStopRes");
    }


    //STEP 5: ============ Update Flags ===========
    EVCOMM_SYS_INFO.ConnectorLocked = FALSE;   //Indicating CSU that the Connector is unlocked.
                                               //Once this is set, the CSU should

    // =========== Annouce to CSU [To-Be Implemented]=============
    CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;    //This should be also added to EV Error events.


    // =========== Re-initialized [To-Be Implemented]=============
    //Keep 5% PWM for 2 seconds
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "PWM 5\% countdown: 2");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "PWM 5\% countdown: 1");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "PWM 5\% countdown: 0");
    OutputCpPwmDuty(100);

    //[To-Do] Reset All Share memory

    //[To-Do] CCS Module enter "idle" mode and CSU should check for this state.

    //system("reboot -f");
    //sleep(5);
    //system("reboot -f");

    return errn;
}


/*===========================================================================
FUNCTION: Proc_iso1_SessionStopRes
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_SessionStopRes(int AcceptFd)
{
    //[Joseph, To-Do] Check SessionID of ServiceDiscoveryReq,
    //if it is not the same, the packet should be ignored.

    //STEP 1: ============ Initialize ============
    //int i = 0;
    int errn = 0;
    bitstream_t v2g_tx_stream;
    struct SessionStopResponse_ISO15118_2014 *stp;
    //struct ChargingInfoData *sys;

    size_t pos = 0;
    v2g_tx_stream.pos = &pos;
    v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE;	//(64*1024)   //65,536 = 65.5KB
    v2g_tx_stream.data = V2GTP_Tx_buf;
    stp = &ShmCcsData->V2GMessage_ISO15118_2014.SessionStopResponse;
    //sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    stp->ResponseCode = OK_ISO15118_2014;

    //[HEADER] Check Req SessionID
    if (Check_iso1_V2G_Rx_MSG_SessionID(&ccs_exi_doc_ISO1) < 0)
    {
        stp->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]unmatched SessionID => End_Process");
        errn = -1;
    }

    //Check for SequenceError
    if (EVCOMM_SYS_INFO.SequenceError == TRUE)
    {
        stp->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[ERROR]SequenceError => End_Process");
        errn = -1;

        //Update_ShmStatusCode(); //[To-Do] to be implemented
        //CCS_SECC_ResponseCode_FAILED_SequenceError (023758)
        ShmStatusCodeData->PresentStatusCode[0][0] = 0;
        ShmStatusCodeData->PresentStatusCode[0][1] = 2;
        ShmStatusCodeData->PresentStatusCode[0][2] = 3;
        ShmStatusCodeData->PresentStatusCode[0][3] = 7;
        ShmStatusCodeData->PresentStatusCode[0][4] = 5;
        ShmStatusCodeData->PresentStatusCode[0][5] = 8;
    }

    //STEP 2: ============ Modifiy Parameter of ShmCcsData ============


    //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============
    #if PARAMETER_NORMAL_MODE == ENABLE
    SHM_Read_iso1_SessionStopRes(&ccs_exi_doc_ISO1, ShmCcsData);
    #else
    Sudo_Parameter_iso1_SessionStopRes();
    #endif


    //STEP 4: ============ Encode and Send Response Message ===========
    if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &ccs_exi_doc_ISO1) != 0)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Tx]SessionStopRes: fail");
        errn = -1;
    }
    else
    {
        //send response successfully.
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Tx]SessionStopRes");
    }

    //STEP 5: ============ Update Flags ===========
    EVCOMM_SYS_INFO.ConnectorLocked = FALSE;   //Indicating CSU that the Connector is unlocked.
                                               //Once this is set, the CSU should

    // =========== Annouce to CSU [To-Be Implemented]=============
    CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;    //This should be also added to EV Error events.


    // =========== Re-initialized [To-Be Implemented]=============
    //Keep 5% PWM for 2 seconds
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "PWM 5\% countdown: 2");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "PWM 5\% countdown: 1");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "PWM 5\% countdown: 0");
    OutputCpPwmDuty(100);

    //[To-Do] Reset All Share memory

    //[To-Do] CCS Module enter "idle" mode and CSU should check for this state.

    //system("reboot -f");
    //sleep(5);
    //system("reboot -f");

    return errn;
}


/*===========================================================================
FUNCTION: Proc_din_SessionStopReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_din_SessionStopReq(int AcceptFd)
{
    int errn = 0;
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]SessionStopReq");

    //Print the decoded XML Document
    PRINT_XML_DOC_DIN_SessionStopReq(&ccs_exi_doc_DIN);

    //Save into Share Memory
    SHM_Save_din_SessionStopReq(ShmCcsData, &ccs_exi_doc_DIN, ShmSysConfigAndInfo);

    errn = Proc_din_SessionStopRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_din_SessionStopReq]Proc_iso1_SessionStopRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}

/*===========================================================================
FUNCTION: Proc_iso1_SessionStopReq
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Proc_iso1_SessionStopReq(int AcceptFd)
{
    int errn = 0;
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]SessionStopReq");

    //Print the decoded XML Document
    PRINT_XML_DOC_ISO1_SessionStopReq(&ccs_exi_doc_ISO1);

    //Save into Share Memory
    SHM_Save_iso1_SessionStopReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo);

    errn = Proc_iso1_SessionStopRes(AcceptFd);
    if (errn == 0)
    {
        //send response successfully.
    }
    else
    {
        sprintf((char*)buf_log_evcomm,
                "[Error][SeccComm][Proc_iso1_SessionStopReq]Proc_iso1_SessionStopRes(): %d (DEC)",
                errn);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }
    return errn;
}


/*===========================================================================
FUNCTION: V2gMsg_Process_din
DESCRIPTION:
PRE-CONDITION:
INPUT:
        1. V2gFlowStatus
OUTPUT:
GLOBAL VARIABLES:
        1. V2gFlowStatus
=============================================================================*/
int V2gMsg_Process_din(int AcceptFd)
{
    unsigned char req_is_responsed = FALSE;
    while (req_is_responsed == FALSE)
    {
        //Check if it is in End_Process
        if (EVCOMM_SYS_INFO.End_Process_inused == TRUE)
        {
            break;
        }

        switch(V2gFlowStatus)
        {
            //-------------------------------------------
            case SupportedAppProtocolRequest:
            {
                if (ccs_handshake.supportedAppProtocolReq_isUsed == 1u)
                {
                    ccs_handshake.supportedAppProtocolReq_isUsed = 0;
                    if (Proc_supportedAppProtocolReq(AcceptFd) == 0)   //0: no error
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                        Update_V2G_Flow_Status(SupportedAppProtocolResponse);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]supportedAppProtocolResReq: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                }
                req_is_responsed = TRUE;
                break;
            }
            case SupportedAppProtocolResponse:
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionSetupRequest)
                {
                    Update_V2G_Flow_Status(SessionSetupRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case SessionSetupRequest:               //19
            {
                if (Proc_din_SessionSetupReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(SessionSetupResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]SessionSetupReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case SessionSetupResponse:              //20
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceDiscoveryRequest)
                {
                    Update_V2G_Flow_Status(ServiceDiscoveryRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case ServiceDiscoveryRequest:           //21
            {
                if (Proc_din_ServiceDiscoveryReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ServiceDiscoveryResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ServiceDiscoveryReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ServiceDiscoveryResponse:          //22
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceAndPaymentSelectionRequest)
                {
                    Update_V2G_Flow_Status(ServiceAndPaymentSelectionRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm, "[ERROR]SequenceError(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case ServiceAndPaymentSelectionRequest:     //25
            {
                if (Proc_din_ServiceAndPaymentSelectionReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ServiceAndPaymentSelectionResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ServiceAndPaymentSelectionReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ServiceAndPaymentSelectionResponse:    //26
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == AuthorizationRequest)
                {
                    Update_V2G_Flow_Status(AuthorizationRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            //case ContractAuthenticationReq:
            case AuthorizationRequest:              //29
            {
                if (Proc_din_ContractAuthenticationReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(AuthorizationResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]AuthorizationReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case AuthorizationResponse:             //30
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == AuthorizationRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_din_ContractAuthenticationReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]AuthorizationReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }
                //Check for ChargeParameterDiscoveryReq
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargeParameterDiscoveryRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(ChargeParameterDiscoveryRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]ChargeParameterDiscoveryReq: CSU Permission?");

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case ChargeParameterDiscoveryRequest:   //35
            {
                if (Proc_din_ChargeParameterDiscoveryReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ChargeParameterDiscoveryResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ChargeParameterDiscoveryReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ChargeParameterDiscoveryResponse:
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_ChargingParameter_Performance_Time)  //60 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "ChargingParameter Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            V2G_SECC_ChargingParameter_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);
                    break;
                }
                #endif

                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargeParameterDiscoveryRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_din_ChargeParameterDiscoveryReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ChargeParameterDiscoveryReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                    break;
                }
                //STEP 2: Check for CableCheckReq message
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CableCheckRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]CableCheckReqReq: isolated?");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_Start);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_End);

                    Update_V2G_Flow_Status(CableCheckRequest);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                //STEP 3: Wait for PowerDeliveryReq Message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    Update_V2G_Flow_Status(PowerDeliveryRequestStop);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    //ftime(&EVCOMM_SYS_INFO.V2G_SECC_ChargeParameterDiscovery_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif

                    if (Proc_din_PowerDeliveryStopReq(AcceptFd) == 0)
                    {
                        Update_V2G_Flow_Status(PowerDeliveryResponseStop);
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStopReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case CableCheckRequest:                 //37
            {
                //STEP 3: Execute Cable Check Process
                if (Proc_din_CableCheckReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(CableCheckResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]CableCheckReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case CableCheckResponse:                //38
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_CableCheck_Performance_Time)  //38 seconds
                {
                    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[CableCheck] end counting...");
                    sprintf((char*)buf_log_evcomm,
                            "CableCheck Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            V2G_SECC_CableCheck_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);

                    //Update_ShmStatusCode(); //[To-Do] to be implemented
                    //CCS_SECC_TIMEOUT_V2G_CableCheck_Performance_Time (023847)
                    ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                    ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                    ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                    ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                    ShmStatusCodeData->PresentStatusCode[0][4] = 4;
                    ShmStatusCodeData->PresentStatusCode[0][5] = 7;
                    break;
                }
                #endif

                //STEP 2: Check for CableCheckReq message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CableCheckRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    //STEP 3: Execute Cable Check Process
                    if (Proc_din_CableCheckReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]CableCheckReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }
                //STEP 3: Check for PreChargeReq message
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == PreChargeRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(PreChargeRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]PreChargeReqReq: waiting for precharge voltage...");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_End);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Precharge_Timer_Start);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                //STEP 3: Wait for PowerDeliveryReq Message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    Update_V2G_Flow_Status(PowerDeliveryRequestStop);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    //ftime(&EVCOMM_SYS_INFO.V2G_SECC_ChargeParameterDiscovery_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif

                    if (Proc_din_PowerDeliveryStopReq(AcceptFd) == 0)
                    {
                        Update_V2G_Flow_Status(PowerDeliveryResponseStop);
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStopReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case PreChargeRequest:                  //39
            {
                if (Proc_din_PreChargeReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(PreChargeResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PreChargeReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case PreChargeResponse:                 //40
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_PreCharge_Performance_Time)  //5 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "Precharge Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            V2G_SECC_PreCharge_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);

                    //Update_ShmStatusCode(); //[To-Do] to be implemented
                    //CCS_SECC_TIMEOUT_V2G_PreCharge_Performace_Time (023850)
                    ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                    ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                    ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                    ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                    ShmStatusCodeData->PresentStatusCode[0][4] = 5;
                    ShmStatusCodeData->PresentStatusCode[0][5] = 0;
                    break;
                }
                #endif

                //STEP 2: Check for PreChargeReq message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == PreChargeRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_din_PreChargeReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PreChargeReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }
                //STEP 3: Check for PowerDeliveryReq message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(PowerDeliveryRequestStart);

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Precharge_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case PowerDeliveryRequestStart:         //41
            {
                if (Proc_din_PowerDeliveryStartReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(PowerDeliveryResponsetStart);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStartReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case PowerDeliveryResponsetStart:        //42
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                if (ccs_exi_doc_DIN.V2G_Message.Body.PowerDeliveryReq_isUsed == 1u)
                {
                    ftime(&SeqEndTime);
                    if(DiffTimeb(SeqStartTime, SeqEndTime) > 2000)  //5 seconds
                    {
                        sprintf((char*)buf_log_evcomm,
                                "Wait for CurrentDemandReq Timeout - (%.02lf of %d ms)\n",
                                DiffTimeb(SeqStartTime, SeqEndTime),
                                2000);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        Update_V2G_Flow_Status(Sequence_Timeout);
                    }
                    break;
                }
                #endif

                //STEP 2: Wait for CurrentDemandReq Message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CurrentDemandRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(CurrentDemandRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]CurrentDemandReqReq: energy transfering...");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CurrentDemand_Timer_Start);
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case CurrentDemandRequest:              //45,
            {
                if (Proc_din_CurrentDemandReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(CurrentDemandResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]CurrentDemandReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case CurrentDemandResponse:             //46,
            {
                //STEP 1: Wait for CurrentDemandReq Message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CurrentDemandRequest)
                {
                   EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    if (Proc_din_CurrentDemandReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]CurrentDemandReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                    break;
                }

                //STEP 2: Wait for PowerDeliveryReq Message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    Update_V2G_Flow_Status(PowerDeliveryRequestStop);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CurrentDemand_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case PowerDeliveryRequestStop:          //49,
            {
                if (Proc_din_PowerDeliveryStopReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(PowerDeliveryResponseStop);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStopReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case PowerDeliveryResponseStop:        //50,
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > 2000)  //2 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "Wait for WeldingDetectionReq or SessionStopReq Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            2000);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);
                    break;
                }
                #endif

                //STEP 2: Check for WeldingDetectionReq Message
                if(EVCOMM_SYS_INFO.V2G_Rx_Msg == WeldingDetectionRequest)
                {
                   EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(WeldingDetectionRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]WeldingDetectionReq: ongoing...");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_WeldingDetection_Timer_Start);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest)
                {
                    Update_V2G_Flow_Status(SessionStopRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_din_SessionStopReq(AcceptFd) == 0)
                    {
                        Update_V2G_Flow_Status(SessionStopResponse);
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]SessionStopReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    break;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case WeldingDetectionRequest:           //51,
            {
                if (Proc_din_WeldingDetectionReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(WeldingDetectionResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]WeldingDetectionReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case WeldingDetectionResponse:          //52,
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_WeldingDetection_Performance_Time)  //20 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "Wait for SessionStopReq Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            V2G_SECC_WeldingDetection_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);
                    break;
                }
                #endif

                //STEP 2: Check for WeldingDetectionReq Message
                if(EVCOMM_SYS_INFO.V2G_Rx_Msg == WeldingDetectionRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    if (Proc_din_WeldingDetectionReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]WeldingDetectionReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }
                //STEP 3: Check for SessionStopReq Message
                else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest)
                {
                    Update_V2G_Flow_Status(SessionStopRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_WeldingDetection_Timer_End);
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case SessionStopRequest:                //53,
            {
                if (Proc_din_SessionStopReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(SessionStopResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]SessionStopReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case SessionStopResponse:               //54,
            {
                break;
            }
            //-------------------------------------------
            default:
            {
                break;
            }
        }
    }

    return 0;
}

/*===========================================================================
FUNCTION: V2gMsg_Process_iso1_DC
DESCRIPTION:
PRE-CONDITION:
INPUT:
        1. V2gFlowStatus
OUTPUT:
GLOBAL VARIABLES:
        1. V2gFlowStatus
=============================================================================*/
int V2gMsg_Process_iso1_DC(int AcceptFd)
{
    unsigned char req_is_responsed = FALSE;
    while (req_is_responsed == FALSE)
    {
        //Check if it is in End_Process
        if (EVCOMM_SYS_INFO.End_Process_inused == TRUE)
        {
            break;
        }

        switch(V2gFlowStatus)
        {
            //-------------------------------------------
            case SupportedAppProtocolRequest:
            {
                if (ccs_handshake.supportedAppProtocolReq_isUsed == 1u)
                {
                    ccs_handshake.supportedAppProtocolReq_isUsed = 0;
                    if (Proc_supportedAppProtocolReq(AcceptFd) == 0)   //0: no error
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                        Update_V2G_Flow_Status(SupportedAppProtocolResponse);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]supportedAppProtocolResReq: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                }
                req_is_responsed = TRUE;
                break;
            }
            case SupportedAppProtocolResponse:
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionSetupRequest)
                {
                    Update_V2G_Flow_Status(SessionSetupRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case SessionSetupRequest:               //19
            {
                if (Proc_iso1_SessionSetupReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(SessionSetupResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]SessionSetupReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case SessionSetupResponse:              //20
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceDiscoveryRequest)
                {
                    Update_V2G_Flow_Status(ServiceDiscoveryRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case ServiceDiscoveryRequest:           //21
            {
                if (Proc_iso1_ServiceDiscoveryReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ServiceDiscoveryResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ServiceDiscoveryReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ServiceDiscoveryResponse:          //22
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceAndPaymentSelectionRequest)
                {
                    Update_V2G_Flow_Status(ServiceAndPaymentSelectionRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case ServiceAndPaymentSelectionRequest:     //25
            {
                if (Proc_iso1_ServiceAndPaymentSelectionReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ServiceAndPaymentSelectionResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ServiceAndPaymentSelectionReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ServiceAndPaymentSelectionResponse:    //26
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == AuthorizationRequest)
                {
                    Update_V2G_Flow_Status(AuthorizationRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            //case ContractAuthenticationReq:
            case AuthorizationRequest:              //29
            {
                if (Proc_iso1_AuthenticationReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(AuthorizationResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]AuthorizationReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case AuthorizationResponse:             //30
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == AuthorizationRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_iso1_AuthenticationReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]AuthorizationReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }
                //Check for ChargeParameterDiscoveryReq
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargeParameterDiscoveryRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(ChargeParameterDiscoveryRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]ChargeParameterDiscoveryReq: CSU Permission?");

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case ChargeParameterDiscoveryRequest:   //35
            {
                if (Proc_iso1_ChargeParameterDiscoveryReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ChargeParameterDiscoveryResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ChargeParameterDiscoveryReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ChargeParameterDiscoveryResponse:
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_ChargingParameter_Performance_Time)  //60 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "ChargingParameter Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            V2G_SECC_ChargingParameter_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);
                    break;
                }
                #endif

                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargeParameterDiscoveryRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_iso1_ChargeParameterDiscoveryReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ChargeParameterDiscoveryReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }
                //STEP 2: Check for CableCheckReq message
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CableCheckRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]CableCheckReqReq: isolated?");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_Start);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_End);

                    Update_V2G_Flow_Status(CableCheckRequest);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                //STEP 3: Wait for PowerDeliveryReq Message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    Update_V2G_Flow_Status(PowerDeliveryRequestStop);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    //ftime(&EVCOMM_SYS_INFO.V2G_SECC_ChargeParameterDiscovery_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif

                    if (Proc_iso1_PowerDeliveryStopReq(AcceptFd) == 0)
                    {
                        Update_V2G_Flow_Status(PowerDeliveryResponseStop);
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStopReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    break;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }
                break;
            }
            //-------------------------------------------
            case CableCheckRequest:                 //37
            {
                //STEP 3: Execute Cable Check Process
                if (Proc_iso1_CableCheckReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(CableCheckResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]CableCheckReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case CableCheckResponse:                //38
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_CableCheck_Performance_Time)  //38 seconds
                {
                    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[CableCheck] end counting...");
                    sprintf((char*)buf_log_evcomm,
                            "CableCheck Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            V2G_SECC_CableCheck_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);

                    //Update_ShmStatusCode(); //[To-Do] to be implemented
                    //CCS_SECC_TIMEOUT_V2G_CableCheck_Performance_Time (023847)
                    ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                    ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                    ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                    ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                    ShmStatusCodeData->PresentStatusCode[0][4] = 4;
                    ShmStatusCodeData->PresentStatusCode[0][5] = 7;
                    break;
                }
                #endif

                //STEP 2: Check for CableCheckReq message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CableCheckRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    //STEP 3: Execute Cable Check Process
                    if (Proc_iso1_CableCheckReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]CableCheckReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }
                //STEP 3: Check for PreChargeReq message
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == PreChargeRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(PreChargeRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]PreChargeReqReq: waiting for precharge voltage...");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_End);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Precharge_Timer_Start);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                //STEP 3: Wait for PowerDeliveryReq Message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    Update_V2G_Flow_Status(PowerDeliveryRequestStop);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    //ftime(&EVCOMM_SYS_INFO.V2G_SECC_ChargeParameterDiscovery_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif

                    if (Proc_iso1_PowerDeliveryStopReq(AcceptFd) == 0)
                    {
                        Update_V2G_Flow_Status(PowerDeliveryResponseStop);
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStopReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case PreChargeRequest:                  //39
            {
                if (Proc_iso1_PreChargeReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(PreChargeResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PreChargeReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case PreChargeResponse:                 //40
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_PreCharge_Performance_Time)  //5 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "Precharge Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            V2G_SECC_PreCharge_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);

                    //Update_ShmStatusCode(); //[To-Do] to be implemented
                    //CCS_SECC_TIMEOUT_V2G_PreCharge_Performace_Time (023850)
                    ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                    ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                    ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                    ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                    ShmStatusCodeData->PresentStatusCode[0][4] = 5;
                    ShmStatusCodeData->PresentStatusCode[0][5] = 0;
                    break;
                }
                #endif

                //STEP 2: Check for PreChargeReq message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == PreChargeRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_iso1_PreChargeReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PreChargeReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }
                //STEP 3: Check for PowerDeliveryReq message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(PowerDeliveryRequestStart);

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Precharge_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case PowerDeliveryRequestStart:         //41
            {
                if (Proc_iso1_PowerDeliveryStartReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(PowerDeliveryResponsetStart);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStartReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case PowerDeliveryResponsetStart:        //42
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                if (ccs_exi_doc_ISO1.V2G_Message.Body.PowerDeliveryReq_isUsed == 1u)
                {
                    ftime(&SeqEndTime);
                    if(DiffTimeb(SeqStartTime, SeqEndTime) > 2000)  //5 seconds
                    {
                        sprintf((char*)buf_log_evcomm,
                                "Wait for CurrentDemandReq Timeout - (%.02lf of %d ms)\n",
                                DiffTimeb(SeqStartTime, SeqEndTime),
                                2000);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        Update_V2G_Flow_Status(Sequence_Timeout);
                    }
                    break;
                }
                #endif

                //STEP 2: Wait for CurrentDemandReq Message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CurrentDemandRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(CurrentDemandRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]CurrentDemandReqReq: energy transfering...");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CurrentDemand_Timer_Start);
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }
                break;
            }
            //-------------------------------------------
            case CurrentDemandRequest:              //45,
            {
                if (Proc_iso1_CurrentDemandReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(CurrentDemandResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]CurrentDemandReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case CurrentDemandResponse:             //46,
            {
                //STEP 1: Wait for CurrentDemandReq Message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CurrentDemandRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    if (Proc_iso1_CurrentDemandReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]CurrentDemandReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }
                //STEP 2: Wait for PowerDeliveryReq Message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    Update_V2G_Flow_Status(PowerDeliveryRequestStop);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CurrentDemand_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case PowerDeliveryRequestStop:          //49,
            {
                if (Proc_iso1_PowerDeliveryStopReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(PowerDeliveryResponseStop);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStopReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case PowerDeliveryResponseStop:        //50,
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > 2000)  //2 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "Wait for WeldingDetectionReq or SessionStopReq Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            2000);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);
                    break;
                }
                #endif

                //STEP 2: Check for WeldingDetectionReq Message
                if(EVCOMM_SYS_INFO.V2G_Rx_Msg == WeldingDetectionRequest)
                {
                   EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(WeldingDetectionRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]WeldingDetectionReq: ongoing...");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_WeldingDetection_Timer_Start);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest)
                {
                    Update_V2G_Flow_Status(SessionStopRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_iso1_SessionStopReq(AcceptFd) == 0)
                    {
                        Update_V2G_Flow_Status(SessionStopResponse);
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]SessionStopReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case WeldingDetectionRequest:           //51,
            {
                if (Proc_iso1_WeldingDetectionReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(WeldingDetectionResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]WeldingDetectionReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case WeldingDetectionResponse:          //52,
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_WeldingDetection_Performance_Time)  //20 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "Wait for SessionStopReq Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            V2G_SECC_WeldingDetection_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);
                    break;
                }
                #endif

                //STEP 2: Check for WeldingDetectionReq Message
                if(EVCOMM_SYS_INFO.V2G_Rx_Msg == WeldingDetectionRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    if (Proc_iso1_WeldingDetectionReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]WeldingDetectionReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }
                //STEP 3: Check for SessionStopReq Message
                else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest)
                {
                    Update_V2G_Flow_Status(SessionStopRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_WeldingDetection_Timer_End);
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case SessionStopRequest:                //53,
            {
                if (Proc_iso1_SessionStopReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(SessionStopResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]SessionStopReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case SessionStopResponse:               //54,
            {
                break;
            }
            //-------------------------------------------
            default:
            {
                break;
            }
        }
    }

    return 0;
}


/*===========================================================================
FUNCTION: V2gMsg_Process_iso1_AC
DESCRIPTION:
PRE-CONDITION:
INPUT:
        1. V2gFlowStatus
OUTPUT:
GLOBAL VARIABLES:
        1. V2gFlowStatus
=============================================================================*/
int V2gMsg_Process_iso1_AC(int AcceptFd)
{
    unsigned char req_is_responsed = FALSE;
    while (req_is_responsed == FALSE)
    {
        //Check if it is in End_Process
        if (EVCOMM_SYS_INFO.End_Process_inused == TRUE)
        {
            break;
        }

        switch(V2gFlowStatus)
        {
            //-------------------------------------------
            case SupportedAppProtocolRequest:       //17
            {
                if (ccs_handshake.supportedAppProtocolReq_isUsed == 1u)
                {
                    ccs_handshake.supportedAppProtocolReq_isUsed = 0;
                    if (Proc_supportedAppProtocolReq(AcceptFd) == 0)   //0: no error
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                        Update_V2G_Flow_Status(SupportedAppProtocolResponse);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]supportedAppProtocolResReq: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                }
                req_is_responsed = TRUE;
                break;
            }
            case SupportedAppProtocolResponse:      //18
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionSetupRequest)
                {
                    Update_V2G_Flow_Status(SessionSetupRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case SessionSetupRequest:               //19
            {
                if (Proc_iso1_SessionSetupReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(SessionSetupResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]SessionSetupReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case SessionSetupResponse:              //20
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceDiscoveryRequest)
                {
                    Update_V2G_Flow_Status(ServiceDiscoveryRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case ServiceDiscoveryRequest:           //21
            {
                if (Proc_iso1_ServiceDiscoveryReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ServiceDiscoveryResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ServiceDiscoveryReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ServiceDiscoveryResponse:          //22
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceAndPaymentSelectionRequest)
                {
                    Update_V2G_Flow_Status(ServiceAndPaymentSelectionRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case ServiceAndPaymentSelectionRequest: //25
            {
                if (Proc_iso1_ServiceAndPaymentSelectionReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ServiceAndPaymentSelectionResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ServiceAndPaymentSelectionReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ServiceAndPaymentSelectionResponse://26
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == AuthorizationRequest)
                {
                    Update_V2G_Flow_Status(AuthorizationRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            //case ContractAuthenticationReq:
            case AuthorizationRequest:              //29
            {
                if (Proc_iso1_AuthenticationReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(AuthorizationResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]AuthorizationReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                break;
            }
            case AuthorizationResponse:             //30
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == AuthorizationRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_iso1_AuthenticationReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]AuthorizationReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }
                //Check for ChargeParameterDiscoveryReq
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargeParameterDiscoveryRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(ChargeParameterDiscoveryRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]ChargeParameterDiscoveryReq: CSU Permission?");

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case ChargeParameterDiscoveryRequest:   //35
            {
                if (Proc_iso1_ChargeParameterDiscoveryReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ChargeParameterDiscoveryResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ChargeParameterDiscoveryReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ChargeParameterDiscoveryResponse:  //36
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
    	        ftime(&SeqEndTime);
    	        if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_ChargingParameter_Performance_Time)  //60 seconds
    	        {
    	            sprintf((char*)buf_log_evcomm,
                            "ChargingParameter Timeout - (%.02lf of %d ms)\n",
    	                    DiffTimeb(SeqStartTime, SeqEndTime),
    	                    V2G_SECC_ChargingParameter_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    	            Update_V2G_Flow_Status(Sequence_Timeout);
                    break;
    	        }
                #endif

                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargeParameterDiscoveryRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_iso1_ChargeParameterDiscoveryReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ChargeParameterDiscoveryReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }

                //STEP 3: Wait for PowerDeliveryReq Message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    Update_V2G_Flow_Status(PowerDeliveryRequestStart);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    //ftime(&EVCOMM_SYS_INFO.V2G_SECC_ChargeParameterDiscovery_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif

                    if (Proc_iso1_PowerDeliveryStopReq(AcceptFd) == 0)
                    {
                        Update_V2G_Flow_Status(PowerDeliveryResponseStop);
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStopReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
    		#if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
            #endif
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }
                break;
            }
            //-------------------------------------------
            case PowerDeliveryRequestStart:         //41
            {
                if (Proc_iso1_PowerDeliveryStartReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(PowerDeliveryResponsetStart);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStartReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case PowerDeliveryResponsetStart:       //42
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                if (ccs_exi_doc_ISO1.V2G_Message.Body.PowerDeliveryReq_isUsed == 1u)
                {
                    ftime(&SeqEndTime);
                    if(DiffTimeb(SeqStartTime, SeqEndTime) > 2000)  //5 seconds
                    {
                        sprintf((char*)buf_log_evcomm,
                                "Wait for ChargingStatusReq Timeout - (%.02lf of %d ms)\n",
                                DiffTimeb(SeqStartTime, SeqEndTime),
                                2000);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        Update_V2G_Flow_Status(Sequence_Timeout);
                    }
                    break;
                }
                #endif

                //STEP 2: Wait for ChargingStatusReq Message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargingStatusRequest)
                {
    	            EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(ChargingStatusRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]ChargingStatusReq: energy transfering...");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_ChargingStatus_Timer_Start);
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case ChargingStatusRequest:             //43
            {
                if (Proc_iso1_ChargingStatusReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ChargingStatusResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ChargingStatusRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ChargingStatusResponse:            //44
            {
                //STEP 1: Wait for ChargingStatusReq Message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargingStatusRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    if (Proc_iso1_ChargingStatusReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ChargingStatusRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                }
                //STEP 2: Wait for PowerDeliveryReq Message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    Update_V2G_Flow_Status(PowerDeliveryRequestStop);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_ChargingStatus_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case PowerDeliveryRequestStop:          //49
            {
                if (Proc_iso1_PowerDeliveryStopReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(PowerDeliveryResponseStop);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStopReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case PowerDeliveryResponseStop:         //50
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > 2000)  //2 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "Wait for SessionStopReq Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            2000);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);
                    break;
                }
                #endif

                //STEP 3: Check for SessionStopReq Message
                else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest)
                {
                    Update_V2G_Flow_Status(SessionStopRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case SessionStopRequest:                //53
            {
                if (Proc_iso1_SessionStopReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(SessionStopResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]SessionStopReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case SessionStopResponse:               //54
            {
                break;
            }
            //-------------------------------------------
            default:
            {
                break;
            }
        }
    }

    return 0;
}


/*===========================================================================
FUNCTION: V2gMsg_Process_iso1
DESCRIPTION:
    1. EnergyTransferMode:
        AC_single_phase_core =  0,
        AC_three_phase_core =   1,
        DC_core =               2,
        DC_extended =           3,
        DC_combo_core =         4,
        DC_unique =             5

        iso1EnergyTransferModeType_AC_single_phase_core = 0,
    	iso1EnergyTransferModeType_AC_three_phase_core = 1,
    	iso1EnergyTransferModeType_DC_core = 2,
    	iso1EnergyTransferModeType_DC_extended = 3,
    	iso1EnergyTransferModeType_DC_combo_core = 4,
    	iso1EnergyTransferModeType_DC_unique = 5
PRE-CONDITION:
INPUT:
        1. V2gFlowStatus
OUTPUT:
GLOBAL VARIABLES:
        1. V2gFlowStatus
=============================================================================*/
int V2gMsg_Process_iso1(int AcceptFd, unsigned char EnergyTransferMode)
{
    switch (EnergyTransferMode)
    {
        case DC_extended:
        {
            V2gMsg_Process_iso1_DC(AcceptFd);
            break;
        }

        case AC_single_phase_core:
        case AC_three_phase_core:
        {
            V2gMsg_Process_iso1_AC(AcceptFd);
            break;
        }

        default:
        {
            sprintf((char*)buf_log_evcomm,
                    "[ISO1][Warning]Unexpected EnergyTransferMode(%d)",
                    EnergyTransferMode);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            break;
        }
    }

    return 0;
}

/*===========================================================================
FUNCTION: V2gMsg_Process_iso2_DC
DESCRIPTION:
PRE-CONDITION:
INPUT:
        1. V2gFlowStatus
OUTPUT:
GLOBAL VARIABLES:
        1. V2gFlowStatus
=============================================================================*/
int V2gMsg_Process_iso2_DC(int AcceptFd)
{
    unsigned char req_is_responsed = FALSE;
    while (req_is_responsed == FALSE)
    {
        //Check if it is in End_Process
        if (EVCOMM_SYS_INFO.End_Process_inused == TRUE)
        {
            break;
        }

        switch(V2gFlowStatus)
        {
            //-------------------------------------------
            case SupportedAppProtocolRequest:
            {
                if (ccs_handshake.supportedAppProtocolReq_isUsed == 1u)
                {
                    ccs_handshake.supportedAppProtocolReq_isUsed = 0;
                    if (Proc_supportedAppProtocolReq(AcceptFd) == 0)   //0: no error
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                        Update_V2G_Flow_Status(SupportedAppProtocolResponse);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]supportedAppProtocolResReq: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                }
                req_is_responsed = TRUE;
                break;
            }
            case SupportedAppProtocolResponse:
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionSetupRequest)
                {
                    Update_V2G_Flow_Status(SessionSetupRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
            //-------------------------------------------
            case SessionSetupRequest:               //19
            {
                if (Proc_iso2_SessionSetupReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(SessionSetupResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]SessionSetupReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case SessionSetupResponse:              //20
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceDiscoveryRequest)
                {
                    Update_V2G_Flow_Status(ServiceDiscoveryRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {

                }

                break;
            }
    #if 0
            //-------------------------------------------
            case ServiceDiscoveryRequest:           //21
            {
                if (Proc_iso2_ServiceDiscoveryReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ServiceDiscoveryResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ServiceDiscoveryReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ServiceDiscoveryResponse:          //22
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceAndPaymentSelectionRequest)
                {
                    Update_V2G_Flow_Status(ServiceAndPaymentSelectionRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {
                    break;
                }
            }
            //-------------------------------------------
            case ServiceAndPaymentSelectionRequest:     //25
            {
                if (Proc_iso2_ServiceAndPaymentSelectionReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ServiceAndPaymentSelectionResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ServiceAndPaymentSelectionReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ServiceAndPaymentSelectionResponse:    //26
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == AuthorizationRequest)
                {
                    Update_V2G_Flow_Status(AuthorizationRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {
                    break;
                }
            }
            //-------------------------------------------
            //case ContractAuthenticationReq:
            case AuthorizationRequest:              //29
            {
                if (Proc_iso2_AuthenticationReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(AuthorizationResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]AuthorizationReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case AuthorizationResponse:             //30
            {
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == AuthorizationRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_iso2_AuthenticationReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]AuthorizationReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                    break;
                }

                //Check for ChargeParameterDiscoveryReq
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargeParameterDiscoveryRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(ChargeParameterDiscoveryRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]ChargeParameterDiscoveryReq: CSU Permission?");

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {
                    break;
                }
            }
            //-------------------------------------------
            case ChargeParameterDiscoveryRequest:   //35
            {
                if (Proc_iso2_ChargeParameterDiscoveryReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(ChargeParameterDiscoveryResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ChargeParameterDiscoveryReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case ChargeParameterDiscoveryResponse:
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_ChargingParameter_Performance_Time)  //60 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "ChargingParameter Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            V2G_SECC_ChargingParameter_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);
                    break;
                }
                #endif

                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargeParameterDiscoveryRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_iso2_ChargeParameterDiscoveryReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]ChargeParameterDiscoveryReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                    break;
                }
                //STEP 2: Check for CableCheckReq message
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CableCheckRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(CableCheckRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]CableCheckReqReq: isolated?");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_Start);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                //STEP 3: Wait for PowerDeliveryReq Message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    Update_V2G_Flow_Status(PowerDeliveryRequestStop);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    //ftime(&EVCOMM_SYS_INFO.V2G_SECC_ChargeParameterDiscovery_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif

                    if (Proc_iso2_PowerDeliveryStopReq(AcceptFd) == 0)
                    {
                        Update_V2G_Flow_Status(PowerDeliveryResponseStop);
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStopReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    break;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {
                    break;
                }
            }
            //-------------------------------------------
            case CableCheckRequest:                 //37
            {
                //STEP 3: Execute Cable Check Process
                if (Proc_iso2_CableCheckReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(CableCheckResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]CableCheckReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case CableCheckResponse:                //38
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_CableCheck_Performance_Time)  //38 seconds
                {
                    //SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[CableCheck] end counting...");
                    sprintf((char*)buf_log_evcomm,
                            "CableCheck Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            V2G_SECC_CableCheck_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);

                    //Update_ShmStatusCode(); //[To-Do] to be implemented
                    //CCS_SECC_TIMEOUT_V2G_CableCheck_Performance_Time (023847)
                    ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                    ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                    ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                    ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                    ShmStatusCodeData->PresentStatusCode[0][4] = 4;
                    ShmStatusCodeData->PresentStatusCode[0][5] = 7;
                    break;
                }
                #endif

                //STEP 2: Check for CableCheckReq message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CableCheckRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    //STEP 3: Execute Cable Check Process
                    if (Proc_iso2_CableCheckReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]CableCheckReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                    break;
                }
                //STEP 3: Check for PreChargeReq message
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == PreChargeRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(PreChargeRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]PreChargeReqReq: waiting for precharge voltage...");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_End);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Precharge_Timer_Start);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                //STEP 3: Wait for PowerDeliveryReq Message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    Update_V2G_Flow_Status(PowerDeliveryRequestStop);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    //ftime(&EVCOMM_SYS_INFO.V2G_SECC_ChargeParameterDiscovery_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif

                    if (Proc_iso2_PowerDeliveryStopReq(AcceptFd) == 0)
                    {
                        Update_V2G_Flow_Status(PowerDeliveryResponseStop);
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStopReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    break;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {
                    break;
                }
            }
            //-------------------------------------------
            case PreChargeRequest:                  //39
            {
                if (Proc_iso2_PreChargeReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(PreChargeResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PreChargeReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case PreChargeResponse:                 //40
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_PreCharge_Performance_Time)  //5 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "Precharge Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            V2G_SECC_PreCharge_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);

                    //Update_ShmStatusCode(); //[To-Do] to be implemented
                    //CCS_SECC_TIMEOUT_V2G_PreCharge_Performace_Time (023850)
                    ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                    ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                    ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                    ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                    ShmStatusCodeData->PresentStatusCode[0][4] = 5;
                    ShmStatusCodeData->PresentStatusCode[0][5] = 0;
                    break;
                }
                #endif

                //STEP 2: Check for PreChargeReq message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == PreChargeRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_iso2_PreChargeReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PreChargeReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                    break;
                }
                //STEP 3: Check for PowerDeliveryReq message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(PowerDeliveryRequestStart);

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Precharge_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {
                    break;
                }
            }
            //-------------------------------------------
            case PowerDeliveryRequestStart:         //41
            {
                if (Proc_iso2_PowerDeliveryStartReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(PowerDeliveryResponsetStart);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStartReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case PowerDeliveryResponsetStart:        //42
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                if (ccs_exi_doc_ISO2.V2G_Message.Body.PowerDeliveryReq_isUsed == 1u)
                {
                    ftime(&SeqEndTime);
                    if(DiffTimeb(SeqStartTime, SeqEndTime) > 2000)  //5 seconds
                    {
                        sprintf((char*)buf_log_evcomm,
                                "Wait for CurrentDemandReq Timeout - (%.02lf of %d ms)\n",
                                DiffTimeb(SeqStartTime, SeqEndTime),
                                2000);
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                        Update_V2G_Flow_Status(Sequence_Timeout);
                    }
                    break;
                }
                #endif

                //STEP 2: Wait for CurrentDemandReq Message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CurrentDemandRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(CurrentDemandRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]CurrentDemandReqReq: energy transfering...");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CurrentDemand_Timer_Start);
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {
                    break;
                }
            }
            //-------------------------------------------
            case CurrentDemandRequest:              //45,
            {
                if (Proc_iso2_CurrentDemandReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(CurrentDemandResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]CurrentDemandReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case CurrentDemandResponse:             //46,
            {
                //STEP 1: Wait for CurrentDemandReq Message
                if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CurrentDemandRequest)
                {
                     EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    if (Proc_iso2_CurrentDemandReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]CurrentDemandReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                    break;
                }
                //STEP 2: Wait for PowerDeliveryReq Message
                else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) ||
                        (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart))
                {
                    Update_V2G_Flow_Status(PowerDeliveryRequestStop);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_CurrentDemand_Timer_End);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {
                    break;
                }
            }
            //-------------------------------------------
            case PowerDeliveryRequestStop:          //49,
            {
                if (Proc_iso2_PowerDeliveryStopReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(PowerDeliveryResponseStop);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]PowerDeliveryStopReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case PowerDeliveryResponseStop:        //50,
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > 2000)  //2 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "Wait for WeldingDetectionReq or SessionStopReq Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            2000);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);
                    break;
                }
                #endif

                //STEP 2: Check for WeldingDetectionReq Message
                if(EVCOMM_SYS_INFO.V2G_Rx_Msg == WeldingDetectionRequest)
                {
                   EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    Update_V2G_Flow_Status(WeldingDetectionRequest);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[V2G][Rx]WeldingDetectionReq: ongoing...");

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_WeldingDetection_Timer_Start);

                    #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                    ftime(&SeqStartTime);
                    #endif
                }
                else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest)
                {
                    Update_V2G_Flow_Status(SessionStopRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    if (Proc_iso2_SessionStopReq(AcceptFd) == 0)
                    {
                        Update_V2G_Flow_Status(SessionStopResponse);
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]SessionStopReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    break;
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {
                    break;
                }
            }
            //-------------------------------------------
            case WeldingDetectionRequest:           //51,
            {
                if (Proc_iso2_WeldingDetectionReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(WeldingDetectionResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]WeldingDetectionReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                break;
            }
            case WeldingDetectionResponse:          //52,
            {
                //STEP 1: Check for Process Timeout
                #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > V2G_SECC_WeldingDetection_Performance_Time)  //20 seconds
                {
                    sprintf((char*)buf_log_evcomm,
                            "Wait for SessionStopReq Timeout - (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            V2G_SECC_WeldingDetection_Performance_Time);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);
                    break;
                }
                #endif

                //STEP 2: Check for WeldingDetectionReq Message
                if(EVCOMM_SYS_INFO.V2G_Rx_Msg == WeldingDetectionRequest)
                {
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                    if (Proc_iso1_WeldingDetectionReq(AcceptFd) == 0)
                    {
                        ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    }
                    else
                    {
                        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]WeldingDetectionReqRes: fail");
                        Update_V2G_Flow_Status(Other_Fault);
                    }
                    req_is_responsed = TRUE;
                    break;
                }
                //STEP 3: Check for SessionStopReq Message
                else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest)
                {
                    Update_V2G_Flow_Status(SessionStopRequest);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;

                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_WeldingDetection_Timer_End);
                }
                else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest &&
                         EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest)
                {
                    sprintf((char*)buf_log_evcomm,
                            "[ERROR]SequenceError(%d) => Tx Res MSG",
                            EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.SequenceError = TRUE;

                    Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg);
                    EVCOMM_SYS_INFO.V2G_Rx_Msg = 0;
                }
                else
                {
                    break;
                }
            }
            //-------------------------------------------
            case SessionStopRequest:                //53,
            {
                if (Proc_iso2_SessionStopReq(AcceptFd) == 0)
                {
                    Update_V2G_Flow_Status(SessionStopResponse);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                }
                else
                {
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Error]SessionStopReqRes: fail");
                    Update_V2G_Flow_Status(Other_Fault);
                }
                req_is_responsed = TRUE;
                //break;
            }
            case SessionStopResponse:               //54,
            {
                break;
            }
    #endif
            //-------------------------------------------
            default:
            {
                break;
            }
        }
    }

    return 0;
}



/*===========================================================================
FUNCTION: V2gMsg_Process_iso2_AC
DESCRIPTION:
PRE-CONDITION:
INPUT:
        1. V2gFlowStatus
OUTPUT:
GLOBAL VARIABLES:
        1. V2gFlowStatus
=============================================================================*/
int V2gMsg_Process_iso2_AC(int AcceptFd)
{

	return 0;
}

/*===========================================================================
FUNCTION: V2gMsg_Process_iso2
DESCRIPTION:
PRE-CONDITION:
INPUT:
        1. V2gFlowStatus
OUTPUT:
GLOBAL VARIABLES:
        1. V2gFlowStatus
=============================================================================*/
int V2gMsg_Process_iso2(int AcceptFd, unsigned char EnergyTransferMode)
{
    switch (EnergyTransferMode)
    {
        case DC_extended:
        {
            V2gMsg_Process_iso2_DC(AcceptFd);
            break;
        }

        case AC_single_phase_core:
        case AC_three_phase_core:
        {
            V2gMsg_Process_iso2_AC(AcceptFd);
            break;
        }

        default:
        {
            sprintf((char*)buf_log_evcomm,
                    "[ISO2][Warning]Unexpected EnergyTransferMode(%d)",
                    EnergyTransferMode);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            break;
        }
    }

    return 0;
}

/*===========================================================================
FUNCTION: V2gMsg_Process
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int V2gMsg_Process(int AcceptFd)
{
    int errn = 0;

    switch (ShmCcsData->CommProtocol)
    {
        case V2GT_MSG_PROTOCOL_DIN70121:        //0
        {
            V2gMsg_Process_din(AcceptFd);
            break;
        }

        case V2GT_MSG_PROTOCOL_ISO15118_2014:   //1
        {
            V2gMsg_Process_iso1(AcceptFd, ShmCcsData->EnergyTransferMode);
            break;
        }

        case V2GT_MSG_PROTOCOL_ISO15118_2018:   //2
        {
            V2gMsg_Process_iso2(AcceptFd, ShmCcsData->EnergyTransferMode);
            break;
        }

        default:
        {
            sprintf((char*)buf_log_evcomm,
                    "[Warning]Unexpected CommProtocol(%d)",
                    ShmCcsData->CommProtocol);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            break;
        }
    }

    return errn;
}


/*===========================================================================
FUNCTION: V2gMsg_Rx
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int V2gMsg_Rx(int AcceptFd)
{
    int errn = 0;
    unsigned int packet_size = 0;

    memset(V2gtpMsgRxBuf, 0, V2GTP_MSG_RX_BUFFER_SIZE);
    packet_size = recv(AcceptFd, V2gtpMsgRxBuf, V2GTP_MSG_RX_BUFFER_SIZE, 0);
    //[CAUTION] Everytime recv() is called, it will take a default time to wait for TCP packets.
    //The more time you call recv(), the more time you will waste here.
    //Here it is suggested that response immediatedly once you receive any packets.
    //For configuring the Rx waiting time, please use setsockopt().

    if(packet_size > 0) //[Joseph] If there is no data, ignore. (TBD)
    {
        //DEBUG_PRINTF_EVCOMM_DETAIL("\n\n Got TCP V2GTP Message: size = %d Bytes\n", packet_size);
        errn = V2gMsgDecoder(V2gtpMsgRxBuf, packet_size, V2gFlowStatus);
        if (errn < 0)
        {
            sprintf((char*)buf_log_evcomm, "[ERROR]V2gMsgDecoder (%d)", errn);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        }
    }
    return errn;
}

/*===========================================================================
FUNCTION: V2gComm
DESCRIPTION:
PRE-CONDITION:
        1. TCP socket is connected.
INPUT:
        1. AcceptFd         //TCP Connection ID
        2. V2gtpMsgRxBuf[]     //V2GTP Messages (Header + Payload)
        3. V2GTP_MSG_RX_BUFFER_SIZE   //64*1024 = 65,536 = 65.5K (Bytes)

OUTPUT:
GLOBAL VARIABLES:
        1. V2gtpMsgRxBuf[]
=============================================================================*/
int V2gComm(int AcceptFd)
{
    int errn = 0;

    if (V2gMsg_Rx(AcceptFd) < 0)
    {
        Update_V2G_Flow_Status(Other_Fault);
        errn = -1;
    }

    //following are the response message handling according to status flag
    if (V2gMsg_Process(AcceptFd) < 0)
    {
        errn = -1;
    }

    //Error Check
    //V2G_Error_Monitor();

    return errn;
}

/*===========================================================================
FUNCTION: SdpUdpConnected
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int SdpUdpConnected()
{
    int packet_size,Rtn;
    struct sockaddr_in6 ServerAddr,ClientAddr;
    struct V2gtpHeader *header;
    unsigned char *payload;

    if(UdpSock <= 0)
    {
        if ((UdpSock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "SdpUdpConnected: Fail to open UdpSock");
            return 0;
        }
        memset(&ServerAddr,0, sizeof(struct sockaddr_in));
        ServerAddr.sin6_family = AF_INET6;
        ServerAddr.sin6_addr = in6addr_any;
        ServerAddr.sin6_port = htons(SdpUdpServerPort);
        if(bind(UdpSock, (struct sockaddr *)&ServerAddr, sizeof(struct sockaddr_in6)) <0)
        {
            sprintf((char*)buf_log_evcomm,
                    "SdpUdpConnected: Fail to bind UdpSock(%d)",
                    UdpSock);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

            close(UdpSock);
            UdpSock = -1;
            return 0;
        }
        sprintf((char*)buf_log_evcomm, "[UdpSock]opend:%d", UdpSock);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

        sprintf((char*)buf_log_evcomm, "[SDP]Req from EVCC: waiting...(%d)", UdpSock);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
    }

    memset(V2gtpMsgRxBuf, 0, V2GTP_MSG_RX_BUFFER_SIZE);
    memset(&ClientAddr, 0, sizeof(struct sockaddr_in));
    Rtn = sizeof(struct sockaddr_in6);
    packet_size = recvfrom(UdpSock, V2gtpMsgRxBuf, V2GTP_MSG_RX_BUFFER_SIZE, MSG_DONTWAIT, (struct sockaddr *)&ClientAddr, (socklen_t *)&Rtn);

    if(packet_size > 0)
    {
        header = (struct V2gtpHeader *) V2gtpMsgRxBuf;
        payload = V2gtpMsgRxBuf+sizeof(struct V2gtpHeader);

        #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
        {
            DEBUG_PRINTF_EVCOMM_DETAIL("\n\n Got UDP packet_size = %d (Bytes)\n", packet_size);

            DEBUG_PRINTF_EVCOMM_DETAIL("\n\n***********************************\n");
            DEBUG_PRINTF_EVCOMM_DETAIL("***** Received SDP Packet *****\n");
            DEBUG_PRINTF_EVCOMM_DETAIL("***********************************\n");
            DEBUG_PRINTF_EVCOMM_DETAIL("ClientAddress=");

            for(Rtn = 0; Rtn < 16; Rtn += 2)
            {
                DEBUG_PRINTF_EVCOMM_DETAIL("%02x%02x:",ClientAddr.sin6_addr.s6_addr[Rtn],ClientAddr.sin6_addr.s6_addr[Rtn+1]);
            }
            DEBUG_PRINTF_EVCOMM_DETAIL("\n");
            DEBUG_PRINTF_EVCOMM_DETAIL("ClientPort=%d\n",ClientAddr.sin6_port);
            DEBUG_PRINTF_EVCOMM_DETAIL("ProtocolVersion=%d\n",header->ProtocolVersion);
            DEBUG_PRINTF_EVCOMM_DETAIL("InverseProtocolVersion=0x%x\n",header->InverseProtocolVersion);
            DEBUG_PRINTF_EVCOMM_DETAIL("PayloadType=0x%x\n",htons(header->PayloadType));
            DEBUG_PRINTF_EVCOMM_DETAIL("PayloadLength=0x%x\n",htonl(header->PayloadLength));
            DEBUG_PRINTF_EVCOMM_DETAIL("htons(header->PayloadType)=0x%x\n",htons(header->PayloadType));
        }
        #endif

        if( (header->ProtocolVersion == 0x01) &&
            (header->InverseProtocolVersion == 0xFE) &&
            (htons(header->PayloadType) == V2GTP_PAYLOAD_TYPE_SDP_REQUEST))
        {
            sprintf((char*)buf_log_evcomm, "[SDP][Rx]Req from EVCC: GOT(%d)", UdpSock);
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

            DEBUG_PRINTF_EVCOMM_DETAIL("Security=0x%x\n", *(payload + 0));
            DEBUG_PRINTF_EVCOMM_DETAIL("TransportProtocol=0x%x\n", *(payload + 1));

            header->PayloadType = htons(V2GTP_PAYLOAD_TYPE_SDP_RESPONSE);
            header->PayloadLength = htonl(20);    //Fixed Length=20
            memset(payload, 0, 20);
            // MAC address[0:2] + FFFE + MAC address[3:5]
            payload[0] = (IPV6_LINK_LOCAL_PREFIX>>8) & 0xFF;
            payload[1] = IPV6_LINK_LOCAL_PREFIX & 0xFF;
            payload[8 ]= CsuMac[0];
            payload[8] ^= 0x02;// bit 1 should complemented.
            payload[9] = CsuMac[1];
            payload[10] = CsuMac[2];
            payload[11] = 0xFF;
            payload[12] = 0xFE;
            payload[13] = CsuMac[3];
            payload[14] = CsuMac[4];
            payload[15] = CsuMac[5];
            //TCP port
            payload[16] = (EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active>>8) & 0xFF;
            payload[17] = EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active & 0xFF;
            payload[18] = SDP_PAYLOAD_SECURITY_NONE;      //Security
            payload[19] = SDP_PAYLOAD_TRANS_PROTOCOL_TCP; //Transport protocol

            //[To-Do] Setup the TCP in advance to receive the coming TCP handshke messages after SDP response.

            Rtn = sendto(UdpSock, V2gtpMsgRxBuf, sizeof(struct V2gtpHeader) + htonl(header->PayloadLength), 0, (struct sockaddr *)&ClientAddr, sizeof(struct sockaddr_in6));

            sprintf((char*)buf_log_evcomm, "[SDP][Tx]Res from SECC");
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

            #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
            {
                DEBUG_PRINTF_EVCOMM_DETAIL("\n\n***** Response SDP Packet *****\n");
                DEBUG_PRINTF_EVCOMM_DETAIL("Send size=%d\n",Rtn);
                DEBUG_PRINTF_EVCOMM_DETAIL("Destination Address=");
                for(Rtn = 0; Rtn < 16; Rtn++)
                {
                    DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ", ClientAddr.sin6_addr.s6_addr[Rtn]);
                }
                DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                DEBUG_PRINTF_EVCOMM_DETAIL("Destination Port=%d\n", ClientAddr.sin6_port);
                DEBUG_PRINTF_EVCOMM_DETAIL("ProtocolVersion=%d\n", header->ProtocolVersion);
                DEBUG_PRINTF_EVCOMM_DETAIL("InverseProtocolVersion=0x%x\n", header->InverseProtocolVersion);
                DEBUG_PRINTF_EVCOMM_DETAIL("PayloadType=0x%x\n", htons(header->PayloadType));
                DEBUG_PRINTF_EVCOMM_DETAIL("PayloadLength=0x%x\n", htonl(header->PayloadLength));
                DEBUG_PRINTF_EVCOMM_DETAIL("SECC Ipv6 Address=");
                for(Rtn = 0; Rtn < 16; Rtn++)
                {
                    DEBUG_PRINTF_EVCOMM_DETAIL("%02x:",payload[Rtn]);
                }
                DEBUG_PRINTF_EVCOMM_DETAIL("\n");
                DEBUG_PRINTF_EVCOMM_DETAIL("SECC Port=%d\n", (payload[16]<<8 | payload[17]));
                DEBUG_PRINTF_EVCOMM_DETAIL("Security=0x%x\n", payload[19]);
                DEBUG_PRINTF_EVCOMM_DETAIL("TransportProtocol=0x%x\n", payload[20]);
            }
            #endif

            if(Rtn > 0)
            {
                return 1;
            }
        }
    }
    return 0;
}

/*===========================================================================
FUNCTION: V2gTcpConnected
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int V2gTcpConnected()
{
    int Rtn,AcceptFd;
    struct sockaddr_in6 ServerAddr,ClientAddr;

    if(TcpSock <= 0)
    {
        if ((TcpSock = socket(PF_INET6, SOCK_STREAM, 0)) < 0)
        {
            sprintf((char*)buf_log_evcomm,
                    "V2gTcpConnected: Fail to open TcpSock (%s)",
                    strerror(errno));
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            usleep(100000); //100ms

            return 0;
        }
        fcntl(TcpSock, F_SETFL, O_NONBLOCK);    //set to O_NONBLOCK
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[TCP]socket set: DONE");

        memset(&ServerAddr,0, sizeof(struct sockaddr_in));
        ServerAddr.sin6_family = PF_INET6;
        ServerAddr.sin6_addr = in6addr_any;
        ServerAddr.sin6_port = htons(EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active);
        //ServerAddr.sin6_port = htons(SdpTcpServerPort + (rand() % 10) + 1);
        //printf("SdpTcpServerPort = %d(DEC)\n", htons(ServerAddr.sin6_port));
        if(bind(TcpSock, (struct sockaddr *)&ServerAddr, sizeof(struct sockaddr_in6)) < 0)
        {
            sprintf((char*)buf_log_evcomm,
                    "V2gTcpConnected: Fail to bind TcpSock (%s), SdpTcpServerPort = %d",
                    strerror(errno),
                    EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active
                    );
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

            //Change to another TCP port
            /*
            memset(&ServerAddr, 0, sizeof(struct sockaddr_in));
            ServerAddr.sin6_family = PF_INET6;
            ServerAddr.sin6_addr = in6addr_any;
            //ServerAddr.sin6_port = htons(SdpTcpServerPort + (rand() % 1000) + 1);
            ServerAddr.sin6_port = htons(EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active);
            */
            if(bind(TcpSock, (struct sockaddr *)&ServerAddr, sizeof(struct sockaddr_in6)) < 0)
            {
                sprintf((char*)buf_log_evcomm,
                        "V2gTcpConnected: Fail to bind TcpSock (%s), SdpTcpServerPort = %d",
                        strerror(errno),
                        EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active
                        );
                SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

                usleep(100000); //100ms
                close(TcpSock);
                TcpSock = -1;
                return 0;
            }
        }
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[TCP]blid: DONE");

        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[TCP]listen: START");

        if(listen(TcpSock, 1) == -1)     //only accept one connection
        {
            sprintf((char*)buf_log_evcomm,
                    "V2gTcpConnected: Fail to listen TcpSock (%s)",
                    strerror(errno));
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
            usleep(100000); //100ms

            close(TcpSock);
            TcpSock = -1;
            return 0;
        }
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[TCP]listen: DONE");

        sprintf((char*)buf_log_evcomm, "[TCP]TcpSock: opened(%d), port=%d", TcpSock, htons(ServerAddr.sin6_port));
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[TCP]accept: START");
    }
    Rtn = sizeof(struct sockaddr_in6);
    if((AcceptFd = accept(TcpSock, (struct sockaddr *)&ClientAddr, (socklen_t *)&Rtn)) == -1)
    {
        static BOOL tmp = 0;
        if (tmp == 0)
        {
            SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[TCP]Wait TCP connection...");
            tmp = 1;
        }
        else
        {
            //DEBUG_PRINTF_EVCOMM_DETAIL(".");
        }
        return 0;
    }

    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[TCP]accept: DONE\n");

    #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE)
    {
        DEBUG_PRINTF_EVCOMM_DETAIL("\n\nAccept one TCP connection:\n");
        DEBUG_PRINTF_EVCOMM_DETAIL("AcceptFd=%d\n",AcceptFd);
        DEBUG_PRINTF_EVCOMM_DETAIL("ClientAddress=");

        for(Rtn = 0; Rtn < 16; Rtn += 2)
        {
            DEBUG_PRINTF_EVCOMM_DETAIL("%02x%02x:", ClientAddr.sin6_addr.s6_addr[Rtn], ClientAddr.sin6_addr.s6_addr[Rtn+1]);
        }
        DEBUG_PRINTF_EVCOMM_DETAIL("\n");
        DEBUG_PRINTF_EVCOMM_DETAIL("ClientPort=%d\n", ClientAddr.sin6_port);
    }
    #endif

    return AcceptFd;
}

/*===========================================================================
FUNCTION: End_Process
DESCRIPTION:
PRE-CONDITION:
        1. <CAUTION> This function could only be used in SeccComm fork2.
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int End_Process()
{
    if(EVCOMM_SYS_INFO.End_Process_inused == TRUE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "End_Process has been triggered by another event.");
        return -1;
    }

    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "Entering...");

    //STEP 1: Ask CSU to Stop
    EVCOMM_SYS_INFO.End_Process_inused = TRUE;
    CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE;
    EVCOMM_SYS_INFO.ConnectorLocked = FALSE;
    ShmInternalComm->ChargingPermission = FALSE;

    //Step 2: Close sockets
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "Close sockets...");
    if(RawSock > 0)
    {
        close(RawSock);
    }
    if(UdpSock > 0)
    {
        close(UdpSock);
    }
    if(TcpSock > 0)
    {
        close(TcpSock);
        close(TcpAcceptFd);
    }
    RawSock = UdpSock = TcpSock = TcpAcceptFd = -1;

    //STEP 3: Switch to State E
    //SwitchCpStateE(ENABLE);

    //STEP 4: Close tcpdump
    Sniffer_Tcpdump(DISABLE);

    //STEP 5: Keep 100% PWM for 5 seconds
    OutputCpPwmDuty(100);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "PWM 100\% countdown: 5");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "PWM 100\% countdown: 4");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "PWM 100\% countdown: 3");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "PWM 100\% countdown: 2");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "PWM 100\% countdown: 1");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "PWM 100\% countdown: 0");

    AttenProfileCnt = 0;
    init_appHandEXIDocument(&ccs_handshake);
    // Qca7kPowerReset();  //reset QCA7000 /* +++ 20200808, vern, should disconnected PLC connection after session stop ---*/

    #if (FIRMWARE_VERSION_COMPILE_SETTING_RELEASE_MODE == DISABLE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[End_Process]1st sync...");
        system("sync");
    }
    #endif

    //STEP 4: Switch to State E
    //Keep State E for 5 seconds
    #if 0
    SwitchCpStateE(ENABLE); //Set PWM Duty as 0 and set State as E (0V)
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "State E countdown: 5");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "State E countdown: 4");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "State E countdown: 3");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "State E countdown: 2");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "State E countdown: 1");
    sleep(1);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "State E countdown: 0");
    #endif

    //Reset Memory
    unsigned char SlaveAddress_backup;
    unsigned int matched_backup;
    //unsigned char state_backup;


    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "Soft reset (closing SeccComm)...");
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "---------------------------------------------");
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "--               EVCOMM: END               --");
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "---------------------------------------------\n");

    #if (FIRMWARE_VERSION_COMPILE_SETTING_RELEASE_MODE == DISABLE)
    {
        SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "2nd sync...");
        system("sync");
    }
    #endif

    system("sleep 1");

    //Backup CsuComm flags
    SlaveAddress_backup = ShmInternalComm->SlaveAddress;
    matched_backup = CSUCOMMDC_TASK_FLAG.matched;
    //state_backup = Check_V2G_Flow_Status();

    memset(V2gtpMsgRxBuf, 0, V2GTP_MSG_RX_BUFFER_SIZE);
    memset(V2gtpMsgTxBuf, 0, V2GTP_MSG_TX_BUFFER_SIZE);
    memset(&ccs_handshake, 0, sizeof(struct appHandEXIDocument));
    memset(&ccs_exi_doc_DIN, 0, sizeof(struct dinEXIDocument));
    memset(V2GTP_Tx_buf, 0, V2GTP_MSG_TX_BUFFER_SIZE);
    memset(buf_log_evcomm, 0, sizeof(buf_log_evcomm));
    memset(ShmStatusCodeData, 0, sizeof(struct StatusCodeData));
    memset(ShmInternalComm, 0, sizeof(struct InternalComm));
    memset(ShmCcsData, 0, sizeof(struct CcsData));

    //Resume CsuComm flags
    ShmInternalComm->SlaveAddress = SlaveAddress_backup;
    CSUCOMMDC_TASK_FLAG.matched = matched_backup;
    Sniffer_Candump(DISABLE);
    Sniffer_Candump(ENABLE);
    //memset(ShmSysConfigAndInfo, 0, sizeof(struct SysConfigAndInfo)); //EVCOMM_SYS_INFO.End_Process_inused = FALSE;
    //EVCOMM_SYS_INFO.End_Process_inused = TRUE;
    //Update_V2G_Flow_Status(state_backup);
    //CP_Detection_Pid = 0;
    //PP_Detection_Pid = 0;
    //Error_Monitor_Pid = 0;
    //system("cd /root;./reset_soft.sh");
    system("pkill Module_CCS");
    while(1)
    {
        //wait for CSU configrm
    }
}


/*===========================================================================
FUNCTION: Parameters_Init
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int Parameters_Init()
{
    //Step 0: Generate random number
    unsigned int value_random;
    struct timeb time_seed;
    ftime(&time_seed);
    srand(time_seed.millitm);

    //Step 1: Init SDP TCP Port
    value_random = rand();
    EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active = (unsigned short)(SdpTcpServerPort + (value_random % 10000) + 1);

    sprintf((char*)buf_log_evcomm,
            "[Init]TCP Port:OK(%d)",
            EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

    //Step 2: Init SessionID
    value_random = rand();
    memcpy(&EVCOMM_SYS_INFO.SessionID[0], &value_random, 4);

    value_random = rand();
    memcpy(&EVCOMM_SYS_INFO.SessionID[4], &value_random, 4);

    sprintf((char*)buf_log_evcomm,
            "[Init]SessionID:OK(%02X%02X%02X%02X%02X%02X%02X%02X)",
            EVCOMM_SYS_INFO.SessionID[0],
            EVCOMM_SYS_INFO.SessionID[1],
            EVCOMM_SYS_INFO.SessionID[2],
            EVCOMM_SYS_INFO.SessionID[3],
            EVCOMM_SYS_INFO.SessionID[4],
            EVCOMM_SYS_INFO.SessionID[5],
            EVCOMM_SYS_INFO.SessionID[6],
            EVCOMM_SYS_INFO.SessionID[7]);
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);

    return 0;
}

/*===========================================================================
FUNCTION: AC share memory synchronize
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int SyncAcShreaMemory()
{
#if (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE)
	pid_t pid;

	pid = fork();
	if(pid == 0)
	{
		for(;;)
		{
			if(!EVCOMM_SYS_INFO.End_Process_inused)
			{
				for(uint8_t gun_index=0;gun_index<1;gun_index++)
				{
					//========================================
					// CSU -> CCS setting
					//========================================
					// Permission
					if(ShmInternalComm->ChargingPermission != ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission)
					{
						DEBUG_INFO("AC permission: %d -> %d\n", ShmInternalComm->ChargingPermission, ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission);
						ShmInternalComm->ChargingPermission_new = ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission;
						ShmInternalComm->ChargingPermission_pre = ShmInternalComm->ChargingPermission;
						ShmInternalComm->ChargingPermission = ShmInternalComm->ChargingPermission_new;
					}

					// CP
					ShmInternalComm->AC_CpPositiveVoltage = ShmCharger->gun_info[gun_index].acCcsInfo.CpPositiveVoltage;
					if(ShmInternalComm->AC_CpPresentState != ShmCharger->gun_info[gun_index].acCcsInfo.CpPresentState)
					{
						DEBUG_INFO("CP state: %d -> %d\n", ShmInternalComm->AC_CpPresentState, ShmCharger->gun_info[gun_index].acCcsInfo.CpPresentState);
						ShmInternalComm->AC_CpPresentState = ShmCharger->gun_info[gun_index].acCcsInfo.CpPresentState;
					}

					//========================================
					// CCS -> CSU check
					//========================================
					// V2G message flow status
					if(ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus != Check_V2G_Flow_Status())
					{
						//DEBUG_INFO("PresentMsgFlowStatus: %d -> %d\n", ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus, Check_V2G_Flow_Status());
						ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus = Check_V2G_Flow_Status();

						switch(ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus)
						{
							case PowerDeliveryRequestStart ... ChargingStatusResponse:
								ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress = HLC_START_MODE;
								break;
							case CM_SLAC_PARM_REQ ... PreChargeResponse:
								ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress = HLC_STANDBY_MODE;
								break;
							default:
								ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress = HLC_STOP_MODE;
								break;
						}
					}
				}
			}


			usleep(1000);
		}
	}
#endif

	return 0;
}

/*===========================================================================
FUNCTION: main
DESCRIPTION:
PRE-CONDITION:
INPUT:
OUTPUT:
GLOBAL VARIABLES:
=============================================================================*/
int main(int argc, char *argv[])
{
    //unsigned char Rtn;

    //Initialization
    ShareMemory_Init();
    memset(ShmSysConfigAndInfo, 0, sizeof(struct SysConfigAndInfo));

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

    RawSock = UdpSock = TcpSock = -1;
    Update_V2G_Flow_Status(IDLE);

    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "---------------------------------------------");
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "--               EVCOMM: START             --");
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "---------------------------------------------");
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "init...");

    //Init V2G TCP/IPv6 packets buffer
    memset(V2gtpMsgRxBuf, 0, V2GTP_MSG_RX_BUFFER_SIZE);
    memset(V2gtpMsgTxBuf, 0, V2GTP_MSG_TX_BUFFER_SIZE);

    //Release State E Control
    SwitchCpStateE(DISABLE);
    OutputCpPwmDuty(100);

    //start to detect CP pilot state
    CP_Detection_Pid = 0;
    CP_Detection();     //fork1
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[fork1]CP Detection: ON");

    //start to detect errors
    Error_Monitor();    //fork2
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[fork2]Error Monitor: ON");

    //start to detect PP
    PP_Detection_Pid = 0;
    #if (PP_PROTECTION_MECHANISM == ENABLE)
    PP_Detection();
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[fork3]PP Detection: ON");
    #else
    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[fork3]PP Detection: OFF");
    #endif

    //Init communication parameters
    GetEthMac((uint8_t*)QcaInterface, CsuMac);

    AttenProfileCnt = 0;
    init_appHandEXIDocument(&ccs_handshake);

    //Init Energy transfer mode
    //[To-Do] Parsing Model Name
    ShmCcsData->EnergyTransferMode = CCS_ENERGY_TRANSFER_MODE;

    //struct ChargingInfoData *ccs;
    //ccs = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0];

    Parameters_Init();
    Sniffer_Tcpdump(ENABLE);
    #if (TCPDUMP_PACKETS_SNIFFER_SWITCH == ENABLE)
    sleep(1); //wait for tcpdump getting ready
    #endif

    SyncAcShreaMemory();

    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", "[Init]DONE");

    while(1)
    {
        //DEBUG_PRINTF_EVCOMM_DETAIL("\nV2gFlowStatus = %d\n", V2gFlowStatus);
        //if((ShmInternalComm->ChargingPermission == 0x01) && (CheckConnectorPlugIn() == 1))
        //if((CheckConnectorPlugIn() == TRUE) && (ShmInternalComm->ChargingPermission == TRUE))
        //if(ShmInternalComm->ChargingPermission == 0x01)
        //if(CheckConnectorPlugIn() == TRUE)
        if (EVCOMM_SYS_INFO.End_Process_inused == FALSE)
        {
            if(V2gFlowStatus < SLACC_SDP_UDP_Connection)
            {
                SlacComm();
            }
            else if(V2gFlowStatus == SLACC_SDP_UDP_Connection)
            {
                if(SdpUdpConnected() == 1)
                {
                    Update_V2G_Flow_Status(SLACC_SDP_TCP_Connection);
                    continue;
                }
                SlacComm(); //TC_SECC_VTB_CmSlacMatch_004
                ftime(&SeqEndTime);
                if(DiffTimeb(SeqStartTime, SeqEndTime) > TT_match_join)
                {
                    sprintf((char*)buf_log_evcomm,
                            "Wait SLACC_SDP_UDP_Connection Timeout - TT_match_join (%.02lf of %d ms)\n",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            TT_match_join);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);
                    //Update_ShmStatusCode(); //[To-Do] to be implemented
                    //CCS_SECC_TIMEOUT_SLACC_SDP_UDP_TT_match_join (023823)
                    ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                    ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                    ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                    ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                    ShmStatusCodeData->PresentStatusCode[0][4] = 2;
                    ShmStatusCodeData->PresentStatusCode[0][5] = 3;
                    //CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;
                    Proc_EVStopRes(ShmInternalComm->FD_CAN_Socket);
                }
            }
            else if(V2gFlowStatus == SLACC_SDP_TCP_Connection)
            {
                if((TcpAcceptFd = V2gTcpConnected()) > 0)
                {
                    Update_V2G_Flow_Status(SupportedAppProtocolRequest);
                    ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start);
                    continue;
                }
                SlacComm();
                ftime(&SeqEndTime);

                if(DiffTimeb(SeqStartTime, SeqEndTime) > TT_match_join)
                {
                    sprintf((char*)buf_log_evcomm,
                            "Wait SLACC_SDP_TCP_Connection Timeout - TT_match_join (%.02lf / %d ms)",
                            DiffTimeb(SeqStartTime, SeqEndTime),
                            TT_match_join);
                    SAVE_SYS_LOG_MSG_EVCOMM("%s\n", buf_log_evcomm);
                    Update_V2G_Flow_Status(Sequence_Timeout);
                    //Update_ShmStatusCode(); //[To-Do] to be implemented
                    //CCS_SECC_TIMEOUT_SLACC_SDP_TCP_TT_match_join (023824)
                    ShmStatusCodeData->PresentStatusCode[0][0] = 0;
                    ShmStatusCodeData->PresentStatusCode[0][1] = 2;
                    ShmStatusCodeData->PresentStatusCode[0][2] = 3;
                    ShmStatusCodeData->PresentStatusCode[0][3] = 8;
                    ShmStatusCodeData->PresentStatusCode[0][4] = 2;
                    ShmStatusCodeData->PresentStatusCode[0][5] = 4;
                    //CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE;
                    Proc_EVStopRes(ShmInternalComm->FD_CAN_Socket);
                }
            }
            else if(V2gFlowStatus <= SessionStopResponse)
            {
                if (V2gComm(TcpAcceptFd) < 0)
                {
                    //error occours
                }
            }
            else if (V2gFlowStatus >= Performance_Timeout)
            {
                //End_Process
            }
            else
            {
                //null
            }
        }
        usleep(1000);
    } //while
}//main while