/*=========================================================================== Combined Charging System (CCS): SECC EVComm.c initiated by Vern, Joseph (since 2019/07/19) =============================================================================*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //for pow #include #include #include #include #include #include #include #include #include #include #include "define.h" #include "SeccComm.h" #include "NidNmk.h" #include "SeccComm.h" #include "CsuComm.h" #include "./exi_engine/api/api.h" #include "./exi_engine/appHandshake/appHandEXIDatatypes.h" #include "./exi_engine/transport/v2gtp.h" int MeterSMId[8]; struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct CcsData *ShmCcsData; struct InternalComm *ShmInternalComm; //struct InternalCommAC *ShmInternalCommAC; 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; #ifdef SUPPORT_TLS_CONNECTION SSL_CTX *ctx; SSL *ssl; unsigned char EvSecurity; #endif enum MsgFlowStatus V2gFlowStatus; int RawSock,UdpSock,TcpSock; unsigned char *V2gtpMsgRxBuf, *V2gtpMsgTxBuf; 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]; int writeStringToEXIString(unsigned char* string, exi_string_character_t* exiString) { int pos = 0; while(string[pos]!='\0') { exiString[pos] = string[pos]; pos++; } return pos; } /*=========================================================================== 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: StoreLogMsg DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ #if SAVE_SYS_LOG_MSG_EVCOMM_SWITCH == ENABLE int StoreLogMsg2(unsigned char *DataString) { static unsigned char Buf[1024]; static time_t CurrentTime; static struct tm *tm; static struct timeval tv; memset(Buf, 0, sizeof(Buf)); CurrentTime = time(NULL); tm = localtime(&CurrentTime); gettimeofday(&tv, NULL); // get microseconds, 10^-6 #ifdef AWCCS sprintf(Buf, "echo \"[%04d%02d%02d: %02d:%02d:%02d.%06d][SECC][%d][%02d]%s\" >> /Storage/SystemLog/[%04d.%02d]CCS-SystemLog", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec, EVCOMM_SYS_INFO.CpState, Check_V2G_Flow_Status(), DataString, tm->tm_year + 1900, tm->tm_mon + 1); #else sprintf(Buf, "echo \"[%04d%02d%02d: %02d:%02d:%02d.%06d][SECC][%d][%02d]%s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec, EVCOMM_SYS_INFO.CpState, Check_V2G_Flow_Status(), DataString, tm->tm_year + 1900, tm->tm_mon + 1); #endif system(Buf); DEBUG_PRINTF_EVCOMM_SYSTEM_LOG("[%02d:%02d:%02d.%06d][SECC][%d][%02d]%s \n", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec, EVCOMM_SYS_INFO.CpState, Check_V2G_Flow_Status(), DataString); //Reset the buf_log_evcomm Buffer, i.e. DataString memset(buf_log_evcomm, 0, SIZE_OF_LOG_BUFFER); } #endif /*=========================================================================== 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) { 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; } /*=========================================================================== 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("[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("[candump]init"); system("cd /mnt/;rm -rf candump/"); system("cd /mnt/;mkdir candump"); SAVE_SYS_LOG_MSG_EVCOMM("[candump]on"); system("cd /mnt/candump;candump -l can0 &"); return 0; } else if (cmd == DISABLE) { SAVE_SYS_LOG_MSG_EVCOMM("[candump]off"); system("killall candump"); SAVE_SYS_LOG_MSG_EVCOMM("[candump]save"); system("cd /;cp -rfv /mnt/candump /Storage/SystemLog/"); return 0; } else { sprintf(buf_log_evcomm_fork2, "[candump]unexpected cmd(%d)", cmd); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm_fork2); return -1; } #endif } /*=========================================================================== 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("[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(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("[tcpdump]on"); system(buf); return 0; } else if (cmd == DISABLE) { SAVE_SYS_LOG_MSG_EVCOMM("[tcpdump]off"); system("killall tcpdump"); SAVE_SYS_LOG_MSG_EVCOMM("[tcpdump]wait: 2s"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("[tcpdump]wait: 1s"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("[tcpdump]save"); system("cd /;cp -rfv /mnt/tcpdump /Storage/SystemLog/"); return 0; } else { sprintf(buf_log_evcomm, "[tcpdump]unexpected cmd(%d)", cmd); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); return -1; } #endif } /*=========================================================================== 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; state_now = Check_V2G_Flow_Status(); 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(buf_log_evcomm, "[Warning]state(%d) change: ignored (End_Process_inused:%d, FW_Update_Task_inused:%d)", state_new, EVCOMM_SYS_INFO.End_Process_inused, CSUCOMMDC_TASK_FLAG.FW_Update_Task_inused ); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm, "[Warning]state(%d) change: ignored(now in error state)", state_new, state_now); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); } return -1; } } //Updating the state formally. sprintf(buf_log_evcomm, "[stt]%02d >> %02d", state_now, state_new ); SAVE_SYS_LOG_MSG_EVCOMM(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; } } } 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(buf_log_evcomm, "[Warning]StartTime(%.02lf) > EndTime(%.02lf), d(%.02lf)", StartTime, EndTime, t_diff); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm_fork2, "[fork1][Warning]S(%.02lf) > E(%.02lf), d(%.02lf)", StartTime, EndTime, t_diff); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm_fork2, "[fork2][Warning]S(%.02lf) > E(%.02lf), d(%.02lf)", StartTime, EndTime, t_diff); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm_fork2); } #endif return -1; } return t_diff; } int CreateShareMemory() { int MeterSMId; //create ShmSysConfigAndInfo if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), IPC_CREAT | 0777)) < 0) { SAVE_SYS_LOG_MSG_EVCOMM("[main]CreateShareMemory:shmget ShmSysConfigAndInfo NG"); return 0; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { SAVE_SYS_LOG_MSG_EVCOMM("[main]CreateShareMemory:shmat ShmSysConfigAndInfo NG"); return 0; } memset(ShmSysConfigAndInfo,0,sizeof(struct SysConfigAndInfo)); //create ShmStatusCodeData if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), IPC_CREAT | 0777)) < 0) { SAVE_SYS_LOG_MSG_EVCOMM("[main]CreateShareMemory:shmget ShmStatusCodeData NG"); return 0; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { SAVE_SYS_LOG_MSG_EVCOMM("[main]CreateShareMemory:shmat ShmStatusCodeData NG"); return 0; } memset(ShmStatusCodeData,0,sizeof(struct StatusCodeData)); //create ShmCcsData if ((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData), IPC_CREAT | 0777)) < 0) { SAVE_SYS_LOG_MSG_EVCOMM("[main]CreateShareMemory:shmget ShmCcsData NG"); return 0; } else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { SAVE_SYS_LOG_MSG_EVCOMM("[main]CreateShareMemory:shmat ShmCcsData NG"); return 0; } memset(ShmCcsData,0,sizeof(struct CcsData)); return 1; } void DetachShareMemory() { if(MeterSMId[0]>0) { shmdt(ShmSysConfigAndInfo); shmctl(MeterSMId[0], IPC_RMID, 0); } if(MeterSMId[1]>0) { shmdt(ShmStatusCodeData); shmctl(MeterSMId[1], IPC_RMID, 0); } if(MeterSMId[2]>0) { shmdt(ShmCcsData); shmctl(MeterSMId[2], IPC_RMID, 0); } if(MeterSMId[3]>0) { shmdt(ShmInternalComm); shmctl(MeterSMId[3], IPC_RMID, 0); } /*if(MeterSMId[4]>0) { shmdt(ShmInternalCommAC); shmctl(MeterSMId[4], IPC_RMID, 0); }*/ } /*=========================================================================== FUNCTION: ShareMemory_Init DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int ShareMemory_Init() { memset(MeterSMId,0,sizeof(MeterSMId)); //create ShmSysConfigAndInfo if ((MeterSMId[0] = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0) { SAVE_SYS_LOG_MSG_EVCOMM("ShareMemory_Init:shmget ShmSysConfigAndInfo NG"); return 0; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId[0], NULL, 0)) == (void *) -1) { SAVE_SYS_LOG_MSG_EVCOMM("ShareMemory_Init:shmat ShmSysConfigAndInfo NG"); return 0; } //create ShmStatusCodeData if ((MeterSMId[1] = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0) { SAVE_SYS_LOG_MSG_EVCOMM("ShareMemory_Init:shmget ShmStatusCodeData NG"); return 0; } else if ((ShmStatusCodeData = shmat(MeterSMId[1], NULL, 0)) == (void *) -1) { SAVE_SYS_LOG_MSG_EVCOMM("ShareMemory_Init:shmat ShmStatusCodeData NG"); return 0; } //create ShmCcsData if ((MeterSMId[2] = shmget(ShmCcsCommKey, sizeof(struct CcsData), 0777)) < 0) { SAVE_SYS_LOG_MSG_EVCOMM("ShareMemory_Init:shmget ShmCcsData NG"); return 0; } else if ((ShmCcsData = shmat(MeterSMId[2], NULL, 0)) == (void *) -1) { SAVE_SYS_LOG_MSG_EVCOMM("ShareMemory_Init:shmat ShmCcsData NG"); return 0; } //create ShmInternalComm if ((MeterSMId[3] = shmget(ShmInternalCommKey, sizeof(struct InternalComm), 0777)) < 0) { SAVE_SYS_LOG_MSG_EVCOMM("ShareMemory_Init:shmget ShmInternalComm NG"); return 0; } else if ((ShmInternalComm = shmat(MeterSMId[3], NULL, 0)) == (void *) -1) { SAVE_SYS_LOG_MSG_EVCOMM("ShareMemory_Init:shmat ShmInternalComm NG"); return 0; } #if 0 //create ShmInternalCommAC if ((MeterSMId[4] = shmget(ShmInternalCommACKey, sizeof(struct InternalCommAC), 0777)) < 0) { SAVE_SYS_LOG_MSG_EVCOMM("ShareMemory_Init:shmget ShmInternalCommAC NG"); return 0; } else if ((ShmInternalCommAC = shmat(MeterSMId[4], NULL, 0)) == (void *) -1) { SAVE_SYS_LOG_MSG_EVCOMM("ShareMemory_Init:shmat ShmInternalCommAC NG"); return 0; } #endif //[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, rd = 0; unsigned char addr[18], Buffer[128]; memset(Buffer, 0, sizeof(Buffer)); sprintf(Buffer, "cat /sys/class/net/%s/address > /mnt/GetEthInfo", Eth); //CsuMac (Eth = eth1) system(Buffer); fd = open("/mnt/GetEthInfo", O_RDONLY); if(fd < 0) { system("rm -f /mnt/GetEthInfo"); SAVE_SYS_LOG_MSG_EVCOMM("GetEthMac: MAC Address open error"); return 0; } memset(mac, 0, 6); memset(addr, 0, sizeof(addr)); rd = read(fd, addr, 17); close(fd); system("rm -f /mnt/GetEthInfo"); sscanf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); //CsuMac (Eth = eth1) sprintf(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(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(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 < 30) //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(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(str, "cat /sys/bus/iio/devices/iio\\:device0/in_voltage%d_raw", AdcChannel); fp=popen(str, "r"); if(fgets(AdcValue,sizeof(AdcValue),fp) == NULL) { pclose(fp); return -1; } pclose(fp); //Vin = Vref *D / (2^n - 1) return ((float)1.8*(float)atoi(AdcValue))/4095; } } /*=========================================================================== 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() { 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(SampleBuf); lseek(fd, 0, SEEK_SET); AvgSample += TmpVolt; } close(fd); AvgSample /= AvgTimes; V_pp = (1.8*AvgSample)/4095; //PP //CCS1: plug : 0.61<=V_pp<=1.18 //CCS2:plug : 1.2<=V_pp<=2.4 #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; } } /*=========================================================================== 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) { 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("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("SwitchCpStateE: enabled!\n"); } } #else //CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED { if(OnOff == DISABLE) { //SAVE_SYS_LOG_MSG_EVCOMM("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("SwitchCpStateE: enabled!\n"); } } #endif if (ccs->SwitchCpStateE_status_pre != ccs->SwitchCpStateE_status) { sprintf(buf_log_evcomm, "SwitchCpStateE: %d >> %d", ccs->SwitchCpStateE_status_pre, ccs->SwitchCpStateE_status ); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); ccs->SwitchCpStateE_status_pre = ccs->SwitchCpStateE_status; } } /*=========================================================================== FUNCTION: OutputCpPwmDuty DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int OutputCpPwmDuty(unsigned char Duty) { int DutyInNanoSec; 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(buf_log_evcomm, "echo %d > /sys/class/pwm/pwmchip0/pwm0/duty_cycle", DutyInNanoSec);//nanoseconds system(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(buf_log_evcomm, "CP Duty: %d\% >> %d\%", ccs->CpDuty_pre, ccs->CpDuty); SAVE_SYS_LOG_MSG_EVCOMM(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(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(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: GLOBAL VARIABLES: =============================================================================*/ int CheckConnectorPlugIn() { //return 0 => unplug //return 1 => plug-in //float TmpProximity; //unsigned char Rtn = 0; static struct ChargingInfoData *ccs; ccs = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; #if (CP_PROTECTION_MECHANISM == ENABLE) return (int)ccs->ConnectorPlugIn; #else return TRUE; #endif /* // PP Detection TmpProximity = ReadAdcVolt(ADC_CHANNEL_AIN2_PP); //[CAUTION] This function takes a period of time to deal with. //Designers should avoid to call it in main function, repeatly. if(((FIRMWARE_VERSION & 0x0000FF00) >> 8) == 0x01) { //UL version: judge with CP and proximity //TmpProximity = ReadAdcVolt(ADC_CHANNEL_AIN2_PP); //SAVE_SYS_LOG_MSG_EVCOMM("Connector: UL"); if((ccs->CpState >= 2) && (ccs->CpState <= 5) && (TmpProximity >= 0.4) && (TmpProximity <= 0.9)) { Rtn = 1; } } else { //SAVE_SYS_LOG_MSG_EVCOMM("Connector: CE"); //CE version: judge with CP only if((ccs->CpState >=2 ) && (ccs->CpState <=5 )) { Rtn = 1; } } */ //CE version: judge with CP only /* if((ccs->CpState >= 2 ) && (ccs->CpState <= 5 )) { Rtn = TRUE; } ccs->ConnectorPlugIn = Rtn; //ccs->PpVoltage = TmpProximity; return Rtn; */ } /*=========================================================================== 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; double time_diff = 0; 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("[fork1][CP][Error]before CPD"); //CPD: ChargeParameterDiscoveryRequest //CPD: ChargeParameterDiscovery } ccs->CpState_err = TRUE; } } #else { #ifdef AWCCS if((ccs->CpState != 2) && (ccs->CpState != 3)) { if (ccs->CpState_err == FALSE) { SAVE_SYS_LOG_MSG_EVCOMM("[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("[fork1][CP][Error]before CPD"); //CPD: ChargeParameterDiscoveryRequest //CPD: ChargeParameterDiscovery } ccs->CpState_err = TRUE; } #endif } #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("[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("[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(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(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("[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("[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 <=1) { if (ccs->CpState_err == FALSE) { SAVE_SYS_LOG_MSG_EVCOMM("[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(buf_log_evcomm_fork1, "[fork1][Erorr]CP(%d) Error in state %d(%d)", ccs->CpState, state, ccs->CableCheckPreCountDownDone ); SAVE_SYS_LOG_MSG_EVCOMM(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 Voltage /* //Issues waiting to debug //[CAUTION] This function shall not be used in charging state. if (((int)(ccs->CpVoltage * 10)) != ((int)(ccs->CpVoltage_pre * 10))) { memset(buf, 0, sizeof(buf)); sprintf(buf, "CP Voltage: %.2lf >> %.2lf (%d >> %d)", ccs->CpVoltage_pre, ccs->CpVoltage, (int)(ccs->CpVoltage_pre * 10), (int)(ccs->CpVoltage * 10) ); SAVE_SYS_LOG_MSG_EVCOMM(buf); ccs->CpVoltage_pre = ccs->CpVoltage; } */ //CP State if (ccs->CpState != ccs->CpState_pre) { sprintf(buf_log_evcomm_fork1, "[fork1]CP State: %d >> %d (%.2fV)", ccs->CpState_pre, ccs->CpState, ccs->CpVoltage ); SAVE_SYS_LOG_MSG_EVCOMM(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; unsigned char Statetmp; float TotalTmpVolt; 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(buf, "renice -20 -p %d", tmp); sprintf(buf, "renice -10 -p %d", tmp); system(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)) { usleep(100000); ccs->CpVoltage = ShmInternalComm->AC_CpPositiveVoltage; ccs->CpState = ShmInternalComm->AC_CpPresentState; } #else //CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED { usleep(1000); 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); #ifndef AWCCS Check_CP_State_Error_fork1(ccs); #endif //Updating Plugin status #if (PP_PROTECTION_MECHANISM == ENABLE) if((ccs->CpState >= 2 ) && (ccs->CpState <= 5 ) && (ShmInternalComm->CCSConnectorType>0?((EVCOMM_SYS_INFO.PpVoltage > 1.2)&&(EVCOMM_SYS_INFO.PpVoltage <= 2.4)):((EVCOMM_SYS_INFO.PpVoltage > 0.61)&&(EVCOMM_SYS_INFO.PpVoltage <= 1.185))) ) #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)); }//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; unsigned char Statetmp; 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(buf, "renice -10 -p %d", tmp); system(buf); #endif return; } } TotalTmpVolt = ReadAdcVolt_PP_fork3(); while(1) { TotalTmpVolt = ReadAdcVolt_PP_fork3(); EVCOMM_SYS_INFO.PpVoltage = TotalTmpVolt; if (EVCOMM_SYS_INFO.PpVoltage_pre != EVCOMM_SYS_INFO.PpVoltage) { if((( (ShmInternalComm->CCSConnectorType>0?((EVCOMM_SYS_INFO.PpVoltage > 1.2)&&(EVCOMM_SYS_INFO.PpVoltage <= 2.4)):((EVCOMM_SYS_INFO.PpVoltage > 0.61)&&(EVCOMM_SYS_INFO.PpVoltage <= 1.185))))&&(ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].ConnectorPlugIn==FALSE)) ||(( (ShmInternalComm->CCSConnectorType>0?((EVCOMM_SYS_INFO.PpVoltage <= 1.2)||(EVCOMM_SYS_INFO.PpVoltage > 2.4)):((EVCOMM_SYS_INFO.PpVoltage <= 0.61)||(EVCOMM_SYS_INFO.PpVoltage > 1.185))))&&(ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].ConnectorPlugIn==TRUE))) { // plug-in : CCS1 (0.61 < V <1.185), CCS2 (1.2 < V <2.4) sprintf(buf_log_evcomm_fork3, "[fork3]PP(%.2f >> %.2fV)", EVCOMM_SYS_INFO.PpVoltage_pre, EVCOMM_SYS_INFO.PpVoltage ); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm_fork3); EVCOMM_SYS_INFO.PpVoltage_pre = EVCOMM_SYS_INFO.PpVoltage; } } #if 0 sleep(5); printf("V_pp = %.02f\n", TotalTmpVolt); #endif }//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(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("[fork2] Emergency Stop (due to Connector is plugged out during communication.)"); SAVE_SYS_LOG_MSG_EVCOMM("[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("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(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(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; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; 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("[Error_Monitor]EVSE_Shutdown"); Update_V2G_Flow_Status(Other_Fault); } else if (EVCOMM_SYS_INFO.DC_EVSEStatus == EVSE_EmergencyShutdown) { SAVE_SYS_LOG_MSG_EVCOMM("[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("[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(buf_log_evcomm_fork2, "[fork2]Timeout or Fault State(%d) => End_Process", status); SAVE_SYS_LOG_MSG_EVCOMM(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("[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(buf_log_evcomm_fork2, "[fork2]EVSE Shutdown(%d) => End_Process", EVCOMM_SYS_INFO.DC_EVSEStatus); SAVE_SYS_LOG_MSG_EVCOMM(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("[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(buf_log_evcomm_fork2, "[fork2]Permission OFF before V2G msg(%d) => End_Process", ShmInternalComm->ChargingPermission); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm_fork2); Update_V2G_Flow_Status(Other_Fault); End_Process(); } } #if 0 //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(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(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(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(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(); } } #endif #if 1 //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("[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(); } } #endif //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("[fork2]Unplug Reset => End_Process"); Update_V2G_Flow_Status(Other_Fault); End_Process(); } usleep(100000); }//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, 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("[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); } /*=========================================================================== FUNCTION: GetQca7kMac DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int GetQca7kMac() { int i = 0; 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; i = sendto(RawSock, &SendPacket, 20, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll)); DEBUG_PRINTF_EVCOMM_DETAIL("GetQca7kMac: send size =%d\n", i); SAVE_SYS_LOG_MSG_EVCOMM("[QCA7K][Tx][VENDOR_VS_NW_INFO]Req for QCA7K MacAddr"); } /*=========================================================================== 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(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(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(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(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(buf_log_evcomm, "[SLAC_DB_Add]data does not exist => added to %d-th", SLAC_INFO.arrayLen); DEBUG_PRINTF_EVCOMM_DETAIL(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(buf_log_evcomm, "[ERROR][SLAC_DB_Add]arrayLen: unexpected(%d)", SLAC_INFO.arrayLen); DEBUG_PRINTF_EVCOMM_DETAIL(buf_log_evcomm); SLAC_INFO.arrayLen = 0; } } else { //DB is full sprintf(buf_log_evcomm, "[SLAC_DB_Add]DB is full(%d) => bypass", SLAC_INFO.arrayLen); DEBUG_PRINTF_EVCOMM_DETAIL(buf_log_evcomm); } } else { #if 0 sprintf(buf_log_evcomm, "[SLAC_DB_Add]EvMac: existed (%d)", idx); SAVE_SYS_LOG_MSG_EVCOMM(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("[SLAC_DB_Add]RunID: same"); } else { SAVE_SYS_LOG_MSG_EVCOMM("[SLAC_DB_Add]RunID: diff"); } //Reset all corresponding parameters #if 0 sprintf(buf_log_evcomm, "[SLAC_DB_Add]EvMac: reset para(%d)", idx); SAVE_SYS_LOG_MSG_EVCOMM(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("[SLAC_DB_Reset]DONE"); } /*=========================================================================== 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; unsigned char *EvMac_in; unsigned char *RunID_in; int Rtn = 0; int idx = 0; MmePacket = (struct MmeHeader *)Buffer; state = Check_V2G_Flow_Status(); #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == ENABLE) { DEBUG_PRINTF_EVCOMM_DETAIL("\n\n***********************************\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("[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("[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("[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("[SLAC][Rx]CM_SLAC_PARM_REQ: ignored(in error state)"); break; } //Printing EV MAC Address //SAVE_SYS_LOG_MSG_EVCOMM("[SLAC][Rx]CM_SLAC_PARM_REQ"); //Avoid Coupled SLAC_PARM_REQ if (CheckConnectorPlugIn() == FALSE) //12V(State 1) { #if 0 sprintf(buf_log_evcomm, "[WARNING][SLAC][Rx]CM_SLAC_PARM_REQ: ignored(coupled SLAC,%d)", CheckConnectorPlugIn()); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #endif break; } //[TC_SECC_VTB_CmSlacParm_003] SECURITY_TYPE needs to be 0x00 (no security) if (MmePacket->MMENTRY[1] != 0) { sprintf(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(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(buf_log_evcomm, "Check Permission: %d (SLAC first => START)", ShmInternalComm->ChargingPermission); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm, "[WARNING][CM_SLAC_PARM_REQ]DB is full or errors occour(%d) => ignore", idx); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); break; } //Select the 1st EV MAC address if (SLAC_INFO.arrayLen == 1) //1st Req { #if 1 sprintf(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(buf_log_evcomm); #endif /* sprintf(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(buf_log_evcomm); sprintf(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(buf_log_evcomm); */ } else //2nd Req { #if 1 sprintf(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(buf_log_evcomm); #endif /* sprintf(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(buf_log_evcomm); sprintf(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(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("\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); 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("[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(buf_log_evcomm, "[WARNING][SLAC][Rx]CM_START_ATTEN_CHAR_IND: ignored(coupled SLAC,%d)", CheckConnectorPlugIn()); SAVE_SYS_LOG_MSG_EVCOMM(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 + 1); 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); //[TC_SECC_VTB_AttenuationCharacterization_013] if (MmePacket->MMENTRY[0] != 0) //APPLICATION_TYPE must be 0x00(EV-EVSE Matching) { sprintf(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(buf_log_evcomm); break; } //[TC_SECC_VTB_AttenuationCharacterization_014] if (MmePacket->MMENTRY[1] != 0) //SECURITY_TYPE must be 0x00(No Security) { sprintf(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(buf_log_evcomm); break; } //[TC_SECC_VTB_AttenuationCharacterization_016] if (MmePacket->MMENTRY[3] != 0x06) //Time_Out must be 0x06 , (600ms) { sprintf(buf_log_evcomm, "[WARNING][SLAC][Rx][CM_START_ATTEN_CHAR_IND]Time_Out(%d): invalid => ignore Req", MmePacket->MMENTRY[3]); SAVE_SYS_LOG_MSG_EVCOMM(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(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(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(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(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(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(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(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(buf_log_evcomm, "[WARNING][SLAC][Rx][CM_START_ATTEN_CHAR_IND]EvMac-RunID: unmatched => ignore Req"); SAVE_SYS_LOG_MSG_EVCOMM(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("[WARNING][SLAC][Rx]CM_MNBC_SOUND_IND: ignored(timeup)"); break; } //Avoid Coupled CM_MNBC_SOUND_IND if (CheckConnectorPlugIn() == FALSE) //12V(State 1) { sprintf(buf_log_evcomm, "[WARNING][SLAC][Rx]CM_MNBC_SOUND_IND: ignored(coupled SLAC,%d)", CheckConnectorPlugIn()); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); break; } #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == TRUE) { DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_MNBC_SOUND_IND (counter : %d/%d) ---\n",counter + 1 , 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); //Check for RunID if (SLAC_DB_Check_EvMac_RunID_Matching(&SLAC_INFO, EvMac_in, RunID_in) == TRUE) { SLAC_INFO.array[idx].MnbcSoundCnt++; /* sprintf(buf_log_evcomm, "[SLAC][Rx]CM_MNBC_SOUND_IND[%d]:%d-th", (idx + 1), SLAC_INFO.array[idx].MnbcSoundCnt); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); */ } else { //RunID is not matched or does not exist. sprintf(buf_log_evcomm, "[WARNING][SLAC][Rx]CM_MNBC_SOUND_IND]EvMac-RunID: unmatched"); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); } } else { //ignore sprintf(buf_log_evcomm, "[WARNING][SLAC][Rx]CM_MNBC_SOUND_IND]EvMac does not exist"); SAVE_SYS_LOG_MSG_EVCOMM(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("[WARNING][SLAC][Rx]CM_ATTEN_PROFILE_IND: ignore(timeup)"); break; } #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == TRUE) { DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_ATTEN_PROFILE_IND (counter : %d/%d) ---\n", counter, 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]); DEBUG_PRINTF_EVCOMM_DETAIL("AAG: \n"); for(Rtn = 0; Rtn < MmePacket->MMENTRY[6]; Rtn++) { DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",MmePacket->MMENTRY[8 + Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("\n"); } #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(buf_log_evcomm, "[SLAC][Rx]CM_ATTEN_PROFILE_IND[%d]:%d-th", (idx + 1), SLAC_INFO.array[idx].AttenProfileCnt); SAVE_SYS_LOG_MSG_EVCOMM(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(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(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]); DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ID: \n"); for(Rtn = 0; Rtn < 17; Rtn++) { DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",MmePacket->MMENTRY[16 + Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("\n"); DEBUG_PRINTF_EVCOMM_DETAIL("RESP_ID: \n"); for(Rtn = 0; Rtn < 17; Rtn++) { DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",MmePacket->MMENTRY[33 + Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("\n"); 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("[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(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(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("[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(buf_log_evcomm, "[SLAC][Rx]CM_ATTEN_CHAR_RSP[%d]:%d-th", (idx + 1), SLAC_INFO.array[idx].AttenCharRspCnt); SAVE_SYS_LOG_MSG_EVCOMM(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(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(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("[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(buf_log_evcomm, "[SLAC][Rx]CM_VALIDATE_REQ[%d]:%d-th", (idx + 1), SLAC_INFO.array[idx].ValidateReqCnt); SAVE_SYS_LOG_MSG_EVCOMM(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))||(EVCOMM_SYS_INFO.CpState == 1)) { 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) if(ToggleNum==0) SendMmePacket.MMENTRY[SendMmePacketSize++] = 3; //0x02 = Failure else 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("[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("[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(buf_log_evcomm, "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]:%d-th", (idx + 1), SLAC_INFO.array[idx].MatchReqNum); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm, "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]:wrong APPLICATION_TYPE(%d)", (idx + 1), MmePacket->MMENTRY[0]); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm, "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]:wrong SECURITY_TYPE(%d)", (idx + 1), MmePacket->MMENTRY[1]); SAVE_SYS_LOG_MSG_EVCOMM(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(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(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(buf_log_evcomm, "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]: wrong EV ID", (idx + 1)); SAVE_SYS_LOG_MSG_EVCOMM(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(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(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(buf_log_evcomm, "[SLAC][Rx]CM_SLAC_MATCH_REQ[%d]: wrong EVSE ID", (idx + 1)); SAVE_SYS_LOG_MSG_EVCOMM(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(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(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(buf_log_evcomm, "[SLAC][Tx]CM_SLAC_MATCH_CNF[%d]", (idx + 1)); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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("[SLAC][Tx]CM_SLAC_MATCH_CNF"); ftime(&SeqStartTime); break; } #endif } case MMTYPE_CM_AMP_MAP_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 //Check ODA (Destination Address) if (Array_Compare_Identity(CsuMac, MmePacket->ODA, SLAC_EVSE_MAC_LENGTH) == FALSE) { SAVE_SYS_LOG_MSG_EVCOMM("[SLAC][Rx][CM_AMP_MAP_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_AMP_MAP_REQ); SLAC_INFO.array[idx].MatchReqNum++; sprintf(buf_log_evcomm, "[SLAC][Rx]CM_AMP_MAP_REQ[%d]:%d-th", (idx + 1), SLAC_INFO.array[idx].MatchReqNum); SAVE_SYS_LOG_MSG_EVCOMM(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] != 0x3A)||(MmePacket->MMENTRY[1] != 0)) { sprintf(buf_log_evcomm, "[SLAC][Rx]CM_AMP_MAP_REQ[%d]:wrong AMLEN(%d)", (idx + 1), MmePacket->MMENTRY[0]); SAVE_SYS_LOG_MSG_EVCOMM(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_AMP_MAP_CNF; SendMmePacket.FMI[0] = SendMmePacket.FMI[1] = 0; SendMmePacketSize = 0; SendMmePacket.MMENTRY[SendMmePacketSize++] = 0x00; //success Update_V2G_Flow_Status(CM_AMP_MAP_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(buf_log_evcomm, "[SLAC][Tx]CM_AMP_MAP_CNF[%d]", (idx + 1)); SAVE_SYS_LOG_MSG_EVCOMM(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("[CM_SLAC_MATCH_REQ]No Real MATCH_REQ"); SLAC_DB_Reset(); } } else { //OSA(EvMac) does not exist } break; } 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: { struct QcaVendorMmeHeader *RecvPacket; RecvPacket = (struct QcaVendorMmeHeader *)Buffer; memcpy(QcaMac, RecvPacket->OSA, 6); sprintf(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(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(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(buf_log_evcomm); Update_V2G_Flow_Status(Other_Fault); } else Update_V2G_Flow_Status(CM_SET_KEY_REQ); ftime(&SeqStartTime); break; } default: { break; } } } /*=========================================================================== FUNCTION: SlacComm DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int SlacComm() { static unsigned char qca7k_comm_retry = 0; unsigned char *EvMac_in; unsigned char *RunID_in; double t_diff = 0; int packet_size = 0; int count = 0; int idx = 0; int i = 0; 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;countSysInfo.SystemAmbientTemp=RawSock; if (setsockopt(RawSock, SOL_SOCKET, SO_BINDTODEVICE, QcaInterface, 4) < 0) { SAVE_SYS_LOG_MSG_EVCOMM("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("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("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("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("[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(buf_log_evcomm, "[QCA7K]re-try connecting...(%.02lf/%dms)", t_diff, V2G_SECC_QCA7000_GET_MAC_ADDR_REQ_RETRY_PERIOD); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); GetQca7kMac(); //re-send req ftime(&SeqStartTime); break; } else { //null } //Retry by 3 times if (qca7k_comm_retry >= 3) { sprintf(buf_log_evcomm, "[QCA7K][Error]comm: fail (retry by %d times)", qca7k_comm_retry); SAVE_SYS_LOG_MSG_EVCOMM(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 = TRUE; 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) > ((CCS_ENERGY_TRANSFER_MODE<=1)?20:TT_EVSE_SLAC_init)) { sprintf(buf_log_evcomm, "SlacComm: Wait CM_SLAC_PARM_REQ Timeout - TT_EVSE_SLAC_init, NowTime(%d)-PwmStartTime(%d)>%d (sec)", time(NULL), PwmStartTime, TT_EVSE_SLAC_init); SAVE_SYS_LOG_MSG_EVCOMM(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("[QCA7K][Rx]CM_SET_KEY_REQ"); ftime(&SeqEndTime); t_diff = DiffTimeb(SeqStartTime, SeqEndTime); if (t_diff > V2G_SECC_QCA7000_COMM_TIMEOUT) //10 seconds { sprintf(buf_log_evcomm, "[QCA7K]Failed on SetKey => End_Process (%.02lf/%dms)", t_diff, V2G_SECC_QCA7000_COMM_TIMEOUT); SAVE_SYS_LOG_MSG_EVCOMM(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 = TRUE; 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(buf_log_evcomm, "[QCA7K]SetKey: proceed (%.02lf/%dms)", t_diff, V2G_SECC_QCA7000_SEND_SET_KEY_PERIOD); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); SendSetKey(); ftime(&SeqStartTime); } else { //null } break; } case CM_SET_KEY_CNF: //14 { sprintf(buf_log_evcomm, "[SECCReady]Wait: plugin(%d), matached(%d), permission(%d)...", CheckConnectorPlugIn(), CSUCOMMDC_TASK_FLAG.matched, ShmInternalComm->ChargingPermission ); SAVE_SYS_LOG_MSG_EVCOMM(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(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(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 = TRUE; 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(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(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 = TRUE; 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(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(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(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(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(buf_log_evcomm, "[NOTE][SLAC][Tx]CM_ATTEN_CHAR_IND[%d]: canceled", (i + 1)); SAVE_SYS_LOG_MSG_EVCOMM(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 == TRUE) { 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]); DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ID: \n"); for(count=0; count<17; count++) { DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[16+count]); } DEBUG_PRINTF_EVCOMM_DETAIL("\n"); DEBUG_PRINTF_EVCOMM_DETAIL("RESP_ID: \n"); for(count=0; count<17; count++) { DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[33+count]); } DEBUG_PRINTF_EVCOMM_DETAIL("\n"); DEBUG_PRINTF_EVCOMM_DETAIL("NumSounds: 0x%x\n", SendMmePacket.MMENTRY[50]); DEBUG_PRINTF_EVCOMM_DETAIL("ATTEN_PROFILE: \n"); for(count=0; count 0) { sprintf(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(buf_log_evcomm); } else if (EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry == 0) { sprintf(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(buf_log_evcomm); } else { sprintf(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(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(TmpBuf,"SlacComm: bad Aag[%d]=%d",count,TmpAag); SAVE_SYS_LOG_MSG_EVCOMM(TmpBuf); } */ printf("%d,", TmpAag); TmpAag = 37; } #endif #endif SendMmePacket.MMENTRY[SendMmePacketSize++] = TmpAag; } SendMmePacketSize += 19; //the size before MMENTRY #if (DEBUG_PRINTF_EVCOMM_DETAIL_SHOW == TRUE) { 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]); DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ID: \n"); for(count=0; count<17; count++) { DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[16+count]); } DEBUG_PRINTF_EVCOMM_DETAIL("\n"); DEBUG_PRINTF_EVCOMM_DETAIL("RESP_ID: \n"); for(count=0; count<17; count++) { DEBUG_PRINTF_EVCOMM_DETAIL("%02x, ",SendMmePacket.MMENTRY[33+count]); } DEBUG_PRINTF_EVCOMM_DETAIL("\n"); DEBUG_PRINTF_EVCOMM_DETAIL("NumSounds: 0x%x\n", SendMmePacket.MMENTRY[50]); DEBUG_PRINTF_EVCOMM_DETAIL("ATTEN_PROFILE: \n"); for(count=0; count 0) { sprintf(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(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. { // Alston - 2022/07/05 : Fix can't resend Atten_char_ind problem if(EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry < 2) { EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry++; Update_V2G_Flow_Status(CM_MNBC_SOUND_IND); } else { sprintf(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(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 = TRUE; 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(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(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 = TRUE; 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(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(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 = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Flow_Status(Sequence_Timeout); return -1; } break; } case CM_AMP_MAP_CNF: 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("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(buf_log_evcomm, "[ERROR = %d (DEC)]V2gMsgDecoder: API_V2GMSG_EXI_Decoder_DIN()", errn); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm, "[ERROR = %d (DEC)]V2gMsgDecoder: API_V2GMSG_EXI_Decoder_ISO1()", errn); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm, "[ERROR = %d (DEC)]V2gMsgDecoder: API_V2GMSG_EXI_Decoder_ISO2()", errn); SAVE_SYS_LOG_MSG_EVCOMM(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; #ifdef SUPPORT_TLS_CONNECTION if(EvSecurity == 0)//support security { rtn = SSL_write(ssl, v2g_tx_stream->data, v2g_tx_stream->size); } else { rtn = send(AcceptFd, v2g_tx_stream->data, v2g_tx_stream->size, 0); } #else rtn = send(AcceptFd, v2g_tx_stream->data, v2g_tx_stream->size, 0); #endif 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; #ifdef SUPPORT_TLS_CONNECTION if(EvSecurity == 0)//support security { rtn = SSL_write(ssl, v2g_tx_stream->data, v2g_tx_stream->size); } else { rtn = send(AcceptFd, v2g_tx_stream->data, v2g_tx_stream->size, 0); } #else rtn = send(AcceptFd, v2g_tx_stream->data, v2g_tx_stream->size, 0); #endif 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; #ifdef SUPPORT_TLS_CONNECTION if(EvSecurity == 0)//support security { rtn = SSL_write(ssl, v2g_tx_stream->data, v2g_tx_stream->size); } else { rtn = send(AcceptFd, v2g_tx_stream->data, v2g_tx_stream->size, 0); } #else rtn = send(AcceptFd, v2g_tx_stream->data, v2g_tx_stream->size, 0); #endif 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(buf_log_evcomm, "[ERROR]SessionID: incorrect length(%d)", leng); SAVE_SYS_LOG_MSG_EVCOMM(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(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(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(buf_log_evcomm, "[ERROR]SessionID: incorrect length(%d)", leng); SAVE_SYS_LOG_MSG_EVCOMM(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(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(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(buf_log_evcomm, "[ERROR]SessionID: incorrect length(%d)", leng); SAVE_SYS_LOG_MSG_EVCOMM(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(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(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 urn:din:70121:2012:MsgDef //[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(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(buf_log_evcomm); #ifdef AWCCS continue; #endif if (target == V2GT_MSG_PROTOCOL_DIN70121) { sprintf(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(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(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(buf_log_evcomm); if (target == V2GT_MSG_PROTOCOL_ISO15118_2014) { sprintf(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(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(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(buf_log_evcomm); if (target == V2GT_MSG_PROTOCOL_ISO15118_2018) { sprintf(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(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(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(buf_log_evcomm); //return -1; } } else { sprintf(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(buf_log_evcomm); //return -1; } } //The final result of highest priority protocol sprintf(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(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(buf_log_evcomm, "[Error]No avalible CCS protocol (id = %d, preference = %d)", id, V2GT_MSG_PROTOCOL_PREFERENCE); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); } else { //selected SchemaID ccs_handshake.supportedAppProtocolRes.SchemaID = (unsigned char) id; } if (sys->DC_EVSEStatus == EVSE_Shutdown) { SAVE_SYS_LOG_MSG_EVCOMM("[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("[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("[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(buf_log_evcomm, "[Proc_supportedAppProtocolRes]Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm, "[Proc_supportedAppProtocolRes]Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); SAVE_SYS_LOG_MSG_EVCOMM(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; #ifdef SUPPORT_TLS_CONNECTION if(EvSecurity == 0)//support security { Rtn = SSL_write(ssl, v2g_tx_stream.data, v2g_tx_stream.size); } else { Rtn = send(AcceptFd, v2g_tx_stream.data, v2g_tx_stream.size, 0); } #else Rtn = send(AcceptFd, v2g_tx_stream.data, v2g_tx_stream.size, 0); #endif //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("[V2G][Rx]supportedAppProtocolReq"); SHM_Save_din_supportedAppProtocolReq(ShmCcsData, &ccs_handshake, ShmSysConfigAndInfo); errn = Proc_supportedAppProtocolRes(AcceptFd); if (errn == 0) { SAVE_SYS_LOG_MSG_EVCOMM("[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("[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(buf_log_evcomm, "[Proc_din_SessionSetupRes]Emergency Stop by CP Error (%d)\n", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #else sprintf(buf_log_evcomm, "[Proc_din_SessionSetupRes]Emergency Stop by CP Error (%d): ignored\n", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(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(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(buf_log_evcomm); errn = -1; } else if (sys->DC_EVSEStatus == EVSE_Shutdown/* || sys->DC_EVSEStatus == EVSE_EmergencyShutdown*/) { ccs_exi_doc_DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = dinresponseCodeType_FAILED; sprintf(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(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("[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("[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("[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 //Benz already CP=4 if ((sys->CpState < 2) ||(sys->CpState > 5)) //State B1, B2 //Benz already CP=4 { #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(buf_log_evcomm, "[Proc_iso1_SessionSetupRes]Emergency Stop by CP Error (%d)\n", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #else sprintf(buf_log_evcomm, "[Proc_iso1_SessionSetupRes]Emergency Stop by CP Error (%d): ignored\n", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(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(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(buf_log_evcomm); errn = -1; } else if (sys->DC_EVSEStatus == EVSE_Shutdown /*|| sys->DC_EVSEStatus == EVSE_EmergencyShutdown*/) { ccs_exi_doc_ISO1.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_FAILED; sprintf(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(buf_log_evcomm); // errn = -1; } //Check for Permission Changing from TRUE to FALSE if (ShmInternalComm->ChargingPermission_pre >=1 && ShmInternalComm->ChargingPermission == FALSE) { SAVE_SYS_LOG_MSG_EVCOMM("[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("[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("[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(buf_log_evcomm, "[Proc_iso2_SessionSetupRes]Emergency Stop by CP Error (%d)", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #else sprintf(buf_log_evcomm, "[Proc_iso2_SessionSetupRes]Emergency Stop by CP Error (%d): ignored", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(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(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(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("[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("[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("[DIN][V2G][Tx]SessionSetupRes"); } else { sprintf(buf_log_evcomm, "[Error]Proc_din_SessionSetupRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[ISO1][V2G][Tx]SessionSetupRes"); } else { sprintf(buf_log_evcomm, "[Error]Proc_iso1_SessionSetupRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[ISO2][V2G][Tx]SessionSetupRes"); } else { sprintf(buf_log_evcomm, "[Error]Proc_iso2_SessionSetupRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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(buf_log_evcomm, "[Proc_din_ServiceDiscoveryRes]Emergency Stop by CP Error (%d)", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #else sprintf(buf_log_evcomm, "[Proc_din_ServiceDiscoveryRes]Emergency Stop by CP Error (%d): ignored", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(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("[Proc_din_ServiceDiscoveryRes]shutdown by EVSE"); // errn = -1; } else 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("[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("[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("[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("[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(buf_log_evcomm, "[Proc_iso1_ServiceDiscoveryRes]Emergency Stop by CP Error (%d)", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #else sprintf(buf_log_evcomm, "[Proc_iso1_ServiceDiscoveryRes]Emergency Stop by CP Error (%d): ignored", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(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("[Proc_iso1_ServiceDiscoveryRes]shutdown by EVSE"); errn = -1; } else 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("[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("[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 #ifdef SUPPORT_ISO15118_PnC ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.PaymentOptionList.PaymentOption.arrayLen = 2u; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.PaymentOptionList.PaymentOption.array[1] = iso1paymentOptionType_Contract; //0 #endif //[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; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceName.charactersLen = strlen("AC_DC_Charging");//AC_Charging writeStringToEXIString("AC_DC_Charging", ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceName.characters); ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceCategory = iso1serviceCategoryType_EVCharging; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.FreeService = 1; 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: { ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.array[0] = iso1EnergyTransferModeType_DC_extended; sprintf(buf_log_evcomm, "[ISO1][ServiceDiscoveryRes][Warning]unexpected EnergyTransferMode(%d)", ShmCcsData->EnergyTransferMode); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); break; } } //[4/4] Service List i=0; #ifdef SUPPORT_ISO15118_PnC ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList_isUsed = 1u; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.arrayLen=i; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].ServiceID = 2; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].ServiceName_isUsed = 1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].ServiceName.charactersLen = strlen("Certificate"); writeStringToEXIString("Certificate", ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].ServiceName.characters); ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].ServiceCategory = iso1serviceCategoryType_ContractCertificate; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].FreeService = 0; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.arrayLen++; i++; #endif #ifdef SUPPORT_ISO15118_VAS ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList_isUsed = 1u; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.arrayLen=i; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].ServiceID = 3; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].ServiceName_isUsed = 1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].ServiceName.charactersLen = strlen("InternetAccess"); writeStringToEXIString("InternetAccess", ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].ServiceName.characters); ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].ServiceCategory = iso1serviceCategoryType_Internet; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].FreeService = 0; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.arrayLen++; i++; #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_iso1_ServiceDetailReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_iso1_ServiceDetailReq(int AcceptFd) { int errn = 0; //Save into Share Memory SHM_Save_iso1_ServiceDetailReq(ShmCcsData, &ccs_exi_doc_ISO1, ShmSysConfigAndInfo); errn = Proc_iso1_ServiceDetailRes(AcceptFd); if (errn == 0) { //send response successfully. SAVE_SYS_LOG_MSG_EVCOMM("[ISO1][V2G][Tx]ServiceDetailRes"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_iso1_ServiceDetailReq]Proc_iso1_ServiceDetailRes(): %d (DEC)", errn ); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); } return errn; } /*=========================================================================== FUNCTION: Proc_iso1_ServiceDetailRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_iso1_ServiceDetailRes(int AcceptFd) { int i = 0; int errn = 0; bitstream_t v2g_tx_stream; struct ChargingInfoData *sys; struct ServiceDetailRequest_ISO15118_2014 *req; struct ServiceDetailResponse_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.ServiceDetailRequest; res = &ShmCcsData->V2GMessage_ISO15118_2014.ServiceDetailResponse; init_iso1BodyType(&ccs_exi_doc_ISO1.V2G_Message.Body); init_iso1ServiceDetailResType(&ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes); //[1/4] Response Code ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes_isUsed = 1u; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.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.ServiceDetailRes.ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 SAVE_SYS_LOG_MSG_EVCOMM("[ERROR]unmatched SessionID => End_Process"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 SAVE_SYS_LOG_MSG_EVCOMM("[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.ServiceDetailRes.ResponseCode = iso1responseCodeType_FAILED; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Flow_Status(Other_Fault); errn = -1; sprintf(buf_log_evcomm, "[ServiceDetailRes]Emergency Stop by CP Error (%d)", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #else sprintf(buf_log_evcomm, "[ServiceDetailRes]Emergency Stop by CP Error (%d): ignored", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #endif } if (/*sys->DC_EVSEStatus == EVSE_Shutdown ||*/ sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ResponseCode = iso1responseCodeType_FAILED; SAVE_SYS_LOG_MSG_EVCOMM("[ServiceDetailRes]shutdown by EVSE"); errn = -1; } else if (sys->DC_EVSEStatus == EVSE_Shutdown /*|| sys->DC_EVSEStatus == EVSE_EmergencyShutdown*/) { ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ResponseCode = iso1responseCodeType_FAILED; SAVE_SYS_LOG_MSG_EVCOMM("[ServiceDetailRes]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("[Error][ISO1][ServiceDetailRes]Permission OFF"); ccs_exi_doc_DIN.V2G_Message.Body.ServiceDetailRes.ResponseCode = iso1responseCodeType_FAILED; // errn = -1; } switch (req->ServiceID) { #ifdef SUPPORT_ISO15118_PnC case 2: ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceID = req->ServiceID; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList_isUsed = 1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.arrayLen = 2;//Installation(1), Update(2) //=============Set ParameterSet=================== { unsigned char ServiceName[16]; for(int j=0;j0) { ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].ParameterSetID=j+1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.arrayLen=1;//Service //Name= Protocol ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[0].Name.charactersLen= strlen("Service"); writeStringToEXIString("Service", ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[0].Name.characters); ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[0].stringValue_isUsed=1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[0].stringValue.charactersLen=strlen(ServiceName); writeStringToEXIString(ServiceName, ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[0].stringValue.characters); } else break; }//for } break; #endif #ifdef SUPPORT_ISO15118_VAS case 3: ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceID = req->ServiceID; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList_isUsed = 1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.arrayLen = 4;//ftp(1), ftp(2), http(3), https(4) //=============Set ParameterSet=================== { unsigned char ProtocolName[16]; int ProtocolPort; for(int j=0;j0) { ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].ParameterSetID=j+1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.arrayLen=2;//protocol and port //Name= Protocol ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[0].Name.charactersLen= strlen("Protocol"); writeStringToEXIString("Protocol", ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[0].Name.characters); ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[0].stringValue_isUsed=1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[0].stringValue.charactersLen=strlen(ProtocolName); writeStringToEXIString(ProtocolName, ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[0].stringValue.characters); //Name= Port ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[1].Name.charactersLen= strlen("Port"); writeStringToEXIString("Port", ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[1].Name.characters); ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[1].intValue_isUsed=1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[j].Parameter.array[1].intValue=ProtocolPort; } else break; }//for } /* //=============http,ParameterSetID=3=================== ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].ParameterSetID=3;//http ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.arrayLen=2;//protocol and port //Name= Protocol, value= "HTTP" ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.charactersLen= strlen("Protocol"); writeStringToEXIString("Protocol", ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters); ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].stringValue_isUsed=1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].stringValue.charactersLen=strlen("http"); writeStringToEXIString("http", ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].stringValue.characters); //Name= Port, value= 80 ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.charactersLen= strlen("Port"); writeStringToEXIString("Port", ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters); ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].intValue_isUsed=1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].intValue=80; //==================https,ParameterSetID=4===================== ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].ParameterSetID=4;//https ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.arrayLen=2;//protocol and port //Name= Protocol, value= "HTTP" ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.charactersLen= strlen("Protocol"); writeStringToEXIString("Protocol", ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters); ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].stringValue_isUsed=1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].stringValue.charactersLen=strlen("https"); writeStringToEXIString("https", ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].stringValue.characters); //Name= Port, value= 443 ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[1].Name.charactersLen= strlen("Port"); writeStringToEXIString("Port", ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[1].Name.characters); ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[1].intValue_isUsed=1; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[1].intValue=443; */ break; #endif default: ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceID = req->ServiceID; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ServiceParameterList_isUsed = 0; ccs_exi_doc_ISO1.V2G_Message.Body.ServiceDetailRes.ResponseCode = iso1responseCodeType_FAILED_ServiceIDInvalid; break; } // ============ 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("[DIN][V2G][Tx]ServiceDiscoveryRes"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_din_ServiceDiscoveryReq]Proc_din_ServiceDiscoveryRes(): %d (DEC)", errn ); SAVE_SYS_LOG_MSG_EVCOMM(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("\n[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("[ISO1][V2G][Tx]ServiceDiscoveryRes"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_iso1_ServiceDiscoveryReq]Proc_iso1_ServiceDiscoveryRes(): %d (DEC)", errn ); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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 != dinpaymentOptionType_ExternalPayment) //1 { ccs_exi_doc_DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED_PaymentSelectionInvalid; sprintf(buf_log_evcomm, "[ERROR]unexpected SelectedPaymentOption(%d) => End_Process (EIM only, no PnC, yet.)", req->SelectedPaymentOption); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm, "[ERROR]Wrong selected ServiceID(%d) => End_Process", req->SelectedServiceList.SelectedService[0].ServiceID); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm, "[Proc_din_ServiceAndPaymentSelectionRes]Emergency Stop by CP Error (%d)", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #else sprintf(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(buf_log_evcomm); #endif } if (sys->DC_EVSEStatus == EVSE_Shutdown /*|| sys->DC_EVSEStatus == EVSE_EmergencyShutdown*/) { SAVE_SYS_LOG_MSG_EVCOMM("[Proc_din_ServiceAndPaymentSelectionRes]shutdown by EVSE"); ccs_exi_doc_DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED; // errn = -1; } else if (/*sys->DC_EVSEStatus == EVSE_Shutdown ||*/ sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { SAVE_SYS_LOG_MSG_EVCOMM("[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("[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("[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("[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("[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; } #ifdef SUPPORT_ISO15118_PnC if (req->SelectedPaymentOption > iso1paymentOptionType_ExternalPayment) //1 { ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_PaymentSelectionInvalid; sprintf(buf_log_evcomm, "[ERROR]unexpected SelectedPaymentOption(%d) => End_Process (EIM only, no PnC, yet.)", req->SelectedPaymentOption); SAVE_SYS_LOG_MSG_EVCOMM(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; } #else //Check for SelectedPaymentOption (TC_SECC_VTB_ServicePaymentSelection_007) if (req->SelectedPaymentOption != iso1paymentOptionType_ExternalPayment) //1 { ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_PaymentSelectionInvalid; sprintf(buf_log_evcomm, "[ERROR]unexpected SelectedPaymentOption(%d) => End_Process (EIM only, no PnC, yet.)", req->SelectedPaymentOption); SAVE_SYS_LOG_MSG_EVCOMM(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; } #endif for(i=0;iSelectedServiceList.SelectedServiceLen;i++) { switch(req->SelectedServiceList.SelectedService[i].ServiceID) { case 1: break; case 2: #ifndef SUPPORT_ISO15118_PnC ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_ServiceSelectionInvalid; //8 sprintf(buf_log_evcomm, "[ERROR]Wrong selected ServiceID(%d) => End_Process", req->SelectedServiceList.SelectedService[0].ServiceID); SAVE_SYS_LOG_MSG_EVCOMM(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; #endif break; case 3: #ifndef SUPPORT_ISO15118_VAS ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_ServiceSelectionInvalid; //8 sprintf(buf_log_evcomm, "[ERROR]Wrong selected ServiceID(%d) => End_Process", req->SelectedServiceList.SelectedService[0].ServiceID); SAVE_SYS_LOG_MSG_EVCOMM(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; #endif break; default: ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_ServiceSelectionInvalid; //8 sprintf(buf_log_evcomm, "[ERROR]Wrong selected ServiceID(%d) => End_Process", req->SelectedServiceList.SelectedService[0].ServiceID); SAVE_SYS_LOG_MSG_EVCOMM(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; break; } } //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(buf_log_evcomm, "[Proc_iso1_ServiceAndPaymentSelectionRes]Emergency Stop by CP Error (%d)", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #else sprintf(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(buf_log_evcomm); #endif } if (sys->DC_EVSEStatus == EVSE_Shutdown /*|| sys->DC_EVSEStatus == EVSE_EmergencyShutdown*/) { SAVE_SYS_LOG_MSG_EVCOMM("[Proc_iso1_ServiceAndPaymentSelectionRes]shutdown by EVSE"); ccs_exi_doc_ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED; //errn = -1; } else if (/*sys->DC_EVSEStatus == EVSE_Shutdown ||*/ sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { SAVE_SYS_LOG_MSG_EVCOMM("[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("[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("[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("[DIN][V2G][Tx]ServiceAndPaymentSelectionRes"); } else { sprintf(buf_log_evcomm, "[Error][Proc_iso1_ServiceAndPaymentSelectionReq]Proc_iso1_ServiceAndPaymentSelectionRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[ISO1][V2G][Tx]ServiceAndPaymentSelectionRes"); } else { sprintf(buf_log_evcomm, "[Error][Proc_iso1_ServiceAndPaymentSelectionReq]Proc_iso1_ServiceAndPaymentSelectionRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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(buf_log_evcomm, "[Proc_din_ContractAuthenticationRes]Emergency Stop by CP Error (%d)", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(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("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("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("[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("[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("[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("[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(buf_log_evcomm, "[Proc_iso1_AuthorizationRes]Emergency Stop by CP Error (%d)", sys->CpState); SAVE_SYS_LOG_MSG_EVCOMM(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("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("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("[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("[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("[DIN][V2G][Tx]ContractAuthenticationRes"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_din_ContractAuthenticationReq]Proc_iso1_AuthenticationRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("\n[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("[ISO1][V2G][Tx]AuthorizationRes"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_iso1_AuthenticationReq]Proc_iso1_AuthenticationRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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) || (sys->EvBatteryMaxVoltage<150) ) { sprintf(buf_log_evcomm, "[ERROR]EvBatteryMaxCurrent is negative(%.02f) => End_Process", sys->EvBatteryMaxCurrent); SAVE_SYS_LOG_MSG_EVCOMM(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, MIN_SUPPORTED_CURRENT*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 != dinEVSESupportedEnergyTransferType_DC_extended) { sprintf(buf_log_evcomm, "[ERROR]Wrong EVRequestedEnergyTransferType(%d,%d)", req->EVRequestedEnergyTransferType, dinEVSESupportedEnergyTransferType_DC_extended); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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(buf_log_evcomm, "[Proc_din_ChargeParameterDiscoveryRes]Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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("[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("[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; } /* printf("req->RequestedEnergyTransferMode=%d\n",req->RequestedEnergyTransferMode); printf("req->AC_EVChargeParameter.DepartureTime=%d\n",req->AC_EVChargeParameter.DepartureTime); printf("req->AC_EVChargeParameter.EAmount.Multiplier=%d\n",req->AC_EVChargeParameter.EAmount.Multiplier); printf("req->AC_EVChargeParameter.EAmount.Unit=%d\n",req->AC_EVChargeParameter.EAmount.Unit); printf("req->AC_EVChargeParameter.EAmount.Value=%d\n",req->AC_EVChargeParameter.EAmount.Value); printf("req->AC_EVChargeParameter.EVMaxVoltage.Multiplier=%d\n",req->AC_EVChargeParameter.EVMaxVoltage.Multiplier); printf("req->AC_EVChargeParameter.EVMaxVoltage.Unit=%d\n",req->AC_EVChargeParameter.EVMaxVoltage.Unit); printf("req->AC_EVChargeParameter.EVMaxVoltage.Value=%d\n",req->AC_EVChargeParameter.EVMaxVoltage.Value); printf("req->AC_EVChargeParameter.EVMaxCurrent.Multiplier=%d\n",req->AC_EVChargeParameter.EVMaxCurrent.Multiplier); printf("req->AC_EVChargeParameter.EVMaxCurrent.Unit=%d\n",req->AC_EVChargeParameter.EVMaxCurrent.Unit); printf("req->AC_EVChargeParameter.EVMaxCurrent.Value=%d\n",req->AC_EVChargeParameter.EVMaxCurrent.Value); printf("req->AC_EVChargeParameter.EVMinCurrent.Multiplier=%d\n",req->AC_EVChargeParameter.EVMinCurrent.Multiplier); printf("req->AC_EVChargeParameter.EVMinCurrent.Unit=%d\n",req->AC_EVChargeParameter.EVMinCurrent.Unit); printf("req->AC_EVChargeParameter.EVMinCurrent.Value=%d\n",req->AC_EVChargeParameter.EVMinCurrent.Value);*/ if(req->RequestedEnergyTransferMode <= 1)//0 for 1P, 1 for 3P { //AC parameters SAVE_SYS_LOG_MSG_EVCOMM("[Proc_iso1_ChargeParameterDiscoveryRes]AC charging"); //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); SAVE_PhysicalValueType_ISO15118_2014(&ac_para->EVSEMaxCurrent, (int) (ShmInternalComm->AC_EVSEMaxCurrent * 10), A_ISO15118_2014); } else { //DC parameters SAVE_SYS_LOG_MSG_EVCOMM("[Proc_iso1_ChargeParameterDiscoveryRes]DC charging"); //[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(buf_log_evcomm, "[ERROR]EvBatteryMaxCurrent/MaxVolatge is mismatch(current=%.02f, voltage=%.02f) => End_Process", sys->EvBatteryMaxCurrent,sys->EvBatteryMaxVoltage); SAVE_SYS_LOG_MSG_EVCOMM(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, MIN_SUPPORTED_CURRENT*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 #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 //Check for CSU command of "Stop by EVSE" if (sys->DC_EVSEStatus == EVSE_Shutdown) { SAVE_SYS_LOG_MSG_EVCOMM("[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("[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(buf_log_evcomm, "[Proc_iso1_ChargeParameterDiscoveryRes]Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); } #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(buf_log_evcomm, "[ERROR]Unmatched RequestedEnergyTransferMode(%d,%d)", req->RequestedEnergyTransferMode, ShmCcsData->EnergyTransferMode); SAVE_SYS_LOG_MSG_EVCOMM(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 Permission from CSU if(ShmInternalComm->ChargingPermission == TRUE) { res->EVSEProcessing = iso1EVSEProcessingType_Finished; } //Check for Permission Off if (ShmInternalComm->ChargingPermission == FALSE) { SAVE_SYS_LOG_MSG_EVCOMM("[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("[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("[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("[DIN][V2G][Tx]ChargeParameterDiscoveryRes"); } else { sprintf(buf_log_evcomm, "[Error][DIN][ChargeParameterDiscoveryRes]%d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[ISO1][V2G][Tx]ChargeParameterDiscoveryRes"); } else { sprintf(buf_log_evcomm, "[Error][ISO1][ChargeParameterDiscoveryRes]%d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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(buf_log_evcomm, "[V2G][CableCheck]Pass (V_now = %.02f, Isolated = %d)", sys->PresentChargingVoltage, sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm, "[WARNING]unexpected IsolationStatus(%d)", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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("[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(buf_log_evcomm, "[Proc_din_CableCheckRes]Undefined Isolation Status(%d)", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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("[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(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(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("[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("[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(buf_log_evcomm, "[V2G][CableCheck]Pass (V_now = %.02f, Isolated = %d)", sys->PresentChargingVoltage, sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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(buf_log_evcomm, "[WARNING]unexpected IsolationStatus(%d)", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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("[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("[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("[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(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(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("[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("[DIN][V2G][Tx]CableCheckRes"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_din_CableCheckReq]Proc_iso1_CableCheckRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[ISO1][V2G][Tx]CableCheckRes"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_iso1_CableCheckReq]Proc_iso1_CableCheckRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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 { #if 0 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(buf_log_evcomm, "[Error][Proc_din_PreChargeRes]IsolationStatus = %d", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #else pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid; //1 #endif } 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("[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(buf_log_evcomm, "[Error][Proc_din_PreChargeRes]IsolationStatus = %d (undefined)", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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("[Error][Proc_din_PreChargeRes]CCS GFD trip => EVSE_Shutdown"); pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault; } else { SAVE_SYS_LOG_MSG_EVCOMM("[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("[Error][Proc_din_PreChargeRes]CCS GFD trip => EVSE_EmergencyShutdown"); pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault; } else { SAVE_SYS_LOG_MSG_EVCOMM("[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("[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(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(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("[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("[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("[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) { #if 0 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(buf_log_evcomm, "[Error][Proc_iso1_PreChargeRes]IsolationStatus = %d", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #else pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid; //1 #endif } 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("[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(buf_log_evcomm, "[Error][Proc_iso1_PreChargeRes]IsolationStatus = %d (undefined)", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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("[Error][Proc_iso1_PreChargeRes]CCS GFD trip => EVSE_Shutdown"); pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault; } else { SAVE_SYS_LOG_MSG_EVCOMM("[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("[Error][Proc_iso1_PreChargeRes]CCS GFD trip => EVSE_EmergencyShutdown"); pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault; } else { SAVE_SYS_LOG_MSG_EVCOMM("[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("[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(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(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("[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("[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("[DIN][V2G][Tx]PreChargeRes"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_din_PreChargeReq]Proc_iso1_PreChargeRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[ISO1][V2G][Tx]PreChargeRes"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_iso1_PreChargeReq]Proc_iso1_PreChargeRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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; errn = -1; } 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("[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("[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; errn = -1; } 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("[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("[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("[DIN][V2G][Tx]PowerDeliveryStartRes"); } else { sprintf(buf_log_evcomm, "[Error][Proc_din_PowerDeliveryStartReq]Proc_iso1_PowerDeliveryStartRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[ISO1][V2G][Tx]PowerDeliveryStartRes"); } else { sprintf(buf_log_evcomm, "[Error][Proc_iso1_PowerDeliveryStartReq]Proc_iso1_PowerDeliveryStartRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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(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(res->MeterInfo.MeterID , CCS_AC_METER_ID); //[MeterInfo][2/5] SigMeterReading (optional) //sprintf(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) { struct ChargingInfoData *sys; sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; if (code != NO_ERROR) //NO_ERROR = 0 { //Asking CSU to Stop switch (code) { /*case dinDC_EVErrorCodeType_NO_ERROR: // = 0, { DEBUG_PRINTF_EXI_ENGINE_DETAIL("(NO_ERROR)"); break; }*/ case dinDC_EVErrorCodeType_FAILED_RESSTemperatureInhibit: // = 1, { //023737 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 3; ShmStatusCodeData->PresentStatusCode[0][5] = 7; DEBUG_PRINTF_EXI_ENGINE_DETAIL("(FAILED_RESSTemperatureInhibit)"); break; } case dinDC_EVErrorCodeType_FAILED_EVShiftPosition: // = 2, {//023738 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 3; ShmStatusCodeData->PresentStatusCode[0][5] = 8; DEBUG_PRINTF_EXI_ENGINE_DETAIL("(FAILED_EVShiftPosition)"); break; } case dinDC_EVErrorCodeType_FAILED_ChargerConnectorLockFault: // = 3, { //023739 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 3; ShmStatusCodeData->PresentStatusCode[0][5] = 9; DEBUG_PRINTF_EXI_ENGINE_DETAIL("(ChargerConnectorLockFault)"); break; } case dinDC_EVErrorCodeType_FAILED_EVRESSMalfunction: // = 4, { //023740 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 4; ShmStatusCodeData->PresentStatusCode[0][5] = 0; DEBUG_PRINTF_EXI_ENGINE_DETAIL("(FAILED_EVRESSMalfunction)"); break; } case dinDC_EVErrorCodeType_FAILED_ChargingCurrentdifferential: // = 5, { //023741 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 4; ShmStatusCodeData->PresentStatusCode[0][5] = 1; DEBUG_PRINTF_EXI_ENGINE_DETAIL("(FAILED_ChargingCurrentdifferential)"); break; } case dinDC_EVErrorCodeType_FAILED_ChargingVoltageOutOfRange: // = 6, { //023742 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 4; ShmStatusCodeData->PresentStatusCode[0][5] = 2; DEBUG_PRINTF_EXI_ENGINE_DETAIL("(FAILED_ChargingVoltageOutOfRange)"); break; } case dinDC_EVErrorCodeType_Reserved_A: // = 7, { //023983 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; DEBUG_PRINTF_EXI_ENGINE_DETAIL("(Reserved_A)"); break; } case dinDC_EVErrorCodeType_Reserved_B: // = 8, { //023983 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; DEBUG_PRINTF_EXI_ENGINE_DETAIL("(Reserved_B)"); break; } case dinDC_EVErrorCodeType_Reserved_C: // = 9, { //023983 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; DEBUG_PRINTF_EXI_ENGINE_DETAIL("(Reserved_C)"); break; } case dinDC_EVErrorCodeType_FAILED_ChargingSystemIncompatibility:// = 10, { //023743 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 4; ShmStatusCodeData->PresentStatusCode[0][5] = 3; DEBUG_PRINTF_EXI_ENGINE_DETAIL("(FAILED_ChargingSystemIncompatibility)"); break; } case dinDC_EVErrorCodeType_NoData: // = 11 { //023746 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 4; ShmStatusCodeData->PresentStatusCode[0][5] = 6; DEBUG_PRINTF_EXI_ENGINE_DETAIL("(NoData)"); break; } default: { if(sys->EvBatterySoc==100) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 7; ShmStatusCodeData->PresentStatusCode[0][5] = 9; } else { //023983 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; } DEBUG_PRINTF_EXI_ENGINE_DETAIL("([WARNING] Unexpected din EVErrorCode)"); break; } } CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; //Update_V2G_Flow_Status(Other_Fault); //memset(buf_log_evcomm, 0, sizeof(buf_log_evcomm)); sprintf(buf_log_evcomm, "Stop by EV (EVErrorCode = %d (DEC))", code); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); } else { if(Check_V2G_Flow_Status()>=49) { if((sys->EvBatterySoc==100)||(ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryRequest.DC_EVPowerDeliveryParameter.ChargingComplete)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 7; ShmStatusCodeData->PresentStatusCode[0][5] = 9; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE; sprintf(buf_log_evcomm, "Check_EVErrorCode => Stop by EV (EVErrorCode = %d (023979))", code); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); } else if(ShmStatusCodeData->PresentStatusCode[0][1] ==0) { if(!( (ShmInternalComm->ChargingPermission == FALSE)|| (sys->DC_EVSEStatus == EVSE_Shutdown)|| (sys->DC_EVSEStatus == EVSE_EmergencyShutdown))) { //023983 ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; sprintf(buf_log_evcomm, "Check_EVErrorCode => Stop by EV (EVErrorCode = %d (023983))", code); SAVE_SYS_LOG_MSG_EVCOMM(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 i = 0; int errn = 0; bitstream_t v2g_tx_stream; static struct CurrentDemandResponse_DIN70121 *cur; static struct ChargingInfoData *sys; 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("[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("[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(buf_log_evcomm, "[ERROR]EvBatteryMaxCurrent is negative(%.02f) => End_Process", sys->EvBatteryMaxCurrent); SAVE_SYS_LOG_MSG_EVCOMM(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) { #if 0 cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid; //0 cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; sprintf(buf_log_evcomm, "[Error][Proc_din_CurrentDemandRes]IsolationStatus = %d", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); //Update_V2G_Flow_Status(Other_Fault); //errn = -1; #else cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid; //1 #endif } 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("[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(buf_log_evcomm, "[Error][Proc_din_CurrentDemandRes]IsolationStatus = %d(undefined)", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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("[DIN][Error][CurrentDemandRes]CCS GFD trip => EVSE_Shutdown"); cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault; } else { SAVE_SYS_LOG_MSG_EVCOMM("[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("[DIN][Error][CurrentDemandRes]CCS GFD trip => EVSE_EmergencyShutdown"); cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault; } else { SAVE_SYS_LOG_MSG_EVCOMM("[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("[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) { if(sys->CpState <= 1) { 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(buf_log_evcomm, "[CurrentDemand]Emergency Stop by CP Error (%d, %.02f V)", sys->CpState, sys->CpVoltage); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); } else { SAVE_SYS_LOG_MSG_EVCOMM("[DIN][Error][CurrentDemandRes]EVSE Normal Stop"); //cur->ResponseCode = FAILED_DIN70121; cur->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus; cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown; //errn = -1; } } #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 i = 0; int errn = 0; bitstream_t v2g_tx_stream; static struct CurrentDemandResponse_ISO15118_2014 *cur; static struct ChargingInfoData *sys; 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("[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("[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(buf_log_evcomm, "[ERROR]EvBatteryMaxCurrent is negative(%.02f) => End_Process", sys->EvBatteryMaxCurrent); SAVE_SYS_LOG_MSG_EVCOMM(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) { #if 0 cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Invalid; //0 cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; sprintf(buf_log_evcomm, "[Error][Proc_iso1_CurrentDemandRes]IsolationStatus = %d", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); // Update_V2G_Flow_Status(Other_Fault); //errn = -1; #else cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid; //1 #endif } 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 = iso1isolationLevelType_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("[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(buf_log_evcomm, "[Error][Proc_iso1_CurrentDemandRes]IsolationStatus = %d(undefined)", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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("[ISO1][Error][CurrentDemandRes]CCS GFD trip => EVSE_Shutdown"); cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault; } else { SAVE_SYS_LOG_MSG_EVCOMM("[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("[ISO1][Error][CurrentDemandRes]CCS GFD trip => EVSE_EmergencyShutdown"); cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault; } else { SAVE_SYS_LOG_MSG_EVCOMM("[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("[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) { if(sys->CpState <= 1) { 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(buf_log_evcomm, "[CurrentDemand]Emergency Stop by CP Error (%d, %.02f V)", sys->CpState, sys->CpVoltage); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); } else { SAVE_SYS_LOG_MSG_EVCOMM("[ISO1][Error][CurrentDemandRes]EVSE Normal Stop"); //cur->ResponseCode = FAILED_ISO15118_2014; cur->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus; cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown; } } #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 = 1; 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("[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("[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)); res->EVSEID[0]='Z'; res->EVSEID[1]='Z'; res->EVSEID[2]='0'; res->EVSEID[3]='0'; res->EVSEID[4]='0'; res->EVSEID[5]='0'; res->EVSEID[6]='0'; //sprintf(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 strcpy(res->MeterInfo.MeterID , ShmSysConfigAndInfo->SysConfig.SerialNumber); //[MeterInfo][2/5] SigMeterReading (optional) //sprintf(res->MeterInfo.SigMeterReading , CCS_AC_SIG_METER_READING); //[MeterInfo][3/5] MeterStatus (optional) res->MeterInfo.MeterStatus = 1; //[MeterInfo][4/5] MeterReading (optional) res->MeterInfo.MeterReading = ShmInternalComm->AC_MeterReadingValue;//Wh //[MeterInfo][5/5] TMeter (optional) res->MeterInfo.TMeter = time(NULL); //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 (ShmInternalComm->AC_RcdStatus == 1) //RCD tripped,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(buf_log_evcomm, "[ISO1][Error][ChargingStatusRes]IsolationStatus = %d", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); Update_V2G_Flow_Status(Other_Fault); errn = -1; } if (ShmInternalComm->ChargingPermission == FALSE) { //res->ResponseCode = FAILED_ISO15118_2014; res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging; sprintf(buf_log_evcomm, "[ISO1][ChargingStatusRes]ChargingPermission = FALSE"); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); //errn = -1; } //Response to CP Error //#if CP_PROTECTION_MECHANISM == ENABLE #if 1 // if ((sys->CpState != 4) && (sys->CpState != 5)) //State C (6V), D (3V) if ((sys->CpState < 3) || (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(buf_log_evcomm, "[ChargingStatus]Emergency Stop by CP Error (%d, %.02f V)", sys->CpState, sys->CpVoltage); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[DIN][V2G][Tx]CurrentDemandRes"); } else { sprintf(buf_log_evcomm, "[DIN][Error][CurrentDemandReq]CurrentDemandRes: fail(%d,DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[ISO1][V2G][Tx]CurrentDemandRes"); } else { sprintf(buf_log_evcomm, "[ISO1][Error][CurrentDemandReq]CurrentDemandRes: fail(%d,DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[ISO1][V2G][Tx]ChargingStatusRes"); } else { sprintf(buf_log_evcomm, "[ISO1][Error][ChargingStatusReq]ChargingStatusRes: fail(%d,DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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; errn = -1; } 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("[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("[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("[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 if(ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryRequest.ChargeProgress==iso1chargeProgressType_Stop) 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; errn = -1; } 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("[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; struct ChargingInfoData *sys; //Request CSU to STOP //This should be reponsed as soon as possible once this message is received. sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; EVCOMM_SYS_INFO.EvBatterytargetVoltage = 0; EVCOMM_SYS_INFO.EvBatterytargetCurrent = 0; SAVE_SYS_LOG_MSG_EVCOMM("[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); CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; //[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("[DIN][V2G][Tx]PowerDeliveryRes (2nd)\n"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_din_PowerDeliveryStopReq]Proc_iso1_PowerDeliveryStopRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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; struct ChargingInfoData *sys; //Request CSU to STOP //This should be reponsed as soon as possible once this message is received. sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; //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); if(ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryRequest.ChargeProgress==iso1chargeProgressType_Stop) { //CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; EVCOMM_SYS_INFO.EvBatterytargetVoltage = 0; EVCOMM_SYS_INFO.EvBatterytargetCurrent = 0; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; SAVE_SYS_LOG_MSG_EVCOMM("[V2G][Rx]PowerDeliveryReq (2nd-Stop)\n"); //[To-Do] Sending response after the EVSE output voltage decreases to under 60V usleep(1500000); //1.5 seconds //sleep(1); //1 second } else SAVE_SYS_LOG_MSG_EVCOMM("[V2G][Rx]PowerDeliveryReq (2nd-Renegotiation)\n"); //Check for EV Error Code Check_EVErrorCode(ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryRequest.DC_EVPowerDeliveryParameter.DC_EVStatus.EVErrorCode); errn = Proc_iso1_PowerDeliveryStopRes(AcceptFd); if (errn == 0) { //send response successfully. SAVE_SYS_LOG_MSG_EVCOMM("[ISO1][V2G][Tx]PowerDeliveryRes (2nd-stop)"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_iso1_PowerDeliveryStopReq]Proc_iso1_PowerDeliveryStopRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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; errn = -1; } 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.EVSEIsolationStatus = dinisolationLevelType_Valid; //1 //wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; sprintf(buf_log_evcomm, "[Error][Proc_din_WeldingDetectionRes]IsolationStatus = %d", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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("[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(buf_log_evcomm, "[Error][Proc_din_WeldingDetectionRes]IsolationStatus = %d(undefined)", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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("[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_Ready; } else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { //wel->ResponseCode = FAILED_ISO15118_2014; wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown; errn = -1; } else if (ShmInternalComm->ChargingPermission == FALSE) { //wel->ResponseCode = FAILED_ISO15118_2014; wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready; } //Isolation Status if (sys->IsolationStatus == GFD_Invalid) //0: invalid (on going) { //wel->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Invalid; //0 wel->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid; //1 // wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; sprintf(buf_log_evcomm, "[Error][Proc_iso1_WeldingDetectionRes]IsolationStatus = %d", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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("[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(buf_log_evcomm, "[Error][Proc_iso1_WeldingDetectionRes]IsolationStatus = %d(undefined)", sys->IsolationStatus); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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("[DIN][V2G][Tx]WeldingDetectionRes"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_din_WeldingDetectionReq]Proc_din_WeldingDetectionRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[ISO1][V2G][Tx]WeldingDetectionRes"); } else { sprintf(buf_log_evcomm, "[Error][SeccComm][Proc_iso1_WeldingDetectionReq]Proc_iso1_WeldingDetectionRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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; 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_DIN70121.SessionStopResponse; sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; 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("[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("[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("[V2G][Tx]SessionStopRes: fail"); errn = -1; } else { //send response successfully. SAVE_SYS_LOG_MSG_EVCOMM("[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("PWM 5\% countdown: 2"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("PWM 5\% countdown: 1"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("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("[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("[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("[V2G][Tx]SessionStopRes: fail"); errn = -1; } else { //send response successfully. SAVE_SYS_LOG_MSG_EVCOMM("[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("PWM 5\% countdown: 2"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("PWM 5\% countdown: 1"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("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("[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(buf_log_evcomm, "[Error][SeccComm][Proc_din_SessionStopReq]Proc_iso1_SessionStopRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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(buf_log_evcomm, "[Error][SeccComm][Proc_iso1_SessionStopReq]Proc_iso1_SessionStopRes(): %d (DEC)", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } } else { break; } 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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; } } else { break; } 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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; } } else { break; } 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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; } } else { break; } 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("[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("[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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; } } else { break; } 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("[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(buf_log_evcomm, "ChargingParameter Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), V2G_SECC_ChargingParameter_Performance_Time); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; } } else { break; } 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("[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("[CableCheck] end counting..."); sprintf(buf_log_evcomm, "CableCheck Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), V2G_SECC_CableCheck_Performance_Time); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; } } else { break; } 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("[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(buf_log_evcomm, "Precharge Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), V2G_SECC_PreCharge_Performance_Time); SAVE_SYS_LOG_MSG_EVCOMM(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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; } } else { break; } 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("[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(buf_log_evcomm, "Wait for CurrentDemandReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), 2000); SAVE_SYS_LOG_MSG_EVCOMM(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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; } } else { break; } 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("[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("[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((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; } #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&SeqStartTime); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; } } else { break; } 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("[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(buf_log_evcomm, "Wait for WeldingDetectionReq or SessionStopReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), 2000); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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(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; } 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("[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(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(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("[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(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; } 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("[Error]SessionStopReqRes: fail"); Update_V2G_Flow_Status(Other_Fault); } req_is_responsed = TRUE; break; } case SessionStopResponse: //54, { break; } //------------------------------------------- default: { break; } } } } /*=========================================================================== 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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } } else { break; } 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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } } else { break; } 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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } } else { break; } 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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } } else { break; } 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("[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("[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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } } else { break; } 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("[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(buf_log_evcomm, "ChargingParameter Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), V2G_SECC_ChargingParameter_Performance_Time); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } } else { break; } 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("[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("[CableCheck] end counting..."); sprintf(buf_log_evcomm, "CableCheck Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), V2G_SECC_CableCheck_Performance_Time); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); Update_V2G_Flow_Status(Sequence_Timeout); //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_TIMEOUT_V2G_CableCheck_Performance_Time (023847) if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } 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("[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("[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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } } else { break; } 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("[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(buf_log_evcomm, "Precharge Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), V2G_SECC_PreCharge_Performance_Time); SAVE_SYS_LOG_MSG_EVCOMM(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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } } else { break; } 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("[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(buf_log_evcomm, "Wait for CurrentDemandReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), 2000); SAVE_SYS_LOG_MSG_EVCOMM(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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } } else { break; } 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("[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("[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 if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; } } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if((EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown) && (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown)) { ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 9; ShmStatusCodeData->PresentStatusCode[0][4] = 8; ShmStatusCodeData->PresentStatusCode[0][5] = 3; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; } } else { break; } 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("[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(buf_log_evcomm, "Wait for WeldingDetectionReq or SessionStopReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), 2000); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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 < PowerDeliveryRequestStop) { sprintf(buf_log_evcomm, "[ERROR]SequenceError(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); if(ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryRequest.ChargeProgress==iso1chargeProgressType_Stop) EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } 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("[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(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(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("[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 < PowerDeliveryRequestStop) { sprintf(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 if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= PowerDeliveryRequestStop && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(buf_log_evcomm, "[ERROR]Receive EV Stop Message(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } 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("[Error]SessionStopReqRes: fail"); Update_V2G_Flow_Status(Other_Fault); } req_is_responsed = TRUE; break; } case SessionStopResponse: //54, { break; } //------------------------------------------- default: { break; } } } } /*=========================================================================== 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("[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(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; } 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("[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(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; } 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("[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(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; } 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("[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(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; } 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("[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("[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("[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(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; } 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("[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(buf_log_evcomm, "ChargingParameter Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), V2G_SECC_ChargingParameter_Performance_Time); SAVE_SYS_LOG_MSG_EVCOMM(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("[Error]ChargeParameterDiscoveryReqRes: fail"); Update_V2G_Flow_Status(Other_Fault); } req_is_responsed = TRUE; break; } //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 break; } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { sprintf(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; } 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("[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(buf_log_evcomm, "Wait for ChargingStatusReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), 2000); SAVE_SYS_LOG_MSG_EVCOMM(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("[V2G][Rx]ChargingStatusReq: energy transfering..."); ftime(&EVCOMM_SYS_INFO.V2G_SECC_ChargingStatus_Timer_Start); } else { break; } 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("[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("[Error]ChargingStatusRes: 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_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(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; break; } else { break; } 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("[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(buf_log_evcomm, "Wait for SessionStopReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), 2000); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); Update_V2G_Flow_Status(Sequence_Timeout); break; } #endif //STEP 3: Check for SessionStopReq Message 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(buf_log_evcomm, "[ERROR]SequenceError(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); if(ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryRequest.ChargeProgress==iso1chargeProgressType_Stop) EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Flow_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } 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("[Error]SessionStopReqRes: fail"); Update_V2G_Flow_Status(Other_Fault); } req_is_responsed = TRUE; break; } case SessionStopResponse: //54 { break; } //------------------------------------------- default: { break; } } } } /*=========================================================================== 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(buf_log_evcomm, "[ISO1][Warning]Unexpected EnergyTransferMode(%d)", EnergyTransferMode); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); break; } } } /*=========================================================================== 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("[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(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; } 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("[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(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; } 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("[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(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; } 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("[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(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; } 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("[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("[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("[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(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; } 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("[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(buf_log_evcomm, "ChargingParameter Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), V2G_SECC_ChargingParameter_Performance_Time); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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("[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(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; } 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("[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("[CableCheck] end counting..."); sprintf(buf_log_evcomm, "CableCheck Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), V2G_SECC_CableCheck_Performance_Time); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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("[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(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; } 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("[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(buf_log_evcomm, "Precharge Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), V2G_SECC_PreCharge_Performance_Time); SAVE_SYS_LOG_MSG_EVCOMM(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("[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(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; } 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("[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(buf_log_evcomm, "Wait for CurrentDemandReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), 2000); SAVE_SYS_LOG_MSG_EVCOMM(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("[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(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; } 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("[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("[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(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; } 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("[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(buf_log_evcomm, "Wait for WeldingDetectionReq or SessionStopReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(SeqStartTime, SeqEndTime), 2000); SAVE_SYS_LOG_MSG_EVCOMM(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("[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("[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(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; } 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("[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(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(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("[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(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; } 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("[Error]SessionStopReqRes: fail"); Update_V2G_Flow_Status(Other_Fault); } req_is_responsed = TRUE; break; } case SessionStopResponse: //54, { break; } #endif //------------------------------------------- default: { break; } } } } /*=========================================================================== FUNCTION: V2gMsg_Process_iso2_AC DESCRIPTION: PRE-CONDITION: INPUT: 1. V2gFlowStatus OUTPUT: GLOBAL VARIABLES: 1. V2gFlowStatus =============================================================================*/ int V2gMsg_Process_iso2_AC(int AcceptFd) { } /*=========================================================================== 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(buf_log_evcomm, "[ISO2][Warning]Unexpected EnergyTransferMode(%d)", EnergyTransferMode); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); break; } } } /*=========================================================================== 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(buf_log_evcomm, "[Warning]Unexpected CommProtocol(%d)", ShmCcsData->CommProtocol); SAVE_SYS_LOG_MSG_EVCOMM(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); #ifdef SUPPORT_TLS_CONNECTION if(EvSecurity == 0)//support security { packet_size = SSL_read(ssl, V2gtpMsgRxBuf, V2GTP_MSG_RX_BUFFER_SIZE); } else { packet_size = recv(AcceptFd, V2gtpMsgRxBuf, V2GTP_MSG_RX_BUFFER_SIZE, 0); } #else packet_size = recv(AcceptFd, V2gtpMsgRxBuf, V2GTP_MSG_RX_BUFFER_SIZE, 0); #endif //[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(buf_log_evcomm, "[ERROR]V2gMsgDecoder", errn); SAVE_SYS_LOG_MSG_EVCOMM(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("SdpUdpConnected: Fail to open UdpSock"); return 0; } ShmSysConfigAndInfo->SysInfo.SystemCriticalTemp=UdpSock; 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(buf_log_evcomm, "SdpUdpConnected: Fail to bind UdpSock(%d)", UdpSock); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); close(UdpSock); UdpSock = -1; return 0; } sprintf(buf_log_evcomm, "[UdpSock]opend:%d", UdpSock); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); sprintf(buf_log_evcomm, "[SDP]Req from EVCC: waiting...(%d)", UdpSock); SAVE_SYS_LOG_MSG_EVCOMM(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, &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(buf_log_evcomm, "[SDP][Rx]Req from EVCC: GOT(%d)", UdpSock); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); DEBUG_PRINTF_EVCOMM_DETAIL("Security=0x%x\n", *(payload + 0)); DEBUG_PRINTF_EVCOMM_DETAIL("TransportProtocol=0x%x\n", *(payload + 1)); #ifdef SUPPORT_TLS_CONNECTION EvSecurity= *(payload); #endif 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; #ifdef SUPPORT_TLS_CONNECTION if(EvSecurity == 0)//support security payload[18] = SDP_PAYLOAD_SECURITY_TLS; //Security else payload[18] = SDP_PAYLOAD_SECURITY_NONE; // No Security #else payload[18] = SDP_PAYLOAD_SECURITY_NONE; //No Security #endif 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(buf_log_evcomm, "[SDP][Tx]Res from SECC"); SAVE_SYS_LOG_MSG_EVCOMM(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 >= 28) { return 1; } } } return 0; } /*=========================================================================== FUNCTION: V2gTcpConnected DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int V2gTcpConnected() { int packet_size,Rtn,AcceptFd; struct sockaddr_in6 ServerAddr,ClientAddr; if(TcpSock <= 0) { if ((TcpSock = socket(PF_INET6, SOCK_STREAM, 0)) < 0) { sprintf(buf_log_evcomm, "V2gTcpConnected: Fail to open TcpSock (%s)", strerror(errno)); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); usleep(100000); //100ms return 0; } ShmSysConfigAndInfo->SysInfo.PsuAmbientTemp=TcpSock; fcntl(TcpSock, F_SETFL, O_NONBLOCK); //set to O_NONBLOCK SAVE_SYS_LOG_MSG_EVCOMM("[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(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(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(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(buf_log_evcomm); usleep(100000); //100ms close(TcpSock); TcpSock = -1; return 0; } } SAVE_SYS_LOG_MSG_EVCOMM("[TCP]blid: DONE"); SAVE_SYS_LOG_MSG_EVCOMM("[TCP]listen: START"); if(listen(TcpSock, 1) < 0) //only accept one connection { sprintf(buf_log_evcomm, "V2gTcpConnected: Fail to listen TcpSock (%s)", strerror(errno)); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); usleep(100000); //100ms close(TcpSock); TcpSock = -1; return 0; } SAVE_SYS_LOG_MSG_EVCOMM("[TCP]listen: DONE"); sprintf(buf_log_evcomm, "[TCP]TcpSock: opened(%d), port=%d", TcpSock, htons(ServerAddr.sin6_port)); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); SAVE_SYS_LOG_MSG_EVCOMM("[TCP]accept: START"); } Rtn = sizeof(struct sockaddr_in6); if((AcceptFd = accept(TcpSock, (struct sockaddr *)&ClientAddr, &Rtn)) < 0 ) { static BOOL tmp = 0; if (tmp = 0) { SAVE_SYS_LOG_MSG_EVCOMM("[TCP]Wait TCP connection..."); tmp = 1; } else { //DEBUG_PRINTF_EVCOMM_DETAIL("."); } return 0; } ShmSysConfigAndInfo->SysInfo.PsuFanRotaSpeed=AcceptFd; SAVE_SYS_LOG_MSG_EVCOMM("[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 #ifdef SUPPORT_TLS_CONNECTION /* TCP connection is ready. Do server side SSL connection. */ if(EvSecurity == 0)//support security { ssl = SSL_new(ctx); SSL_set_fd(ssl, AcceptFd); if (SSL_accept(ssl) <= 0) { //SAVE_SYS_LOG_MSG_EVCOMM("[SSL]SSL_accept Failed"); //SSL_free(ssl); //close(AcceptFd); //AcceptFd = -1; return 0; } } #endif return AcceptFd; } /*=========================================================================== FUNCTION: End_Process DESCRIPTION: PRE-CONDITION: 1. 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("End_Process has been triggered by another event."); return -1; } SAVE_SYS_LOG_MSG_EVCOMM("[End_Process]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("[End_Process]close sockets..."); if(RawSock > 0) { close(RawSock); } if(UdpSock > 0) { close(UdpSock); } if(TcpSock > 0) { close(TcpSock); close(TcpAcceptFd); } RawSock = UdpSock = TcpSock = TcpAcceptFd = -1; if(ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp > 0) { close(ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp); ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp=0; } if(ShmSysConfigAndInfo->SysInfo.SystemCriticalTemp > 0) { close(ShmSysConfigAndInfo->SysInfo.SystemCriticalTemp); ShmSysConfigAndInfo->SysInfo.SystemCriticalTemp=0; } if(ShmSysConfigAndInfo->SysInfo.PsuAmbientTemp > 0) { close(ShmSysConfigAndInfo->SysInfo.PsuAmbientTemp); close(ShmSysConfigAndInfo->SysInfo.PsuFanRotaSpeed); ShmSysConfigAndInfo->SysInfo.PsuAmbientTemp=0; ShmSysConfigAndInfo->SysInfo.PsuFanRotaSpeed=0; } /*#ifdef SUPPORT_TLS_CONNECTION if(EvSecurity == 0)//support security { SSL_shutdown(ssl); SSL_free (ssl); } SSL_CTX_free (ctx); #endif*/ //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("PWM 100\% countdown: 5"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("PWM 100\% countdown: 4"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("PWM 100\% countdown: 3"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("PWM 100\% countdown: 2"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("PWM 100\% countdown: 1"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("PWM 100\% countdown: 0"); AttenProfileCnt = 0; init_appHandEXIDocument(&ccs_handshake); #if (FIRMWARE_VERSION_COMPILE_SETTING_RELEASE_MODE == DISABLE) { SAVE_SYS_LOG_MSG_EVCOMM("[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("State E countdown: 5"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("State E countdown: 4"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("State E countdown: 3"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("State E countdown: 2"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("State E countdown: 1"); sleep(1); SAVE_SYS_LOG_MSG_EVCOMM("State E countdown: 0"); #endif //Reset Memory unsigned char SlaveAddress_backup; unsigned int matched_backup; //unsigned char state_backup; SAVE_SYS_LOG_MSG_EVCOMM("[CCS Board]soft reset (closing SeccComm)..."); SAVE_SYS_LOG_MSG_EVCOMM("---------------------------------------------"); SAVE_SYS_LOG_MSG_EVCOMM("-- EVCOMM: END --"); SAVE_SYS_LOG_MSG_EVCOMM("-----------------------------------------\n"); #if (FIRMWARE_VERSION_COMPILE_SETTING_RELEASE_MODE == DISABLE) { SAVE_SYS_LOG_MSG_EVCOMM("[End_Process]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)); ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryRequest.ChargeProgress= 0xFF; //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; EVCOMM_SYS_INFO.DC_EVSEStatus=EVSE_NotReady; //Update_V2G_Flow_Status(state_backup); //CP_Detection_Pid = 0; //PP_Detection_Pid = 0; //Error_Monitor_Pid = 0; /* while(CheckConnectorPlugIn() != TRUE) { sleep(1); }*/ free(V2gtpMsgRxBuf); free(V2gtpMsgTxBuf); //DetachShareMemory(); Qca7kPowerReset(); //reset QCA7000 /* +++ 20200808, vern, should disconnected PLC connection after session stop ---*/ #ifdef AWCCS system("killall SeccComm"); #else system("cd /root;./reset_soft.sh"); #endif 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); if((EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active <= 49152)||(EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active >= 65535))//49152-65535 EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active=59438; sprintf(buf_log_evcomm, "[Init]TCP Port:OK(%d)", EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active); SAVE_SYS_LOG_MSG_EVCOMM(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(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(buf_log_evcomm); } #ifdef SUPPORT_TLS_CONNECTION SSL_CTX *create_sslcontext() { const SSL_METHOD *method; SSL_CTX *ctx; // Support only TLSv1.2 method = TLSv1_2_server_method(); // Create context ctx = SSL_CTX_new(method); if (!ctx) { ERR_print_errors_fp(stderr); return NULL; } return ctx; } int configure_sslcertkey_file(SSL_CTX *ctx) { SSL_CTX_set_ecdh_auto(ctx, 1); // Load certificate file if (SSL_CTX_use_certificate_file(ctx, "/root/cacert.pem", SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); return -1; } // Load private key file if (SSL_CTX_use_PrivateKey_file(ctx, "/root/cakey.pem", SSL_FILETYPE_PEM) <= 0 ) { ERR_print_errors_fp(stderr); return -1; } return 0; } #endif /*=========================================================================== FUNCTION: main DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int main(int argc, char *argv[]) { unsigned char Rtn; //Initialization if(ShareMemory_Init()==0) { system("reboot -f"); sleep(5); system("reboot -f"); } 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("---------------------------------------------"); SAVE_SYS_LOG_MSG_EVCOMM("-- EVCOMM: START --"); SAVE_SYS_LOG_MSG_EVCOMM("---------------------------------------------\n"); //Print Linux Kernel Version sprintf(buf_log_evcomm, "\nLinux Image SHA1: %s\n", LINUX_IMAGE_VERSION); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); //Print Hardware Version sprintf(buf_log_evcomm, "HW: %s\n", HARDWARE_VERSION); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); //Print Firmware Version sprintf(buf_log_evcomm, "FW: %s\n", FIRMWARE_VERSION); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); SAVE_SYS_LOG_MSG_EVCOMM("init..."); //Init V2G TCP/IPv6 packets buffer V2gtpMsgRxBuf = (unsigned char *)malloc(V2GTP_MSG_RX_BUFFER_SIZE); memset(V2gtpMsgRxBuf, 0, V2GTP_MSG_RX_BUFFER_SIZE); V2gtpMsgTxBuf = (unsigned char *)malloc(V2GTP_MSG_TX_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("[fork1]CP Detection: ON"); //start to detect errors Error_Monitor(); //fork2 SAVE_SYS_LOG_MSG_EVCOMM("[fork2]Error Monitor: ON"); //CCS connector type sprintf(buf_log_evcomm, "CCS connector type : %s\n", ShmInternalComm->CCSConnectorType > 0? "CCS2":"CCS1" ); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); //start to detect PP PP_Detection_Pid = 0; #if (PP_PROTECTION_MECHANISM == ENABLE) PP_Detection(); SAVE_SYS_LOG_MSG_EVCOMM("[fork3]PP Detection: ON"); #else SAVE_SYS_LOG_MSG_EVCOMM("[fork3]PP Detection: OFF"); #endif //Init communication parameters GetEthMac(QcaInterface, CsuMac); AttenProfileCnt = 0; init_appHandEXIDocument(&ccs_handshake); //Init Energy transfer mode //[To-Do] Parsing Model Name if(CCS_ENERGY_TRANSFER_MODE<=1) { if((ShmInternalComm->AC_EVSEModelName[2]=='Y') || (ShmInternalComm->AC_EVSEModelName[2]=='D') || (ShmInternalComm->AC_EVSEModelName[2]=='W')) //if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount==3) ShmCcsData->EnergyTransferMode = MODE_AC_THREE_PHASE_CORE; else ShmCcsData->EnergyTransferMode = MODE_AC_SINGLE_PHASE_CORE; } else 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 #ifdef SUPPORT_TLS_CONNECTION // SSL init //SSL_free (ssl); //SSL_CTX_free (ctx); SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); // Create SSL_CTX ctx = create_sslcontext(); if (ctx == NULL) { SAVE_SYS_LOG_MSG_EVCOMM("[SSL]create_sslcontext Failed"); } else SAVE_SYS_LOG_MSG_EVCOMM("[SSL]create_sslcontext OK"); // Configure cert and key if (configure_sslcertkey_file(ctx) < 0) { SAVE_SYS_LOG_MSG_EVCOMM("[SSL]configure_sslcertkey_file Failed"); } else SAVE_SYS_LOG_MSG_EVCOMM("[SSL]configure_sslcertkey_file OK"); #endif SAVE_SYS_LOG_MSG_EVCOMM("[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(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(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(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(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 } if(V2gFlowStatus == SessionStopResponse) { if(RawSock > 0) { close(RawSock); } if(UdpSock > 0) { close(UdpSock); } if(TcpSock > 0) { close(TcpSock); close(TcpAcceptFd); } RawSock = UdpSock = TcpSock = TcpAcceptFd = -1; #ifdef SUPPORT_TLS_CONNECTION if(EvSecurity == 0)//support security { SSL_shutdown(ssl); SSL_free (ssl); } SSL_CTX_free (ctx); #endif } } else if (V2gFlowStatus >= Performance_Timeout) { //End_Process if(RawSock > 0) { close(RawSock); } if(UdpSock > 0) { close(UdpSock); } if(TcpSock > 0) { close(TcpSock); close(TcpAcceptFd); } RawSock = UdpSock = TcpSock = TcpAcceptFd = -1; #ifdef SUPPORT_TLS_CONNECTION if(EvSecurity == 0)//support security { SSL_shutdown(ssl); SSL_free (ssl); } SSL_CTX_free (ctx); #endif } else { //null } } // printf("V2gFlowStatus=%d, socket=%d,%d,%d\n",V2gFlowStatus,RawSock,UdpSock,TcpSock); } //while }//main while