/* * Module_CCS.c * * Created on: 2020/03/16 * Author: foluswen */ #include "Module_CCS.h" #include "define_ccs.h" #include "main.h" enum MsgFlowStatus V2gFlowStatus; struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct CcsData *ShmCcsData; struct InternalComm *ShmInternalComm; struct Charger *ShmCharger; struct V2G_OBJECT { struct appHandEXIDocument appHandshake; struct dinEXIDocument DIN; struct iso1EXIDocument ISO1; struct iso2EXIDocument ISO2; }v2gObject; struct V2G_BUFFER { unsigned char rx[V2GTP_MSG_RX_BUFFER_SIZE]; unsigned char tx[V2GTP_MSG_TX_BUFFER_SIZE]; }v2gBuffer; struct SOCKET_HANDLE { int Raw; int Udp; int Tcp; int TcpAccept; }socketFd; struct PID_T { pid_t CP_Detection; pid_t PP_Detection; pid_t Error_Monitor; }pid; struct MAC { unsigned char eth0[6]; unsigned char eth1[6]; unsigned char qca[6]; unsigned char evcc[6]; }macAddr; struct QCA_INFO { struct MmeHeader SendMmePacket; struct sockaddr_ll DestSocketAddress; int SendMmePacketSize; unsigned char SlacRunId[8]; struct ifreq Req; unsigned char AagGroupsNum; unsigned char MnbcSoundNum; unsigned char AttenProfileCnt; unsigned char NewNmkKey[16]; unsigned char Nid[7]; }qcaInfo; struct TIMER { unsigned int PwmStart; struct timeb SeqStart; struct timeb SeqEnd; }timerStart; /** * * @param statusCode * @param statusName * @return */ uint8_t get_V2G_Status_Name(uint8_t statusCode, char *statusName) { int result = PASS; switch(statusCode) { case IDLE: sprintf(statusName, "IDLE"); break; case CM_SLAC_PARM_REQ: sprintf(statusName, "CM_SLAC_PARM_REQ"); break; case CM_SLAC_PARM_CONF: sprintf(statusName, "CM_SLAC_PARM_CONF"); break; case CM_START_ATTEN_CHAR_IND: sprintf(statusName, "CM_START_ATTEN_CHAR_IND"); break; case CM_MNBC_SOUND_IND: sprintf(statusName, "CM_MNBC_SOUND_IND"); break; case CM_ATTEN_CHAR_IND: sprintf(statusName, "CM_ATTEN_CHAR_IND"); break; case CM_ATTEN_CHAR_RSP: sprintf(statusName, "CM_ATTEN_CHAR_RSP"); break; case CM_VALIDATE_REQ: sprintf(statusName, "CM_VALIDATE_REQ"); break; case CM_VALIDATE_CNF: sprintf(statusName, "CM_VALIDATE_CNF"); break; case CM_SLAC_MATCH_REQ: sprintf(statusName, "CM_SLAC_MATCH_REQ"); break; case CM_SLAC_MATCH_CNF: sprintf(statusName, "CM_SLAC_MATCH_CNF"); break; case CM_AMP_MAP_REQ: sprintf(statusName, "CM_AMP_MAP_REQ"); break; case CM_AMP_MAP_CNF: sprintf(statusName, "CM_AMP_MAP_CNF"); break; case CM_SET_KEY_REQ: sprintf(statusName, "CM_SET_KEY_REQ"); break; case CM_SET_KEY_CNF: sprintf(statusName, "CM_SET_KEY_CNF"); break; case SLACC_SDP_UDP_Connection: sprintf(statusName, "SLACC_SDP_UDP_Connection"); break; case SLACC_SDP_TCP_Connection: sprintf(statusName, "SLACC_SDP_TCP_Connection"); break; case SupportedAppProtocolRequest: sprintf(statusName, "SupportedAppProtocolReq"); break; case SupportedAppProtocolResponse: sprintf(statusName, "SupportedAppProtocolRes"); break; case SessionSetupRequest: sprintf(statusName, "SessionSetupReq"); break; case SessionSetupResponse: sprintf(statusName, "UnSessionSetupResknown"); break; case ServiceDiscoveryRequest: sprintf(statusName, "ServiceDiscoveryReq"); break; case ServiceDiscoveryResponse: sprintf(statusName, "ServiceDiscoveryRes"); break; case ServiceDetailRequest: sprintf(statusName, "ServiceDetailReq"); break; case ServiceDetailResponse: sprintf(statusName, "ServiceDetailRes"); break; case ServiceAndPaymentSelectionRequest: sprintf(statusName, "ServiceAndPaymentSelectionReq"); break; case ServiceAndPaymentSelectionResponse: sprintf(statusName, "ServiceAndPaymentSelectionRes"); break; case PaymentDetailsRequest: sprintf(statusName, "PaymentDetailsReq"); break; case PaymentDetailsResponse: sprintf(statusName, "PaymentDetailsRes"); break; case AuthorizationRequest: sprintf(statusName, "AuthorizationReq"); break; case AuthorizationResponse: sprintf(statusName, "AuthorizationRes"); break; case CertificateUpdateRequest: sprintf(statusName, "CertificateUpdateReq"); break; case CertificateUpdateResponse: sprintf(statusName, "CertificateUpdateRes"); break; case CertificateInstallationRequest: sprintf(statusName, "CertificateInstallationReq"); break; case CertificateInstallationResponse: sprintf(statusName, "CertificateInstallationRes"); break; case ChargeParameterDiscoveryRequest: sprintf(statusName, "ChargeParameterDiscoveryReq"); break; case ChargeParameterDiscoveryResponse: sprintf(statusName, "ChargeParameterDiscoveryRes"); break; case CableCheckRequest: sprintf(statusName, "CableCheckReq"); break; case CableCheckResponse: sprintf(statusName, "CableCheckRes"); break; case PreChargeRequest: sprintf(statusName, "PreChargeReq"); break; case PreChargeResponse: sprintf(statusName, "PreChargeRes"); break; case PowerDeliveryRequestStart: sprintf(statusName, "PowerDeliveryReqStart"); break; case PowerDeliveryResponsetStart: sprintf(statusName, "PowerDeliveryResStart"); break; case ChargingStatusRequest: sprintf(statusName, "ChargingStatusReq"); break; case ChargingStatusResponse: sprintf(statusName, "ChargingStatusRes"); break; case CurrentDemandRequest: sprintf(statusName, "CurrentDemandReq"); break; case CurrentDemandResponse: sprintf(statusName, "CurrentDemandRes"); break; case MeteringReceiptRequest: sprintf(statusName, "MeteringReceiptReq"); break; case MeteringReceiptResponse: sprintf(statusName, "MeteringReceiptRes"); break; case PowerDeliveryRequestStop: sprintf(statusName, "PowerDeliveryReqStop"); break; case PowerDeliveryResponseStop: sprintf(statusName, "PowerDeliveryResStop"); break; case WeldingDetectionRequest: sprintf(statusName, "WeldingDetectionReq"); break; case WeldingDetectionResponse: sprintf(statusName, "WeldingDetectionRes"); break; case SessionStopRequest: sprintf(statusName, "SessionStopReq"); break; case SessionStopResponse: sprintf(statusName, "SessionStopRes"); break; case Performance_Timeout: sprintf(statusName, "Performance_Timeout"); break; case Sequence_Timeout: sprintf(statusName, "Sequence_Timeout"); break; case Other_Fault: sprintf(statusName, "Other_Fault"); break; default: sprintf(statusName, "Unknown"); result = FAIL; break; } return result; } /** * * @return */ unsigned char Get_V2G_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; } /** * * @return */ unsigned char Get_V2G_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; } /** * * @param Fd * @param MsgId * @param SlaveAddress * @param DataLength * @param SendData * @return */ int CAN_Tx_MSG(int Fd, unsigned int MsgId, unsigned char SlaveAddress, unsigned char DataLength, unsigned char *SendData) { #if 0 struct can_frame frame; struct timeb StartTime, EndTime; unsigned int tmp = 0; int nbytes = 0; int i = 0; //Protection: To avoid unexpected length for CAN bus payload. if (DataLength > 8) { DataLength = 8; } memset(&frame, 0, sizeof(struct can_frame)); frame.can_id = 0x80000000 | CAN_SEND_DIRECTION | MsgId | SlaveAddress; //0x80000000: extension ID format frame.can_dlc = DataLength; memcpy(frame.data, SendData, DataLength); nbytes = write(Fd, &frame, sizeof(struct can_frame)); return nbytes; #else return -1; #endif } /** * * @param Fd * @return */ 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 } 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 DEBUG_INFO("Sending STOP Command to CSU\n"); CSUCOMMDC_TASK_FLAG.Send_EVStopReq = FALSE; return nbytes; } /** * * @param cmd * @return */ int Sniffer_Candump(char cmd) { #if (CANDUMP_PACKETS_SNIFFER_SWITCH == ENABLE) if (cmd == ENABLE) { DEBUG_INFO("Candump init\n"); system("cd /mnt/;rm -rf candump/"); system("cd /mnt/;mkdir candump"); DEBUG_INFO("Candump on\n"); system("cd /mnt/candump;candump -l can0 &"); return 0; } else if (cmd == DISABLE) { DEBUG_INFO("Candump off\n"); system("killall candump"); DEBUG_INFO("Candump save\n"); system("cd /;cp -rfv /mnt/candump /Storage/SystemLog/"); return 0; } else { DEBUG_INFO("Candump unexpected cmd(%d)\n", cmd); return -1; } #endif return 0; } /** * * @param cmd * @return */ int Sniffer_Tcpdump(char cmd) { #if (TCPDUMP_PACKETS_SNIFFER_SWITCH == ENABLE) if (cmd == ENABLE) { DEBUG_INFO("Tcpdump init...\n"); system("cd /mnt/;rm -rf tcpdump/"); system("cd /mnt/;mkdir tcpdump"); unsigned char cmdBuf[256]; time_t CurrentTime; struct tm *tm; struct timeval tv; memset(cmdBuf, 0, sizeof(cmdBuf)); CurrentTime = time(NULL); tm = localtime(&CurrentTime); gettimeofday(&tv, NULL); // get microseconds, 10^-6 sprintf((char*)cmdBuf, "tcpdump -i eth1 -p \"udp or ether proto 0x88e1\" -w /mnt/tcpdump/[%04d.%02d]CCS_SlacPackets_%02X%02X%02X%02X%02X%02X%02X%02X.log &", (tm->tm_year+1900), (tm->tm_mon+1), 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]); DEBUG_INFO("Tcpdump on\n"); system((char*)cmdBuf); return 0; } else if (cmd == DISABLE) { DEBUG_INFO("Tcpdump off\n"); system("killall tcpdump"); for(int idx=2;idx>0;idx--) { DEBUG_INFO("Tcpdump wait: %ds\n", idx); sleep(1); } DEBUG_INFO("Tcpdump save\n"); system("cd /;cp -rfv /mnt/tcpdump/* /Storage/SystemLog/"); system("cd /mnt/;rm -rf tcpdump/"); return 0; } else { DEBUG_INFO("Tcpdump unexpected cmd(%d)\n", cmd); return -1; } #endif return 0; } /** * * @param state_new * @return */ int Update_V2G_Status(unsigned int state_new) { unsigned char state_now; char nameNow[64], nameNew[64]; state_now = Get_V2G_Status(); get_V2G_Status_Name(state_now, nameNow); get_V2G_Status_Name(state_new, nameNew); if (EVCOMM_SYS_INFO.End_Process_inused == TRUE || CSUCOMMDC_TASK_FLAG.FW_Update_Task_inused == TRUE) { if (state_now != Performance_Timeout && //253 state_now != Sequence_Timeout && //254 state_now != Other_Fault) //255 { DEBUG_WARN("state-%s(%d) change: ignored (End_Process_inused:%d, FW_Update_Task_inused:%d)\n", nameNew, state_new, EVCOMM_SYS_INFO.End_Process_inused, CSUCOMMDC_TASK_FLAG.FW_Update_Task_inused); 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; DEBUG_WARN("state-%s(%d) change: ignored(now in error state-%s(%d))\n", nameNow, state_new, nameNew, state_now); } return -1; } } //Updating the state formally. DEBUG_INFO("%s(%02d) > %s(%02d)\n", nameNow, state_now, nameNew, state_new); V2gFlowStatus = state_new; state_now = state_new; switch (ShmCcsData->CommProtocol) { case V2GT_MSG_PROTOCOL_DIN70121: //0 { ShmCcsData->V2GMessage_DIN70121.PresentMsgFlowStatus_pre = ShmCcsData->V2GMessage_DIN70121.PresentMsgFlowStatus; ShmCcsData->V2GMessage_DIN70121.PresentMsgFlowStatus = V2gFlowStatus; break; } case V2GT_MSG_PROTOCOL_ISO15118_2014: //1 { ShmCcsData->V2GMessage_ISO15118_2014.PresentMsgFlowStatus_pre = ShmCcsData->V2GMessage_ISO15118_2014.PresentMsgFlowStatus; ShmCcsData->V2GMessage_ISO15118_2014.PresentMsgFlowStatus = V2gFlowStatus; break; } case V2GT_MSG_PROTOCOL_ISO15118_2018: //2 { ShmCcsData->V2GMessage_ISO15118_2018.PresentMsgFlowStatus_pre = ShmCcsData->V2GMessage_ISO15118_2018.PresentMsgFlowStatus; ShmCcsData->V2GMessage_ISO15118_2018.PresentMsgFlowStatus = V2gFlowStatus; break; } default: break; } } return 0; } /** * * @param ST * @param ET * @return */ 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) { return -1; } return t_diff; } /** * * @param ST * @param ET * @return */ 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) { return -1; } return t_diff; } /** * * @param ST * @param ET * @return */ 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) { return -1; } return t_diff; } /** * * @return */ int ShareMemory_Init() { int MeterSMId; //create ShmSysConfigAndInfo if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("ShareMemory_Init:shmget ShmSysConfigAndInfo NG\n"); return 0; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("ShareMemory_Init:shmat ShmSysConfigAndInfo NG\n"); return 0; } //create ShmStatusCodeData if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("ShareMemory_Init:shmget ShmStatusCodeData NG\n"); return 0; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("ShareMemory_Init:shmat ShmStatusCodeData NG\n"); return 0; } //create ShmCcsData if ((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("ShareMemory_Init:shmget ShmCcsData NG\n"); return 0; } else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("ShareMemory_Init:shmat ShmCcsData NG\n"); return 0; } //create ShmInternalComm if ((MeterSMId = shmget(ShmInternalCommKey, sizeof(struct InternalComm), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("ShareMemory_Init:shmget ShmInternalComm NG\n"); return 0; } else if ((ShmInternalComm = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("ShareMemory_Init:shmat ShmInternalComm NG\n"); return 0; } //Initial ShmCharger if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), 0777)) < 0) { DEBUG_ERROR("shmget ShmChargerKey NG\n"); return 0; } else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmChargerKey NG\n"); return 0; } //[To-Do] The initialization here is reduntant and should be removed partially. //SHM_Init_supportedAppProtocolRes(ShmCcsData); //SHM_Init_din_SessionSetupRes(ShmCcsData); //SHM_Init_din_ServiceDiscoveryRes(ShmCcsData); //SHM_Init_din_ServiceAndPaymentSelectionRes(ShmCcsData); //SHM_Init_din_ContractAuthenticationRes(ShmCcsData); SHM_Init_din_ChargeParameterDiscoveryRes(ShmCcsData); SHM_Init_din_CableCheckRes(ShmCcsData); SHM_Init_din_PreChargeRes(ShmCcsData); SHM_Init_din_PowerDeliveryRes(ShmCcsData); SHM_Init_din_CurrentDemandRes(ShmCcsData); SHM_Init_din_WeldingDetectionRes(ShmCcsData); SHM_Init_din_SessionStopRes(ShmCcsData); return 1; } /** * 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. * @param Eth * @param mac * @return */ int GetEthMac(unsigned char *Eth, unsigned char *mac) { //Parameters:MAC,IP,Mask,Gateway int fd; unsigned char addr[18], Buffer[128]; memset(Buffer, 0, sizeof(Buffer)); sprintf((char*)Buffer, "cat /sys/class/net/%s/address > /mnt/GetEthInfo", Eth); //CsuMac (Eth = eth1) system((char*)Buffer); fd = open("/mnt/GetEthInfo", O_RDONLY); if(fd < 0) { system("rm -f /mnt/GetEthInfo"); DEBUG_ERROR("GetEthMac: MAC Address open error\n"); return 0; } memset(mac, 0, 6); memset(addr, 0, sizeof(addr)); read(fd, addr, 17); close(fd); system("rm -f /mnt/GetEthInfo"); sscanf((char*)addr, "%02x:%02x:%02x:%02x:%02x:%02x", (uint32_t *)&mac[0], (uint32_t *)&mac[1], (uint32_t *)&mac[2], (uint32_t *)&mac[3], (uint32_t *)&mac[4], (uint32_t *)&mac[5]); //CsuMac (Eth = eth1) DEBUG_INFO("EVSE MAC address(%s): %02X:%02X:%02X:%02X:%02X:%02X\n", Eth, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); return 1; } /** * * @param AdcChannel * @return */ float ReadAdcVolt(unsigned char AdcChannel) { //AIN0=CCS GUN Temp 1 //AIN1=CCS GUN Temp 2 //AIN2=CCS_Proximity/2 //AIN3=pilot voltage #if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE)) return 0; #else if(AdcChannel == 3) { int fd,count,AvgTimes; unsigned char SampleBuf[4]; float TmpVolt, MinSample, AvgSample = 0; fd = open("/sys/bus/iio/devices/iio\\:device0/in_voltage3_raw", O_RDONLY); if(fd > 0) { //system("echo 1 > /sys/class/gpio/gpio89/value"); //for test for(AvgTimes = 0; AvgTimes < 3; AvgTimes++) //period = 60~91 ms(renice -10, , CurrentDemand()) /*+++ 20200909, vern, extend detection time for interference ---*/ { count = 0; MinSample = 2306; //system("echo 1 > /sys/class/gpio/gpio89/value"); //for test while(count < 40) //period = 21~42ms (renice -10, CurrentDemand()) /*+++ 20200909, vern, extend detection time for interference ---*/ { //re-sampling period = 3~13ms (renice -10, SLAC()) //system("echo 1 > /sys/class/gpio/gpio89/value"); //for test read(fd, SampleBuf, 4); //period = 3.2~10ms (renice -10, SLAC()) //system("echo 0 > /sys/class/gpio/gpio89/value"); //for test TmpVolt = atoi((char*)SampleBuf); if((TmpVolt < 2306) && (TmpVolt > 0))//positive voltage { if(TmpVolt < MinSample) { MinSample = TmpVolt; } count++; } lseek(fd, 0, SEEK_SET); } //system("echo 0 > /sys/class/gpio/gpio89/value"); //for test AvgSample += MinSample; } AvgSample /= AvgTimes; close(fd); //system("echo 0 > /sys/class/gpio/gpio89/value"); //for test return ((0.954-(1.8*AvgSample/4095))/0.06); } else { return -1; } } else { FILE *fp; unsigned char str[64]; unsigned char AdcValue[8]; if(AdcChannel > 7) { return -1; } memset(str,0,sizeof(str)); memset(AdcValue,0,sizeof(AdcValue)); sprintf((char*)str, "cat /sys/bus/iio/devices/iio\\:device0/in_voltage%d_raw", AdcChannel); fp=popen((char*)str, "r"); if(fgets((char*)AdcValue,sizeof(AdcValue),fp) == NULL) { pclose(fp); return -1; } pclose(fp); //Vin = Vref *D / (2^n - 1) return ((float)1.8*(float)atoi((char*)AdcValue))/4095; } #endif } /** * * @return */ float ReadAdcVolt_PP_fork3() { #if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE)) return 0; #else int fd, AvgTimes; unsigned char SampleBuf[4]; float TmpVolt = 0; float AvgSample = 0; float V_pp = 0; fd = open("/sys/bus/iio/devices/iio\\:device0/in_voltage2_raw", O_RDONLY); //PP if(fd > 0) { for(AvgTimes = 0; AvgTimes < 5; AvgTimes++) //get 5 samples { read(fd, SampleBuf, 4); TmpVolt = atoi((char*)SampleBuf); lseek(fd, 0, SEEK_SET); AvgSample += TmpVolt; } close(fd); AvgSample /= AvgTimes; V_pp = (3.6*AvgSample)/4095; //PP usleep(20000); //20ms return V_pp; } else { return -1; } #endif } /** * */ void Qca7kPowerReset() { DEBUG_INFO("QCA7000 reset...\n"); system("ifconfig eth1 down"); usleep(500000); system("echo 0 > /sys/class/gpio/gpio115/value"); usleep(500000); system("echo 1 > /sys/class/gpio/gpio115/value"); usleep(500000); system("ifconfig eth1 up"); usleep(500000); } /** * * @param OnOff * @return */ int SwitchCpStateE(unsigned char OnOff) { /* * TODO: Request CP change to state E */ if((OnOff != ENABLE) && (OnOff != DISABLE)) { return -1; } struct ChargingInfoData *ccs; ccs = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; ccs->SwitchCpStateE_status = OnOff; //OnOff = 1 => switch State to E //OnOff = 0 => return noraml #if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE)) { if(OnOff == DISABLE) { //DEBUG_INFO("SwitchCpStateE: released\n"); CSUCOMMAC_SHM.CpSetStateE = DISABLE; } else { OutputCpPwmDuty(100); //set CP duty as 100, firstly. CSUCOMMAC_SHM.CpSetStateE = ENABLE; //DEBUG_INFO("SwitchCpStateE: enabled!\n"); } } #else //CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED { if(OnOff == DISABLE) { //DEBUG_INFO("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"); //DEBUG_INFO("SwitchCpStateE: enabled!\n"); } } #endif if (ccs->SwitchCpStateE_status_pre != ccs->SwitchCpStateE_status) { DEBUG_INFO("SwitchCpStateE: %d >> %d\n", ccs->SwitchCpStateE_status_pre, ccs->SwitchCpStateE_status); ccs->SwitchCpStateE_status_pre = ccs->SwitchCpStateE_status; } return 0; } /** * * @param Duty * @return */ int OutputCpPwmDuty(unsigned char Duty) { #if ((CCS_ENERGY_TRANSFER_MODE != MODE_AC_SINGLE_PHASE_CORE) && (CCS_ENERGY_TRANSFER_MODE != MODE_AC_THREE_PHASE_CORE)) char cmdBuf[1024]; int DutyInNanoSec; #endif struct ChargingInfoData *ccs; ccs = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; if((Duty < 0)||(Duty > 100)) { return -1; } #if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE)) { CSUCOMMAC_SHM.CpSetPWMDuty = Duty; } #else //CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED { DutyInNanoSec = 10000 * Duty; sprintf((char*)cmdBuf, "echo %d > /sys/class/pwm/pwmchip0/pwm0/duty_cycle", DutyInNanoSec);//nanoseconds system((char*)cmdBuf); } #endif ccs->CpDuty = Duty; //CP Duty if (ccs->CpDuty != ccs->CpDuty_pre) { DEBUG_INFO("CP Duty: %d%% >> %d%%\n", ccs->CpDuty_pre, ccs->CpDuty); ccs->CpDuty_pre = ccs->CpDuty; } return 0; } /** * * @param ccs */ //#if DEBUG_INFO_SWITCH == ENABLE void Check_Plugin_Status_Update(struct ChargingInfoData *ccs) { if (ccs->ConnectorPlugIn != ccs->ConnectorPlugIn_new) { DEBUG_INFO("[fork1]Plugin: %d >> %d (CP=%.2fV, PP=%.2fV)\n", ccs->ConnectorPlugIn, ccs->ConnectorPlugIn_new, ccs->CpVoltage, ccs->PpVoltage); ccs->ConnectorPlugIn_pre = ccs->ConnectorPlugIn; ccs->ConnectorPlugIn = ccs->ConnectorPlugIn_new; //ccs->CpVoltage_pre = ccs->CpVoltage; } } //#endif /** * * @return */ int CheckConnectorPlugIn() { /* * TODO: Return connector status depedon CP */ static struct ChargingInfoData *ccs; ccs = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; #if (CP_PROTECTION_MECHANISM == ENABLE) return (int)ccs->ConnectorPlugIn; #else return TRUE; #endif } /** * * @param ccs * @return */ int Check_CP_State_Error(struct ChargingInfoData *ccs) { #if (CP_PROTECTION_MECHANISM == DISABLE) { return -1; } #endif unsigned char state = 0; #if ((CCS_ENERGY_TRANSFER_MODE != MODE_AC_SINGLE_PHASE_CORE) && (CCS_ENERGY_TRANSFER_MODE != MODE_AC_THREE_PHASE_CORE)) double time_diff = 0; #endif state = Get_V2G_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) { #ifdef TEST_WITH_ETH0 if((ShmCcsData->EnergyTransferMode == MODE_DC_EXTENDED) && ((ccs->CpState != CCS_CP_STATE_B1) && (ccs->CpState != CCS_CP_STATE_B2))) #else if((ccs->CpState != CCS_CP_STATE_B1) && (ccs->CpState != CCS_CP_STATE_B2)) #endif { if (ccs->CpState_err == FALSE) { DEBUG_ERROR("[fork1][CP]before CPD\n"); //CPD: ChargeParameterDiscoveryRequest //CPD: ChargeParameterDiscovery } ccs->CpState_err = TRUE; } } #else { if(ccs->CpState != CCS_CP_STATE_B2) { if (ccs->CpState_err == FALSE) { DEBUG_ERROR("[fork1][CP]]before CPD\n"); //CPD: ChargeParameterDiscoveryRequest //CPD: ChargeParameterDiscovery } ccs->CpState_err = TRUE; } } #endif } #if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE)) { //ChargeParameterDiscovery if(state >= ChargeParameterDiscoveryRequest && //35 state <= ChargeParameterDiscoveryResponse) //36 { #ifdef TEST_WITH_ETH0 if((ccs->CpState != CCS_CP_STATE_B2) && ((ShmCcsData->EnergyTransferMode != MODE_DC_EXTENDED) && (ccs->CpState != CCS_CP_STATE_C))) #else if(ccs->CpState != CCS_CP_STATE_B2) #endif { if (ccs->CpState_err == FALSE) { DEBUG_ERROR("[fork1][CP]]CPD\n"); //PRC: Precharge //CUD: CurrentDemand } ccs->CpState_err = TRUE; } } //ChargingStatus if(state >= ChargingStatusRequest && //43 state <= ChargingStatusResponse) //44 { if((ccs->CpState != CCS_CP_STATE_B2) && (ccs->CpState != CCS_CP_STATE_C) && (ccs->CpState != CCS_CP_STATE_D)) { if (ccs->CpState_err == FALSE) { DEBUG_ERROR("[fork1][CP]CGS\n"); //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 { DEBUG_INFO("[fork1][CP]check C(4),D(5): ON (%.02lf of %dms)\n", time_diff, V2G_SECC_CP_Timeout_CableCheck); ccs->CableCheckPreCountDownDone = TRUE; } } if(ccs->CableCheckPreCountDownDone == TRUE) { if(ccs->CpState != CCS_CP_STATE_C && ccs->CpState != CCS_CP_STATE_D) { if (ccs->CpState_err == FALSE) { DEBUG_ERROR("[fork1][CP]]CPD and CCK (after CNT)\n"); //CPD: ChargeParameterDiscovery //CCK: CableCheck //CNT: count down } ccs->CpState_err = TRUE; } } else { if((ccs->CpState != CCS_CP_STATE_B2) && (ccs->CpState != CCS_CP_STATE_C) && (ccs->CpState != CCS_CP_STATE_D)) { if (ccs->CpState_err == FALSE) { DEBUG_ERROR("[fork1][CP]CPD and CCK (before CNT)\n"); //CPD: ChargeParameterDiscovery //CCK: CableCheck //CNT: count down } ccs->CpState_err = TRUE; } } } //Precharge, CurrentDemand if(state >= PreChargeRequest && //39 state <= CurrentDemandResponse) //46 { if((ccs->CpState != CCS_CP_STATE_C) && (ccs->CpState != CCS_CP_STATE_D)) { if (ccs->CpState_err == FALSE) { DEBUG_ERROR("[fork1][CP]PRC and CUD\n"); //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); DEBUG_ERROR("[fork1]CP(%d) Error in state %d(%d)\n", ccs->CpState, state, ccs->CableCheckPreCountDownDone); ccs->CpState_err_logged = TRUE; } return 0; } /** * * @param ccs */ void Check_CP_State_Update(struct ChargingInfoData *ccs) { //CP State if (ccs->CpState != ccs->CpState_pre) { DEBUG_INFO("[fork1]CP State: %d >> %d (%.2fV)\n", ccs->CpState_pre, ccs->CpState, ccs->CpVoltage); ccs->CpState_pre = ccs->CpState; } } /** * */ void CP_Detection() { pid_t tmp = 0; #if ((CCS_ENERGY_TRANSFER_MODE != MODE_AC_SINGLE_PHASE_CORE) && (CCS_ENERGY_TRANSFER_MODE != MODE_AC_THREE_PHASE_CORE)) unsigned char Statetmp; float TotalTmpVolt; #endif struct ChargingInfoData *ccs; ccs = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; if(pid.CP_Detection == 0) { tmp = fork(); if(tmp > 0) { pid.CP_Detection = tmp; #if 1 unsigned char buf[64]; memset(buf, 0, sizeof(buf)); //sprintf((char*)buf, "renice -20 -p %d", tmp); sprintf((char*)buf, "renice -10 -p %d", tmp); system((char*)buf); #endif return; } } while(1) { //ADC_Voltage = (1+RE62/RE63)*0.9 - (RE62/RE63)*Pilot_Voltage, RE62/RE63=0.06 //=>Pilot_Voltage=(0.954-ADC_Voltage)/0.06 #if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE)) { ccs->CpVoltage = ShmInternalComm->AC_CpPositiveVoltage; ccs->CpState = ShmInternalComm->AC_CpPresentState; } #else //CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED { TotalTmpVolt = ReadAdcVolt(3); ccs->CpVoltage = TotalTmpVolt; if (ccs->CpVoltage_pre != ccs->CpVoltage) { ccs->CpVoltage_pre = ccs->CpVoltage; } //printf("TotalTmpVolt = %.02f\n", TotalTmpVolt); //If CP voltage is higer than 13.5V if(TotalTmpVolt >= 13.5) { //Pilot Error if((ccs->CpState == CCS_CP_STATE_A) && (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 >= CCS_CP_STATE_B1) && (ccs->CpState <= CCS_CP_STATE_B2) && (TotalTmpVolt < 10.75)) { if((ccs->CpDuty >= 5) && (ccs->CpDuty < 100)) { Statetmp = 3; } else { Statetmp = 2; } } else if((ccs->CpState == CCS_CP_STATE_G) && (TotalTmpVolt >= 13.25)) { Statetmp = 8; } else { Statetmp = 1; } } else if((TotalTmpVolt >= 7.5) && (TotalTmpVolt < 10.5)) { //State B (9V) if((ccs->CpState == CCS_CP_STATE_C) && (TotalTmpVolt < 7.75)) { Statetmp = 4; } else if((ccs->CpState == CCS_CP_STATE_A) && (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 == CCS_CP_STATE_D) && (TotalTmpVolt < 4.75)) { Statetmp = 5; } else if((ccs->CpState >= CCS_CP_STATE_B1) && (ccs->CpState <= CCS_CP_STATE_B2) && (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 == CCS_CP_STATE_E)&&(TotalTmpVolt < 1.75)) { Statetmp = 6; } else if((ccs->CpState == CCS_CP_STATE_C)&&(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 == CCS_CP_STATE_G) && (TotalTmpVolt < -1.25)) { Statetmp = 8; } else if((ccs->CpState == CCS_CP_STATE_D) && (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 == CCS_CP_STATE_G) && (TotalTmpVolt >= -10.75)) { Statetmp = 8; } else { Statetmp = 7; } } else { //null } ccs->CpState = Statetmp; } #endif Check_CP_State_Update(ccs); Check_CP_State_Error(ccs); //Updating Plugin status #if (PP_PROTECTION_MECHANISM == ENABLE) if((ccs->CpState >= CCS_CP_STATE_B1 ) && (ccs->CpState <= CCS_CP_STATE_D ) && (ccs->PpVoltage >= 1.0)) //PP >= 1.0V #else if((ccs->CpState >= CCS_CP_STATE_B1 ) && (ccs->CpState <= CCS_CP_STATE_D )) #endif { ccs->ConnectorPlugIn_new = TRUE; } else { ccs->ConnectorPlugIn_new = FALSE; OutputCpPwmDuty(100); } Check_Plugin_Status_Update(ccs); usleep(1000); }//while } /** * 1. In order to detect CP in efficient response time, we create an independent * thread for this procedure. 2. The priority of this thread is set as the same as other tasks. */ void PP_Detection() { pid_t tmp = 0; // struct timeb StartTime, EndTime; #if ((CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED)) //unsigned char Statetmp; #endif float TotalTmpVolt; if(pid.PP_Detection == 0) { tmp = fork(); if(tmp > 0) { pid.PP_Detection = tmp; #if 0 unsigned char buf[64]; memset(buf, 0, sizeof(buf)); sprintf((char*)buf, "renice -20 -p %d", tmp); system(buf); #endif return; } } while(1) { TotalTmpVolt = ReadAdcVolt_PP_fork3(); EVCOMM_SYS_INFO.PpVoltage = TotalTmpVolt; if (EVCOMM_SYS_INFO.PpVoltage_pre != EVCOMM_SYS_INFO.PpVoltage) { if ((EVCOMM_SYS_INFO.PpVoltage_pre < 0.5 && EVCOMM_SYS_INFO.PpVoltage >= 1.0) || (EVCOMM_SYS_INFO.PpVoltage_pre >= 1.0 && EVCOMM_SYS_INFO.PpVoltage < 0.5)) { DEBUG_INFO("[fork3]PP(%.2f >> %.2fV)\n", EVCOMM_SYS_INFO.PpVoltage_pre, EVCOMM_SYS_INFO.PpVoltage); EVCOMM_SYS_INFO.PpVoltage_pre = EVCOMM_SYS_INFO.PpVoltage; } } usleep(1000); }//while } /** * */ void Error_Monitor() { pid_t tmp = 0; double time_diff = 0; unsigned char status = 0; struct ChargingInfoData *ccs; ccs = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; if(pid.Error_Monitor == 0) { tmp = fork(); //SeccComm fork2 if(tmp > 0) { pid.Error_Monitor = tmp; #if 0 unsigned char buf[64]; memset(buf, 0, sizeof(buf)); sprintf((char*)buf, "renice -20 -p %d", tmp); system(buf); #endif return; } } for(;;) { //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 = Get_V2G_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) //DEBUG_INFO("[fork2] Emergency Stop (due to Connector is plugged out during communication.)\n"); DEBUG_ERROR("[fork2]Plug out Error => End_Process\n"); //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 //DEBUG_INFO("CP_PROTECTION_MECHANISM is disabled. Emergency Stop: skipped\n"); #endif } } //Step 2: Check for V2G_SECC_Sequence_Timeout //#if V2G_SECC_TIMEOUT_PROTECTION == ENABLE status = Get_V2G_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 { DEBUG_ERROR("[fork2]V2G_SECC_Sequence_Timeout in state %d - (%.02lf of %d ms)\n", status, time_diff, V2G_SECC_Sequence_Timeout); Update_V2G_Status(Sequence_Timeout); //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_TIMEOUT_V2G_Sequence_Time (023844) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 8; ShmStatusCodeData->PresentStatusCode[0][4] = 4; ShmStatusCodeData->PresentStatusCode[0][5] = 4; End_Process(); break; } else if (time_diff > 4000) //4s { //Check for CSU command of "Stop by EVSE" if (EVCOMM_SYS_INFO.DC_EVSEStatus == EVSE_Shutdown) { DEBUG_INFO("[Error_Monitor]EVSE_Shutdown\n"); Update_V2G_Status(Other_Fault); } else if (EVCOMM_SYS_INFO.DC_EVSEStatus == EVSE_EmergencyShutdown) { DEBUG_INFO("[Error_Monitor]EVSE_EmergencyShutdown\n"); Update_V2G_Status(Other_Fault); } else if (ShmInternalComm->ChargingPermission == FALSE) { if (status >= ChargeParameterDiscoveryRequest) //&& status < SessionStopRequest { DEBUG_INFO("[Error_Monitor]ChargingPermission = FALSE\n"); Update_V2G_Status(Other_Fault); } } else { //null } } else { //null } } //Step 3: Check and Response to Error V2gFlowStatus status = Get_V2G_Status(); if (status == Performance_Timeout || status == Sequence_Timeout || status == Other_Fault) { //Normal Stop DEBUG_ERROR("[fork2]Timeout or Fault State(%d) => End_Process\n", status); End_Process(); } //Step 4: Check and Response to CP State Error if(ccs->CpState_err == TRUE) { DEBUG_ERROR("[fork2]CP Error => End_Process\n"); Update_V2G_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 (Get_V2G_Status() <= SLACC_SDP_TCP_Connection) { DEBUG_INFO("[fork2]EVSE Shutdown(%d) => End_Process\n", EVCOMM_SYS_INFO.DC_EVSEStatus); Update_V2G_Status(Other_Fault); End_Process(); } } //Step 6: Check and Response to SessionStop status = Get_V2G_Status(); if (status == SessionStopResponse) { DEBUG_INFO("[fork2]SessionStopResponse => End_Process\n"); 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 >= CCS_CP_STATE_B2) && (ccs->CpState <= CCS_CP_STATE_D)) { if (status >= CM_SLAC_PARM_REQ && status != CM_SET_KEY_REQ && status != CM_SET_KEY_CNF && status <= SLACC_SDP_TCP_Connection) { DEBUG_INFO("[fork2]Permission OFF before V2G msg(%d) => End_Process\n", ShmInternalComm->ChargingPermission); Update_V2G_Status(Other_Fault); End_Process(); } } //Step 8: DC OVP Protection if (CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED && status > CableCheckResponse && status <= SessionStopRequest && status != ChargingStatusRequest && status != ChargingStatusResponse && EVCOMM_SYS_INFO.EvBatteryMaxVoltage != 0) { //Part A: OVP Protection if (EVCOMM_SYS_INFO.PresentChargingVoltage >= (EVCOMM_SYS_INFO.EvBatteryMaxVoltage * 1.02)) // 2% { DEBUG_ERROR("[fork2]OVP => End_Process (%.02f > %.02f)\n", EVCOMM_SYS_INFO.PresentChargingVoltage, (EVCOMM_SYS_INFO.EvBatteryMaxVoltage * 1.02)); Update_V2G_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)) { DEBUG_INFO("[fork2]Over V Req => End_Process (%.02f > %.02f)\n", EVCOMM_SYS_INFO.EvBatterytargetVoltage, (EVCOMM_SYS_INFO.EvBatteryMaxVoltage * 1.02)); Update_V2G_Status(Other_Fault); //Update_ShmStatusCode(); //[To-Do] to be implemented //System CCS output OVP (012219) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 1; ShmStatusCodeData->PresentStatusCode[0][2] = 2; ShmStatusCodeData->PresentStatusCode[0][3] = 2; ShmStatusCodeData->PresentStatusCode[0][4] = 1; ShmStatusCodeData->PresentStatusCode[0][5] = 9; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; Proc_EVStopRes(ShmInternalComm->FD_CAN_Socket); End_Process(); } } //Step 9: Check 60V /*+++ 20200808, vern, sync with Tesla CHAdeMO adaptor, 2 for start communication(not yet auth), 1 for star charging (authorized) ---*/ if (CCS_ENERGY_TRANSFER_MODE == MODE_DC_EXTENDED && ShmInternalComm->ChargingPermission >= 1 && status < CableCheckRequest) { if (EVCOMM_SYS_INFO.PresentChargingVoltage >= 60) //60V { DEBUG_INFO("[fork2]DC Output Voltage is over 60V => End_Process\n"); Update_V2G_Status(Other_Fault); //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_Unexpected_60V_Before_Charing_Error (023890) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 8; ShmStatusCodeData->PresentStatusCode[0][4] = 9; ShmStatusCodeData->PresentStatusCode[0][5] = 0; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; //Proc_EVStopRes(ShmInternalComm->FD_CAN_Socket); End_Process(); } } //Step 10: Check if the connector is unplug from plugin if (EVCOMM_SYS_INFO.ConnectorPlugIn_pre == TRUE && EVCOMM_SYS_INFO.ConnectorPlugIn == FALSE) { DEBUG_INFO("[fork2]Unplug Reset => End_Process\n"); Update_V2G_Status(Other_Fault); End_Process(); } usleep(1000); }//while } /** * * @return */ int SendSetKey() { unsigned char nRandValue = 0x0; unsigned char ConstString[16] = "PhihongKey000000"; memset(&qcaInfo.SendMmePacket, 0, sizeof(struct MmeHeader)); memcpy(qcaInfo.SendMmePacket.ODA, macAddr.qca, 6); memcpy(qcaInfo.SendMmePacket.OSA, macAddr.eth1, 6); qcaInfo.SendMmePacket.MTYPE = htons(EtherType_HomePlug); qcaInfo.SendMmePacket.MMV = 0x01; qcaInfo.SendMmePacket.MMTYPE = MMTYPE_CM_SET_KEY_REQ; qcaInfo.SendMmePacket.FMI[0] = qcaInfo.SendMmePacket.FMI[1] = 0; qcaInfo.SendMmePacketSize = 0; qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0x01;//Fixed value (0x01) to indicate ��NMK�� memset(qcaInfo.SendMmePacket.MMENTRY+qcaInfo.SendMmePacketSize, 0, 4);//My Nonce, Fixed value(0x00000000), encrypted payload not used qcaInfo.SendMmePacketSize += 4; memset(qcaInfo.SendMmePacket.MMENTRY+qcaInfo.SendMmePacketSize, 0, 4);//Your Nonce, Fixed value(0x00000000), encrypted payload not used qcaInfo.SendMmePacketSize += 4; qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0x04;//PID, Fixed value (0x04) to indicate ��HLE protocol�� memset(qcaInfo.SendMmePacket.MMENTRY+qcaInfo.SendMmePacketSize, 0, 2);//PRN, Fixed value(0x00), encrypted payload not used qcaInfo.SendMmePacketSize += 2; qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0x00;//PMN, Fixed value(0x00) encrypted payload not used qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0x01;//CCo Capablility srand(time(NULL)); for(int 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(qcaInfo.NewNmkKey, 0, sizeof(qcaInfo.NewNmkKey)); memset(qcaInfo.Nid, 0, sizeof(qcaInfo.Nid)); HPAVKeyNMK(qcaInfo.NewNmkKey, (char*)ConstString); HPAVKeyNID(qcaInfo.Nid, qcaInfo.NewNmkKey, DEFAULT_LEVEL); memcpy(qcaInfo.SendMmePacket.MMENTRY+qcaInfo.SendMmePacketSize, qcaInfo.Nid, sizeof(qcaInfo.Nid)); //NID, 54 LSBs contain the NID 2 MSBs = 0b00 qcaInfo.SendMmePacketSize += sizeof(qcaInfo.Nid); qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0x01;//NewEKS,Fixed value (0x01)to indicate ��NMK�� memcpy(qcaInfo.SendMmePacket.MMENTRY+qcaInfo.SendMmePacketSize, qcaInfo.NewNmkKey,sizeof(qcaInfo.NewNmkKey));//NewKey qcaInfo.SendMmePacketSize += sizeof(qcaInfo.NewNmkKey); qcaInfo.SendMmePacketSize += 19; //the size before MMENTRY DEBUG_INFO("QCA7000 [TX]CM_SET_KEY_REQ\n"); DEBUG_INFO("SendSetKey: send size: %d\n", sendto(socketFd.Raw, &qcaInfo.SendMmePacket, qcaInfo.SendMmePacketSize, 0, (struct sockaddr*)&qcaInfo.DestSocketAddress, sizeof(struct sockaddr_ll))); Update_V2G_Status(CM_SET_KEY_REQ); return 0; } /** * * @return */ int GetQca7kMac() { struct QcaVendorMmeHeader SendPacket; DEBUG_INFO("Req for QCA7K MacAddr\n"); memset(&SendPacket, 0, sizeof(struct QcaVendorMmeHeader)); memset(SendPacket.ODA, 0xFF, 6); //broadcast memcpy(SendPacket.OSA, macAddr.eth1, 6); SendPacket.MTYPE = htons(EtherType_HomePlug); SendPacket.MMV = 0x00; SendPacket.MMTYPE = MMTYPE_VENDOR_VS_NW_INFO; SendPacket.OUI[0] = 0x00; SendPacket.OUI[1] = 0xB0; SendPacket.OUI[2] = 0x52; DEBUG_INFO("GetQca7kMac: send size: %d\n", sendto(socketFd.Raw, &SendPacket, 20, 0, (struct sockaddr*)&qcaInfo.DestSocketAddress, sizeof(struct sockaddr_ll))); return 0; } /** * * @param ptr * @param size * @return */ 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; } /** * * @param ptrA * @param ptrB * @param size * @return */ 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 DEBUG_INFO("[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); #endif break; } } return result; } /** * * @param evcc * @param EvMac_in * @return */ 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 DEBUG_ERROR("DB length(%d) > %d\n", evcc->arrayLen, EVCC_SLAC_DATA_ARRAY_TYPE_ARRAY_SIZE); 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; } /** * * @param evcc * @param EvMac_in * @param RunID_in * @return */ 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; } /** * * @param EvMac_in * @param RunID_in * @return */ 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 { DEBUG_PRINTF_EVCOMM_DETAIL("data does not exist => added to %d-th\n", SLAC_INFO.arrayLen); 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 { DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR]arrayLen: unexpected(%d)\n", SLAC_INFO.arrayLen); SLAC_INFO.arrayLen = 0; } } else { //DB is full DEBUG_PRINTF_EVCOMM_DETAIL("DB is full(%d) => bypass\n", SLAC_INFO.arrayLen); } } else { #if 0 DEBUG_INFO("EvMac: existed (%d)\n", idx); #endif //Check RunID if (Array_Compare_Identity(SLAC_INFO.array[idx].RunID, RunID_in, SLAC_RUNID_LENGTH) == TRUE) { //RunID is the same //DEBUG_INFO("RunID: same\n"); } else { DEBUG_INFO("RunID: diff\n"); } //Reset all corresponding parameters #if 0 DEBUG_INFO("EvMac: reset para(%d)\n", idx); #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; } /** * * @return */ int SLAC_DB_Reset() { memset(&SLAC_INFO, 0, sizeof(struct EVCC_SLAC_DATA_TYPE)); DEBUG_INFO("DONE\n"); return 0; } /** * * @param Buffer * @param DataLength * @return */ int MmeProcess(unsigned char *Buffer, int DataLength) { //struct ethhdr *EthPacket; struct MmeHeader *MmePacket; static unsigned char counter; unsigned char state = 0; unsigned char tmpBuf[2048]={0}; int Rtn = 0; int idx = 0; unsigned char *EvMac_in; unsigned char *RunID_in; MmePacket = (struct MmeHeader *)Buffer; state = Get_V2G_Status(); DEBUG_PRINTF_EVCOMM_DETAIL("***********************************\n"); DEBUG_PRINTF_EVCOMM_DETAIL("******* Received MME Packet *******\n"); DEBUG_PRINTF_EVCOMM_DETAIL("***********************************\n"); DEBUG_PRINTF_EVCOMM_DETAIL("DataLength=%d\n",DataLength); DEBUG_PRINTF_EVCOMM_DETAIL("ODA: %02x:%02x:%02x:%02x:%02x:%02x\n", //Destination MAC Address MmePacket->ODA[0], MmePacket->ODA[1], MmePacket->ODA[2], MmePacket->ODA[3], MmePacket->ODA[4], MmePacket->ODA[5]); DEBUG_PRINTF_EVCOMM_DETAIL("OSA: %02x:%02x:%02x:%02x:%02x:%02x\n", //Source MAC Address (EV MAC) MmePacket->OSA[0], MmePacket->OSA[1], MmePacket->OSA[2], MmePacket->OSA[3], MmePacket->OSA[4], MmePacket->OSA[5]); DEBUG_PRINTF_EVCOMM_DETAIL("MTYPE: 0x%x\n", htons(MmePacket->MTYPE)); DEBUG_PRINTF_EVCOMM_DETAIL("MMV: 0x%x\n", MmePacket->MMV); DEBUG_PRINTF_EVCOMM_DETAIL("MMTYPE: 0x%x\n", MmePacket->MMTYPE); DEBUG_PRINTF_EVCOMM_DETAIL("FMI 0x%x, 0x%x\n", MmePacket->FMI[0],MmePacket->FMI[1]); #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 ) { //DEBUG_INFO("[SLAC]ignored(wrong CP state)\n"); 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%02x\n", MmePacket->MMENTRY[0]); DEBUG_INFO("CM_SET_KEY_CNF (SetKey: DONE)\n"); Update_V2G_Status(CM_SET_KEY_CNF); break; } case MMTYPE_CM_SLAC_PARM_REQ: { //Check QCA7000 status if (EVCOMM_SYS_INFO.QCA7K_SetKeyDone == FALSE) { //DEBUG_WARN("[SLAC][RX]CM_SLAC_PARM_REQ: ignored(QCA7K init...)\n"); break; } //Check error state state = Get_V2G_Status(); if (state == Performance_Timeout || //253 state == Sequence_Timeout || //254 state == Other_Fault) //255 { DEBUG_WARN("CM_SLAC_PARM_REQ: ignored(in error state)\n"); break; } //Printing EV MAC Address DEBUG_INFO("CM_SLAC_PARM_REQ\n"); //Avoid Coupled SLAC_PARM_REQ if (CheckConnectorPlugIn() == FALSE) //12V(State 1) { #if 0 DEBUG_WARN("[SLAC][RX]CM_SLAC_PARM_REQ: ignored(coupled SLAC,%d)\n", CheckConnectorPlugIn()); #endif break; } //[TC_SECC_VTB_CmSlacParm_003] SECURITY_TYPE needs to be 0x00 (no security) if (MmePacket->MMENTRY[1] != 0) { DEBUG_INFO("CM_SLAC_PARM_REQ: ignored(invalid SECURITY_TYPE,%d)\n", //Source MAC Address (EV MAC) MmePacket->MMENTRY[1]); break; } //=================== Legal CM_SLAC_PARM_REQ Zone ================= Update_V2G_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); DEBUG_INFO("Check Permission: %d (SLAC first => START)\n", ShmInternalComm->ChargingPermission); } 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]); //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) { DEBUG_WARN("DB is full or errors occour(%d) => ignore\n", idx); break; } //Select the 1st EV MAC address if (SLAC_INFO.arrayLen == 1) //1st Req { DEBUG_INFO("CM_SLAC_PARM_REQ[%d](%02X:%02X:%02X:%02X:%02X:%02X, %02X%02X%02X%02X%02X%02X%02X%02X):selected\n", (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]); } else //2nd Req { DEBUG_INFO("CM_SLAC_PARM_REQ[%d](%02X:%02X:%02X:%02X:%02X:%02X, %02X%02X%02X%02X%02X%02X%02X%02X):not selected\n", (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]); } memcpy(macAddr.evcc, MmePacket->OSA, sizeof(macAddr.evcc)); memcpy(qcaInfo.DestSocketAddress.sll_addr, MmePacket->OSA, SLAC_EVMAC_LENGTH); memcpy(qcaInfo.SlacRunId, MmePacket->MMENTRY + 2, SLAC_RUNID_LENGTH); memset(&qcaInfo.SendMmePacket, 0, sizeof(struct MmeHeader)); memcpy(qcaInfo.SendMmePacket.ODA, MmePacket->OSA, 6); memcpy(qcaInfo.SendMmePacket.OSA, macAddr.eth1, 6); qcaInfo.SendMmePacket.MTYPE = htons(EtherType_HomePlug); qcaInfo.SendMmePacket.MMV = MmePacket->MMV; qcaInfo.SendMmePacket.MMTYPE = MMTYPE_CM_SLAC_PARM_CNF; qcaInfo.SendMmePacket.FMI[0] = qcaInfo.SendMmePacket.FMI[1] = 0; qcaInfo.SendMmePacketSize = 0; memset(qcaInfo.SendMmePacket.MMENTRY, 0xFF, 6); //M-SOUND_TARGET(6-byte:0xFFFFFFFFFFFF): Fixed value indicating that M-Sounds to be sent as Ethernet broadcast qcaInfo.SendMmePacketSize += 6; qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = C_EV_match_MNBC; //NUM_SOUNDS(0x0A): Number of M-Sounds to be transmitted by the EV GP Station during the SLAC process qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 6; //Time_Out(0x06): unit = 100ms qcaInfo.SendMmePacket.MMENTRY[qcaInfo.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(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, SLAC_INFO.array[idx].EvMac, 6); //FORWARDING_STA(MAC Address of the EV HLE) qcaInfo.SendMmePacketSize += 6; qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0; //APPLICATION_TYPE(0x00): 0x00(PEV-EVSE Association), 0x01-0xFF(Reserved) qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0; //SECURITY_TYPE(0x00): 0x00(No Security), 0x01(Public Key Signature), 0x02-0xFF(Reserved) memcpy(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, qcaInfo.SlacRunId, SLAC_RUNID_LENGTH); //RunID (8-byte) qcaInfo.SendMmePacketSize += SLAC_RUNID_LENGTH; qcaInfo.SendMmePacketSize += 19; //the size before MMENTRY DEBUG_PRINTF_EVCOMM_DETAIL("***** Response MME Packet *****\n"); DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n", qcaInfo.SendMmePacket.ODA[0],qcaInfo.SendMmePacket.ODA[1],qcaInfo.SendMmePacket.ODA[2],qcaInfo.SendMmePacket.ODA[3],qcaInfo.SendMmePacket.ODA[4],qcaInfo.SendMmePacket.ODA[5]); DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n", qcaInfo.SendMmePacket.OSA[0],qcaInfo.SendMmePacket.OSA[1],qcaInfo.SendMmePacket.OSA[2],qcaInfo.SendMmePacket.OSA[3],qcaInfo.SendMmePacket.OSA[4],qcaInfo.SendMmePacket.OSA[5]); DEBUG_PRINTF_EVCOMM_DETAIL("MTYPE: 0x%x\n", htons(qcaInfo.SendMmePacket.MTYPE)); DEBUG_PRINTF_EVCOMM_DETAIL("MMV: 0x%x\n", qcaInfo.SendMmePacket.MMV); DEBUG_PRINTF_EVCOMM_DETAIL("MMTYPE: 0x%x\n", qcaInfo.SendMmePacket.MMTYPE); DEBUG_PRINTF_EVCOMM_DETAIL("FMI 0x%x, 0x%x\n", qcaInfo.SendMmePacket.FMI[0],qcaInfo.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", qcaInfo.SendMmePacket.MMENTRY[0],qcaInfo.SendMmePacket.MMENTRY[1],qcaInfo.SendMmePacket.MMENTRY[2],qcaInfo.SendMmePacket.MMENTRY[3],qcaInfo.SendMmePacket.MMENTRY[4],qcaInfo.SendMmePacket.MMENTRY[5]); DEBUG_PRINTF_EVCOMM_DETAIL("NUM_SOUNDS: 0x%x\n", qcaInfo.SendMmePacket.MMENTRY[6]); DEBUG_PRINTF_EVCOMM_DETAIL("Time_Out: 0x%x\n", qcaInfo.SendMmePacket.MMENTRY[7]); DEBUG_PRINTF_EVCOMM_DETAIL("RESP_TYPE: 0x%x\n", qcaInfo.SendMmePacket.MMENTRY[8]); DEBUG_PRINTF_EVCOMM_DETAIL("M-FORWARDING_STA: %02x:%02x:%02x:%02x:%02x:%02x:\n", qcaInfo.SendMmePacket.MMENTRY[9],qcaInfo.SendMmePacket.MMENTRY[10],qcaInfo.SendMmePacket.MMENTRY[11],qcaInfo.SendMmePacket.MMENTRY[12],qcaInfo.SendMmePacket.MMENTRY[13],qcaInfo.SendMmePacket.MMENTRY[14]); DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", qcaInfo.SendMmePacket.MMENTRY[15]); DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", qcaInfo.SendMmePacket.MMENTRY[16]); DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", qcaInfo.SendMmePacket.MMENTRY[17],qcaInfo.SendMmePacket.MMENTRY[18],qcaInfo.SendMmePacket.MMENTRY[19],qcaInfo.SendMmePacket.MMENTRY[20],qcaInfo.SendMmePacket.MMENTRY[21],qcaInfo.SendMmePacket.MMENTRY[22],qcaInfo.SendMmePacket.MMENTRY[23],qcaInfo.SendMmePacket.MMENTRY[24]); Update_V2G_Status(CM_SLAC_PARM_CONF); Rtn = sendto(socketFd.Raw, &qcaInfo.SendMmePacket, qcaInfo.SendMmePacketSize, 0, (struct sockaddr*)&qcaInfo.DestSocketAddress, sizeof(struct sockaddr_ll)); DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacketSize=%d, Rtn=%d\n", qcaInfo.SendMmePacketSize,Rtn); ftime(&timerStart.SeqStart); counter = 0; break; } case MMTYPE_CM_START_ATTEN_CHAR_IND: { if(V2gFlowStatus >= CM_ATTEN_CHAR_IND) { DEBUG_INFO("CM_START_ATTEN_CHAR_IND: ignored(time up)\n"); break; } //Avoid Coupled CM_START_ATTEN_CHAR_IND if (CheckConnectorPlugIn() == FALSE) //12V(State 1) { DEBUG_INFO("CM_START_ATTEN_CHAR_IND: ignored(coupled SLAC,%d)\n", CheckConnectorPlugIn()); break; } DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_START_ATTEN_CHAR_IND (counter : %d/3 ) ---\n", counter); DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", MmePacket->MMENTRY[0]); DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", MmePacket->MMENTRY[1]); DEBUG_PRINTF_EVCOMM_DETAIL("NUM_SOUNDS: 0x%x\n", MmePacket->MMENTRY[2]); DEBUG_PRINTF_EVCOMM_DETAIL("Time_Out 0x%x\n", MmePacket->MMENTRY[3]); DEBUG_PRINTF_EVCOMM_DETAIL("RESP_TYPE 0x%x\n", MmePacket->MMENTRY[4]); //Fixed value (0x01) indicating ��other Green PHY station�� DEBUG_PRINTF_EVCOMM_DETAIL("FORWARDING_STA: %02x:%02x:%02x:%02x:%02x:%02x\n", MmePacket->MMENTRY[5],MmePacket->MMENTRY[6],MmePacket->MMENTRY[7],MmePacket->MMENTRY[8], MmePacket->MMENTRY[9],MmePacket->MMENTRY[10]); DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", MmePacket->MMENTRY[11],MmePacket->MMENTRY[12],MmePacket->MMENTRY[13],MmePacket->MMENTRY[14], MmePacket->MMENTRY[15],MmePacket->MMENTRY[16],MmePacket->MMENTRY[17],MmePacket->MMENTRY[18]); 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_Status(CM_START_ATTEN_CHAR_IND); counter++; //[TC_SECC_VTB_AttenuationCharacterization_013] if (MmePacket->MMENTRY[0] != 0) //APPLICATION_TYPE must be 0x00(EV-EVSE Matching) { DEBUG_INFO("[CM_START_ATTEN_CHAR_IND]APPLICATION_TYPE(%d): invalid => ignore Req\n", MmePacket->MMENTRY[0]); break; } //[TC_SECC_VTB_AttenuationCharacterization_014] if (MmePacket->MMENTRY[1] != 0) //SECURITY_TYPE must be 0x00(No Security) { DEBUG_INFO("[CM_START_ATTEN_CHAR_IND]SECURITY_TYPE(%d): invalid => ignore Req\n", MmePacket->MMENTRY[1]); break; } //[TC_SECC_VTB_AttenuationCharacterization_017] if (MmePacket->MMENTRY[4] != 0x01) //RESP_TYPE must be 0x01(Send to another GP STA(EV)) { DEBUG_INFO("[CM_START_ATTEN_CHAR_IND]RESP_TYPE(%d): invalid => ignore Req\n", MmePacket->MMENTRY[4]); 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) { DEBUG_INFO("[CM_START_ATTEN_CHAR_IND]FORWARDING_STA(%02X:%02X:%02X:%02X:%02X:%02X): invalid => ignore Req\n", MmePacket->MMENTRY[5], MmePacket->MMENTRY[6], MmePacket->MMENTRY[7], MmePacket->MMENTRY[8], MmePacket->MMENTRY[9], MmePacket->MMENTRY[10]); 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 (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(&timerStart.SeqStart); //start TT_EVSE_match_MNBC } else if (SLAC_INFO.array[idx].StartAttenCharCnt >= 3) { DEBUG_INFO("[CM_START_ATTEN_CHAR_IND]counter(%d): unexpected \n", SLAC_INFO.array[idx].StartAttenCharCnt); } else { //null } } else { //This RunID is not matched with this EvMac, //or this RunID is not found in DB. DEBUG_INFO("[CM_START_ATTEN_CHAR_IND]EvMac-RunID: unmatched => ignore Req\n"); //Response: ignore } } else { //this msg source is not in database //ignore } break; } case MMTYPE_CM_MNBC_SOUND_IND: { if(V2gFlowStatus >= CM_ATTEN_CHAR_IND) { DEBUG_INFO("CM_MNBC_SOUND_IND: ignored(timeup)\n"); break; } //Avoid Coupled CM_MNBC_SOUND_IND if (CheckConnectorPlugIn() == FALSE) //12V(State 1) { DEBUG_INFO("CM_MNBC_SOUND_IND: ignored(coupled SLAC,%d)\n", CheckConnectorPlugIn()); break; } if(V2gFlowStatus == CM_START_ATTEN_CHAR_IND) { counter = 0; } DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_MNBC_SOUND_IND (counter : %d/%d) ---\n", counter, SLAC_INFO.array[idx].MnbcSoundNum); DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", MmePacket->MMENTRY[0]); DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", MmePacket->MMENTRY[1]); DEBUG_PRINTF_EVCOMM_DETAIL("SenderID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", MmePacket->MMENTRY[2],MmePacket->MMENTRY[3],MmePacket->MMENTRY[4],MmePacket->MMENTRY[5], MmePacket->MMENTRY[6],MmePacket->MMENTRY[7],MmePacket->MMENTRY[8],MmePacket->MMENTRY[9], MmePacket->MMENTRY[10],MmePacket->MMENTRY[11],MmePacket->MMENTRY[12],MmePacket->MMENTRY[13], MmePacket->MMENTRY[14],MmePacket->MMENTRY[15],MmePacket->MMENTRY[16],MmePacket->MMENTRY[17], MmePacket->MMENTRY[18]); DEBUG_PRINTF_EVCOMM_DETAIL("Cnt: 0x%x\n", MmePacket->MMENTRY[19]); DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", MmePacket->MMENTRY[20],MmePacket->MMENTRY[21],MmePacket->MMENTRY[22],MmePacket->MMENTRY[23], MmePacket->MMENTRY[24],MmePacket->MMENTRY[25],MmePacket->MMENTRY[26],MmePacket->MMENTRY[27]); DEBUG_PRINTF_EVCOMM_DETAIL("RSVD: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", MmePacket->MMENTRY[28],MmePacket->MMENTRY[29],MmePacket->MMENTRY[30],MmePacket->MMENTRY[31], MmePacket->MMENTRY[32],MmePacket->MMENTRY[33],MmePacket->MMENTRY[34],MmePacket->MMENTRY[35]); DEBUG_PRINTF_EVCOMM_DETAIL("Rnd: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", MmePacket->MMENTRY[36],MmePacket->MMENTRY[37],MmePacket->MMENTRY[38],MmePacket->MMENTRY[39], MmePacket->MMENTRY[40],MmePacket->MMENTRY[41],MmePacket->MMENTRY[42],MmePacket->MMENTRY[43], MmePacket->MMENTRY[44],MmePacket->MMENTRY[45],MmePacket->MMENTRY[46],MmePacket->MMENTRY[47], MmePacket->MMENTRY[48],MmePacket->MMENTRY[49],MmePacket->MMENTRY[50],MmePacket->MMENTRY[51]); 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_Status(CM_MNBC_SOUND_IND); counter++; //Check for RunID if (SLAC_DB_Check_EvMac_RunID_Matching(&SLAC_INFO, EvMac_in, RunID_in) == TRUE) { SLAC_INFO.array[idx].MnbcSoundCnt++; } else { //RunID is not matched or does not exist. DEBUG_INFO("CM_MNBC_SOUND_IND]EvMac-RunID: unmatched\n"); } } else { //ignore DEBUG_INFO("CM_MNBC_SOUND_IND]EvMac does not exist\n"); } break; } case MMTYPE_CM_ATTEN_PROFILE_IND: { if(V2gFlowStatus >= CM_ATTEN_CHAR_IND) { DEBUG_INFO("CM_ATTEN_PROFILE_IND: ignore(timeup)\n"); break; } DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_ATTEN_PROFILE_IND (counter : %d/%d) ---\n", counter, SLAC_INFO.array[idx].MnbcSoundNum); DEBUG_PRINTF_EVCOMM_DETAIL("EV MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", MmePacket->MMENTRY[0], MmePacket->MMENTRY[1], MmePacket->MMENTRY[2], MmePacket->MMENTRY[3], MmePacket->MMENTRY[4], MmePacket->MMENTRY[5]); DEBUG_PRINTF_EVCOMM_DETAIL("NumGroups: 0x%x\n", MmePacket->MMENTRY[6]); //NumGroups, Number of AAG Groups (ex: 0x3A = 58) //NumGroups: Number of OFDM carrier groups used for the SLAC signal characterization. //AAG[i]: Average Attenuation of Group i (i = 1 ~ 58) DEBUG_PRINTF_EVCOMM_DETAIL("RSVD: 0x%x\n", MmePacket->MMENTRY[7]); memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf)); for(Rtn = 0; Rtn < MmePacket->MMENTRY[6]; Rtn++) { sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, MmePacket->MMENTRY[8 + Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("AAG: %s\n", tmpBuf); 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); if (idx >= 0) { SLAC_INFO.array[idx].AttenProfileCnt++; 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_Status(CM_MNBC_SOUND_IND); break; } else { //The EvMac is not in the database //ignore DEBUG_INFO("[CM_ATTEN_PROFILE_IND]EvMac(%02X%02X%02X%02X%02X%02X): not exist => ignore\n", EvMac_in[0], EvMac_in[1], EvMac_in[2], EvMac_in[3], EvMac_in[4], EvMac_in[5]); break; } } case MMTYPE_CM_ATTEN_CHAR_RSP: { DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_CM_ATTEN_CHAR_RSP ---\n"); DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", MmePacket->MMENTRY[0]); DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", MmePacket->MMENTRY[1]); DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x\n", MmePacket->MMENTRY[2],MmePacket->MMENTRY[3],MmePacket->MMENTRY[4],MmePacket->MMENTRY[5], MmePacket->MMENTRY[6],MmePacket->MMENTRY[7]); DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", MmePacket->MMENTRY[8],MmePacket->MMENTRY[9],MmePacket->MMENTRY[10],MmePacket->MMENTRY[11], MmePacket->MMENTRY[12],MmePacket->MMENTRY[13],MmePacket->MMENTRY[14],MmePacket->MMENTRY[15]); memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf)); for(Rtn = 0; Rtn < 17; Rtn++) { sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, MmePacket->MMENTRY[16 + Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ID: %s\n", tmpBuf); ; memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf)); for(Rtn = 0; Rtn < 17; Rtn++) { sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, MmePacket->MMENTRY[33 + Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("RESP_ID: %s\n", tmpBuf); DEBUG_PRINTF_EVCOMM_DETAIL("Result: 0x%x\n", MmePacket->MMENTRY[50]); //Fixed value of 0x00 indicates a successful SLAC process //Check ODA (Destination Address) if (Array_Compare_Identity(macAddr.eth1, MmePacket->ODA, SLAC_EVSE_MAC_LENGTH) == FALSE) { DEBUG_INFO("[CM_ATTEN_CHAR_RSP]wrong ODA: ignore\n"); 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++; DEBUG_WARN("[SLAC][RX]CM_ATTEN_CHAR_RSP:invalid para(%d,%d,%d,%d,%d) => %d-th retry\n", 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 ); if (EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry <= 2) //limited to 2 retries { Update_V2G_Status(CM_MNBC_SOUND_IND); ftime(&timerStart.SeqStart); break; } else { DEBUG_ERROR("[SLAC][RX]CM_ATTEN_CHAR_RSP:invalid para => 2-retry fail => End_Process\n"); Update_V2G_Status(Other_Fault); break; } } else { //The CM_ATTEN_CHAR_IND is legal SLAC_INFO.array[idx].AttenCharRspCnt++; DEBUG_INFO("[SLAC][RX]CM_ATTEN_CHAR_RSP[%d]:%d-th\n", (idx + 1), SLAC_INFO.array[idx].AttenCharRspCnt); EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry = 0; Update_V2G_Status(CM_ATTEN_CHAR_RSP); ftime(&timerStart.SeqStart); break; } } case MMTYPE_CM_VALIDATE_REQ: //BCB Toggle { 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��. counter = 0; EvMac_in = &MmePacket->OSA[0]; idx = SLAC_DB_Search_EvMac_idx(&SLAC_INFO, EvMac_in); if (idx >= 0) { Update_V2G_Status(CM_VALIDATE_CNF); SLAC_INFO.array[idx].ValidateReqCnt++; DEBUG_INFO("[SLAC][RX]CM_VALIDATE_REQ[%d]:%d-th\n", (idx + 1), SLAC_INFO.array[idx].ValidateReqCnt); //TODO: // 1. Protection memset(&qcaInfo.SendMmePacket, 0, sizeof(struct MmeHeader)); memcpy(qcaInfo.SendMmePacket.ODA, EvMac_in, SLAC_EVMAC_LENGTH); memcpy(qcaInfo.SendMmePacket.OSA, macAddr.eth1, 6); qcaInfo.SendMmePacket.MTYPE = htons(EtherType_HomePlug); qcaInfo.SendMmePacket.MMV = 0x01; qcaInfo.SendMmePacket.MMTYPE = MMTYPE_CM_VALIDATE_CNF; qcaInfo.SendMmePacket.FMI[0] = qcaInfo.SendMmePacket.FMI[1] = 0; qcaInfo.SendMmePacketSize = 0; if(counter == 0) { //The First MMTYPE_CM_VALIDATE_REQ because Unicast qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0; //SignalType(0x00): Fixed value to indicate "EV S2 toggles on control pilot line" qcaInfo.SendMmePacket.MMENTRY[qcaInfo.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) qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 1; //0x01 = Ready #else qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 4; //0x04 = Not Required #endif } else { //The Second MMTYPE_CM_VALIDATE_REQ because Broadcast unsigned char PreStatus = 3; unsigned char ToggleNum = 0; ftime(&timerStart.SeqStart); while(1) { if((EVCOMM_SYS_INFO.CpState == 4) && (PreStatus == 3)) { ToggleNum++; PreStatus = 4; } else { PreStatus = 3; } ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) >= (qcaInfo.SendMmePacket.MMENTRY[1]*100 + 100)) { qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0; //Fixed value to indicate "PEV S2 toggles on control pilot line" qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = ToggleNum; #if (SUPPORT_BCB_TOGGLE_FUNCTION == ENABLE) qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 2; //0x02 = Success #else qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 4; //0x04 = Not Required #endif break; } usleep(1000); } } qcaInfo.SendMmePacketSize += 19; //the size before MMENTRY Rtn = sendto(socketFd.Raw, &qcaInfo.SendMmePacket, qcaInfo.SendMmePacketSize, 0, (struct sockaddr*)&qcaInfo.DestSocketAddress, sizeof(struct sockaddr_ll)); ftime(&timerStart.SeqStart); } else { //EvMac does not exist. //ignore } break; } case MMTYPE_CM_SLAC_MATCH_REQ: { char buf[512]; 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 memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<17; Rtn++) { sprintf(buf, "%s%02x ", buf, MmePacket->MMENTRY[4+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("PEV ID: %s\n", buf); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<6; Rtn++) { sprintf(buf, "%s%02x ", buf, MmePacket->MMENTRY[21+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("PEV MAC: %s\n", buf); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<17; Rtn++) { sprintf(buf, "%s%02x ", buf, MmePacket->MMENTRY[27+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("EVSE ID: %d\n", buf); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<6; Rtn++) { sprintf(buf, "%s%02x ", buf, MmePacket->MMENTRY[44+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("EVSE MAC: %s\n", buf); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<8; Rtn++) { sprintf(buf, "%s%02x ", buf, MmePacket->MMENTRY[50+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %s\n", buf); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<8; Rtn++) { sprintf(buf, "%s%02x ", buf, MmePacket->MMENTRY[58+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("RSVD: %s\n", buf); //Check ODA (Destination Address) if (Array_Compare_Identity(macAddr.eth1, MmePacket->ODA, SLAC_EVSE_MAC_LENGTH) == FALSE) { DEBUG_WARN("[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_Status(CM_SLAC_MATCH_REQ); SLAC_INFO.array[idx].MatchReqNum++; DEBUG_INFO("CM_SLAC_MATCH_REQ[%d]:%d-th\n", (idx + 1), SLAC_INFO.array[idx].MatchReqNum); //[TC_SECC_VTB_CmSlacMatch_007] APPLICATION_TYPE must be 0x00(EV-EVSE Matching) //[TC_SECC_VTB_CmSlacMatch_008] if (MmePacket->MMENTRY[0] != 0) { DEBUG_WARN("CM_SLAC_MATCH_REQ[%d]:wrong APPLICATION_TYPE(%d)\n", (idx + 1), MmePacket->MMENTRY[0]); break; } //[TC_SECC_VTB_CmSlacMatch_009] SECURITY_TYPE must be 0x00(No Security) //[TC_SECC_VTB_CmSlacMatch_010] if (MmePacket->MMENTRY[1] != 0) { DEBUG_WARN("CM_SLAC_MATCH_REQ[%d]:wrong SECURITY_TYPE(%d)\n", (idx + 1), MmePacket->MMENTRY[1]); 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) { DEBUG_WARN("CM_SLAC_MATCH_REQ[%d]:wrong MVFLength(%d,%d)\n", (idx + 1), MmePacket->MMENTRY[2], MmePacket->MMENTRY[3]); 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) { DEBUG_WARN("CM_SLAC_MATCH_REQ[%d]: wrong EV ID\n", (idx + 1)); 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) { DEBUG_WARN("CM_SLAC_MATCH_REQ[%d]: wrong EV MAC(%02X:%02X:%02X:%02X:%02X:%02X)\n", (idx + 1), MmePacket->MMENTRY[21], MmePacket->MMENTRY[22], MmePacket->MMENTRY[23], MmePacket->MMENTRY[24], MmePacket->MMENTRY[25], MmePacket->MMENTRY[26]); 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) { DEBUG_WARN("CM_SLAC_MATCH_REQ[%d]: wrong EVSE ID\n", (idx + 1)); break; } //[TC_SECC_VTB_CmSlacMatch_019] EVSE MAC //[TC_SECC_VTB_CmSlacMatch_020] if (Array_Compare_Identity(macAddr.eth1, &MmePacket->MMENTRY[44], SLAC_EVSE_MAC_LENGTH) == FALSE) { DEBUG_WARN("CM_SLAC_MATCH_REQ[%d]: wrong EVSE MAC(%02X:%02X:%02X:%02X:%02X:%02X)\n", (idx + 1), MmePacket->MMENTRY[44], MmePacket->MMENTRY[45], MmePacket->MMENTRY[46], MmePacket->MMENTRY[47], MmePacket->MMENTRY[48], MmePacket->MMENTRY[49]); 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(&qcaInfo.SendMmePacket, 0, sizeof(struct MmeHeader)); memcpy(qcaInfo.SendMmePacket.ODA, MmePacket->OSA, 6); memcpy(qcaInfo.SendMmePacket.OSA, macAddr.eth1, 6); qcaInfo.SendMmePacket.MTYPE = htons(EtherType_HomePlug); qcaInfo.SendMmePacket.MMV = MmePacket->MMV; qcaInfo.SendMmePacket.MMTYPE = MMTYPE_CM_SLAC_MATCH_CNF; qcaInfo.SendMmePacket.FMI[0] = qcaInfo.SendMmePacket.FMI[1] = 0; qcaInfo.SendMmePacketSize = 0; qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0x00; //APPLICATION_TYPE: Fixed value (0x00: EV-EVSE matching) qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0x00; //SECURITY_TYPE: Fixed value (0x00: No Security) qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0x56; //MVFLength: MatchVarField Length (Fixed value: 0x0056) qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0x00; //MVFLength: MatchVarField Length (Fixed value: 0x0056) memset(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, 0, 17); //EV ID qcaInfo.SendMmePacketSize += 17; memcpy(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, EvMac_in, SLAC_EVMAC_LENGTH); //EV MAC qcaInfo.SendMmePacketSize += 6; memset(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, 0, 17); //EVSE ID qcaInfo.SendMmePacketSize += 17; memcpy(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, macAddr.eth1, 6); //EVSE MAC qcaInfo.SendMmePacketSize += 6; memcpy(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, RunID_in, SLAC_RUNID_LENGTH); qcaInfo.SendMmePacketSize += SLAC_RUNID_LENGTH; memset(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, 0, 8); //RSVD qcaInfo.SendMmePacketSize += 8; memcpy(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, qcaInfo.Nid, sizeof(qcaInfo.Nid)); //NID: Network ID given by the CCo(EVSE) qcaInfo.SendMmePacketSize += sizeof(qcaInfo.Nid); //NID caculated from the random NMK that will be set. qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0x00; //RSVD memcpy(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, qcaInfo.NewNmkKey, sizeof(qcaInfo.NewNmkKey)); //NMK: Random value qcaInfo.SendMmePacketSize += sizeof(qcaInfo.NewNmkKey); //NMK: Private NMK of the EVSE (random value) qcaInfo.SendMmePacketSize += 19; //the size before MMENTRY DEBUG_PRINTF_EVCOMM_DETAIL("***** Response MME Packet *****\n"); DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n", qcaInfo.SendMmePacket.ODA[0],qcaInfo.SendMmePacket.ODA[1],qcaInfo.SendMmePacket.ODA[2],qcaInfo.SendMmePacket.ODA[3],qcaInfo.SendMmePacket.ODA[4],qcaInfo.SendMmePacket.ODA[5]); DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n", qcaInfo.SendMmePacket.OSA[0],qcaInfo.SendMmePacket.OSA[1],qcaInfo.SendMmePacket.OSA[2],qcaInfo.SendMmePacket.OSA[3],qcaInfo.SendMmePacket.OSA[4],qcaInfo.SendMmePacket.OSA[5]); DEBUG_PRINTF_EVCOMM_DETAIL("MTYPE: 0x%x\n", htons(qcaInfo.SendMmePacket.MTYPE)); DEBUG_PRINTF_EVCOMM_DETAIL("MMV: 0x%x\n", qcaInfo.SendMmePacket.MMV); DEBUG_PRINTF_EVCOMM_DETAIL("MMTYPE: 0x%x\n", qcaInfo.SendMmePacket.MMTYPE); DEBUG_PRINTF_EVCOMM_DETAIL("FMI 0x%x, 0x%x\n", qcaInfo.SendMmePacket.FMI[0],qcaInfo.SendMmePacket.FMI[1]); DEBUG_PRINTF_EVCOMM_DETAIL("--- CM_SLAC_MATCH_CNF ---\n"); DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", qcaInfo.SendMmePacket.MMENTRY[0]); DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", qcaInfo.SendMmePacket.MMENTRY[1]); DEBUG_PRINTF_EVCOMM_DETAIL("MVFLength: 0x%x, 0x%x\n", qcaInfo.SendMmePacket.MMENTRY[2],qcaInfo.SendMmePacket.MMENTRY[3]); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<17; Rtn++) { sprintf(buf, "%s%02x ", buf, qcaInfo.SendMmePacket.MMENTRY[4+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("PEV ID: %d\n", buf); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<6; Rtn++) { sprintf(buf, "%s%02x ", buf, qcaInfo.SendMmePacket.MMENTRY[21+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("PEV MAC: %s\n", buf); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<17; Rtn++) { sprintf(buf, "%s%02x ", buf, qcaInfo.SendMmePacket.MMENTRY[27+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("EVSE ID: %s\n", buf); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<6; Rtn++) { sprintf(buf, "%s%02x ", buf, qcaInfo.SendMmePacket.MMENTRY[44+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("EVSE MAC: %s\n", buf); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<8; Rtn++) { sprintf(buf, "%s%02x ", buf, qcaInfo.SendMmePacket.MMENTRY[50+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %s\n", buf); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<8; Rtn++) { sprintf(buf, "%s%02x ", buf, qcaInfo.SendMmePacket.MMENTRY[58+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("RSVD: %s\n", buf); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<7; Rtn++) { sprintf(buf, "%s%02x ", buf, qcaInfo.SendMmePacket.MMENTRY[66+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("NID: %s\n", buf); DEBUG_PRINTF_EVCOMM_DETAIL("RSVD: 0x%02x\n", qcaInfo.SendMmePacket.MMENTRY[73]); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn=0; Rtn<16; Rtn++) { sprintf(buf, "%s%02x ", buf, qcaInfo.SendMmePacket.MMENTRY[74+Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("NMK: \n"); Update_V2G_Status(CM_SLAC_MATCH_CNF); Rtn = sendto(socketFd.Raw, &qcaInfo.SendMmePacket, qcaInfo.SendMmePacketSize, 0, (struct sockaddr*)&qcaInfo.DestSocketAddress, sizeof(struct sockaddr_ll)); DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacketSize=%d,Rtn=%d\n", qcaInfo.SendMmePacketSize,Rtn); DEBUG_INFO( "CM_SLAC_MATCH_CNF[%d]\n", (idx + 1)); ftime(&timerStart.SeqStart); } else { //RunID does not match and it's not the first SLAC request //Reset the SLAC database to embrace SLAC retry DEBUG_INFO("[CM_SLAC_MATCH_REQ]No Real MATCH_REQ\n"); 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: { // Only Set key for local QCA7000 if((MmePacket->OSA[0] == MmePacket->MMENTRY[12]) && (MmePacket->OSA[1] == MmePacket->MMENTRY[13]) && (MmePacket->OSA[2] == MmePacket->MMENTRY[14]) && (MmePacket->OSA[3] == MmePacket->MMENTRY[15]) && (MmePacket->OSA[4] == MmePacket->MMENTRY[16]) && (MmePacket->OSA[5] == MmePacket->MMENTRY[17])) { memcpy(macAddr.qca, MmePacket->OSA, 6); DEBUG_PRINTF_EVCOMM_DETAIL("--- MMTYPE_VENDOR_VS_NW_INFO_CNF ---\n"); DEBUG_INFO("EVSE MAC address(QCA): %02X:%02X:%02X:%02X:%02X:%02X(comm:OK)\n", macAddr.qca[0], macAddr.qca[1], macAddr.qca[2], macAddr.qca[3], macAddr.qca[4], macAddr.qca[5]); Update_V2G_Status(CM_SET_KEY_REQ); ftime(&timerStart.SeqStart); } break; } case MMTYPE_VENDOR_VS_PL_LNK_STATUS_CNF: { struct QcaVendorMmeHeader *RecvPacket; RecvPacket = (struct QcaVendorMmeHeader *)Buffer; if(RecvPacket->MBODY[1]==0) { //PLC disconnected DEBUG_INFO("[MMTYPE_VENDOR_VS_PL_LNK_STATUS_CNF]Got PLC Link Status:%d\n", RecvPacket->MBODY[1]); Update_V2G_Status(Other_Fault); } else Update_V2G_Status(CM_SET_KEY_REQ); ftime(&timerStart.SeqStart); break; } default: { break; } } return 0; } /** * * @return */ int SlacComm() { static unsigned char qca7k_comm_retry = 0; double t_diff = 0; int packet_size = 0; int count = 0; unsigned char tmpBuf[2048]={0}; unsigned char *EvMac_in; unsigned char *RunID_in; int i = 0; if(socketFd.Raw >= 0) { memset(v2gBuffer.rx, 0, V2GTP_MSG_RX_BUFFER_SIZE); packet_size = recvfrom(socketFd.Raw, v2gBuffer.rx, V2GTP_MSG_RX_BUFFER_SIZE, 0, NULL, NULL); if(packet_size > 0) { MmeProcess(v2gBuffer.rx, packet_size); } } switch(Get_V2G_Status()) { case IDLE: { if(socketFd.Raw < 0) { socketFd.Raw = socket(PF_PACKET, SOCK_RAW, htons(EtherType_HomePlug)); DEBUG_INFO("[RawSock]opened(%d)\n", socketFd.Raw); if(socketFd.Raw == -1) { DEBUG_ERROR("SlacComm:Failed to create socket\n"); Update_V2G_Status(Other_Fault); return -1; } if (setsockopt(socketFd.Raw, SOL_SOCKET, SO_BINDTODEVICE, QcaInterface, 4) < 0) { DEBUG_ERROR("SlacComm:Set SO_BINDTODEVICE NG\n"); Update_V2G_Status(Other_Fault); return -1; } struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 100000; //100ms (Rx timeout) if (setsockopt(socketFd.Raw, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { DEBUG_ERROR("SlacComm:Set SO_RCVTIMEO NG\n"); Update_V2G_Status(Other_Fault); return -1; } tv.tv_usec = 100000; //100ms (Tx timeout) if (setsockopt(socketFd.Raw, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { DEBUG_ERROR("SlacComm:Set SO_SNDTIMEO NG\n"); Update_V2G_Status(Other_Fault); return -1; } memset(&qcaInfo.Req, 0, sizeof(struct ifreq)); strcpy( (char*)qcaInfo.Req.ifr_name, QcaInterface); if (ioctl(socketFd.Raw, SIOCGIFINDEX, &qcaInfo.Req) < 0) { DEBUG_ERROR("SlacComm: ioctl NG\n"); Update_V2G_Status(Other_Fault); return -1; } memset(&qcaInfo.DestSocketAddress, 0, sizeof(struct sockaddr_ll)); qcaInfo.DestSocketAddress.sll_ifindex = qcaInfo.Req.ifr_ifindex; qcaInfo.DestSocketAddress.sll_halen = ETH_ALEN; timerStart.PwmStart = 0; EVCOMM_SYS_INFO.QCA7K_SetKeyDone = FALSE; DEBUG_INFO("QCA7000 connecting...\n"); //Get QCA7K MAC address GetQca7kMac(); ftime(&timerStart.SeqStart); break; } else //RawSock: opened { if(EVCOMM_SYS_INFO.QCA7K_SetKeyDone == FALSE) { ftime(&timerStart.SeqEnd); t_diff = DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd); if (t_diff > V2G_SECC_QCA7000_GET_MAC_ADDR_REQ_RETRY_PERIOD) //3 secs { qca7k_comm_retry++; DEBUG_INFO("Re-try connecting...(%.02lf/%dms)\n", t_diff, V2G_SECC_QCA7000_GET_MAC_ADDR_REQ_RETRY_PERIOD); GetQca7kMac(); //re-send req ftime(&timerStart.SeqStart); break; } else {} //Retry by 3 times if (qca7k_comm_retry >= 3) { DEBUG_ERROR("Comm: fail (retry by %d times)\n", qca7k_comm_retry); //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECCC_TIMEOUT_QCA7000_COMM (023892): The firmware code of QCA7000 may not be installed, yet ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 8; ShmStatusCodeData->PresentStatusCode[0][4] = 9; ShmStatusCodeData->PresentStatusCode[0][5] = 2; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Proc_EVStopRes(ShmInternalComm->FD_CAN_Socket); Update_V2G_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(timerStart.PwmStart <= 0) { //Sniffer_Tcpdump(ENABLE); //#if (TCPDUMP_PACKETS_SNIFFER_SWITCH == ENABLE) //sleep(1); //wait for tcpdump to be ready. //#endif SwitchCpStateE(DISABLE); OutputCpPwmDuty(5); timerStart.PwmStart = time(NULL); #ifdef TEST_WITH_ETH0 Update_V2G_Status(SLACC_SDP_UDP_Connection); #endif } else { if((time(NULL) - timerStart.PwmStart) > TT_EVSE_SLAC_init) { DEBUG_ERROR("SlacComm: Wait CM_SLAC_PARM_REQ Timeout - TT_EVSE_SLAC_init, NowTime(%ld)-timerStart.PwmStart(%d)>%d (sec)\n", time(NULL), timerStart.PwmStart, TT_EVSE_SLAC_init); //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_Status(Sequence_Timeout); timerStart.PwmStart = 0; return -1; } else { //waiting for CM_SLAC_PARM_REQ } } } else { timerStart.PwmStart = 0; } } } break; } case CM_SET_KEY_REQ: //13 { //CM_SET_KEY_REQ //DEBUG_INFO("QCA7000 [RX]CM_SET_KEY_REQ\n"); ftime(&timerStart.SeqEnd); t_diff = DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd); if (t_diff > V2G_SECC_QCA7000_COMM_TIMEOUT) //10 seconds { DEBUG_ERROR("QCA7000 Failed on SetKey => End_Process (%.02lf/%dms)\n", t_diff, V2G_SECC_QCA7000_COMM_TIMEOUT); //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECCC_TIMEOUT_QCA7000_COMM (023892): The firmware code of QCA7000 may not be installed, yet ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 8; ShmStatusCodeData->PresentStatusCode[0][4] = 9; ShmStatusCodeData->PresentStatusCode[0][5] = 2; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Sequence_Timeout); } else if (t_diff > V2G_SECC_QCA7000_SEND_SET_KEY_PERIOD) //2 seconds { DEBUG_INFO("QCA7000 SetKey: proceed (%.02lf/%dms)\n", t_diff, V2G_SECC_QCA7000_SEND_SET_KEY_PERIOD); SendSetKey(); ftime(&timerStart.SeqStart); } else { //null } break; } case CM_SET_KEY_CNF: //14 { DEBUG_INFO("Wait: plugin(%d), matached(%d), permission(%d)...\n", CheckConnectorPlugIn(), CSUCOMMDC_TASK_FLAG.matched, ShmInternalComm->ChargingPermission); EVCOMM_SYS_INFO.QCA7K_SetKeyDone = TRUE; timerStart.PwmStart = 0; Update_V2G_Status(IDLE); break; } case CM_SLAC_PARM_CONF: { ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > TT_match_sequence) { DEBUG_ERROR("SlacComm: Wait CM_START_ATTEN_CHAR_IND Timeout - TT_match_sequence (%.02lf of %dms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), TT_match_sequence); //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_TIMEOUT_CM_START_ATTEN_CHAR_IND (023811): //[Possible Reason] CCS Board image might not be updated properly. The 2nd reboot process is not finished. //[Verification Method] By tying reboot command to the terminal and see if it could be executed immediately. ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 8; ShmStatusCodeData->PresentStatusCode[0][4] = 1; ShmStatusCodeData->PresentStatusCode[0][5] = 1; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Sequence_Timeout); return -1; } break; } case CM_START_ATTEN_CHAR_IND: { ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > (TP_EV_batch_msg_interval)) //one more time interval for tolerance { DEBUG_ERROR("SlacComm: Wait CM_MNBC_SOUND_IND Timeout - TP_EV_batch_msg_interval (%.02lf of %dms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), TP_EV_batch_msg_interval); //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_TIMEOUT_SLAC_CM_MNBC_SOUND_IND (023818): //[Possible Reason] CCS Board image might not be updated properly. The 2nd reboot process is not finished. //[Verification Method] By tying reboot command to the terminal and see if it could be executed immediately. ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 8; ShmStatusCodeData->PresentStatusCode[0][4] = 1; ShmStatusCodeData->PresentStatusCode[0][5] = 8; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Sequence_Timeout); return -1; } break; } case CM_MNBC_SOUND_IND: { ftime(&timerStart.SeqEnd); t_diff = DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd); //printf("time:%.02lf, profilNum:%d\n",DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd),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) { DEBUG_WARN("[SLAC][TX]CM_ATTEN_CHAR_IND[%d]: timeup(%.2f/%dms) => send\n", (i + 1), t_diff, TT_EVSE_match_MNBC); } //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) DEBUG_WARN("[SLAC][TX]CM_ATTEN_CHAR_IND[%d]: para err(%d,%d,%d,%d,%d) => canceled\n", (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); 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)) { DEBUG_INFO("[SLAC][TX]CM_ATTEN_CHAR_IND[%d]: canceled\n", (i + 1)); break; } EvMac_in = SLAC_INFO.array[i].EvMac; RunID_in = SLAC_INFO.array[i].RunID; memset(&qcaInfo.SendMmePacket, 0, sizeof(struct MmeHeader)); memcpy(qcaInfo.SendMmePacket.ODA, EvMac_in, SLAC_EVMAC_LENGTH); memcpy(qcaInfo.SendMmePacket.OSA, macAddr.eth1, 6); qcaInfo.SendMmePacket.MTYPE = htons(EtherType_HomePlug); qcaInfo.SendMmePacket.MMV = 0x01; qcaInfo.SendMmePacket.MMTYPE = MMTYPE_CM_ATTEN_CHAR_IND; qcaInfo.SendMmePacket.FMI[0] = qcaInfo.SendMmePacket.FMI[1] = 0; qcaInfo.SendMmePacketSize = 0; qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0; //APPLICATION_TYPE(0x00: EV-EVSE Matching) qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = 0; //SECURITY_TYPE(0x00: No Security) memcpy(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, EvMac_in, SLAC_EVMAC_LENGTH); //SOURCE_ADDRESS, MAC address of the EV Host qcaInfo.SendMmePacketSize += SLAC_EVMAC_LENGTH; memcpy(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, RunID_in, SLAC_RUNID_LENGTH); qcaInfo.SendMmePacketSize += SLAC_RUNID_LENGTH; memset(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, 0, 17); //SOURCE_ID(0x00) qcaInfo.SendMmePacketSize += 17; memset(qcaInfo.SendMmePacket.MMENTRY + qcaInfo.SendMmePacketSize, 0, 17); //RESP_ID(0x00) qcaInfo.SendMmePacketSize += 17; qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = SLAC_INFO.array[i].AttenProfileCnt; //NumSounds: Number of M-Sounds used for generation of the ATTEN_PROFILE qcaInfo.SendMmePacket.MMENTRY[qcaInfo.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 qcaInfo.SendMmePacket.MMENTRY[qcaInfo.SendMmePacketSize++] = TmpAag; SLAC_INFO.array[i].AAG_quality_refined += (float) TmpAag; //refined signal quality } qcaInfo.SendMmePacketSize += 19; //the size before MMENTRY DEBUG_PRINTF_EVCOMM_DETAIL("***** Send MME Packet *****\n"); DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n", qcaInfo.SendMmePacket.ODA[0],qcaInfo.SendMmePacket.ODA[1],qcaInfo.SendMmePacket.ODA[2],qcaInfo.SendMmePacket.ODA[3],qcaInfo.SendMmePacket.ODA[4],qcaInfo.SendMmePacket.ODA[5]); DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacket.OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n", qcaInfo.SendMmePacket.OSA[0],qcaInfo.SendMmePacket.OSA[1],qcaInfo.SendMmePacket.OSA[2],qcaInfo.SendMmePacket.OSA[3],qcaInfo.SendMmePacket.OSA[4],qcaInfo.SendMmePacket.OSA[5]); DEBUG_PRINTF_EVCOMM_DETAIL("MTYPE: 0x%x\n", htons(qcaInfo.SendMmePacket.MTYPE)); DEBUG_PRINTF_EVCOMM_DETAIL("MMV: 0x%x\n", qcaInfo.SendMmePacket.MMV); DEBUG_PRINTF_EVCOMM_DETAIL("MMTYPE: 0x%x\n", qcaInfo.SendMmePacket.MMTYPE); DEBUG_PRINTF_EVCOMM_DETAIL("FMI 0x%x, 0x%x\n", qcaInfo.SendMmePacket.FMI[0],qcaInfo.SendMmePacket.FMI[1]); DEBUG_PRINTF_EVCOMM_DETAIL("--- CM_ATTEN_CHAR_IND ---\n"); DEBUG_PRINTF_EVCOMM_DETAIL("APPLICATION_TYPE: 0x%x\n", qcaInfo.SendMmePacket.MMENTRY[0]); DEBUG_PRINTF_EVCOMM_DETAIL("SECURITY_TYPE: 0x%x\n", qcaInfo.SendMmePacket.MMENTRY[1]); DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x\n", qcaInfo.SendMmePacket.MMENTRY[2],qcaInfo.SendMmePacket.MMENTRY[3],qcaInfo.SendMmePacket.MMENTRY[4],qcaInfo.SendMmePacket.MMENTRY[5],qcaInfo.SendMmePacket.MMENTRY[6],qcaInfo.SendMmePacket.MMENTRY[7]); DEBUG_PRINTF_EVCOMM_DETAIL("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", qcaInfo.SendMmePacket.MMENTRY[8],qcaInfo.SendMmePacket.MMENTRY[9],qcaInfo.SendMmePacket.MMENTRY[10],qcaInfo.SendMmePacket.MMENTRY[11],qcaInfo.SendMmePacket.MMENTRY[12],qcaInfo.SendMmePacket.MMENTRY[13],qcaInfo.SendMmePacket.MMENTRY[14],qcaInfo.SendMmePacket.MMENTRY[15]); memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf)); for(count=0; count<17; count++) { sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, qcaInfo.SendMmePacket.MMENTRY[16+count]); } DEBUG_PRINTF_EVCOMM_DETAIL("SOURCE_ID: %s\n", tmpBuf); memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf)); for(count=0; count<17; count++) { sprintf((char*)tmpBuf, "%s%02x,", tmpBuf, qcaInfo.SendMmePacket.MMENTRY[33+count]); } DEBUG_PRINTF_EVCOMM_DETAIL("RESP_ID: %s\n", tmpBuf); DEBUG_PRINTF_EVCOMM_DETAIL("NumSounds: 0x%x\n", qcaInfo.SendMmePacket.MMENTRY[50]); memset(tmpBuf, 0x00, ARRAY_SIZE(tmpBuf)); for(count=0; count 0) { DEBUG_INFO("[SLAC][TX]CM_ATTEN_CHAR_IND[%d]: %d-th resend (Q=%.2f/%.2f)(%d/%d)\n", (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); } else if (EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry == 0) { DEBUG_INFO("[SLAC][TX]CM_ATTEN_CHAR_IND[%d]: Q=%.2f/%.2f(%d/%d)\n", (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); } else { DEBUG_INFO("[SLAC][TX]CM_ATTEN_CHAR_IND[%d]: unexpected CM_ATTEN_CHAR_IND_retry(%d))\n", i, EVCOMM_SYS_INFO.CM_ATTEN_CHAR_IND_retry); } DEBUG_PRINTF_EVCOMM_DETAIL("SendMmePacketSize=%d,Rtn=%d\n", qcaInfo.SendMmePacketSize, count); } //end of for loop Update_V2G_Status(CM_ATTEN_CHAR_IND); ftime(&timerStart.SeqStart); } break; } case CM_ATTEN_CHAR_IND: { ftime(&timerStart.SeqEnd); //if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd)>TT_match_response) if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > TT_match_response) //extended to 400ms due to the response of CM_ATTEN_CHAR.RSP of some EVCC is slower than 200ms. { DEBUG_ERROR("SlacComm: Wait CM_ATTEN_CHAR_RSP Timeout - TT_match_response (%.02lf of %dms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), TT_match_response); //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_TIMEOUT_SLAC_CM_ATTEN_CHAR_RSP (023814): //[Possible Reason] Frequent on BMW i3, need to drive the EV a bit. ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 8; ShmStatusCodeData->PresentStatusCode[0][4] = 1; ShmStatusCodeData->PresentStatusCode[0][5] = 4; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Sequence_Timeout); return -1; } break; } case CM_ATTEN_CHAR_RSP: { ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > TT_EVSE_match_session) { DEBUG_ERROR("SlacComm: Wait CM_VALIDATE_REQ_1ST or CM_SLAC_MATCH_REQ Timeout - TT_EVSE_match_session (%.02lf of %dms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), TT_EVSE_match_session); //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_TIMEOUT_SLAC_CM_VALIDATE_REQ_1ST__CM_SLAC_MATCH_REQ (023815): //[Possible Reason] Frequent on BMW i3, need to drive the EV a bit. ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 8; ShmStatusCodeData->PresentStatusCode[0][4] = 1; ShmStatusCodeData->PresentStatusCode[0][5] = 5; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Sequence_Timeout); return -1; } break; } case CM_VALIDATE_CNF: { ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > TT_match_sequence) { DEBUG_ERROR("SlacComm: Wait CM_VALIDATE_REQ_2ND or CM_SLAC_MATCH_REQ Timeout - TT_match_sequence (%.02lf of %dms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), TT_match_sequence); //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_TIMEOUT_SLAC_CM_VALIDATE_REQ_2ND__CM_SLAC_MATCH_REQ (023819): //[Possible Reason] Frequent on BMW i3, need to drive the EV a bit. ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 8; ShmStatusCodeData->PresentStatusCode[0][4] = 1; ShmStatusCodeData->PresentStatusCode[0][5] = 9; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Sequence_Timeout); return -1; } break; } case CM_SLAC_MATCH_CNF: { if(socketFd.Udp > 0) { close(socketFd.Udp); socketFd.Udp = -1; } if(socketFd.Tcp > 0) { close(socketFd.Tcp); socketFd.Tcp = -1; } ftime(&timerStart.SeqStart); V2gTcpConnected(); Update_V2G_Status(SLACC_SDP_UDP_Connection); DEBUG_INFO("SLAAC, SDP, UDP: connecting...\n"); break; } default: { break; } } return 0; } /** * 1. Decode the V2GTP messages inside "msg" and save the decoded messages in v2gObject.DIN, v2gObject.ISO1, and v2gObject.ISO2, respectively. 2. After decoding, V2gMsg_Process() could then use v2gObject.DIN, v2gObject.ISO1, or v2gObject.ISO2 to deal with the corresponding Response messages, respectively. * @param msg * @param msg_length * @param v2g_state * @return */ 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, &v2gObject.appHandshake)) < 0) { DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR = %d (DEC)]V2gMsgDecoder: SupportedAppProtocolRequest()\n", errn); } else //decoded successfully. { //PRINT_XML_DOC_supportedAppProtocolReq(&v2gObject.appHandshake); } } //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, &v2gObject.DIN)) < 0) { DEBUG_INFO("[ERROR = %d (DEC)]V2gMsgDecoder: API_V2GMSG_EXI_Decoder_DIN()\n", errn); } break; } case V2GT_MSG_PROTOCOL_ISO15118_2014: //1 { //ISO1 if((errn = API_V2GMSG_EXI_Decoder_ISO1(msg, msg_length, &v2gObject.ISO1)) < 0) { DEBUG_INFO("[ERROR = %d (DEC)]V2gMsgDecoder: API_V2GMSG_EXI_Decoder_ISO1()\n", errn); } break; } case V2GT_MSG_PROTOCOL_ISO15118_2018: //2 { //ISO2 if((errn = API_V2GMSG_EXI_Decoder_ISO2(msg, msg_length, &v2gObject.ISO2)) < 0) { DEBUG_INFO("[ERROR = %d (DEC)]V2gMsgDecoder: API_V2GMSG_EXI_Decoder_ISO2()\n", errn); } break; } default: break; } } else { DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR = %d (DEC)]V2gMsgDecoder: Unexpected v2g_state\n", errn); errn = -1; } return errn; } /** * * @param v2g_tx_stream * @param v2gObject * @return */ int encode_din_V2GTP_stream(bitstream_t *v2g_tx_stream, struct dinEXIDocument *v2gObject) { int errn = 0; *v2g_tx_stream->pos = V2GTP_HEADER_LENGTH; errn = encode_dinExiDocument(v2g_tx_stream, v2gObject); 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]write_v2gtpHeader(): %d (DEC)\n", errn); } } else { DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][SeccComm]encode_dinExiDocument(): %d (DEC)\n", errn); } return errn; } /** * * @param v2g_tx_stream * @param v2gObject * @return */ int encode_iso1_V2GTP_stream(bitstream_t *v2g_tx_stream, struct iso1EXIDocument *v2gObject) { int errn = 0; *v2g_tx_stream->pos = V2GTP_HEADER_LENGTH; errn = encode_iso1ExiDocument(v2g_tx_stream, v2gObject); 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]write_v2gtpHeader(): %d (DEC)\n", errn); } } else { DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][SeccComm]encode_iso1ExiDocument(): %d (DEC)\n", errn); } return errn; } /** * * @param v2g_tx_stream * @param v2gObject * @return */ int encode_iso2_V2GTP_stream(bitstream_t *v2g_tx_stream, struct iso2EXIDocument *v2gObject) { int errn = 0; *v2g_tx_stream->pos = V2GTP_HEADER_LENGTH; errn = encode_iso2ExiDocument(v2g_tx_stream, v2gObject); 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]write_v2gtpHeader(): %d (DEC)\n", errn); } } else { DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR][SeccComm]encode_iso2ExiDocument(): %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @param v2g_tx_stream * @param v2gObject * @return */ int send_encoded_din_V2GTP_Stream(int AcceptFd, bitstream_t *v2g_tx_stream, struct dinEXIDocument *v2gObject) { int errn = 0; // STEP 1: =========== Encoding into EXI and Composing into V2GTP Stream ========== errn = encode_din_V2GTP_stream(v2g_tx_stream, v2gObject); // STEP 2: =========== Send Response Packet =========== int rtn = 0; rtn = send(AcceptFd, v2g_tx_stream->data, v2g_tx_stream->size, 0); if (rtn == v2g_tx_stream->size) { /* DEBUG_PRINTF_EVCOMM_DETAIL("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]Incomplete Tx ( %d / %d ). (Bytes, DEC): FAIL\n", rtn, v2g_tx_stream->size); } else { errn = rtn; DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR]send(): %d (DEC)\n", errn); } //STEP 3: ========= Reset V2G MSG Flags ========== init_dinBodyType(&v2gObject->V2G_Message.Body); return errn; } /** * * @param AcceptFd * @param v2g_tx_stream * @param v2gObject * @return */ int send_encoded_iso1_V2GTP_Stream(int AcceptFd, bitstream_t *v2g_tx_stream, struct iso1EXIDocument *v2gObject) { int errn = 0; // STEP 1: =========== Encoding into EXI and Composing into V2GTP Stream ========== errn = encode_iso1_V2GTP_stream(v2g_tx_stream, v2gObject); // STEP 2: =========== Send Response Packet =========== int rtn = 0; rtn = send(AcceptFd, v2g_tx_stream->data, v2g_tx_stream->size, 0); if (rtn == v2g_tx_stream->size) { //DEBUG_PRINTF_EVCOMM_DETAIL("Response message 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]Incomplete Tx (%d/%d)(Bytes, DEC): FAIL\n", rtn, v2g_tx_stream->size); } else { errn = rtn; DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR]send(): %d(DEC)\n", errn); } //STEP 3: ========= Reset V2G MSG Flags ========== init_iso1BodyType(&v2gObject->V2G_Message.Body); return errn; } /** * * @param AcceptFd * @param v2g_tx_stream * @param v2gObject * @return */ int send_encoded_iso2_V2GTP_Stream(int AcceptFd, bitstream_t *v2g_tx_stream, struct iso2EXIDocument *v2gObject) { int errn = 0; // STEP 1: =========== Encoding into EXI and Composing into V2GTP Stream ========== errn = encode_iso2_V2GTP_stream(v2g_tx_stream, v2gObject); // STEP 2: =========== Send Response Packet =========== int rtn = 0; rtn = send(AcceptFd, v2g_tx_stream->data, v2g_tx_stream->size, 0); if (rtn == v2g_tx_stream->size) { /* DEBUG_PRINTF_EVCOMM_DETAIL("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]Incomplete Tx ( %d / %d ). (Bytes, DEC): FAIL\n", rtn, v2g_tx_stream->size); } else { errn = rtn; DEBUG_PRINTF_EVCOMM_DETAIL("[ERROR]send(): %d (DEC)\n", errn); } //STEP 3: ========= Reset V2G MSG Flags ========== init_iso2BodyType(&v2gObject->V2G_Message.Body); return errn; } /** * * @param exi_doc_DIN * @return */ 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 { DEBUG_ERROR("SessionID: incorrect length(%d)\n", leng); 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 { DEBUG_ERROR("SessionID: incorrect ID(RX:%02X%02X%02X%02X%02X%02X%02X%02X, ORI:%02X%02X%02X%02X%02X%02X%02X%02X)\n", 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]); } //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; } /** * * @param exi_doc_ISO1 * @return */ 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 { DEBUG_ERROR("SessionID: incorrect length(%d)\n", leng); 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 { DEBUG_ERROR("SessionID: incorrect ID (RX:%02X%02X%02X%02X%02X%02X%02X%02X, ORI:%02X%02X%02X%02X%02X%02X%02X%02X)\n", 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]); } //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; } /** * * @param exi_doc_ISO2 * @return */ 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 { DEBUG_ERROR("SessionID: incorrect length(%d)\n", leng); 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 { DEBUG_ERROR("SessionID: incorrect ID(RX:%02X%02X%02X%02X%02X%02X%02X%02X, ORI:%02X%02X%02X%02X%02X%02X%02X%02X)\n", 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]); } //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; } /** * 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? * @param target * @return */ int GetSchemaID_of_Protocol(unsigned char target) { int i = 0; int ii = 0; int id = 0; unsigned char pri = 20; //priority = 1(highest)~20(lowerest) char num[10]; //Choose the 1st protocol as default. 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) { DEBUG_INFO("support(%d/%d): DIN 70121(%d:v%d.%d;id=%d,pri=%d)\n", (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); if (target == V2GT_MSG_PROTOCOL_DIN70121) { DEBUG_INFO("select(%d/%d): DIN 70121(%d:v%d.%d;id=%d,pri=%d)\n", (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); 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) { DEBUG_INFO("support(%d/%d): ISO 15118-2(ed1,%d:v%d.%d;id=%d,pri=%d)\n", (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); if (target == V2GT_MSG_PROTOCOL_ISO15118_2014) { DEBUG_INFO("select(%d/%d): ISO 15118-2,ed1(%d:v%d.%d;id=%d,pri=%d)\n", (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); 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 { DEBUG_INFO("support(%d/%d): ISO 15118-20(ed2,%d:v%d.%d;id=%d,pri=%d)\n", (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); if (target == V2GT_MSG_PROTOCOL_ISO15118_2018) { DEBUG_INFO("select(%d/%d): ISO 15118-20,ed2(%d:v%d.%d;id=%d,pri=%d)\n", (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); 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 DEBUG_INFO("unsupport(%d/%d): ISO 15118-X(unexpected year:%d,v%d.%d),id=%d,pri=%d\n", (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); } } else { DEBUG_INFO("unsupport protocol(%d/%d)(%d:v%d.%d;id=%d,pri=%d)\n", (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); } } //The final result of highest priority protocol DEBUG_INFO("select(%d/%d): pro=%d(0:DIN,1:ISO1,2:ISO2);id=%d,pri=%d\n", (ii+1), CCS_HANDSHAKE_PROTOCOLS.arrayLen, ShmCcsData->CommProtocol, id, pri); if (id < 0) { EVCOMM_SYS_INFO.SupportedAppProtocol_result = appHandresponseCodeType_Failed_NoNegotiation; } return id; } /** * * @param AcceptFd * @return */ 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(&v2gObject.appHandshake); v2gObject.appHandshake.supportedAppProtocolRes.ResponseCode = appHandresponseCodeType_OK_SuccessfulNegotiation; v2gObject.appHandshake.supportedAppProtocolRes_isUsed = 1u; //select the 1st one as the default v2gObject.appHandshake.supportedAppProtocolRes.SchemaID = CCS_HANDSHAKE_PROTOCOLS.array[0].SchemaID; v2gObject.appHandshake.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 ---*/ v2gObject.appHandshake.supportedAppProtocolRes.ResponseCode = EVCOMM_SYS_INFO.SupportedAppProtocol_result; //updating the response code if (id < 0) { DEBUG_ERROR("No available CCS protocol (id = %d, preference = %d)\n", id, V2GT_MSG_PROTOCOL_PREFERENCE); } else { //selected SchemaID v2gObject.appHandshake.supportedAppProtocolRes.SchemaID = (unsigned char) id; } if (sys->DC_EVSEStatus == EVSE_Shutdown) { DEBUG_INFO("EVSE_Shutdown => End_Process\n"); v2gObject.appHandshake.supportedAppProtocolRes.ResponseCode = appHandresponseCodeType_Failed_NoNegotiation; errn = -1; } else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { DEBUG_INFO("EVSE_EmergencyShutdown => End_Process\n"); v2gObject.appHandshake.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) { DEBUG_ERROR("[DIN][supportedAppProtocolRes]Permission OFF\n"); v2gObject.appHandshake.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 { v2gObject.appHandshake.supportedAppProtocolRes.ResponseCode = appHandresponseCodeType_Failed_NoNegotiation; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); DEBUG_INFO("Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); } } #else { //Detect for CP State should be 9V (State B) if (sys->CpState != 3) //B2 { v2gObject.appHandshake.supportedAppProtocolRes.ResponseCode = appHandresponseCodeType_Failed_NoNegotiation; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); DEBUG_INFO("Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); } } #endif } #endif //STEP 2: =========== Encode into EXI =========== if ((errn = API_V2GMSG_EXI_Encoder_AppProtocol(&v2gObject.appHandshake, &v2g_tx_stream)) !=0) { DEBUG_PRINTF_EVCOMM_DETAIL("[Error]API_V2GMSG_EXI_Encoder_AppProtocol\n"); return errn; } //STEP 3: =========== Send Response Packet =========== int Rtn = 0; Rtn = send(AcceptFd, v2g_tx_stream.data, v2g_tx_stream.size, 0); //Rtn = send(6, v2g_tx_stream.data, v2g_tx_stream.size, 0); DEBUG_PRINTF_EVCOMM_DETAIL("Send V2GTP Packet Size = %d, Rtn = %d (Bytes, DEC)\n", v2g_tx_stream.size, Rtn); if (Rtn < 0) { return Rtn; } //STEP 4: =========== Save into Share Memory ========= //[ 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(&v2gObject.appHandshake); return errn; } /** * * @param AcceptFd * @return */ int Proc_supportedAppProtocolReq(int AcceptFd) { //[ To-Do] analysis on Req message and choose the prefered protocol //Default: DIN 70121 (find SchemaID) int errn = 0; DEBUG_INFO("Request in.\n"); SHM_Save_din_supportedAppProtocolReq(ShmCcsData, &v2gObject.appHandshake, ShmSysConfigAndInfo); errn = Proc_supportedAppProtocolRes(AcceptFd); if (errn == 0) { DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_supportedAppProtocolRes(): %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ 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 = v2gBuffer.tx; init_dinBodyType(&v2gObject.DIN.V2G_Message.Body); init_dinSessionSetupResType(&v2gObject.DIN.V2G_Message.Body.SessionSetupRes); // ====== [BODY (1/2) ResponseCode ====== v2gObject.DIN.V2G_Message.Body.SessionSetupRes_isUsed = 1u; v2gObject.DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = dinresponseCodeType_OK_NewSessionEstablished; //[HEADER] Assign Res SessionID v2gObject.DIN.V2G_Message.Header.SessionID.bytesLen = 8; memset(v2gObject.DIN.V2G_Message.Header.SessionID.bytes, 0, 8); memcpy(v2gObject.DIN.V2G_Message.Header.SessionID.bytes, EVCOMM_SYS_INFO.SessionID, 8); //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { v2gObject.DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = dinresponseCodeType_FAILED_SequenceError; DEBUG_ERROR("SequenceError => End_Process\n"); 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(&v2gObject.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 v2gObject.DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = dinresponseCodeType_FAILED; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); errn = -1; DEBUG_INFO("Emergency Stop by CP Error (%d)\n", sys->CpState); #else DEBUG_INFO("Emergency Stop by CP Error (%d): ignored\n", sys->CpState); #endif } //Check for shutdown commands from EVSE(DC Main Board) if (sys->DC_EVSEStatus == EVSE_Shutdown || sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { v2gObject.DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = dinresponseCodeType_FAILED; DEBUG_INFO("Stop by EVSE(%d:normal, %d:emergency): (%d)\n", EVSE_Shutdown, EVSE_EmergencyShutdown, sys->DC_EVSEStatus); 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) { DEBUG_ERROR("[DIN]Permission OFF"); v2gObject.DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = dinresponseCodeType_FAILED; errn = -1; } // ====== [BODY (2/3) EVSEID ====== //EVSEID = all zero memset(v2gObject.DIN.V2G_Message.Body.SessionSetupRes.EVSEID.bytes, 0, sizeof(v2gObject.DIN.V2G_Message.Body.SessionSetupRes.EVSEID.bytes)); //vern, should be encode by SN v2gObject.DIN.V2G_Message.Body.SessionSetupRes.EVSEID.bytesLen = 1; //max: DIN = 32, ISO1/ISO2 = 37 bytes // ====== [BODY (3/3) DateTimeNow ====== v2gObject.DIN.V2G_Message.Body.SessionSetupRes.DateTimeNow_isUsed = 1u; v2gObject.DIN.V2G_Message.Body.SessionSetupRes.DateTimeNow = (int64_t)time(NULL); //[Joseph] Format: Unix Time Stamp #if PARAMETER_NORMAL_MODE == ENABLE ///////////SHM_Read_din_SessionSetupRes(&v2gObject.DIN, ShmCcsData); #endif // ============ Encode and Send Response Message =========== if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &v2gObject.DIN) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } return errn; } /** * * @param AcceptFd * @return */ 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 = v2gBuffer.tx; init_iso1BodyType(&v2gObject.ISO1.V2G_Message.Body); init_iso1SessionSetupResType(&v2gObject.ISO1.V2G_Message.Body.SessionSetupRes); // ====== [BODY (1/2) ResponseCode ====== v2gObject.ISO1.V2G_Message.Body.SessionSetupRes_isUsed = 1u; v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_OK_NewSessionEstablished; //[HEADER] Assign Res SessionID v2gObject.ISO1.V2G_Message.Header.SessionID.bytesLen = 8; memset(v2gObject.ISO1.V2G_Message.Header.SessionID.bytes, 0, 8); memcpy(v2gObject.ISO1.V2G_Message.Header.SessionID.bytes, EVCOMM_SYS_INFO.SessionID, 8); //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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(&v2gObject.ISO1, ShmCcsData); //#endif //Detect for CP State should be 9V (State B) if ((sys->CpState != 2) && (sys->CpState != 3)) //State B1, B2 { #if CP_PROTECTION_MECHANISM == ENABLE v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_FAILED; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); errn = -1; DEBUG_INFO("Emergency Stop by CP Error (%d)\n", sys->CpState); #else DEBUG_INFO("Emergency Stop by CP Error (%d): ignored\n", sys->CpState); #endif } //Check for shutdown commands from EVSE(DC Main Board) if (sys->DC_EVSEStatus == EVSE_Shutdown || sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_FAILED; DEBUG_INFO("Stop by EVSE(%d:normal, %d:emergency): (%d)\n", EVSE_Shutdown, EVSE_EmergencyShutdown, sys->DC_EVSEStatus); errn = -1; } //Check for Permission Changing from TRUE to FALSE if (ShmInternalComm->ChargingPermission_pre == TRUE && ShmInternalComm->ChargingPermission == FALSE) { DEBUG_ERROR("Permission OFF\n"); v2gObject.DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_FAILED; errn = -1; } // ====== [BODY (2/3) EVSEID ====== //EVSEID = all zero memset(v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters, 0, sizeof(v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters)); /*+++ 20200808, vern, set default EVSEID +++*/ //vern, should be encoded by SN v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[0]='Z'; v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[1]='Z'; v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[2]='0'; v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[3]='0'; v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[4]='0'; v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[5]='0'; v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.characters[6]='0'; v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.EVSEID.charactersLen = 7; //max: DIN = 32, ISO1/ISO2 = 37 bytes /*--- 20200808, vern, set default EVSEID ---*/ // ====== [BODY (3/3) DateTimeNow ====== v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.EVSETimeStamp_isUsed = 1u; v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.EVSETimeStamp = (int64_t)time(NULL); //[Joseph] Format: Unix Time Stamp #if PARAMETER_NORMAL_MODE == ENABLE ///////////SHM_Read_iso1_SessionSetupRes(&v2gObject.ISO1, ShmCcsData); #endif // ============ Encode and Send Response Message =========== if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } return errn; } /** * * @param AcceptFd * @return */ 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 = v2gBuffer.tx; init_iso2BodyType(&v2gObject.ISO2.V2G_Message.Body); init_iso2SessionSetupResType(&v2gObject.ISO2.V2G_Message.Body.SessionSetupRes); // ====== [BODY (1/2) ResponseCode ====== v2gObject.ISO2.V2G_Message.Body.SessionSetupRes_isUsed = 1u; v2gObject.ISO2.V2G_Message.Body.SessionSetupRes.ResponseCode = iso2responseCodeType_OK_NewSessionEstablished; //[HEADER] Assign Res SessionID v2gObject.ISO2.V2G_Message.Header.SessionID.bytesLen = 8; memset(v2gObject.ISO2.V2G_Message.Header.SessionID.bytes, 0, 8); memcpy(v2gObject.ISO2.V2G_Message.Header.SessionID.bytes, EVCOMM_SYS_INFO.SessionID, 8); //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { v2gObject.ISO1.V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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(&v2gObject.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 v2gObject.ISO2.V2G_Message.Body.SessionSetupRes.ResponseCode = iso2responseCodeType_FAILED; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); errn = -1; DEBUG_INFO("Emergency Stop by CP Error (%d)\n", sys->CpState); #else DEBUG_INFO("Emergency Stop by CP Error (%d): ignored\n", sys->CpState); #endif } //Check for shutdown commands from EVSE(DC Main Board) if (sys->DC_EVSEStatus == EVSE_Shutdown || sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { v2gObject.ISO2.V2G_Message.Body.SessionSetupRes.ResponseCode = iso2responseCodeType_FAILED; DEBUG_INFO("Stop by EVSE(%d:normal, %d:emergency): (%d)\n", EVSE_Shutdown, EVSE_EmergencyShutdown, sys->DC_EVSEStatus); 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) { DEBUG_ERROR("Permission OFF\n"); v2gObject.DIN.V2G_Message.Body.SessionSetupRes.ResponseCode = iso2responseCodeType_FAILED; errn = -1; } // ====== [BODY (2/3) EVSEID ====== //EVSEID = all zero memset(v2gObject.ISO2.V2G_Message.Body.SessionSetupRes.EVSEID.characters, 0, sizeof(v2gObject.ISO2.V2G_Message.Body.SessionSetupRes.EVSEID.characters)); v2gObject.ISO2.V2G_Message.Body.SessionSetupRes.EVSEID.charactersLen = 15; //max: DIN = 32, ISO1/ISO2 = 37 bytes // ====== [BODY (3/3) DateTimeNow ====== v2gObject.ISO2.V2G_Message.Body.SessionSetupRes.EVSETimeStamp_isUsed = 1u; v2gObject.ISO2.V2G_Message.Body.SessionSetupRes.EVSETimeStamp = (int64_t)time(NULL); //[Joseph] Format: Unix Time Stamp #if PARAMETER_NORMAL_MODE == ENABLE ///////////SHM_Read_iso2_SessionSetupRes(&v2gObject.ISO2, ShmCcsData); #endif // ============ Encode and Send Response Message =========== if (send_encoded_iso2_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &v2gObject.ISO2) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } return errn; } /** * * @param AcceptFd * @return */ int Proc_din_SessionSetupReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_DIN_SessionSetupReq(&v2gObject.DIN); //Save into Share Memory SHM_Save_din_SessionSetupReq(ShmCcsData, &v2gObject.DIN, ShmSysConfigAndInfo); errn = Proc_din_SessionSetupRes(AcceptFd); if (errn == 0) { //successfully send response. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_din_SessionSetupRes(): %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_SessionSetupReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO1_SessionSetupReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_SessionSetupReq(ShmCcsData, &v2gObject.ISO1, ShmSysConfigAndInfo); errn = Proc_iso1_SessionSetupRes(AcceptFd); if (errn == 0) { //successfully send response. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_SessionSetupRes(): %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso2_SessionSetupReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO2_SessionSetupReq(&v2gObject.ISO2); //Save into Share Memory SHM_Save_iso2_SessionSetupReq(ShmCcsData, &v2gObject.ISO2, ShmSysConfigAndInfo); errn = Proc_iso2_SessionSetupRes(AcceptFd); if (errn == 0) { //successfully send response. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso2_SessionSetupRes(): %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_din_ServiceDiscoveryRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; //req = &ShmCcsData->V2GMessage_DIN70121.ServiceDiscoveryRequest; res = &ShmCcsData->V2GMessage_DIN70121.ServiceDiscoveryResponse; init_dinBodyType(&v2gObject.DIN.V2G_Message.Body); init_dinServiceDiscoveryResType(&v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes); //[1/4] Response Code v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes_isUsed = 1u; v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = dinresponseCodeType_OK; //[HEADER] Check Req SessionID if (Check_din_V2G_Rx_MSG_SessionID(&v2gObject.DIN) < 0) { v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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 v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = dinresponseCodeType_FAILED; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); errn = -1; DEBUG_INFO("Emergency Stop by CP Error (%d)\n", sys->CpState); #else DEBUG_INFO("Emergency Stop by CP Error (%d): ignored\n", sys->CpState); #endif } if (sys->DC_EVSEStatus == EVSE_Shutdown || sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = dinresponseCodeType_FAILED; DEBUG_INFO("shutdown by EVSE\n"); 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) { DEBUG_ERROR("[DIN]Permission OFF\n"); v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = dinresponseCodeType_FAILED; errn = -1; } //[2/4] PaymentOptions v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes.PaymentOptions.PaymentOption.arrayLen = 1u; v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes.PaymentOptions.PaymentOption.array[0] = dinpaymentOptionType_ExternalPayment; //1 //[3/4] Charge Service res->ChargeService_DIN70121.Services.ServiceTag.ServiceID = 1; v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceTag.ServiceID = (unsigned short) res->ChargeService_DIN70121.Services.ServiceTag.ServiceID; v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceTag.ServiceCategory = dinserviceCategoryType_EVCharging; v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.FreeService = 1; //[Joseph] for test v2gObject.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(&v2gObject.DIN, ShmCcsData); //#endif // ============ Encode and Send Response Message =========== if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &v2gObject.DIN) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_ServiceDiscoveryRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; //req = &ShmCcsData->V2GMessage_ISO15118_2014.ServiceDiscoveryRequest; res = &ShmCcsData->V2GMessage_ISO15118_2014.ServiceDiscoveryResponse; init_iso1BodyType(&v2gObject.ISO1.V2G_Message.Body); init_iso1ServiceDiscoveryResType(&v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes); //[1/4] Response Code v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes_isUsed = 1u; v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso1responseCodeType_OK; //[HEADER] Check Req SessionID if (Check_iso1_V2G_Rx_MSG_SessionID(&v2gObject.ISO1) < 0) { v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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 v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso1responseCodeType_FAILED; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); errn = -1; DEBUG_INFO("Emergency Stop by CP Error (%d)\n", sys->CpState); #else DEBUG_INFO("Emergency Stop by CP Error (%d): ignored", sys->CpState); #endif } if (sys->DC_EVSEStatus == EVSE_Shutdown || sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso1responseCodeType_FAILED; DEBUG_INFO("shutdown by EVSE\n"); 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) { DEBUG_ERROR("Permission OFF\n"); v2gObject.DIN.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso1responseCodeType_FAILED; errn = -1; } //[2/4] PaymentOptionList v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.PaymentOptionList.PaymentOption.arrayLen = 1u; v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.PaymentOptionList.PaymentOption.array[0] = iso1paymentOptionType_ExternalPayment; //1 //[3/4] Charge Service res->ChargeService.Services.ServiceID = 1; v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceID = (unsigned short) res->ChargeService.Services.ServiceID; //v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceName_isUsed = 1; //new in ISO1, not be used, yet. //v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceName.charactersLen = xxx; //v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceName.characters[i] = xxx; v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceCategory = iso1serviceCategoryType_EVCharging; v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.FreeService = 1; //[Joseph] for test v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.arrayLen = 1u; // max = 6 switch (ShmCcsData->EnergyTransferMode) { case DC_extended: { v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.array[0] = iso1EnergyTransferModeType_DC_extended; break; } case AC_single_phase_core: { v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.array[0] = iso1EnergyTransferModeType_AC_single_phase_core; break; } case AC_three_phase_core: { v2gObject.ISO1.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.array[0] = iso1EnergyTransferModeType_AC_three_phase_core; break; } default: { DEBUG_WARN("unexpected EnergyTransferMode(%d)\n", ShmCcsData->EnergyTransferMode); break; } } //[4/4] Service List (null, not be uesed for now.) //#if PARAMETER_NORMAL_MODE == ENABLE ///////////////SHM_Read_iso1_ServiceDiscoveryRes(&v2gObject.ISO1, ShmCcsData); //#endif // ============ Encode and Send Response Message =========== if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } return errn; } /** * * @param AcceptFd * @return */ int Proc_din_ServiceDiscoveryReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_DIN_ServiceDiscoveryReq(&v2gObject.DIN); //Save into Share Memory SHM_Save_din_ServiceDiscoveryReq(ShmCcsData, &v2gObject.DIN, ShmSysConfigAndInfo); errn = Proc_din_ServiceDiscoveryRes(AcceptFd); if (errn == 0) { //send response successfully. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_din_ServiceDiscoveryRes(): %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_ServiceDiscoveryReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO1_ServiceDiscoveryReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_ServiceDiscoveryReq(ShmCcsData, &v2gObject.ISO1, ShmSysConfigAndInfo); errn = Proc_iso1_ServiceDiscoveryRes(AcceptFd); if (errn == 0) { //send response successfully. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_ServiceDiscoveryRes(): %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_din_ServiceAndPaymentSelectionRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; req = &ShmCcsData->V2GMessage_DIN70121.ServiceAndPaymentSelectionRequest; //res = &ShmCcsData->V2GMessage_DIN70121.ServiceAndPaymentSelectionResponse; sd_res = &ShmCcsData->V2GMessage_DIN70121.ServiceDiscoveryResponse; sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; init_dinBodyType(&v2gObject.DIN.V2G_Message.Body); init_dinServicePaymentSelectionResType(&v2gObject.DIN.V2G_Message.Body.ServicePaymentSelectionRes); //[1/1] Response Code v2gObject.DIN.V2G_Message.Body.ServicePaymentSelectionRes_isUsed = 1u; v2gObject.DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_OK; //[HEADER] Check Req SessionID if (Check_din_V2G_Rx_MSG_SessionID(&v2gObject.DIN) < 0) { v2gObject.DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { v2gObject.DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); errn = -1; //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_ResponseCode_FAILED_SequenceError (023758) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 5; ShmStatusCodeData->PresentStatusCode[0][5] = 8; } //Check for SelectedPaymentOption (TC_SECC_VTB_ServicePaymentSelection_007) if (req->SelectedPaymentOption != ExternalPayment) //1 { v2gObject.DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED_PaymentSelectionInvalid; DEBUG_ERROR("unexpected SelectedPaymentOption(%d) => End_Process (EIM only, no PnC, yet.)\n", req->SelectedPaymentOption); 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) { v2gObject.DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED_ServiceSelectionInvalid; //8 DEBUG_ERROR("Wrong selected ServiceID(%d) => End_Process\n", req->SelectedServiceList.SelectedService[0].ServiceID); 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 v2gObject.DIN.V2G_Message.Body.ServicePaymentSelectionRes.ResponseCode = dinresponseCodeType_FAILED; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); errn = -1; DEBUG_INFO("Emergency Stop by CP Error (%d)\n", sys->CpState); #else DEBUG_INFO("Emergency Stop by CP Error (%d): ignored due to function is disabled\n", sys->CpState); #endif } if (sys->DC_EVSEStatus == EVSE_Shutdown || sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { DEBUG_INFO("shutdown by EVSE\n"); v2gObject.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) { DEBUG_ERROR("Permission OFF\n"); v2gObject.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, &v2gObject.DIN) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_ServiceAndPaymentSelectionRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; 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(&v2gObject.ISO1.V2G_Message.Body); init_iso1PaymentServiceSelectionResType(&v2gObject.ISO1.V2G_Message.Body.PaymentServiceSelectionRes); //[1/1] Response Code v2gObject.ISO1.V2G_Message.Body.PaymentServiceSelectionRes_isUsed = 1u; v2gObject.ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_OK; //[HEADER] Check Req SessionID if (Check_iso1_V2G_Rx_MSG_SessionID(&v2gObject.ISO1) < 0) { v2gObject.ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { v2gObject.ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); errn = -1; //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_ResponseCode_FAILED_SequenceError (023758) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 5; ShmStatusCodeData->PresentStatusCode[0][5] = 8; } //Check for SelectedPaymentOption (TC_SECC_VTB_ServicePaymentSelection_007) if (req->SelectedPaymentOption != ExternalPayment) //1 { v2gObject.ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_PaymentSelectionInvalid; DEBUG_ERROR("unexpected SelectedPaymentOption(%d) => End_Process (EIM only, no PnC, yet.)\n", req->SelectedPaymentOption); errn = -1; //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_ResponseCode_FAILED_Payment SelectionInvalid (023762) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 6; ShmStatusCodeData->PresentStatusCode[0][5] = 2; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } //Check for ServiceID (TC_SECC_VTB_ServicePaymentSelection_004) if (req->SelectedServiceList.SelectedService[0].ServiceID != sd_res->ChargeService.Services.ServiceID) { v2gObject.ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED_ServiceSelectionInvalid; //8 DEBUG_ERROR("Wrong selected ServiceID(%d) => End_Process\n", req->SelectedServiceList.SelectedService[0].ServiceID); 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 v2gObject.ISO1.V2G_Message.Body.PaymentServiceSelectionRes.ResponseCode = iso1responseCodeType_FAILED; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); errn = -1; DEBUG_INFO("Emergency Stop by CP Error (%d)\n", sys->CpState); #else DEBUG_INFO("Emergency Stop by CP Error (%d): ignored due to function is disabled\n", sys->CpState); #endif } if (sys->DC_EVSEStatus == EVSE_Shutdown || sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { DEBUG_INFO("shutdown by EVSE\n"); v2gObject.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) { DEBUG_ERROR("Permission OFF\n"); v2gObject.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, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } return errn; } /** * * @param AcceptFd * @return */ int Proc_din_ServiceAndPaymentSelectionReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_DIN_ServiceAndPaymentSelectionReq(&v2gObject.DIN); //Save into Share Memory SHM_Save_din_ServiceAndPaymentSelectionReq(ShmCcsData, &v2gObject.DIN, ShmSysConfigAndInfo); errn = Proc_din_ServiceAndPaymentSelectionRes(AcceptFd); if (errn == 0) { //send response successfully. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_din_ServiceAndPaymentSelectionRes(): %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_ServiceAndPaymentSelectionReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO1_ServiceAndPaymentSelectionReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_ServiceAndPaymentSelectionReq(ShmCcsData, &v2gObject.ISO1, ShmSysConfigAndInfo); errn = Proc_iso1_ServiceAndPaymentSelectionRes(AcceptFd); if (errn == 0) { //send response successfully. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_ServiceAndPaymentSelectionRes(): %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_din_ContractAuthenticationRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; init_dinBodyType(&v2gObject.DIN.V2G_Message.Body); init_dinContractAuthenticationResType(&v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes); v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes_isUsed = 1u; //[BODY (1/2)] ResponseCode v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_OK; v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.EVSEProcessing = dinEVSEProcessingType_Ongoing; //0 //[HEADER] Check Req SessionID if (Check_din_V2G_Rx_MSG_SessionID(&v2gObject.DIN) < 0) { v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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 { v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_FAILED; v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.EVSEProcessing = dinEVSEProcessingType_Finished; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); errn = -1; DEBUG_INFO("Emergency Stop by CP Error (%d)\n", sys->CpState); } #endif //Check for CSU command of "Stop by EVSE" if (sys->DC_EVSEStatus == EVSE_Shutdown) { v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_FAILED; v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.EVSEProcessing = dinEVSEProcessingType_Finished; errn = -1; } else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_FAILED; v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.EVSEProcessing = dinEVSEProcessingType_Finished; errn = -1; } //[BODY (2/2)] EVSEProcessing if(ShmInternalComm->ChargingPermission == TRUE) { v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.EVSEProcessing = dinEVSEProcessingType_Finished; //0 DEBUG_INFO("CSU Permission: OK\n"); #if (SLAC_FIRST_RESPONSE_METHOD == SET_5_PWM_ONCE_GET_PERMISSION_IN_AUTHORIZATIONRES) { //Set PWM as 5% (for SLAC first case) DEBUG_INFO("Set PWM as 5%%\n"); SwitchCpStateE(DISABLE); OutputCpPwmDuty(5); } #endif } //Check for Permission Changing from TRUE to FALSE if (ShmInternalComm->ChargingPermission_pre == TRUE && ShmInternalComm->ChargingPermission == FALSE) { DEBUG_ERROR("Permission OFF\n"); v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.ResponseCode = dinresponseCodeType_FAILED; v2gObject.DIN.V2G_Message.Body.ContractAuthenticationRes.EVSEProcessing = dinEVSEProcessingType_Finished; errn = -1; } #if PARAMETER_NORMAL_MODE == ENABLE ////////////SHM_Read_din_ContractAuthenticationRes(&v2gObject.DIN, ShmCcsData); #endif // ============ Encode and Send Response Message =========== if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &v2gObject.DIN) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_AuthorizationRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; init_iso1BodyType(&v2gObject.ISO1.V2G_Message.Body); init_iso1AuthorizationResType(&v2gObject.ISO1.V2G_Message.Body.AuthorizationRes); v2gObject.ISO1.V2G_Message.Body.AuthorizationRes_isUsed = 1u; //[BODY (1/2)] ResponseCode v2gObject.ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = iso1responseCodeType_OK; /*+++ 20200808, vern, EVSEProcessing should be waiting for Customer during authrization +++*/ v2gObject.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(&v2gObject.ISO1) < 0) { v2gObject.ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { v2gObject.ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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 { v2gObject.ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = iso1responseCodeType_FAILED; v2gObject.ISO1.V2G_Message.Body.AuthorizationRes.EVSEProcessing = iso1EVSEProcessingType_Finished; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); errn = -1; DEBUG_INFO("Emergency Stop by CP Error (%d)\n", sys->CpState); } #endif //Check for CSU command of "Stop by EVSE" if (sys->DC_EVSEStatus == EVSE_Shutdown) { v2gObject.ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = FAILED_ISO15118_2014; v2gObject.ISO1.V2G_Message.Body.AuthorizationRes.EVSEProcessing = iso1EVSEProcessingType_Finished; errn = -1; } else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { v2gObject.ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = FAILED_ISO15118_2014; v2gObject.ISO1.V2G_Message.Body.AuthorizationRes.EVSEProcessing = iso1EVSEProcessingType_Finished; errn = -1; } //[BODY (2/2)] EVSEProcessing //Check for Permission from CSU if(ShmInternalComm->ChargingPermission == TRUE) { v2gObject.ISO1.V2G_Message.Body.AuthorizationRes.EVSEProcessing = iso1EVSEProcessingType_Finished; //0 DEBUG_INFO("CSU Permission: OK\n"); #if (SLAC_FIRST_RESPONSE_METHOD == SET_5_PWM_ONCE_GET_PERMISSION_IN_AUTHORIZATIONRES) { //Set PWM as 5% (for SLAC first case) DEBUG_INFO("Set PWM as 5%%\n"); 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) { DEBUG_ERROR("Permission OFF\n"); v2gObject.ISO1.V2G_Message.Body.AuthorizationRes.ResponseCode = FAILED_ISO15118_2014; v2gObject.ISO1.V2G_Message.Body.AuthorizationRes.EVSEProcessing = iso1EVSEProcessingType_Finished; errn = -1; } #if PARAMETER_NORMAL_MODE == ENABLE ////////////SHM_Read_iso1_AuthorizationRes(&v2gObject.ISO1, ShmCcsData); #endif // ============ Encode and Send Response Message =========== if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } return errn; } /** * * @param AcceptFd * @return */ int Proc_din_ContractAuthenticationReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_DIN_ContractAuthenticationReq(&v2gObject.DIN); //Save into Share Memory SHM_Save_din_ContractAuthenticationReq(ShmCcsData, &v2gObject.DIN, ShmSysConfigAndInfo); errn = Proc_din_ContractAuthenticationRes(AcceptFd); if (errn == 0) { //send response successfully. DEBUG_INFO("Resonse out.\n"); } else { DEBUG_ERROR("Proc_din_ContractAuthenticationRes(): %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_AuthenticationReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO1_AuthorizationReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_AuthorizationReq(ShmCcsData, &v2gObject.ISO1, ShmSysConfigAndInfo); errn = Proc_iso1_AuthorizationRes(AcceptFd); if (errn == 0) { //send response successfully. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_AuthorizationRes(): %d (DEC)\n", errn); } return errn; } /** * * @param in */ 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 } /** * * @param obj * @param value * @param multiplier * @param unit */ void SHM_Save_dinPhysicalValueType(struct PhysicalValueType_DIN70121 *obj, short value, int multiplier, unsigned char unit) { obj->Value = value; obj->Multiplier = multiplier; obj->Unit =unit; } /** * * @param shm_ccs */ 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); } /** * */ void Sudo_Parameter_din_ChargeParameterDiscoveryRes() { init_dinBodyType(&v2gObject.DIN.V2G_Message.Body); init_dinChargeParameterDiscoveryResType(&v2gObject.DIN.V2G_Message.Body.ChargeParameterDiscoveryRes); v2gObject.DIN.V2G_Message.Body.ChargeParameterDiscoveryRes_isUsed = 1u; //----- [BODY (1/5)] ResponseCode ----- struct dinChargeParameterDiscoveryResType *res; res = &v2gObject.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; */ } /** * */ void Sudo_Parameter_iso1_ChargeParameterDiscoveryRes() { init_iso1BodyType(&v2gObject.ISO1.V2G_Message.Body); init_iso1ChargeParameterDiscoveryResType(&v2gObject.ISO1.V2G_Message.Body.ChargeParameterDiscoveryRes); v2gObject.ISO1.V2G_Message.Body.ChargeParameterDiscoveryRes_isUsed = 1u; //----- [BODY (1/5)] ResponseCode ----- struct iso1ChargeParameterDiscoveryResType *res; res = &v2gObject.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; */ } /** * * @param AcceptFd * @return */ int Proc_din_ChargeParameterDiscoveryRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; 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(&v2gObject.DIN) < 0) { res->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { res->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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) { DEBUG_ERROR("EvBatteryMaxCurrent is negative(%.02f) => End_Process\n", sys->EvBatteryMaxCurrent); res->ResponseCode = dinresponseCodeType_FAILED_WrongChargeParameter; //16 res->EVSEProcessing = Finished_DIN70121; dc_para->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown; errn = -1; //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_ResponseCode_FAILED_WrongChargeParameter (023775) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 7; ShmStatusCodeData->PresentStatusCode[0][5] = 5; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } //STEP 2: ============ Modify Parameters of ShmCcsData ============ SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMaximumPowerLimit, (int) (sys->AvailableChargingPower * 10), W_DIN70121); SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMaximumCurrentLimit, (int) (sys->AvailableChargingCurrent * 10), A_DIN70121); SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMaximumVoltageLimit, (int) (sys->MaximumChargingVoltage * 10), V_DIN70121); SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMinimumVoltageLimit, 1500, V_DIN70121); //150V SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMinimumCurrentLimit, 10, A_DIN70121); //1A SAVE_PhysicalValueType_DIN70121(&dc_para->EVSECurrentRegulationTolerance, 10, A_DIN70121); //1A SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEPeakCurrentRipple, 2, A_DIN70121); //0.2A //SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEEnergyToBeDelivered, 0, WH_DIN70121); //optional #if PATCH_FOR_BMW_I3_BUG_EVSEMAXIMUMVOLTAGELIMIT_599V == ENABLE if (sys->EvBatteryMaxVoltage <= 500) { SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMaximumVoltageLimit, (int) (500 * 10), V_DIN70121); //500V } #endif //for test with Tesla Model 3, 10A //SAVE_PhysicalValueType_DIN70121(&dc_para->EVSEMaximumCurrentLimit, (int) (10 * 10), A_DIN70121); //10A, for testing with Tesla Model 3 //Check for EnergyTransferMode [TC_SECC_VTB_ChargeParameterDiscovery_004] if (req->EVRequestedEnergyTransferType != DC_extended) { DEBUG_ERROR("Wrong EVRequestedEnergyTransferType(%d,%d)\n", req->EVRequestedEnergyTransferType, dinEVSESupportedEnergyTransferType_DC_extended); 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_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) { DEBUG_INFO("EVSE_Shutdown\n"); 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) { DEBUG_INFO("EVSE_EmergencyShutdown\n"); 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_Status(Other_Fault); errn = -1; DEBUG_INFO("Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); } #endif //Check for Permission from CSU if (ShmInternalComm->ChargingPermission == TRUE) { res->EVSEProcessing = Finished_DIN70121; } //Check for Permission Off if (ShmInternalComm->ChargingPermission == FALSE) { DEBUG_ERROR("Permission OFF\n"); 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(&v2gObject.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, &v2gObject.DIN) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STPE 5: ============ Update Flags ============ return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_ChargeParameterDiscoveryRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; 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 = 10; //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(&v2gObject.ISO1) < 0) { res->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { res->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); errn = -1; //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_ResponseCode_FAILED_SequenceError (023758) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 5; ShmStatusCodeData->PresentStatusCode[0][5] = 8; } //[TC_SECC_VTB_ChargeParameterDiscovery_005] /*+++ 20200808, vern, should check the voltage and current to see if the range of battery parameter is accepted by charger ---*/ if((ShmCcsData->EnergyTransferMode == MODE_DC_EXTENDED) && ((sys->EvBatteryMaxCurrent < 0) || (sys->EvBatteryMaxVoltage<150))) { DEBUG_ERROR("EvBatteryMaxCurrent is negative(%.02f) or EvBatteryMaxVoltage is under 150(%.02f)=> End_Process\n", sys->EvBatteryMaxCurrent, sys->EvBatteryMaxVoltage); 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 ============ if(ShmCcsData->EnergyTransferMode == MODE_DC_EXTENDED) { //DC SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMaximumPowerLimit, (int) (sys->AvailableChargingPower * 10), W_ISO15118_2014); SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMaximumCurrentLimit, (int) (sys->AvailableChargingCurrent * 10), A_ISO15118_2014); SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMaximumVoltageLimit, (int) (sys->MaximumChargingVoltage * 10), V_ISO15118_2014); SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMinimumVoltageLimit, 1500, V_ISO15118_2014); //150V SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMinimumCurrentLimit, 10, A_ISO15118_2014); //1A SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSECurrentRegulationTolerance, 10, A_ISO15118_2014); //1A SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEPeakCurrentRipple, 2, A_ISO15118_2014); //0.2A //SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEEnergyToBeDelivered, 0, Wh_ISO15118_2014); //optional #if PATCH_FOR_BMW_I3_BUG_EVSEMAXIMUMVOLTAGELIMIT_599V == ENABLE if (sys->EvBatteryMaxVoltage <= 500) { SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMaximumVoltageLimit, (int) (500 * 10), V_ISO15118_2014); //500V } #endif //for test with Tesla Model 3, 10A //SAVE_PhysicalValueType_ISO15118_2014(&dc_para->EVSEMaximumCurrentLimit, (int) (10 * 10), A_ISO15118_2014); //10A, for testing with Tesla Model 3 } else { //AC SAVE_PhysicalValueType_ISO15118_2014(&ac_para->EVSENominalVoltage, (int) (220 * 10), V_ISO15118_2014); SAVE_PhysicalValueType_ISO15118_2014(&ac_para->EVSEMaxCurrent, (int) (sys->AvailableChargingCurrent * 10), A_ISO15118_2014); } //Check for EnergyTransferMode if(req->RequestedEnergyTransferMode != ShmCcsData->EnergyTransferMode) //[CAUTION] Their table should be kept as the same. { DEBUG_ERROR("Unmatched RequestedEnergyTransferMode(%d,%d)\n", req->RequestedEnergyTransferMode, ShmCcsData->EnergyTransferMode); 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_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) { DEBUG_INFO("EVSE_Shutdown\n"); 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) { DEBUG_INFO("EVSE_EmergencyShutdown\n"); 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 != CCS_CP_STATE_B1) && (sys->CpState != CCS_CP_STATE_B2) && (sys->CpState != CCS_CP_STATE_C)) //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_Status(Other_Fault); errn = -1; DEBUG_INFO("Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); } #endif //Check for Permission from CSU if(ShmInternalComm->ChargingPermission == TRUE) { res->EVSEProcessing = iso1EVSEProcessingType_Finished; } //Check for Permission Off if (ShmInternalComm->ChargingPermission == FALSE) { DEBUG_ERROR("Permission OFF\n"); 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(&v2gObject.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, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STPE 5: ============ Update Flags ============ return errn; } /** * * @param AcceptFd * @return */ int Proc_din_ChargeParameterDiscoveryReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //ftime(&timerStart.SeqStart); //Print the decoded XML Document PRINT_XML_DOC_DIN_ChargeParameterDiscoveryReq(&v2gObject.DIN); //Save into Share Memory SHM_Save_din_ChargeParameterDiscoveryReq(ShmCcsData, &v2gObject.DIN, ShmSysConfigAndInfo); //Check for EV Error Code Check_EVErrorCode(ShmCcsData->V2GMessage_DIN70121.ChargeParameterDiscoveryRequest.DC_EVChargeParameter.DC_EVStatus.EVErrorCode); errn = Proc_din_ChargeParameterDiscoveryRes(AcceptFd); //ftime(&timerStart.SeqEnd); //DEBUG_PRINTF_EVCOMM_DETAIL("\ndelta = %.02lf ms\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd)); if ( errn == 0) { //send response successfully. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_din_ChargeParameterDiscoveryRes() fail: %d (DEC)\n",errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_ChargeParameterDiscoveryReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //ftime(&timerStart.SeqStart); //Print the decoded XML Document PRINT_XML_DOC_ISO1_ChargeParameterDiscoveryReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_ChargeParameterDiscoveryReq(ShmCcsData, &v2gObject.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(&timerStart.SeqEnd); //DEBUG_PRINTF_EVCOMM_DETAIL("\ndelta = %.02lf ms\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd)); if (errn == 0) { //send response successfully. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_ChargeParameterDiscoveryRes() fail: %d (DEC)\n", errn); } return errn; } /** * * @param shm_ccs */ 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 } /** * */ void Sudo_Parameter_din_CableCheckRes() { init_dinBodyType(&v2gObject.DIN.V2G_Message.Body); init_dinCableCheckResType(&v2gObject.DIN.V2G_Message.Body.CableCheckRes); v2gObject.DIN.V2G_Message.Body.CableCheckRes_isUsed = 1u; //----- [BODY (1/3)] ResponseCode ----- struct dinCableCheckResType *res; res = &v2gObject.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 } /** * */ void Sudo_Parameter_iso1_CableCheckRes() { init_iso1BodyType(&v2gObject.ISO1.V2G_Message.Body); init_iso1CableCheckResType(&v2gObject.ISO1.V2G_Message.Body.CableCheckRes); v2gObject.ISO1.V2G_Message.Body.CableCheckRes_isUsed = 1u; //----- [BODY (1/3)] ResponseCode ----- struct iso1CableCheckResType *res; res = &v2gObject.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 } /** * * @param AcceptFd * @return */ int Proc_din_CableCheckRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; 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(&v2gObject.DIN) < 0) { cab->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { cab->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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 { DEBUG_INFO("[V2G][CableCheck]Pass (V_now = %.02f, Isolated = %d)\n", sys->PresentChargingVoltage, sys->IsolationStatus); //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 { DEBUG_WARN("unexpected IsolationStatus(%d)\n", sys->IsolationStatus); } 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; DEBUG_INFO("IsolationStatus = 3 (fault)\n"); 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; DEBUG_INFO("Undefined Isolation Status(%d)\n", sys->IsolationStatus); } //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; DEBUG_INFO("EVSE_Shutdown\n"); } 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; DEBUG_INFO("EVSE_EmergencyShutdown\n"); } 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; DEBUG_ERROR("ChargingPermission = FALSE\n"); } 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_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; DEBUG_INFO("Emergency Stop by CP Error (%d, %.02f V, %d)\n", sys->CpState, sys->CpVoltage, cab->cnt ); //cab->cnt = 0; } } #endif //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============ #if PARAMETER_NORMAL_MODE == ENABLE SHM_Read_din_CableCheckRes(&v2gObject.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, &v2gObject.DIN) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== sys->ConnectorLocked = TRUE; //Inicating EVSE that the CCS Connector is Locked. return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_CableCheckRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; 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(&v2gObject.ISO1) < 0) { cab->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { cab->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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 { DEBUG_INFO( "[V2G][CableCheck]Pass (V_now = %.02f, Isolated = %d)\n", sys->PresentChargingVoltage, sys->IsolationStatus); //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 { DEBUG_WARN("unexpected IsolationStatus(%d)\n", sys->IsolationStatus); } 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; DEBUG_INFO("IsolationStatus = 3 (fault)\n"); 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; DEBUG_INFO("Undefined Isolation Status.\n"); } //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; DEBUG_INFO("EVSE_Shutdown\n"); } 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; DEBUG_INFO("EVSE_EmergencyShutdown\n"); } 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; DEBUG_ERROR("ChargingPermission = FALSE\n"); } 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_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; DEBUG_INFO("Emergency Stop by CP Error (%d, %.02f V, %d)\n", sys->CpState, sys->CpVoltage, cab->cnt); //cab->cnt = 0; } } #endif //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============ #if PARAMETER_NORMAL_MODE == ENABLE SHM_Read_iso1_CableCheckRes(&v2gObject.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, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== sys->ConnectorLocked = TRUE; //Inicating EVSE that the CCS Connector is Locked. return errn; } /** * * @param AcceptFd * @return */ int Proc_din_CableCheckReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_DIN_CableCheckReq(&v2gObject.DIN); //Save into Share Memory SHM_Save_din_CableCheckReq(ShmCcsData, &v2gObject.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. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_din_CableCheckRes() fail: %d (DEC)", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_CableCheckReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO1_CableCheckReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_CableCheckReq(ShmCcsData, &v2gObject.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. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_CableCheckRes() fail: %d (DEC)\n", errn); } return errn; } /** * * @param shm_ccs */ 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); } /** * */ void Sudo_Parameter_din_PreChargeRes() { init_dinBodyType(&v2gObject.DIN.V2G_Message.Body); init_dinPreChargeResType(&v2gObject.DIN.V2G_Message.Body.PreChargeRes); v2gObject.DIN.V2G_Message.Body.PreChargeRes_isUsed = 1u; //----- [BODY (1/3)] ResponseCode ----- struct dinPreChargeResType *res; res = &v2gObject.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 } /** * */ void Sudo_Parameter_iso1_PreChargeRes() { init_iso1BodyType(&v2gObject.ISO1.V2G_Message.Body); init_iso1PreChargeResType(&v2gObject.ISO1.V2G_Message.Body.PreChargeRes); v2gObject.ISO1.V2G_Message.Body.PreChargeRes_isUsed = 1u; //----- [BODY (1/3)] ResponseCode ----- struct iso1PreChargeResType *res; res = &v2gObject.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 } /** * * @param AcceptFd * @return */ int Proc_din_PreChargeRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; 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(&v2gObject.DIN) < 0) { pre->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { pre->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); errn = -1; //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_ResponseCode_FAILED_SequenceError (023758) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 5; ShmStatusCodeData->PresentStatusCode[0][5] = 8; } //STEP 2: ============ Modifiy Parameter of ShmCcsData ============ SAVE_PhysicalValueType_DIN70121(&pre->EVSEPresentVoltage, (int) (sys->PresentChargingVoltage * 10), V_DIN70121); //Isolation Status if (sys->IsolationStatus == GFD_Invalid) //0: invalid { pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid; //0 pre->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); errn = -1; DEBUG_ERROR("IsolationStatus = %d\n", sys->IsolationStatus); } 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 { DEBUG_ERROR("GFD_Fault => Emergency Shutdown\n"); 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_Status(Other_Fault); errn = -1; DEBUG_ERROR("IsolationStatus = %d (undefined)\n", sys->IsolationStatus); } //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) { DEBUG_ERROR("CCS GFD trip => EVSE_Shutdown\n"); pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault; } else { DEBUG_ERROR("EVSE_Shutdown\n"); 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) { DEBUG_ERROR("CCS GFD trip => EVSE_EmergencyShutdown\n"); pre->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault; } else { DEBUG_ERROR("EVSE_EmergencyShutdown\n"); 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) { DEBUG_ERROR("ChargingPermission = FALSE\n"); 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_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; DEBUG_ERROR("Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); } #endif //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============ #if PARAMETER_NORMAL_MODE == ENABLE SHM_Read_din_PreChargeRes(&v2gObject.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, &v2gObject.DIN) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_PreChargeRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; 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(&v2gObject.ISO1) < 0) { pre->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { pre->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); errn = -1; //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_ResponseCode_FAILED_SequenceError (023758) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 5; ShmStatusCodeData->PresentStatusCode[0][5] = 8; } //STEP 2: ============ Modifiy Parameter of ShmCcsData ============ SAVE_PhysicalValueType_ISO15118_2014(&pre->EVSEPresentVoltage, (int) (sys->PresentChargingVoltage * 10), V_ISO15118_2014); //Isolation Status if (sys->IsolationStatus == GFD_Invalid) //0: invalid(on going) { pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Invalid; //0 pre->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_Status(Other_Fault); errn = -1; DEBUG_ERROR("IsolationStatus = %d\n", sys->IsolationStatus); } 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 { DEBUG_ERROR("GFD_Fault => Emergency Shutdown\n"); 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_Status(Other_Fault); errn = -1; DEBUG_ERROR("IsolationStatus = %d (undefined)\n", sys->IsolationStatus); } //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) { DEBUG_ERROR("CCS GFD trip => EVSE_Shutdown\n"); pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault; } else { DEBUG_ERROR("EVSE_Shutdown\n"); 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) { DEBUG_ERROR("CCS GFD trip => EVSE_EmergencyShutdown\n"); pre->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault; } else { DEBUG_ERROR("EVSE_EmergencyShutdown\n"); 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) { DEBUG_ERROR("ChargingPermission = FALSE\n"); 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_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; DEBUG_ERROR("Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); } #endif //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============ #if PARAMETER_NORMAL_MODE == ENABLE SHM_Read_iso1_PreChargeRes(&v2gObject.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, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== return errn; } /** * * @param AcceptFd * @return */ int Proc_din_PreChargeReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_DIN_PreChargeReq(&v2gObject.DIN); //Save into Share Memory SHM_Save_din_PreChargeReq(ShmCcsData, &v2gObject.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. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_din_PreChargeRes() fail: %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_PreChargeReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO1_PreChargeReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_PreChargeReq(ShmCcsData, &v2gObject.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. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_PreChargeRes() fail: %d (DEC)\n", errn); } return errn; } /** * * @param shm_ccs */ 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); } /** * */ void Sudo_Parameter_din_PowerDeliveryRes() { init_dinBodyType(&v2gObject.DIN.V2G_Message.Body); init_dinPowerDeliveryResType(&v2gObject.DIN.V2G_Message.Body.PowerDeliveryRes); v2gObject.DIN.V2G_Message.Body.PowerDeliveryRes_isUsed = 1u; //----- [BODY (1/3)] ResponseCode ----- struct dinPowerDeliveryResType *res; res = &v2gObject.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 } /** * */ void Sudo_Parameter_iso1_PowerDeliveryRes() { init_iso1BodyType(&v2gObject.ISO1.V2G_Message.Body); init_iso1PowerDeliveryResType(&v2gObject.ISO1.V2G_Message.Body.PowerDeliveryRes); v2gObject.ISO1.V2G_Message.Body.PowerDeliveryRes_isUsed = 1u; //----- [BODY (1/3)] ResponseCode ----- struct iso1PowerDeliveryResType *res; res = &v2gObject.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 } /** * * @param AcceptFd * @return */ int Proc_din_PowerDeliveryStartRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; res = &v2gObject.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(&v2gObject.DIN) < 0) { res->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { res->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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(&v2gObject.DIN, ShmCcsData); #else Sudo_Parameter_din_PowerDeliveryRes(); #endif //EVSE Status Code res->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid; //1 res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready; //Check for CSU command of "Stop by EVSE" if (sys->DC_EVSEStatus == EVSE_Shutdown) { //res->ResponseCode = FAILED_DIN70121; res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown; } else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { //res->ResponseCode = FAILED_DIN70121; res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown; } else if (ShmInternalComm->ChargingPermission == FALSE) { //res->ResponseCode = FAILED_DIN70121; res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown; } //STEP 4: ============ Encode and Send Response Message =========== if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &v2gObject.DIN) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_PowerDeliveryStartRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; res = &v2gObject.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(&v2gObject.ISO1) < 0) { res->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); 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(&v2gObject.ISO1, ShmCcsData); #else Sudo_Parameter_iso1_PowerDeliveryRes(); #endif //EVSE Status Code res->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid; //1 res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready; //Check for CSU command of "Stop by EVSE" if (sys->DC_EVSEStatus == EVSE_Shutdown) { //res->ResponseCode = FAILED_ISO15118_2014; res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown; } else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { //res->ResponseCode = FAILED_ISO15118_2014; res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown; } else if (ShmInternalComm->ChargingPermission == FALSE) { //res->ResponseCode = FAILED_ISO15118_2014; res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown; } //STEP 4: ============ Encode and Send Response Message =========== if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== return errn; } /** * * @param AcceptFd * @return */ int Proc_din_PowerDeliveryStartReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_DIN_PowerDeliveryReq(&v2gObject.DIN); //Save into Share Memory SHM_Save_din_PowerDeliveryReq(ShmCcsData, &v2gObject.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. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_din_PowerDeliveryStartRes() fail: %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_PowerDeliveryStartReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO1_PowerDeliveryReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_PowerDeliveryReq(ShmCcsData, &v2gObject.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. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_PowerDeliveryStartRes() fail: %d (DEC)\n", errn); } return errn; } /** * * @param shm_ccs */ 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); } /** * */ void Sudo_Parameter_din_CurrentDemandRes() { init_dinBodyType(&v2gObject.DIN.V2G_Message.Body); init_dinCurrentDemandResType(&v2gObject.DIN.V2G_Message.Body.CurrentDemandRes); v2gObject.DIN.V2G_Message.Body.CurrentDemandRes_isUsed = 1u; //----- [BODY (1/10)] ResponseCode ----- struct dinCurrentDemandResType *res; res = &v2gObject.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; } /** * */ void Sudo_Parameter_iso1_CurrentDemandRes() { init_iso1BodyType(&v2gObject.ISO1.V2G_Message.Body); init_iso1CurrentDemandResType(&v2gObject.ISO1.V2G_Message.Body.CurrentDemandRes); v2gObject.ISO1.V2G_Message.Body.CurrentDemandRes_isUsed = 1u; //----- [BODY (1/10)] ResponseCode ----- struct iso1CurrentDemandResType *res; res = &v2gObject.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; } /** * */ void Sudo_Parameter_iso1_ChargingStatusRes() { //int i = 0; struct iso1ChargingStatusResType *res; init_iso1BodyType(&v2gObject.ISO1.V2G_Message.Body); init_iso1ChargingStatusResType(&v2gObject.ISO1.V2G_Message.Body.ChargingStatusRes); res = &v2gObject.ISO1.V2G_Message.Body.ChargingStatusRes; v2gObject.ISO1.V2G_Message.Body.ChargingStatusRes_isUsed = 1u; //----- [BODY (1/10)] ResponseCode ----- res->ResponseCode = OK_ISO15118_2014; //----- [BODY (2/10)] AC_EVSEStatus ----- res->AC_EVSEStatus.RCD = FALSE; //FALSE(no error), TRUE(error is detected) res->AC_EVSEStatus.NotificationMaxDelay = 0; res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None; // iso1EVSENotificationType_None = 0, // iso1EVSENotificationType_StopCharging = 1, // iso1EVSENotificationType_ReNegotiation = 2 //----- [BODY (3/10)] EVSEMaxCurrent ----- res->EVSEMaxCurrent_isUsed = 1u; res->EVSEMaxCurrent.Value = 32; res->EVSEMaxCurrent.Multiplier = 0; res->EVSEMaxCurrent.Unit = iso1unitSymbolType_A; //----- [BODY (4/10)] SAScheduleTupleID ----- res->SAScheduleTupleID = 0; //----- [BODY (5/10)] EVSEID ----- res->EVSEID.charactersLen = 37; memset(res->EVSEID.characters, 0, sizeof(res->EVSEID.characters)); //sprintf((char*)res->EVSEID.characters, CCS_AC_EVSEID); //----- [BODY (6/10)] MeterInfo ----- res->MeterInfo_isUsed = 1u; memset(res->MeterInfo.MeterID.characters, 0, sizeof(res->MeterInfo.MeterID.characters)); memset(res->MeterInfo.SigMeterReading.bytes, 0, sizeof(res->MeterInfo.SigMeterReading.bytes)); //[MeterInfo][1/5] MeterID //sprintf((char*)res->MeterInfo.MeterID , CCS_AC_METER_ID); //[MeterInfo][2/5] SigMeterReading (optional) //sprintf((char*)res->MeterInfo.SigMeterReading , CCS_AC_SIG_METER_READING); //[MeterInfo][3/5] MeterStatus (optional) res->MeterInfo.MeterStatus = 0; //[MeterInfo][4/5] MeterReading (optional) res->MeterInfo.MeterReading = 12345; //[MeterInfo][5/5] TMeter (optional) res->MeterInfo.TMeter = 1586243587; //Unix Time Stamp format //----- [BODY (7/10)] ReceiptRequired ----- res->ReceiptRequired_isUsed = 1u; res->ReceiptRequired = FALSE; //optional } /** * * @param code */ void Check_EVErrorCode(int code) { if (code != NO_ERROR) //NO_ERROR = 0 { //Asking CSU to Stop CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; //Update_V2G_Status(Other_Fault); DEBUG_INFO("Stop by EV (EVErrorCode = %d (DEC))\n", code); } } /** * * @param AcceptFd * @return */ int Proc_din_CurrentDemandRes(int AcceptFd) { //[ To-Do] Check SessionID of ServiceDiscoveryReq, //if it is not the same, the packet should be ignored. //STEP 1: ============ Initialize ============ int errn = 0; bitstream_t v2g_tx_stream; static struct CurrentDemandResponse_DIN70121 *cur; static struct ChargingInfoData *sys; // int i = 0; // static int EVSE_max_current; // int tmp = 0; size_t pos = 0; v2g_tx_stream.pos = &pos; v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE; //(64*1024) //65,536 = 65.5KB v2g_tx_stream.data = v2gBuffer.tx; 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(&v2gObject.DIN) < 0) { cur->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { cur->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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) { DEBUG_ERROR("EvBatteryMaxCurrent is negative(%.02f) => End_Process\n", sys->EvBatteryMaxCurrent); cur->DC_EVSEStatus.EVSEStatusCode = dinresponseCodeType_FAILED_WrongChargeParameter; //16 cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown; errn = -1; //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_ResponseCode_FAILED_WrongChargeParameter (023775) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 7; ShmStatusCodeData->PresentStatusCode[0][5] = 5; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } //STEP 2: ============ Modifiy Parameter of ShmCcsData ============ SAVE_PhysicalValueType_DIN70121(&cur->EVSEPresentCurrent, (int) (sys->PresentChargingCurrent * 10), A_DIN70121); SAVE_PhysicalValueType_DIN70121(&cur->EVSEPresentVoltage, (int) (sys->PresentChargingVoltage * 10), V_DIN70121); #if TESLA_SLOW_INCREASE_CURRENT_FUNCTION == DISABLE SAVE_PhysicalValueType_DIN70121(&cur->EVSEMaximumCurrentLimit, (int) (sys->AvailableChargingCurrent * 10), A_DIN70121); #endif SAVE_PhysicalValueType_DIN70121(&cur->EVSEMaximumPowerLimit, (int) (sys->AvailableChargingPower * 10), W_DIN70121); SAVE_PhysicalValueType_DIN70121(&cur->EVSEMaximumVoltageLimit, (int) (sys->MaximumChargingVoltage * 10), V_DIN70121); #if PATCH_FOR_BMW_I3_BUG_EVSEMAXIMUMVOLTAGELIMIT_599V == ENABLE if (sys->EvBatteryMaxVoltage <= 500) { SAVE_PhysicalValueType_DIN70121(&cur->EVSEMaximumVoltageLimit, (int) (500 * 10), V_DIN70121); //500V } #endif //Limit the EVTargetCurrent should be under EVSEMaximumCurrentLimit if (sys->EvBatterytargetCurrent > sys->AvailableChargingCurrent) { sys->EvBatterytargetCurrent = sys->AvailableChargingCurrent; //[To-Do] Limit is achieved flag } //Isolation Status if (sys->IsolationStatus == GFD_Invalid) //0:invalid (on going) { cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid; //0 cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; DEBUG_ERROR("IsolationStatus = %d\n", sys->IsolationStatus); Update_V2G_Status(Other_Fault); errn = -1; } else if (sys->IsolationStatus == GFD_Valid) //1: valid { cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Valid; //1 } else if (sys->IsolationStatus == GFD_Warning) //2: warning { cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Warning; //2 } else if (sys->IsolationStatus == GFD_Fault) //3: fault { cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault; //3 cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; DEBUG_ERROR("GFD_Fault => Emergency Shutdown\n"); Update_V2G_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; DEBUG_ERROR("IsolationStatus = %d(undefined)\n", sys->IsolationStatus); Update_V2G_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) { DEBUG_ERROR("[DIN]CCS GFD trip => EVSE_Shutdown\n"); cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault; } else { DEBUG_ERROR("[DIN]]EVSE_Shutdown\n"); 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) { DEBUG_INFO("[DIN]]CCS GFD trip => EVSE_EmergencyShutdown\n"); cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Fault; } else { DEBUG_ERROR("[DIN]EVSE_EmergencyShutdown\n"); 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) { DEBUG_ERROR("[DIN]Permission OFF\n"); //cur->ResponseCode = FAILED_DIN70121; cur->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus; cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown; //errn = -1; } else { //null } //Response to CP Error #if CP_PROTECTION_MECHANISM == ENABLE if ((sys->CpState != 4) && (sys->CpState != 5)) //State C (6V), D (3V) { cur->ResponseCode = FAILED_DIN70121; cur->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_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; DEBUG_INFO("Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); } #endif //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============ #if PARAMETER_NORMAL_MODE == ENABLE SHM_Read_din_CurrentDemandRes(&v2gObject.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, &v2gObject.DIN) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_CurrentDemandRes(int AcceptFd) { //[ To-Do] Check SessionID of ServiceDiscoveryReq, //if it is not the same, the packet should be ignored. //STEP 1: ============ Initialize ============ int errn = 0; bitstream_t v2g_tx_stream; static struct CurrentDemandResponse_ISO15118_2014 *cur; static struct ChargingInfoData *sys; // int i = 0; // static int EVSE_max_current; // int tmp = 0; size_t pos = 0; v2g_tx_stream.pos = &pos; v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE; //(64*1024) //65,536 = 65.5KB v2g_tx_stream.data = v2gBuffer.tx; 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(&v2gObject.ISO1) < 0) { cur->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { cur->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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) { DEBUG_ERROR("EvBatteryMaxCurrent is negative(%.02f) => End_Process\n", sys->EvBatteryMaxCurrent); cur->ResponseCode = iso1responseCodeType_FAILED_WrongChargeParameter; //16 cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown; errn = -1; //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_ResponseCode_FAILED_WrongChargeParameter (023775) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 7; ShmStatusCodeData->PresentStatusCode[0][5] = 5; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; } //STEP 2: ============ Modifiy Parameter of ShmCcsData ============ SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEPresentCurrent, (int) (sys->PresentChargingCurrent * 10), A_ISO15118_2014); SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEPresentVoltage, (int) (sys->PresentChargingVoltage * 10), V_ISO15118_2014); #if TESLA_SLOW_INCREASE_CURRENT_FUNCTION == DISABLE SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEMaximumCurrentLimit, (int) (sys->AvailableChargingCurrent * 10), A_ISO15118_2014); #endif SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEMaximumPowerLimit, (int) (sys->AvailableChargingPower * 10), W_ISO15118_2014); SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEMaximumVoltageLimit, (int) (sys->MaximumChargingVoltage * 10), V_ISO15118_2014); #if PATCH_FOR_BMW_I3_BUG_EVSEMAXIMUMVOLTAGELIMIT_599V == ENABLE if (sys->EvBatteryMaxVoltage <= 500) { SAVE_PhysicalValueType_ISO15118_2014(&cur->EVSEMaximumVoltageLimit, (int) (500 * 10), V_ISO15118_2014); //500V } #endif //Limit the EVTargetCurrent should be under EVSEMaximumCurrentLimit if (sys->EvBatterytargetCurrent > sys->AvailableChargingCurrent) { sys->EvBatterytargetCurrent = sys->AvailableChargingCurrent; //[To-Do] Limit is achieved flag } //Isolation Status if (sys->IsolationStatus == GFD_Invalid) //0: invalid (on going) { cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Invalid; //0 cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; DEBUG_ERROR("IsolationStatus = %d\n", sys->IsolationStatus); Update_V2G_Status(Other_Fault); errn = -1; } else if (sys->IsolationStatus == GFD_Valid) //1: valid { cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid; //1 } else if (sys->IsolationStatus == GFD_Warning) //2: warning { cur->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Warning; //2 } else if (sys->IsolationStatus == GFD_Fault) //3: fault { cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault; //3 cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; DEBUG_ERROR("GFD_Fault => EmergencyShutdown\n"); Update_V2G_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; DEBUG_ERROR("IsolationStatus = %d(undefined)\n", sys->IsolationStatus); Update_V2G_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) { DEBUG_ERROR("CCS GFD trip => EVSE_Shutdown\n"); cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault; } else { DEBUG_ERROR("EVSE_Shutdown\n"); 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) { DEBUG_ERROR("CCS GFD trip => EVSE_EmergencyShutdown\n"); cur->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Fault; } else { DEBUG_ERROR("EVSE_EmergencyShutdown\n"); 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) { DEBUG_ERROR("Permission OFF\n"); //cur->ResponseCode = FAILED_ISO15118_2014; cur->DC_EVSEStatus.EVSEIsolationStatus = (unsigned char)sys->IsolationStatus; cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown; //errn = -1; } else { //null } //Response to CP Error #if CP_PROTECTION_MECHANISM == ENABLE if ((sys->CpState != 4) && (sys->CpState != 5)) //State C (6V), D (3V) { cur->ResponseCode = FAILED_ISO15118_2014; cur->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_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; DEBUG_INFO("[CurrentDemand]Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); } #endif //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============ #if PARAMETER_NORMAL_MODE == ENABLE SHM_Read_iso1_CurrentDemandRes(&v2gObject.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, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_ChargingStatusRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; res = &ShmCcsData->V2GMessage_ISO15118_2014.ChargingStatusResponse; sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; //Init res->ResponseCode = OK_ISO15118_2014; res->ReceiptRequired = FALSE; //optional res->SAScheduleTupleID = 0; res->AC_EVSEStatus.RCD = FALSE; //FALSE(no error), TRUE(error is detected) res->AC_EVSEStatus.NotificationMaxDelay = 0; res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None; // iso1EVSENotificationType_None = 0, // iso1EVSENotificationType_StopCharging = 1, // iso1EVSENotificationType_ReNegotiation = 2 //[HEADER] Check Req SessionID if (Check_iso1_V2G_Rx_MSG_SessionID(&v2gObject.ISO1) < 0) { res->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { res->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); errn = -1; //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_ResponseCode_FAILED_SequenceError (023758) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 5; ShmStatusCodeData->PresentStatusCode[0][5] = 8; } //EVSE ID memset(res->EVSEID, 0, sizeof(res->EVSEID)); sprintf((char*)res->EVSEID, CCS_AC_EVSEID); //[MeterInfo][0/5] init //memset(res->MeterInfo.MeterID, 0, sizeof(res->MeterInfo.MeterID)); //memset(res->MeterInfo.SigMeterReading, 0, sizeof(res->MeterInfo.SigMeterReading)); //[MeterInfo][1/5] MeterID //sprintf((char*)res->MeterInfo.MeterID, CCS_AC_METER_ID); //[MeterInfo][2/5] SigMeterReading (optional) //sprintf((char*)res->MeterInfo.SigMeterReading , CCS_AC_SIG_METER_READING); //[MeterInfo][3/5] MeterStatus (optional) res->MeterInfo.MeterStatus = 0; //[MeterInfo][4/5] MeterReading (optional) res->MeterInfo.MeterReading = 12345; //[MeterInfo][5/5] TMeter (optional) res->MeterInfo.TMeter = 1586243587; //Unix Time Stamp format //STEP 2: ============ Modify Parameter of ShmCcsData ============ if(ShmCcsData->EnergyTransferMode == MODE_DC_EXTENDED) { SAVE_PhysicalValueType_ISO15118_2014(&res->EVSEMaxCurrent, (int)(sys->AvailableChargingCurrent * 10), A_ISO15118_2014); //Isolation Status (RCD) if (sys->IsolationStatus == 0) //Isolation is invalid { res->AC_EVSEStatus.RCD = TRUE; //FALSE(no error), TRUE(error is detected) res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; DEBUG_ERROR("IsolationStatus: %d\n", sys->IsolationStatus); Update_V2G_Status(Other_Fault); errn = -1; } else if (sys->IsolationStatus == 1) //Isolation is valid { res->AC_EVSEStatus.RCD = FALSE; //FALSE(no error), TRUE(error is detected) res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None; } else { res->AC_EVSEStatus.RCD = TRUE; //FALSE(no error), TRUE(error is detected) res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; DEBUG_ERROR("IsolationStatus = %d(undefined)\n", sys->IsolationStatus); Update_V2G_Status(Other_Fault); errn = -1; } //Check for CSU command of "Stop by EVSE" if (sys->DC_EVSEStatus == EVSE_Shutdown) { //res->ResponseCode = FAILED_ISO15118_2014; res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging; //errn = -1; } else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { //res->ResponseCode = FAILED_ISO15118_2014; res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging; //errn = -1; } else if (ShmInternalComm->ChargingPermission == FALSE) { //res->ResponseCode = FAILED_ISO15118_2014; res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging; //errn = -1; } //Response to CP Error #if CP_PROTECTION_MECHANISM == ENABLE if ((sys->CpState != 4) && (sys->CpState != 5)) //State C (6V), D (3V) { res->ResponseCode = FAILED_ISO15118_2014; res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_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; DEBUG_INFO("Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); } #endif } else { SAVE_PhysicalValueType_ISO15118_2014(&res->EVSEMaxCurrent, (int)(sys->AvailableChargingCurrent * 10), A_ISO15118_2014); //Isolation Status (RCD) res->AC_EVSEStatus.RCD = FALSE; //FALSE(no error), TRUE(error is detected) res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None; //Check for CSU command of "Stop by EVSE" if (ShmInternalComm->ChargingPermission == FALSE) { //res->ResponseCode = FAILED_ISO15118_2014; res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging; //errn = -1; } //Response to CP Error #if CP_PROTECTION_MECHANISM == ENABLE if((sys->CpState != 3) && (sys->CpState != 4) && (sys->CpState != 5)) //State C (6V), D (3V) { res->ResponseCode = FAILED_ISO15118_2014; res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; Update_V2G_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; DEBUG_ERROR("Emergency Stop by CP Error (%d, %.02f V)\n", sys->CpState, sys->CpVoltage); } #endif } //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============ #if PARAMETER_NORMAL_MODE == ENABLE SHM_Read_iso1_ChargingStatusRes(&v2gObject.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, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== return errn; } /** * * @param AcceptFd * @return */ int Proc_din_CurrentDemandReq(int AcceptFd) { int errn = 0; DEBUG_INFO("[V2G[RX]]CurrentDemandReq\n"); //Print the decoded XML Document PRINT_XML_DOC_DIN_CurrentDemandReq(&v2gObject.DIN); //Save into Share Memory SHM_Save_din_CurrentDemandReq(ShmCcsData, &v2gObject.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. DEBUG_INFO("[V2G][TX]CurrentDemandRes\n"); } else { DEBUG_ERROR("Proc_din_CurrentDemandRes fail: (%d,DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_CurrentDemandReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO1_CurrentDemandReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_CurrentDemandReq(ShmCcsData, &v2gObject.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. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_CurrentDemandRes fail: (%d,DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_ChargingStatusReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO1_ChargingStatusReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_ChargingStatusReq(ShmCcsData, &v2gObject.ISO1, ShmSysConfigAndInfo); //Check for EV Error Code //no content in ISO1 errn = Proc_iso1_ChargingStatusRes(AcceptFd); if (errn == 0) { //Response is sent successfully. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_ChargingStatusRes() fail: (%d,DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_din_PowerDeliveryStopRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; res = &v2gObject.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(&v2gObject.DIN) < 0) { res->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { res->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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(&v2gObject.DIN, ShmCcsData); #else Sudo_Parameter_din_PreChargeRes(); #endif //EVSE Status Code res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready; //Check for CSU command of "Stop by EVSE" if (sys->DC_EVSEStatus == EVSE_Shutdown) { //res->ResponseCode = FAILED_DIN70121; res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown; } else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { //res->ResponseCode = FAILED_DIN70121; res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown; } else if (ShmInternalComm->ChargingPermission == FALSE) { //res->ResponseCode = FAILED_DIN70121; res->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown; } //STEP 4: ============ Encode and Send Response Message =========== if (send_encoded_din_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &v2gObject.DIN) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_PowerDeliveryStopRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; res = &v2gObject.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(&v2gObject.ISO1) < 0) { res->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { res->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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(ShmCcsData->EnergyTransferMode == MODE_DC_EXTENDED) { #if PARAMETER_NORMAL_MODE == ENABLE ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryResponse.DC_EVSEStatus.DC_EVSEStatusCode = EVSE_NotReady; SHM_Read_iso1_PowerDeliveryRes(&v2gObject.ISO1, ShmCcsData); #else Sudo_Parameter_iso1_PreChargeRes(); #endif //EVSE Status Code res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready; res->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Valid; //1 /*+++ 20200808, vern, Isolation Status should be valid during 2nd PowerDelivert ---*/ //Check for CSU command of "Stop by EVSE" if (sys->DC_EVSEStatus == EVSE_Shutdown) { //res->ResponseCode = FAILED_ISO15118_2014; res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready; /*+++ 20200808, vern, Isolation Status should be valid during 2nd PowerDelivert ---*/ } else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { //res->ResponseCode = FAILED_ISO15118_2014; res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown; } else if (ShmInternalComm->ChargingPermission == FALSE) { //res->ResponseCode = FAILED_ISO15118_2014; res->DC_EVSEStatus.EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready; /*+++ 20200808, vern, Isolation Status should be valid during 2nd PowerDelivert ---*/ } } else { #if PARAMETER_NORMAL_MODE == ENABLE SHM_Read_iso1_PowerDeliveryRes(&v2gObject.ISO1, ShmCcsData); #endif //EVSE Status Code res->AC_EVSEStatus.RCD = 0; res->AC_EVSEStatus.EVSENotification = iso1EVSENotificationType_None; res->AC_EVSEStatus.NotificationMaxDelay = 10; } //STEP 4: ============ Encode and Send Response Message =========== if (send_encoded_iso1_V2GTP_Stream(AcceptFd, &v2g_tx_stream, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== return errn; } /** * * @param AcceptFd * @return */ int Proc_din_PowerDeliveryStopReq(int AcceptFd) { int errn = 0; //Request CSU to STOP //This should be reponsed as soon as possible once this message is received. CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; EVCOMM_SYS_INFO.EvBatterytargetVoltage = 0; EVCOMM_SYS_INFO.EvBatterytargetCurrent = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_DIN_PowerDeliveryReq(&v2gObject.DIN); //Save into Share Memory SHM_Save_din_PowerDeliveryReq(ShmCcsData, &v2gObject.DIN, ShmSysConfigAndInfo); //Check for EV Error Code Check_EVErrorCode(ShmCcsData->V2GMessage_DIN70121.PowerDeliveryRequest.DC_EVPowerDeliveryParameter.DC_EVStatus.EVErrorCode); //[To-Do] Sending response after the EVSE output voltage decreases to under 60V usleep(1500000); //1.5 seconds //sleep(1); //1 second errn = Proc_din_PowerDeliveryStopRes(AcceptFd); if (errn == 0) { //send response successfully. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_din_PowerDeliveryStopRes() fail: %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_PowerDeliveryStopReq(int AcceptFd) { int errn = 0; //Request CSU to STOP //This should be reponsed as soon as possible once this message is received. CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; EVCOMM_SYS_INFO.EvBatterytargetVoltage = 0; EVCOMM_SYS_INFO.EvBatterytargetCurrent = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO1_PowerDeliveryReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_PowerDeliveryReq(ShmCcsData, &v2gObject.ISO1, ShmSysConfigAndInfo); //Check for EV Error Code Check_EVErrorCode(ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryRequest.DC_EVPowerDeliveryParameter.DC_EVStatus.EVErrorCode); //[To-Do] Sending response after the EVSE output voltage decreases to under 60V usleep(1500000); //1.5 seconds //sleep(1); //1 second errn = Proc_iso1_PowerDeliveryStopRes(AcceptFd); if (errn == 0) { //send response successfully. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_PowerDeliveryStopRes fail(): %d (DEC)\n", errn); } return errn; } /** * * @param shm_ccs */ 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); } /** * */ void Sudo_Parameter_din_WeldingDetectionRes() { init_dinBodyType(&v2gObject.DIN.V2G_Message.Body); init_dinWeldingDetectionResType(&v2gObject.DIN.V2G_Message.Body.WeldingDetectionRes); v2gObject.DIN.V2G_Message.Body.WeldingDetectionRes_isUsed = 1u; //----- [BODY (1/3)] ResponseCode ----- struct dinWeldingDetectionResType *res; res = &v2gObject.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 } /** * */ void Sudo_Parameter_iso1_WeldingDetectionRes() { init_iso1BodyType(&v2gObject.ISO1.V2G_Message.Body); init_iso1WeldingDetectionResType(&v2gObject.ISO1.V2G_Message.Body.WeldingDetectionRes); v2gObject.ISO1.V2G_Message.Body.WeldingDetectionRes_isUsed = 1u; //----- [BODY (1/3)] ResponseCode ----- struct iso1WeldingDetectionResType *res; res = &v2gObject.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 } /** * * @param AcceptFd * @return */ int Proc_din_WeldingDetectionRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; 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(&v2gObject.DIN) < 0) { wel->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { wel->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); errn = -1; //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_ResponseCode_FAILED_SequenceError (023758) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 5; ShmStatusCodeData->PresentStatusCode[0][5] = 8; } //STEP 2: ============ Modifiy Parameter of ShmCcsData ============ SAVE_PhysicalValueType_DIN70121(&wel->EVSEPresentVoltage, (int) (sys->PresentChargingVoltage * 10), V_DIN70121); //EVSE Status Code wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Ready; //Check for CSU command of "Stop by EVSE" if (sys->DC_EVSEStatus == EVSE_Shutdown) { //wel->ResponseCode = FAILED_DIN70121; wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown; } else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { //wel->ResponseCode = FAILED_DIN70121; wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown; } else if (ShmInternalComm->ChargingPermission == FALSE) { //wel->ResponseCode = FAILED_DIN70121; wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_Shutdown; } //Isolation Status if (sys->IsolationStatus == GFD_Invalid) //0:invalid (on going) { wel->DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid; //0 wel->DC_EVSEStatus.EVSEStatusCode = dinDC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; DEBUG_ERROR("IsolationStatus = %d\n", sys->IsolationStatus); Update_V2G_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; DEBUG_ERROR("GFD_Fault => Emergency Shutdown\n"); Update_V2G_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; DEBUG_ERROR("IsolationStatus = %d(undefined)\n", sys->IsolationStatus); Update_V2G_Status(Other_Fault); errn = -1; } //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============ #if PARAMETER_NORMAL_MODE == ENABLE SHM_Read_din_WeldingDetectionRes(&v2gObject.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, &v2gObject.DIN) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_WeldingDetectionRes(int AcceptFd) { //[ 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 = v2gBuffer.tx; 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(&v2gObject.ISO1) < 0) { wel->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { wel->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); errn = -1; //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_ResponseCode_FAILED_SequenceError (023758) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 7; ShmStatusCodeData->PresentStatusCode[0][4] = 5; ShmStatusCodeData->PresentStatusCode[0][5] = 8; } //STEP 2: ============ Modifiy Parameter of ShmCcsData ============ SAVE_PhysicalValueType_ISO15118_2014(&wel->EVSEPresentVoltage, (int) (sys->PresentChargingVoltage * 10), V_ISO15118_2014); //EVSE Status Code wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Ready; //Check for CSU command of "Stop by EVSE" if (sys->DC_EVSEStatus == EVSE_Shutdown) { //wel->ResponseCode = FAILED_ISO15118_2014; wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown; } else if (sys->DC_EVSEStatus == EVSE_EmergencyShutdown) { //wel->ResponseCode = FAILED_ISO15118_2014; wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown; } else if (ShmInternalComm->ChargingPermission == FALSE) { //wel->ResponseCode = FAILED_ISO15118_2014; wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_Shutdown; } //Isolation Status if (sys->IsolationStatus == GFD_Invalid) //0: invalid (on going) { wel->DC_EVSEStatus.EVSEIsolationStatus = iso1isolationLevelType_Invalid; //0 wel->DC_EVSEStatus.DC_EVSEStatusCode = iso1DC_EVSEStatusCodeType_EVSE_EmergencyShutdown; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; DEBUG_ERROR("IsolationStatus = %d\n", sys->IsolationStatus); Update_V2G_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; DEBUG_ERROR("GFD_Fault => EmergencyShutdown\n"); Update_V2G_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; DEBUG_ERROR("IsolationStatus = %d(undefined)\n", sys->IsolationStatus); Update_V2G_Status(Other_Fault); errn = -1; } //STEP 3: ============ Save Parameters from ShmCcsData to EXI Engine Buffer ============ #if PARAMETER_NORMAL_MODE == ENABLE SHM_Read_iso1_WeldingDetectionRes(&v2gObject.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, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //STEP 5: ============ Update Flags =========== return errn; } /** * * @param AcceptFd * @return */ int Proc_din_WeldingDetectionReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_DIN_WeldingDetectionReq(&v2gObject.DIN); //Save into Share Memory SHM_Save_din_WeldingDetectionReq(ShmCcsData, &v2gObject.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. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_din_WeldingDetectionRes() fail: %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_WeldingDetectionReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO1_WeldingDetectionReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_WeldingDetectionReq(ShmCcsData, &v2gObject.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. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_WeldingDetectionRes() fail: %d (DEC)", errn); } return errn; } /** * * @param shm_ccs */ 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; } /** * */ void Sudo_Parameter_din_SessionStopRes() { init_dinBodyType(&v2gObject.DIN.V2G_Message.Body); init_dinSessionStopResType(&v2gObject.DIN.V2G_Message.Body.SessionStopRes); v2gObject.DIN.V2G_Message.Body.SessionStopRes_isUsed = 1u; //----- [BODY (1/3)] ResponseCode ----- struct dinSessionStopResType *res; res = &v2gObject.DIN.V2G_Message.Body.SessionStopRes; res->ResponseCode = dinresponseCodeType_OK; } /** * */ void Sudo_Parameter_iso1_SessionStopRes() { init_iso1BodyType(&v2gObject.ISO1.V2G_Message.Body); init_iso1SessionStopResType(&v2gObject.ISO1.V2G_Message.Body.SessionStopRes); v2gObject.ISO1.V2G_Message.Body.SessionStopRes_isUsed = 1u; //----- [BODY (1/3)] ResponseCode ----- struct iso1SessionStopResType *res; res = &v2gObject.ISO1.V2G_Message.Body.SessionStopRes; res->ResponseCode = iso1responseCodeType_OK; } /** * * @param AcceptFd * @return */ int Proc_din_SessionStopRes(int AcceptFd) { //[ To-Do] Check SessionID of ServiceDiscoveryReq, //if it is not the same, the packet should be ignored. //STEP 1: ============ Initialize ============ //int i = 0; int errn = 0; bitstream_t v2g_tx_stream; struct SessionStopResponse_DIN70121 *stp; size_t pos = 0; v2g_tx_stream.pos = &pos; v2g_tx_stream.size = V2GTP_MSG_TX_BUFFER_SIZE; //(64*1024) //65,536 = 65.5KB v2g_tx_stream.data = v2gBuffer.tx; stp = &ShmCcsData->V2GMessage_DIN70121.SessionStopResponse; stp->ResponseCode = OK_DIN70121; //[HEADER] Check Req SessionID if (Check_din_V2G_Rx_MSG_SessionID(&v2gObject.DIN) < 0) { stp->ResponseCode = dinresponseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { stp->ResponseCode = dinresponseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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(&v2gObject.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, &v2gObject.DIN) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //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 for(int idx=3;idx>0;idx++) { DEBUG_INFO("PWM 5\%% countdown: %d\n", idx); sleep(1); } 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; } /** * * @param AcceptFd * @return */ int Proc_iso1_SessionStopRes(int AcceptFd) { //[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 = v2gBuffer.tx; 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(&v2gObject.ISO1) < 0) { stp->ResponseCode = iso1responseCodeType_FAILED_UnknownSession; //6 DEBUG_ERROR("unmatched SessionID => End_Process\n"); errn = -1; } //Check for SequenceError if (EVCOMM_SYS_INFO.SequenceError == TRUE) { stp->ResponseCode = iso1responseCodeType_FAILED_SequenceError; //5 DEBUG_ERROR("SequenceError => End_Process\n"); 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(&v2gObject.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, &v2gObject.ISO1) != 0) { DEBUG_ERROR("Tx encoded msg error\n"); errn = -1; } //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 for(int idx=2;idx>0;idx--) { DEBUG_INFO("PWM 5\%% count down: %d\n", idx); sleep(1); } 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; } /** * * @param AcceptFd * @return */ int Proc_din_SessionStopReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_DIN_SessionStopReq(&v2gObject.DIN); //Save into Share Memory SHM_Save_din_SessionStopReq(ShmCcsData, &v2gObject.DIN, ShmSysConfigAndInfo); errn = Proc_din_SessionStopRes(AcceptFd); if (errn == 0) { //send response successfully. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_din_SessionStopRes() fail: %d (DEC)", errn); } return errn; } /** * * @param AcceptFd * @return */ int Proc_iso1_SessionStopReq(int AcceptFd) { int errn = 0; DEBUG_INFO("Request in.\n"); //Print the decoded XML Document PRINT_XML_DOC_ISO1_SessionStopReq(&v2gObject.ISO1); //Save into Share Memory SHM_Save_iso1_SessionStopReq(ShmCcsData, &v2gObject.ISO1, ShmSysConfigAndInfo); errn = Proc_iso1_SessionStopRes(AcceptFd); if (errn == 0) { //send response successfully. DEBUG_INFO("Response out.\n"); } else { DEBUG_ERROR("Proc_iso1_SessionStopRes() fail: %d (DEC)\n", errn); } return errn; } /** * * @param AcceptFd * @return */ 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 (v2gObject.appHandshake.supportedAppProtocolReq_isUsed == 1u) { v2gObject.appHandshake.supportedAppProtocolReq_isUsed = 0; if (Proc_supportedAppProtocolReq(AcceptFd) == 0) //0: no error { ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); Update_V2G_Status(SupportedAppProtocolResponse); } else { DEBUG_ERROR("supportedAppProtocolResReq: fail\n"); Update_V2G_Status(Other_Fault); } } req_is_responsed = TRUE; break; } case SupportedAppProtocolResponse: { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionSetupRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case SessionSetupRequest: //19 { if (Proc_din_SessionSetupReq(AcceptFd) == 0) { Update_V2G_Status(SessionSetupResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("SessionSetupReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case SessionSetupResponse: //20 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceDiscoveryRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case ServiceDiscoveryRequest: //21 { if (Proc_din_ServiceDiscoveryReq(AcceptFd) == 0) { Update_V2G_Status(ServiceDiscoveryResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ServiceDiscoveryReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case ServiceDiscoveryResponse: //22 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceAndPaymentSelectionRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case ServiceAndPaymentSelectionRequest: //25 { if (Proc_din_ServiceAndPaymentSelectionReq(AcceptFd) == 0) { Update_V2G_Status(ServiceAndPaymentSelectionResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ServiceAndPaymentSelectionReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case ServiceAndPaymentSelectionResponse: //26 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == AuthorizationRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- //case ContractAuthenticationReq: case AuthorizationRequest: //29 { if (Proc_din_ContractAuthenticationReq(AcceptFd) == 0) { Update_V2G_Status(AuthorizationResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("AuthorizationReqRes: fail\n"); Update_V2G_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 { DEBUG_ERROR("AuthorizationReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //Check for ChargeParameterDiscoveryReq else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargeParameterDiscoveryRequest) { EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; Update_V2G_Status(ChargeParameterDiscoveryRequest); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case ChargeParameterDiscoveryRequest: //35 { if (Proc_din_ChargeParameterDiscoveryReq(AcceptFd) == 0) { Update_V2G_Status(ChargeParameterDiscoveryResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ChargeParameterDiscoveryReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case ChargeParameterDiscoveryResponse: { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_ChargingParameter_Performance_Time) //60 seconds { DEBUG_ERROR("ChargingParameter Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_ChargingParameter_Performance_Time); Update_V2G_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 { DEBUG_ERROR("ChargeParameterDiscoveryReqRes: fail\n"); Update_V2G_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; DEBUG_INFO("[V2G][RX]CableCheckReqReq: isolated?\n"); ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_Start); ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_End); Update_V2G_Status(CableCheckRequest); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #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_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(&timerStart.SeqStart); #endif if (Proc_din_PowerDeliveryStopReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponseStop); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PowerDeliveryStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case CableCheckRequest: //37 { //STEP 3: Execute Cable Check Process if (Proc_din_CableCheckReq(AcceptFd) == 0) { Update_V2G_Status(CableCheckResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("CableCheckReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case CableCheckResponse: //38 { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_CableCheck_Performance_Time) //38 seconds { //DEBUG_INFO("[CableCheck] end counting...\n"); DEBUG_ERROR("CableCheck Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_CableCheck_Performance_Time); Update_V2G_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 { DEBUG_ERROR("CableCheckReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //STEP 3: Check for PreChargeReq message else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == PreChargeRequest) { EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; Update_V2G_Status(PreChargeRequest); DEBUG_INFO("[V2G][RX]PreChargeReqReq: waiting for pre-charge voltage...\n"); 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(&timerStart.SeqStart); #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_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(&timerStart.SeqStart); #endif if (Proc_din_PowerDeliveryStopReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponseStop); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PowerDeliveryStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case PreChargeRequest: //39 { if (Proc_din_PreChargeReq(AcceptFd) == 0) { Update_V2G_Status(PreChargeResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PreChargeReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case PreChargeResponse: //40 { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_PreCharge_Performance_Time) //5 seconds { DEBUG_ERROR("Precharge Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_PreCharge_Performance_Time); Update_V2G_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 { DEBUG_ERROR("PreChargeReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //STEP 3: Check for PowerDeliveryReq message else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) || (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart)) { EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; Update_V2G_Status(PowerDeliveryRequestStart); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Precharge_Timer_End); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case PowerDeliveryRequestStart: //41 { if (Proc_din_PowerDeliveryStartReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponsetStart); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PowerDeliveryStartReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case PowerDeliveryResponsetStart: //42 { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE if (v2gObject.DIN.V2G_Message.Body.PowerDeliveryReq_isUsed == 1u) { ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > 2000) //5 seconds { DEBUG_ERROR("Wait for CurrentDemandReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), 2000); Update_V2G_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_Status(CurrentDemandRequest); DEBUG_INFO("[V2G][RX]CurrentDemandReqReq: energy transfering...\n"); 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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case CurrentDemandRequest: //45, { if (Proc_din_CurrentDemandReq(AcceptFd) == 0) { Update_V2G_Status(CurrentDemandResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("CurrentDemandReqRes: fail\n"); Update_V2G_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 { DEBUG_ERROR("CurrentDemandReqRes: fail\n"); Update_V2G_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_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(&timerStart.SeqStart); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case PowerDeliveryRequestStop: //49, { if (Proc_din_PowerDeliveryStopReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponseStop); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else { DEBUG_ERROR("PowerDeliveryStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case PowerDeliveryResponseStop: //50, { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > 2000) //2 seconds { DEBUG_ERROR("Wait for WeldingDetectionReq or SessionStopReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), 2000); Update_V2G_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_Status(WeldingDetectionRequest); DEBUG_INFO("[V2G][RX]WeldingDetectionReq: ongoing...\n"); ftime(&EVCOMM_SYS_INFO.V2G_SECC_WeldingDetection_Timer_Start); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest) { Update_V2G_Status(SessionStopRequest); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if (Proc_din_SessionStopReq(AcceptFd) == 0) { Update_V2G_Status(SessionStopResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("SessionStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } break; } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case WeldingDetectionRequest: //51, { if (Proc_din_WeldingDetectionReq(AcceptFd) == 0) { Update_V2G_Status(WeldingDetectionResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("WeldingDetectionReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case WeldingDetectionResponse: //52, { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_WeldingDetection_Performance_Time) //20 seconds { DEBUG_ERROR("Wait for SessionStopReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_WeldingDetection_Performance_Time); Update_V2G_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 { DEBUG_ERROR("WeldingDetectionReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //STEP 3: Check for SessionStopReq Message else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case SessionStopRequest: //53, { if (Proc_din_SessionStopReq(AcceptFd) == 0) { Update_V2G_Status(SessionStopResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("SessionStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case SessionStopResponse: //54, { break; } //------------------------------------------- default: { break; } } usleep(1000); } return 0; } /** * * @param AcceptFd * @return */ 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 (v2gObject.appHandshake.supportedAppProtocolReq_isUsed == 1u) { v2gObject.appHandshake.supportedAppProtocolReq_isUsed = 0; if (Proc_supportedAppProtocolReq(AcceptFd) == 0) //0: no error { ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); Update_V2G_Status(SupportedAppProtocolResponse); } else { DEBUG_ERROR("supportedAppProtocolResReq: fail\n"); Update_V2G_Status(Other_Fault); } } req_is_responsed = TRUE; break; } case SupportedAppProtocolResponse: { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionSetupRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case SessionSetupRequest: //19 { if (Proc_iso1_SessionSetupReq(AcceptFd) == 0) { Update_V2G_Status(SessionSetupResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("SessionSetupReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case SessionSetupResponse: //20 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceDiscoveryRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case ServiceDiscoveryRequest: //21 { if (Proc_iso1_ServiceDiscoveryReq(AcceptFd) == 0) { Update_V2G_Status(ServiceDiscoveryResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ServiceDiscoveryReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case ServiceDiscoveryResponse: //22 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceAndPaymentSelectionRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case ServiceAndPaymentSelectionRequest: //25 { if (Proc_iso1_ServiceAndPaymentSelectionReq(AcceptFd) == 0) { Update_V2G_Status(ServiceAndPaymentSelectionResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ServiceAndPaymentSelectionReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case ServiceAndPaymentSelectionResponse: //26 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == AuthorizationRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- //case ContractAuthenticationReq: case AuthorizationRequest: //29 { if (Proc_iso1_AuthenticationReq(AcceptFd) == 0) { Update_V2G_Status(AuthorizationResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("AuthorizationReqRes: fail\n"); Update_V2G_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 { DEBUG_ERROR("AuthorizationReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //Check for ChargeParameterDiscoveryReq else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargeParameterDiscoveryRequest) { EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; Update_V2G_Status(ChargeParameterDiscoveryRequest); DEBUG_INFO("[V2G][RX]ChargeParameterDiscoveryReq: CSU Permission?\n"); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case ChargeParameterDiscoveryRequest: //35 { if (Proc_iso1_ChargeParameterDiscoveryReq(AcceptFd) == 0) { Update_V2G_Status(ChargeParameterDiscoveryResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ChargeParameterDiscoveryReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case ChargeParameterDiscoveryResponse: { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_ChargingParameter_Performance_Time) //60 seconds { DEBUG_ERROR("ChargingParameter Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_ChargingParameter_Performance_Time); Update_V2G_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 { DEBUG_ERROR("ChargeParameterDiscoveryReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //STEP 2: Check for CableCheckReq message else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CableCheckRequest) { EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; DEBUG_INFO("[V2G][RX]CableCheckReqReq: isolated?\n"); ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_Start); ftime(&EVCOMM_SYS_INFO.V2G_SECC_CableCheck_Timer_End); Update_V2G_Status(CableCheckRequest); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #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_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(&timerStart.SeqStart); #endif if (Proc_iso1_PowerDeliveryStopReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponseStop); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PowerDeliveryStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } break; } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case CableCheckRequest: //37 { //STEP 3: Execute Cable Check Process if (Proc_iso1_CableCheckReq(AcceptFd) == 0) { Update_V2G_Status(CableCheckResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("CableCheckReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case CableCheckResponse: //38 { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_CableCheck_Performance_Time) //38 seconds { //DEBUG_INFO("[CableCheck] end counting...\n"); DEBUG_ERROR("CableCheck Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_CableCheck_Performance_Time); Update_V2G_Status(Sequence_Timeout); //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_TIMEOUT_V2G_CableCheck_Performance_Time (023847) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 8; ShmStatusCodeData->PresentStatusCode[0][4] = 4; ShmStatusCodeData->PresentStatusCode[0][5] = 7; break; } #endif //STEP 2: Check for CableCheckReq message if (EVCOMM_SYS_INFO.V2G_Rx_Msg == CableCheckRequest) { EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; //STEP 3: Execute Cable Check Process if (Proc_iso1_CableCheckReq(AcceptFd) == 0) { ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("CableCheckReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //STEP 3: Check for PreChargeReq message else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == PreChargeRequest) { EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; Update_V2G_Status(PreChargeRequest); DEBUG_INFO("[V2G][RX]PreChargeReqReq: waiting for pre-charge voltage...\n"); 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(&timerStart.SeqStart); #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_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(&timerStart.SeqStart); #endif if (Proc_iso1_PowerDeliveryStopReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponseStop); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PowerDeliveryStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case PreChargeRequest: //39 { if (Proc_iso1_PreChargeReq(AcceptFd) == 0) { Update_V2G_Status(PreChargeResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PreChargeReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case PreChargeResponse: //40 { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_PreCharge_Performance_Time) //5 seconds { DEBUG_ERROR("Precharge Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_PreCharge_Performance_Time); Update_V2G_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 { DEBUG_ERROR("PreChargeReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //STEP 3: Check for PowerDeliveryReq message else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) || (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart)) { EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; Update_V2G_Status(PowerDeliveryRequestStart); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Precharge_Timer_End); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case PowerDeliveryRequestStart: //41 { if (Proc_iso1_PowerDeliveryStartReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponsetStart); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PowerDeliveryStartReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case PowerDeliveryResponsetStart: //42 { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE if (v2gObject.ISO1.V2G_Message.Body.PowerDeliveryReq_isUsed == 1u) { ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > 2000) //5 seconds { DEBUG_ERROR("Wait for CurrentDemandReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), 2000); Update_V2G_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_Status(CurrentDemandRequest); DEBUG_INFO("[V2G][RX]CurrentDemandReqReq: energy transfering...\n"); 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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else {} break; } //------------------------------------------- case CurrentDemandRequest: //45, { if (Proc_iso1_CurrentDemandReq(AcceptFd) == 0) { Update_V2G_Status(CurrentDemandResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("CurrentDemandReqRes: fail\n"); Update_V2G_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 { DEBUG_ERROR("CurrentDemandReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //STEP 2: Wait for PowerDeliveryReq Message else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) || (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart)) { Update_V2G_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(&timerStart.SeqStart); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case PowerDeliveryRequestStop: //49, { if (Proc_iso1_PowerDeliveryStopReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponseStop); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else { DEBUG_ERROR("PowerDeliveryStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case PowerDeliveryResponseStop: //50, { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > 2000) //2 seconds { DEBUG_ERROR("Wait for WeldingDetectionReq or SessionStopReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), 2000); Update_V2G_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_Status(WeldingDetectionRequest); DEBUG_INFO("[V2G][RX]WeldingDetectionReq: ongoing...\n"); ftime(&EVCOMM_SYS_INFO.V2G_SECC_WeldingDetection_Timer_Start); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest) { Update_V2G_Status(SessionStopRequest); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if (Proc_iso1_SessionStopReq(AcceptFd) == 0) { Update_V2G_Status(SessionStopResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("SessionStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case WeldingDetectionRequest: //51, { if (Proc_iso1_WeldingDetectionReq(AcceptFd) == 0) { Update_V2G_Status(WeldingDetectionResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("WeldingDetectionReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case WeldingDetectionResponse: //52, { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_WeldingDetection_Performance_Time) //20 seconds { DEBUG_ERROR("Wait for SessionStopReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_WeldingDetection_Performance_Time); Update_V2G_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 { DEBUG_ERROR("WeldingDetectionReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //STEP 3: Check for SessionStopReq Message else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case SessionStopRequest: //53, { if (Proc_iso1_SessionStopReq(AcceptFd) == 0) { Update_V2G_Status(SessionStopResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("SessionStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case SessionStopResponse: //54, { break; } //------------------------------------------- default: { break; } } usleep(1000); } return 0; } /** * * @param AcceptFd * @return */ 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 (v2gObject.appHandshake.supportedAppProtocolReq_isUsed == 1u) { v2gObject.appHandshake.supportedAppProtocolReq_isUsed = 0; if (Proc_supportedAppProtocolReq(AcceptFd) == 0) //0: no error { ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); Update_V2G_Status(SupportedAppProtocolResponse); } else { DEBUG_ERROR("supportedAppProtocolResReq: fail\n"); Update_V2G_Status(Other_Fault); } } req_is_responsed = TRUE; break; } case SupportedAppProtocolResponse: //18 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionSetupRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n",EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else {} break; } //------------------------------------------- case SessionSetupRequest: //19 { if (Proc_iso1_SessionSetupReq(AcceptFd) == 0) { Update_V2G_Status(SessionSetupResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("SessionSetupReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case SessionSetupResponse: //20 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceDiscoveryRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else {} break; } //------------------------------------------- case ServiceDiscoveryRequest: //21 { if (Proc_iso1_ServiceDiscoveryReq(AcceptFd) == 0) { Update_V2G_Status(ServiceDiscoveryResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ServiceDiscoveryReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case ServiceDiscoveryResponse: //22 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceAndPaymentSelectionRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else {} break; } //------------------------------------------- case ServiceAndPaymentSelectionRequest: //25 { if (Proc_iso1_ServiceAndPaymentSelectionReq(AcceptFd) == 0) { Update_V2G_Status(ServiceAndPaymentSelectionResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ServiceAndPaymentSelectionReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case ServiceAndPaymentSelectionResponse://26 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == AuthorizationRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else {} break; } //------------------------------------------- //case ContractAuthenticationReq: case AuthorizationRequest: //29 { if (Proc_iso1_AuthenticationReq(AcceptFd) == 0) { Update_V2G_Status(AuthorizationResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("AuthorizationReqRes: fail\n"); Update_V2G_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 { DEBUG_ERROR("AuthorizationReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //Check for ChargeParameterDiscoveryReq else if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ChargeParameterDiscoveryRequest) { EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; Update_V2G_Status(ChargeParameterDiscoveryRequest); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else {} break; } //------------------------------------------- case ChargeParameterDiscoveryRequest: //35 { if (Proc_iso1_ChargeParameterDiscoveryReq(AcceptFd) == 0) { Update_V2G_Status(ChargeParameterDiscoveryResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ChargeParameterDiscoveryReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case ChargeParameterDiscoveryResponse: //36 { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_ChargingParameter_Performance_Time) //60 seconds { DEBUG_ERROR("ChargingParameter Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_ChargingParameter_Performance_Time); Update_V2G_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 { DEBUG_ERROR("ChargeParameterDiscoveryReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //STEP 3: Wait for PowerDeliveryReq Message else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) || (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart)) { Update_V2G_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(&timerStart.SeqStart); #endif /* if(Proc_iso1_PowerDeliveryStopReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponseStop); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PowerDeliveryStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); }*/ #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { } break; } //------------------------------------------- case PowerDeliveryRequestStart: //41 { if (Proc_iso1_PowerDeliveryStartReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponsetStart); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PowerDeliveryStartReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case PowerDeliveryResponsetStart: //42 { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE if (v2gObject.ISO1.V2G_Message.Body.PowerDeliveryReq_isUsed == 1u) { ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > 2000) //5 seconds { DEBUG_ERROR("Wait for ChargingStatusReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), 2000); Update_V2G_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_Status(ChargingStatusRequest); DEBUG_INFO("[V2G][RX]ChargingStatusReq: energy transfering...\n"); ftime(&EVCOMM_SYS_INFO.V2G_SECC_ChargingStatus_Timer_Start); } else {} break; } //------------------------------------------- case ChargingStatusRequest: //43 { if (Proc_iso1_ChargingStatusReq(AcceptFd) == 0) { Update_V2G_Status(ChargingStatusResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ChargingStatusRes: fail\n"); Update_V2G_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 { DEBUG_ERROR("ChargingStatusRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; } //STEP 2: Wait for PowerDeliveryReq Message else if((EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStop) || (EVCOMM_SYS_INFO.V2G_Rx_Msg == PowerDeliveryRequestStart)) { Update_V2G_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(&timerStart.SeqStart); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else {} break; } //------------------------------------------- case PowerDeliveryRequestStop: //49 { if (Proc_iso1_PowerDeliveryStopReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponseStop); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else { DEBUG_ERROR("PowerDeliveryStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case PowerDeliveryResponseStop: //50 { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > 2000) //2 seconds { DEBUG_ERROR("Wait for SessionStopReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), 2000); Update_V2G_Status(Sequence_Timeout); break; } #endif //STEP 3: Check for SessionStopReq Message else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest) { Update_V2G_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)) { if((EVCOMM_SYS_INFO.V2G_Rx_Msg != ChargeParameterDiscoveryRequest)) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; } Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else {} break; } case SessionStopRequest: //53 { if (Proc_iso1_SessionStopReq(AcceptFd) == 0) { Update_V2G_Status(SessionStopResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("SessionStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case SessionStopResponse: //54 { break; } default: { break; } } usleep(1000); } return 0; } /** * * @param AcceptFd * @param EnergyTransferMode * @return */ int V2gMsg_Process_iso1(int AcceptFd, unsigned char EnergyTransferMode) { switch (EnergyTransferMode) { case DC_extended: { //DEBUG_INFO("EnergyTransferMode: DC_extended\n"); V2gMsg_Process_iso1_DC(AcceptFd); break; } case AC_single_phase_core: case AC_three_phase_core: { //DEBUG_INFO("EnergyTransferMode: AC_single_phase_core or AC_three_phase_core\n"); V2gMsg_Process_iso1_AC(AcceptFd); break; } default: { DEBUG_WARN("Unexpected EnergyTransferMode: (%d)\n", EnergyTransferMode); break; } } return 0; } /** * * @param AcceptFd * @return */ 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 (v2gObject.appHandshake.supportedAppProtocolReq_isUsed == 1u) { v2gObject.appHandshake.supportedAppProtocolReq_isUsed = 0; if (Proc_supportedAppProtocolReq(AcceptFd) == 0) //0: no error { ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); Update_V2G_Status(SupportedAppProtocolResponse); } else { DEBUG_ERROR("supportedAppProtocolResReq: fail\n"); Update_V2G_Status(Other_Fault); } } req_is_responsed = TRUE; break; } case SupportedAppProtocolResponse: { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionSetupRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else {} break; } //------------------------------------------- case SessionSetupRequest: //19 { if (Proc_iso2_SessionSetupReq(AcceptFd) == 0) { Update_V2G_Status(SessionSetupResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("SessionSetupReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case SessionSetupResponse: //20 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceDiscoveryRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else {} break; } #if 0 //------------------------------------------- case ServiceDiscoveryRequest: //21 { if (Proc_iso2_ServiceDiscoveryReq(AcceptFd) == 0) { Update_V2G_Status(ServiceDiscoveryResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ServiceDiscoveryReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case ServiceDiscoveryResponse: //22 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == ServiceAndPaymentSelectionRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } } //------------------------------------------- case ServiceAndPaymentSelectionRequest: //25 { if (Proc_iso2_ServiceAndPaymentSelectionReq(AcceptFd) == 0) { Update_V2G_Status(ServiceAndPaymentSelectionResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ServiceAndPaymentSelectionReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case ServiceAndPaymentSelectionResponse: //26 { if (EVCOMM_SYS_INFO.V2G_Rx_Msg == AuthorizationRequest) { Update_V2G_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } } //------------------------------------------- //case ContractAuthenticationReq: case AuthorizationRequest: //29 { if (Proc_iso2_AuthenticationReq(AcceptFd) == 0) { Update_V2G_Status(AuthorizationResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("AuthorizationReqRes: fail\n"); Update_V2G_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 { DEBUG_ERROR("AuthorizationReqRes: fail\n"); Update_V2G_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_Status(ChargeParameterDiscoveryRequest); DEBUG_INFO("[V2G][RX]ChargeParameterDiscoveryReq: CSU Permission?\n"); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } } //------------------------------------------- case ChargeParameterDiscoveryRequest: //35 { if (Proc_iso2_ChargeParameterDiscoveryReq(AcceptFd) == 0) { Update_V2G_Status(ChargeParameterDiscoveryResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("ChargeParameterDiscoveryReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case ChargeParameterDiscoveryResponse: { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_ChargingParameter_Performance_Time) //60 seconds { DEBUG_ERROR("ChargingParameter Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_ChargingParameter_Performance_Time); Update_V2G_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 { DEBUG_ERROR("ChargeParameterDiscoveryReqRes: fail\n"); Update_V2G_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_Status(CableCheckRequest); DEBUG_INFO("[V2G][RX]CableCheckReqReq: isolated?\n"); 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(&timerStart.SeqStart); #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_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(&timerStart.SeqStart); #endif if (Proc_iso2_PowerDeliveryStopReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponseStop); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PowerDeliveryStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } break; } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } } //------------------------------------------- case CableCheckRequest: //37 { //STEP 3: Execute Cable Check Process if (Proc_iso2_CableCheckReq(AcceptFd) == 0) { Update_V2G_Status(CableCheckResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("CableCheckReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case CableCheckResponse: //38 { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_CableCheck_Performance_Time) //38 seconds { //DEBUG_INFO("[CableCheck] end counting...\n"); DEBUG_ERROR("CableCheck Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_CableCheck_Performance_Time); Update_V2G_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 { DEBUG_ERROR("CableCheckReqRes: fail\n"); Update_V2G_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_Status(PreChargeRequest); DEBUG_INFO("[V2G][RX]PreChargeReqReq: waiting for pre-charge voltage...\n"); 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(&timerStart.SeqStart); #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_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(&timerStart.SeqStart); #endif if (Proc_iso2_PowerDeliveryStopReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponseStop); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PowerDeliveryStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } break; } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } } //------------------------------------------- case PreChargeRequest: //39 { if (Proc_iso2_PreChargeReq(AcceptFd) == 0) { Update_V2G_Status(PreChargeResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PreChargeReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case PreChargeResponse: //40 { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_PreCharge_Performance_Time) //5 seconds { DEBUG_ERROR("Pre-charge Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_PreCharge_Performance_Time); Update_V2G_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 { DEBUG_ERROR("PreChargeReqRes: fail\n"); Update_V2G_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_Status(PowerDeliveryRequestStart); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Precharge_Timer_End); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } } //------------------------------------------- case PowerDeliveryRequestStart: //41 { if (Proc_iso2_PowerDeliveryStartReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponsetStart); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("PowerDeliveryStartReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case PowerDeliveryResponsetStart: //42 { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE if (v2gObject.ISO2.V2G_Message.Body.PowerDeliveryReq_isUsed == 1u) { ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > 2000) //5 seconds { DEBUG_ERROR("Wait for CurrentDemandReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), 2000); Update_V2G_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_Status(CurrentDemandRequest); DEBUG_INFO("[V2G][RX]CurrentDemandReqReq: energy transfering...\n"); 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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } } //------------------------------------------- case CurrentDemandRequest: //45, { if (Proc_iso2_CurrentDemandReq(AcceptFd) == 0) { Update_V2G_Status(CurrentDemandResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("CurrentDemandReqRes: fail\n"); Update_V2G_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 { DEBUG_ERROR("CurrentDemandReqRes: fail\n"); Update_V2G_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_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(&timerStart.SeqStart); #endif } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } } //------------------------------------------- case PowerDeliveryRequestStop: //49, { if (Proc_iso2_PowerDeliveryStopReq(AcceptFd) == 0) { Update_V2G_Status(PowerDeliveryResponseStop); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else { DEBUG_ERROR("PowerDeliveryStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case PowerDeliveryResponseStop: //50, { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > 2000) //2 seconds { DEBUG_ERROR("Wait for WeldingDetectionReq or SessionStopReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), 2000); Update_V2G_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_Status(WeldingDetectionRequest); DEBUG_INFO("[V2G][RX]WeldingDetectionReq: ongoing...\n"); ftime(&EVCOMM_SYS_INFO.V2G_SECC_WeldingDetection_Timer_Start); #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqStart); #endif } else if(EVCOMM_SYS_INFO.V2G_Rx_Msg == SessionStopRequest) { Update_V2G_Status(SessionStopRequest); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; if (Proc_iso2_SessionStopReq(AcceptFd) == 0) { Update_V2G_Status(SessionStopResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("SessionStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } break; } else if (EVCOMM_SYS_INFO.V2G_Rx_Msg >= SupportedAppProtocolRequest && EVCOMM_SYS_INFO.V2G_Rx_Msg <= SessionStopRequest) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } } //------------------------------------------- case WeldingDetectionRequest: //51, { if (Proc_iso2_WeldingDetectionReq(AcceptFd) == 0) { Update_V2G_Status(WeldingDetectionResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("WeldingDetectionReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; break; } case WeldingDetectionResponse: //52, { //STEP 1: Check for Process Timeout #if V2G_SECC_TIMEOUT_PROTECTION == ENABLE ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > V2G_SECC_WeldingDetection_Performance_Time) //20 seconds { DEBUG_ERROR("Wait for SessionStopReq Timeout - (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), V2G_SECC_WeldingDetection_Performance_Time); Update_V2G_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 { DEBUG_ERROR("WeldingDetectionReqRes: fail\n"); Update_V2G_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_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) { DEBUG_ERROR("SequenceError(%d) => Tx Res MSG\n", EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.SequenceError = TRUE; Update_V2G_Status(EVCOMM_SYS_INFO.V2G_Rx_Msg); EVCOMM_SYS_INFO.V2G_Rx_Msg = 0; } else { break; } } //------------------------------------------- case SessionStopRequest: //53, { if (Proc_iso2_SessionStopReq(AcceptFd) == 0) { Update_V2G_Status(SessionStopResponse); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); } else { DEBUG_ERROR("SessionStopReqRes: fail\n"); Update_V2G_Status(Other_Fault); } req_is_responsed = TRUE; //break; } case SessionStopResponse: //54, { break; } #endif //------------------------------------------- default: { break; } } usleep(1000); } return 0; } /** * * @param AcceptFd * @return */ int V2gMsg_Process_iso2_AC(int AcceptFd) { return 0; } /** * * @param AcceptFd * @param EnergyTransferMode * @return */ 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: { DEBUG_WARN("Unexpected EnergyTransferMode: (%d)\n", EnergyTransferMode); break; } } return 0; } /** * * @param AcceptFd * @return */ 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: { DEBUG_WARN("Unexpected Communication Protocol: (%d)\n", ShmCcsData->CommProtocol); break; } } return errn; } /** * * @param AcceptFd * @return */ int V2gMsg_Rx(int AcceptFd) { int errn = 0; unsigned int packet_size = 0; memset(v2gBuffer.rx, 0, V2GTP_MSG_RX_BUFFER_SIZE); packet_size = recv(AcceptFd, v2gBuffer.rx, V2GTP_MSG_RX_BUFFER_SIZE, 0); //[CAUTION] Everytime recv() is called, it will take a default time to wait for TCP packets. //The more time you call recv(), the more time you will waste here. //Here it is suggested that response immediatedly once you receive any packets. //For configuring the Rx waiting time, please use setsockopt(). if(packet_size > 0) //[Joseph] If there is no data, ignore. (TBD) { //DEBUG_PRINTF_EVCOMM_DETAIL("\n\n Got TCP V2GTP Message: size = %d Bytes\n", packet_size); errn = V2gMsgDecoder(v2gBuffer.rx, packet_size, V2gFlowStatus); if (errn < 0) { DEBUG_ERROR("V2gMsgDecoder fail: (%d)\n", errn); } } return errn; } /** * * @param AcceptFd * @return */ int V2gComm(int AcceptFd) { int errn = 0; if (V2gMsg_Rx(AcceptFd) < 0) { Update_V2G_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; } /** * * @return */ int SdpUdpConnected() { int packet_size,Rtn; struct sockaddr_in6 ServerAddr,ClientAddr; struct V2gtpHeader *header; unsigned char *payload; // UDP server initial if(socketFd.Udp <= 0) { if ((socketFd.Udp = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { DEBUG_ERROR("Fail to open UdpSock\n"); return 0; } memset(&ServerAddr,0, sizeof(struct sockaddr_in)); ServerAddr.sin6_family = AF_INET6; ServerAddr.sin6_addr = in6addr_any; ServerAddr.sin6_port = htons(SdpUdpServerPort); if(bind(socketFd.Udp, (struct sockaddr *)&ServerAddr, sizeof(struct sockaddr_in6)) < 0) { DEBUG_ERROR("Fail to bind UdpSock(%d)\n", socketFd.Udp); close(socketFd.Udp); socketFd.Udp = -1; return 0; } DEBUG_INFO("[UDP] opened(%d), port: %d\n", socketFd.Udp, SdpUdpServerPort); DEBUG_INFO("[UDP] Wait connect request from EVCC\n"); } // Receive packet from udp server memset(v2gBuffer.rx, 0, V2GTP_MSG_RX_BUFFER_SIZE); memset(&ClientAddr, 0, sizeof(struct sockaddr_in)); Rtn = sizeof(struct sockaddr_in6); packet_size = recvfrom(socketFd.Udp, v2gBuffer.rx, V2GTP_MSG_RX_BUFFER_SIZE, MSG_DONTWAIT, (struct sockaddr *)&ClientAddr, (socklen_t *)&Rtn); if(packet_size > 0) { char buf[128]; header = (struct V2gtpHeader *) v2gBuffer.rx; payload = v2gBuffer.rx+sizeof(struct V2gtpHeader); DEBUG_PRINTF_EVCOMM_DETAIL("Got UDP packet_size: %d (Bytes)\n", packet_size); DEBUG_PRINTF_EVCOMM_DETAIL("***********************************\n"); DEBUG_PRINTF_EVCOMM_DETAIL("***** Received SDP Packet *****\n"); DEBUG_PRINTF_EVCOMM_DETAIL("***********************************\n"); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn = 0; Rtn < 16; Rtn += 2) { sprintf(buf, "%s%02x%02x:", buf, ClientAddr.sin6_addr.s6_addr[Rtn],ClientAddr.sin6_addr.s6_addr[Rtn+1]); } DEBUG_PRINTF_EVCOMM_DETAIL("ClientAddress: %s\n", buf); 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)); if( (header->ProtocolVersion == 0x01) && (header->InverseProtocolVersion == 0xFE) && (htons(header->PayloadType) == V2GTP_PAYLOAD_TYPE_SDP_REQUEST)) { DEBUG_INFO("[UDP] Get connect request from EVCC: (%d)\n", socketFd.Udp); DEBUG_PRINTF_EVCOMM_DETAIL("Security: 0x%02X\n", *(payload + 0)); DEBUG_PRINTF_EVCOMM_DETAIL("TransportProtocol: 0x%02X\n", *(payload + 1)); header->PayloadType = htons(V2GTP_PAYLOAD_TYPE_SDP_RESPONSE); header->PayloadLength = htonl(20); //Fixed Length=20 memset(payload, 0, 20); // MAC address[0:2] + FFFE + MAC address[3:5] payload[0] = (IPV6_LINK_LOCAL_PREFIX>>8) & 0xFF; payload[1] = IPV6_LINK_LOCAL_PREFIX & 0xFF; #ifdef TEST_WITH_ETH0 payload[8] = macAddr.eth0[0]; payload[8] ^= 0x02;// bit 1 should complemented. payload[9] = macAddr.eth0[1]; payload[10] = macAddr.eth0[2]; payload[11] = 0xFF; payload[12] = 0xFE; payload[13] = macAddr.eth0[3]; payload[14] = macAddr.eth0[4]; payload[15] = macAddr.eth0[5]; #else payload[8] = macAddr.eth1[0]; payload[8] ^= 0x02;// bit 1 should complemented. payload[9] = macAddr.eth1[1]; payload[10] = macAddr.eth1[2]; payload[11] = 0xFF; payload[12] = 0xFE; payload[13] = macAddr.eth1[3]; payload[14] = macAddr.eth1[4]; payload[15] = macAddr.eth1[5]; #endif // Report TCP port payload[16] = (EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active>>8) & 0xFF; payload[17] = EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active & 0xFF; payload[18] = SDP_PAYLOAD_SECURITY_NONE; //Security payload[19] = SDP_PAYLOAD_TRANS_PROTOCOL_TCP; //Transport protocol // TODO: // Setup the TCP in advance to receive the coming TCP handshake messages after SDP response. Rtn = sendto(socketFd.Udp, v2gBuffer.rx, sizeof(struct V2gtpHeader) + htonl(header->PayloadLength), 0, (struct sockaddr *)&ClientAddr, sizeof(struct sockaddr_in6)); DEBUG_INFO("[UDP] Response to EVCC\n"); DEBUG_PRINTF_EVCOMM_DETAIL("***** Response SDP Packet *****\n"); DEBUG_PRINTF_EVCOMM_DETAIL("Send size: %d\n", Rtn); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn = 0; Rtn < 16; Rtn++) { sprintf(buf, "%s%02x ", buf, ClientAddr.sin6_addr.s6_addr[Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("Destination Address: %s\n", buf); 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)); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn = 0; Rtn < 16; Rtn++) { sprintf(buf, "%s%02x:", buf, payload[Rtn]); } DEBUG_PRINTF_EVCOMM_DETAIL("SECC Ipv6 Address: %s\n", buf); 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]); if(Rtn > 0) { return 1; } } } return 0; } /** * * @return */ int V2gTcpConnected() { int Rtn,AcceptFd; char buf[128]; struct sockaddr_in6 ServerAddr,ClientAddr; // Initial TCP server if(socketFd.Tcp <= 0) { if ((socketFd.Tcp = socket(PF_INET6, SOCK_STREAM, 0)) < 0) { DEBUG_ERROR("Fail to open TcpSock (%s)\n", strerror(errno)); usleep(100000); return 0; } fcntl(socketFd.Tcp, F_SETFL, O_NONBLOCK); //set to O_NONBLOCK DEBUG_INFO("[TCP]Socket set: DONE.\n"); 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); if(bind(socketFd.Tcp, (struct sockaddr *)&ServerAddr, sizeof(struct sockaddr_in6)) < 0) { DEBUG_ERROR("Fail to bind TcpSock(%s), SdpTcpServerPort: %d\n", strerror(errno), EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active); if(bind(socketFd.Tcp, (struct sockaddr *)&ServerAddr, sizeof(struct sockaddr_in6)) < 0) { DEBUG_INFO("[Error Fail to bind TcpSock(%s), SdpTcpServerPort: %d\n", strerror(errno), EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active); usleep(100000); close(socketFd.Tcp); socketFd.Tcp = -1; return 0; } DEBUG_INFO("[TCP]bind: DONE\n"); } DEBUG_INFO("[TCP]listen: START\n"); if(listen(socketFd.Tcp, 1) == -1) //only accept one connection { DEBUG_ERROR("Fail to listen TcpSock(%s)", strerror(errno)); usleep(100000); close(socketFd.Tcp); socketFd.Tcp = -1; return 0; } DEBUG_INFO("[TCP]listen: DONE\n"); DEBUG_INFO("[TCP]TcpSock: opened(%d), port=%d\n", socketFd.Tcp, htons(ServerAddr.sin6_port)); DEBUG_INFO("[TCP]accept: START\n"); } // Wait connection in Rtn = sizeof(struct sockaddr_in6); if((AcceptFd = accept(socketFd.Tcp, (struct sockaddr *)&ClientAddr, (socklen_t *)&Rtn)) == -1) { static BOOL tmp = 0; if (tmp == 0) { DEBUG_INFO("[TCP]Wait TCP connection...\n"); tmp = 1; } else { //DEBUG_PRINTF_EVCOMM_DETAIL("."); } return 0; } DEBUG_INFO("[TCP]Accept: DONE\n"); DEBUG_PRINTF_EVCOMM_DETAIL("Accept one TCP connection:\n"); DEBUG_PRINTF_EVCOMM_DETAIL("AcceptFd: %d\n",AcceptFd); memset(buf, 0x00, ARRAY_SIZE(buf)); for(Rtn = 0; Rtn < 16; Rtn += 2) { sprintf(buf, "%s%02x%02x:", buf, ClientAddr.sin6_addr.s6_addr[Rtn], ClientAddr.sin6_addr.s6_addr[Rtn+1]); } DEBUG_PRINTF_EVCOMM_DETAIL("ClientAddress: %s\n", buf); DEBUG_PRINTF_EVCOMM_DETAIL("ClientPort: %d\n", ClientAddr.sin6_port); return AcceptFd; } /** * * @return */ int End_Process() { if(EVCOMM_SYS_INFO.End_Process_inused == TRUE) { DEBUG_INFO("End_Process has been triggered by another event.\n"); return -1; } DEBUG_INFO("Entering...\n"); //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 DEBUG_INFO("Close RAW, UDP, TCP sockets...\n"); if(socketFd.Raw > 0) { close(socketFd.Raw); } if(socketFd.Udp > 0) { close(socketFd.Udp); } if(socketFd.Tcp > 0) { close(socketFd.Tcp); close(socketFd.TcpAccept); } socketFd.Raw = socketFd.Udp = socketFd.Tcp = socketFd.TcpAccept = -1; //STEP 3: Switch to State E //SwitchCpStateE(ENABLE); //STEP 4: Close tcpdump Sniffer_Tcpdump(DISABLE); //STEP 5: Keep 100% PWM for 5 seconds OutputCpPwmDuty(100); for(int idx=5;idx>0;idx--) { DEBUG_INFO("Wait PWM switch to 100%% count down: %d\n", idx); sleep(1); } qcaInfo.AttenProfileCnt = 0; init_appHandEXIDocument(&v2gObject.appHandshake); // Qca7kPowerReset(); //reset QCA7000 /* +++ 20200808, vern, should disconnected PLC connection after session stop ---*/ #if (FIRMWARE_VERSION_COMPILE_SETTING_RELEASE_MODE == DISABLE) { 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) for(uint8_t idx=5;idx>0;idx--) { DEBUG_INFO("Wait CP change to State E count down: %d\n", idx); sleep(1); } #endif //Reset Memory unsigned char SlaveAddress_backup; unsigned int matched_backup; //unsigned char state_backup; #if (FIRMWARE_VERSION_COMPILE_SETTING_RELEASE_MODE == DISABLE) { system("sync"); } #endif sleep(1); //Backup CsuComm flags SlaveAddress_backup = ShmInternalComm->SlaveAddress; matched_backup = CSUCOMMDC_TASK_FLAG.matched; //state_backup = Get_V2G_Status(); memset(v2gBuffer.rx, 0, V2GTP_MSG_RX_BUFFER_SIZE); memset(v2gBuffer.tx, 0, V2GTP_MSG_TX_BUFFER_SIZE); memset(&v2gObject.appHandshake, 0, sizeof(struct appHandEXIDocument)); memset(&v2gObject.DIN, 0, sizeof(struct dinEXIDocument)); memset(ShmStatusCodeData, 0, sizeof(struct StatusCodeData)); memset(ShmInternalComm, 0, sizeof(struct InternalComm)); memset(ShmCcsData, 0, sizeof(struct CcsData)); //Resume CsuComm flags ShmInternalComm->SlaveAddress = SlaveAddress_backup; CSUCOMMDC_TASK_FLAG.matched = matched_backup; Sniffer_Candump(DISABLE); Sniffer_Candump(ENABLE); DEBUG_INFO("---------------------------------------------\n"); DEBUG_INFO("-- EVCOMM: END --\n"); DEBUG_INFO("---------------------------------------------\n"); system("pkill Module_CCS"); while(1) { //wait for CSU confirm usleep(1000); } } /** * * @return */ 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 srand(time(NULL)); value_random = rand(); EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active = (unsigned short)(SdpTcpServerPort + (value_random % 10000) + 1); DEBUG_INFO("TCP Port assign: %d\n", EVCOMM_SYS_INFO.SDP_TCP_Server_Port_active); //Step 2: Init SessionID srand(time(NULL)); value_random = rand(); memcpy(&EVCOMM_SYS_INFO.SessionID[0], &value_random, 4); srand(time(NULL)); value_random = rand(); memcpy(&EVCOMM_SYS_INFO.SessionID[4], &value_random, 4); DEBUG_INFO("SessionID: (%02X%02X%02X%02X%02X%02X%02X%02X)\n", 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]); return 0; } /** * * @return */ int SyncAcShreaMemory() { #if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE)) pid_t pid; pid = fork(); if(pid == 0) { for(;;) { if(!EVCOMM_SYS_INFO.End_Process_inused) { for(uint8_t gun_index=0;gun_index<1;gun_index++) { //======================================== // CSU -> CCS setting //======================================== // Heart beat ShmCharger->gun_info[gun_index].acCcsInfo.CcsHeartBeat++; // Permission if(ShmInternalComm->ChargingPermission != ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission) { DEBUG_INFO("AC permission: %d -> %d\n", ShmInternalComm->ChargingPermission, ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission); ShmInternalComm->ChargingPermission_new = ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission; ShmInternalComm->ChargingPermission_pre = ShmInternalComm->ChargingPermission; ShmInternalComm->ChargingPermission = ShmInternalComm->ChargingPermission_new; } // CP ShmInternalComm->AC_CpPositiveVoltage = ShmCharger->gun_info[gun_index].acCcsInfo.CpPositiveVoltage; if(ShmInternalComm->AC_CpPresentState != ShmCharger->gun_info[gun_index].acCcsInfo.CpPresentState) { DEBUG_INFO("CP state: %d -> %d\n", ShmInternalComm->AC_CpPresentState, ShmCharger->gun_info[gun_index].acCcsInfo.CpPresentState); ShmInternalComm->AC_CpPresentState = ShmCharger->gun_info[gun_index].acCcsInfo.CpPresentState; } // Charging parameter ShmSysConfigAndInfo->SysInfo.CcsChargingData[gun_index].AvailableChargingCurrent = ShmInternalComm->AvailableChargingCurrent = ShmCharger->gun_info[gun_index].targetCurrent; // RCD status sync ShmInternalComm->AC_RcdStatus = 0; // EVSENotification ShmInternalComm->AC_EVSENotification = 0;//ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification; //======================================== // CCS -> CSU check //======================================== // V2G message flow status if(ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus != Get_V2G_Status()) { //DEBUG_INFO("PresentMsgFlowStatus: %d -> %d\n", ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus, Get_V2G_Status()); ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus = Get_V2G_Status(); switch(ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus) { case PowerDeliveryRequestStart ... SessionStopRequest: ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress = HLC_START_MODE; break; case CM_SLAC_PARM_REQ ... PreChargeResponse: ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress = HLC_STANDBY_MODE; break; default: ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress = HLC_STOP_MODE; break; } } } } usleep(1000); } } #endif return 0; } /** * * @param argc * @param argv * @return */ int main(int argc, char *argv[]) { DEBUG_INFO("---------------------------------------------\n"); DEBUG_INFO("-- EVCOMM: START --\n"); DEBUG_INFO("---------------------------------------------\n"); // QCA7000 chip reset Qca7kPowerReset(); // Share memory Initialization ShareMemory_Init(); memset(ShmSysConfigAndInfo, 0, sizeof(struct SysConfigAndInfo)); // Release socket handler if(socketFd.Raw > 0) { close(socketFd.Raw); } if(socketFd.Udp > 0) { close(socketFd.Udp); } if(socketFd.Tcp > 0) { close(socketFd.Tcp); } socketFd.Raw = socketFd.Udp = socketFd.Tcp = -1; Update_V2G_Status(IDLE); //Init V2G TCP/IPv6 packets buffer memset(v2gBuffer.rx, 0, V2GTP_MSG_RX_BUFFER_SIZE); memset(v2gBuffer.tx, 0, V2GTP_MSG_TX_BUFFER_SIZE); //Release State E Control SwitchCpStateE(DISABLE); OutputCpPwmDuty(100); //start to detect CP pilot state pid.CP_Detection = 0; CP_Detection(); //fork1 DEBUG_INFO("[fork1]CP Detection: ON\n"); //start to detect errors Error_Monitor(); //fork2 DEBUG_INFO("[fork2]Error Monitor: ON\n"); //start to detect PP pid.PP_Detection = 0; #if (PP_PROTECTION_MECHANISM == ENABLE) PP_Detection(); DEBUG_INFO("[fork3]PP Detection: ON\n"); #else DEBUG_INFO("[fork3]PP Detection: OFF\n"); #endif // Get network interface MAC address GetEthMac((uint8_t*)"eth0", macAddr.eth0); GetEthMac((uint8_t*)QcaInterface, macAddr.eth1); // XML parser initialization qcaInfo.AttenProfileCnt = 0; init_appHandEXIDocument(&v2gObject.appHandshake); // Init Energy transfer mode // TODO: // 1. Parsing Model Name ShmCcsData->EnergyTransferMode = CCS_ENERGY_TRANSFER_MODE; Parameters_Init(); Sniffer_Tcpdump(TCPDUMP_PACKETS_SNIFFER_SWITCH); #if (TCPDUMP_PACKETS_SNIFFER_SWITCH == ENABLE) sleep(1); //wait for TCP dump getting ready #endif // AC share memory exchange SyncAcShreaMemory(); DEBUG_INFO("[fork4]AC share memory exchange: ON\n"); DEBUG_INFO("Module_CCS initialize OK.\n"); for(;;) { if(!EVCOMM_SYS_INFO.End_Process_inused) { if(V2gFlowStatus < SLACC_SDP_UDP_Connection) { SlacComm(); } else if(V2gFlowStatus == SLACC_SDP_UDP_Connection) { if(SdpUdpConnected() == 1) { Update_V2G_Status(SLACC_SDP_TCP_Connection); continue; } SlacComm(); //TC_SECC_VTB_CmSlacMatch_004 ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > TT_match_join) { DEBUG_ERROR("Wait SLACC_SDP_UDP_Connection Timeout - TT_match_join (%.02lf of %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), TT_match_join); Update_V2G_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((socketFd.TcpAccept = V2gTcpConnected()) > 0) { Update_V2G_Status(SupportedAppProtocolRequest); ftime(&EVCOMM_SYS_INFO.V2G_SECC_Sequence_Timer_Start); continue; } SlacComm(); ftime(&timerStart.SeqEnd); if(DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd) > TT_match_join) { DEBUG_ERROR("Wait SLACC_SDP_TCP_Connection Timeout - TT_match_join (%.02lf / %d ms)\n", DiffTimeb(timerStart.SeqStart, timerStart.SeqEnd), TT_match_join); Update_V2G_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(socketFd.TcpAccept) < 0) { //error occurs } } else if (V2gFlowStatus >= Performance_Timeout) { //End_Process } else {} } else { // TODO: // 1. After complete or error occur task do not need to end //Update_V2G_Status(IDLE); //SwitchCpStateE(DISABLE); //OutputCpPwmDuty(100); } usleep(1000); } //while }//main while