#include "define.h" #include "main.h" //#define CDFA_CERTIFICATE // Only enable for CDFA certificate to send receipt by Phihong back end API //========================== // System basic sample constant //========================== #define is_error(ptr) ((unsigned long)ptr > (unsigned long)-4000L) #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define PASS 1 #define FAIL -1 #define YES 1 #define NO 0 #define ON 1 #define OFF 0 #define BUFFER_SIZE 128 //========================== // Timeout constant define //========================== #define TIMEOUT_SPEC_HANDSHAKING 180 #define TIMEOUT_SPEC_AUTH 15 #define TIMEOUT_SPEC_HANDSHAKING_LED 185 #define TIMEOUT_SPEC_LOGPPRINTOUT 30 #define TIMEOUT_SPEC_PROFILE_PREPARE 60 #define TIMEOUT_SPEC_BS_HLC_HANDSHAKE 25 #define TIMEOUT_SPEC_EV_READY 30 #define TIMEOUT_SPEC_CCS_HEARTBEAT_COUNT_RESET 10 #define TIMEOUT_SPEC_CCS_HANDSHAKE 120 #define TIMEOUT_SPEC_PWN_CHANGE 5 #define TIMEOUT_SPEC_POWERSAVING_LCD 120 #define TIMEOUT_SPEC_POWERSAVING_RFID 120 #define TIMEOUT_SPEC_POWERSAVING_METER 120 #define TIMEOUT_SPEC_POWERSAVING_LED_STATUS 120 #define TIMEOUT_SPEC_CEHCK_POWER_CONSUMPTION 15 #define TIMEOUT_SPEC_RESET_WIFI_MODULE 300 #define TIMEOUT_SPEC_TASK_CHECK 10 #define TIMEOUT_SPEC_SIMULATION 10 //========================== // GPIO constant define //========================== #define GPIO_OUT_RST_RFID 62 #define GPIO_AC_OUT_RST_4G 114 #define GPIO_OUT_RST_QCA 115 #define GPIO_OUT_RST_ETH 56 #define GPIO_IN_WAKEUP 63 #define GPIO_AC_OUT_RST_4G_WIFI 59 #define GPIO_DC_OUT_RST_4G_WIFI 104 //lwtest #define MtdBlockSize 0x300000 #define DB_FILE "/Storage/ChargeLog/localCgargingRecord.db" //========================== // Declare method //========================== void trim(char *s); int mystrcmp(char *p1, char *p2); void substr(char *dest, const char* src, unsigned int start, unsigned int cnt); void split(char **arr, char *str, const char *del); int isReachableInternet(); int isRouteFail(); int InitRfidPort(void); int GetCardSerialNumber(); void setLedMotion(unsigned char gun_index, unsigned char led_mode); void setRequest(unsigned char gun_index, unsigned char isOn); void setSpeaker(unsigned char isOn, unsigned char speaker_mode); void gpio_set_value(unsigned int gpio, unsigned int value); //========================== // Declare RFID module type //========================== #define MODULE_EWT 0 int wtdFd = -1; int rfidFd = -1; char* rfidPortName = "/dev/ttyS2"; RFID rfid; char *valid_Internet[2] = { "8.8.8.8", "180.76.76.76" }; //========================== // Declare share memory //========================== struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct PsuData *ShmPsuData; struct CHAdeMOData *ShmCHAdeMOData; struct CcsData *ShmCcsData; struct PrimaryMcuData *ShmPrimaryMcuData; struct FanModuleData *ShmFanModuleData; struct RelayModuleData *ShmRelayModuleData; struct OCPP16Data *ShmOCPP16Data; struct OCPP20Data *ShmOCPP20Data; struct OCPP16Data *ShmOCPP16DataPH; struct Charger *ShmCharger; struct timespec startTime[3][TMR_IDX_CNT]; struct timespec startChargingTime[3]; struct timespec endChargingTime[3]; sqlite3 *localDb; struct SysConfigData SysConfigOrg; ParsingRatedCur modelnameInfo = { 0 }; struct PreviousData { uint16_t targetCurrent; uint16_t current_limit; uint16_t primaryMcuCp_Pwn_Duty; float ChargingProfilePower; float ChargingProfileCurrent; } previousData[4]; //================================= // Common routine //================================= long long current_timestamp() { struct timeval te; gettimeofday(&te, NULL); // get current time long long milliseconds = te.tv_sec * 1000LL + te.tv_usec / 1000; // calculate milliseconds return milliseconds; } void trim(char *s) { int i = 0, j, k, l = 0; while ((s[i] == ' ') || (s[i] == '\t') || (s[i] == '\n')) i++; j = strlen(s) - 1; while ((s[j] == ' ') || (s[j] == '\t') || (s[j] == '\n')) j--; if (i == 0 && j == strlen(s) - 1) { } else if (i == 0) s[j + 1] = '\0'; else { for (k = i; k <= j; k++) s[l++] = s[k]; s[l] = '\0'; } } int mystrcmp(char *p1, char *p2) { while (*p1 == *p2) { if (*p1 == '\0' || *p2 == '\0') break; p1++; p2++; } if (*p1 == '\0' && *p2 == '\0') return (PASS); else return (FAIL); } void substr(char *dest, const char* src, unsigned int start, unsigned int cnt) { strncpy(dest, src + start, cnt); dest[cnt] = 0; } void split(char **arr, char *str, const char *del) { char *s = strtok(str, del); while (s != NULL) { *arr++ = s; s = strtok(NULL, del); } } int StoreLogMsg(const char *fmt, ...) { char Buf[4096 + 256]; char buffer[4096]; time_t CurrentTime; struct tm *tm; struct timeval tv; va_list args; va_start(args, fmt); int rc = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); memset(Buf, 0, sizeof(Buf)); CurrentTime = time(NULL); tm = localtime(&CurrentTime); gettimeofday(&tv, NULL); // get microseconds, 10^-6 if ((ShmSysConfigAndInfo->SysConfig.ModelName != NULL) && (ShmSysConfigAndInfo->SysConfig.SerialNumber != NULL) && (strlen((char*) ShmSysConfigAndInfo->SysConfig.ModelName) >= 14)) { sprintf(Buf, "echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]%s_%s_SystemLog", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec, buffer, tm->tm_year + 1900, tm->tm_mon + 1, ShmSysConfigAndInfo->SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.SerialNumber); } else { sprintf(Buf, "echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec, buffer, tm->tm_year + 1900, tm->tm_mon + 1); } #ifdef SystemLogMessage system(Buf); #endif #ifdef ConsloePrintLog printf("[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer); #endif return rc; } void refreshStartTimer(struct timespec *timer) { clock_gettime(CLOCK_MONOTONIC, timer); } int getDiffSecNow(struct timespec timer) { struct timespec timerNow; clock_gettime(CLOCK_MONOTONIC, &timerNow); return (int) ((((unsigned long) (timerNow.tv_sec - timer.tv_sec) * 1000) + ((unsigned long) ((timerNow.tv_nsec / 1000000) - (timer.tv_nsec / 1000000)))) / 1000); } int getDiffSecBetween(struct timespec start, struct timespec end) { return (int) ((((unsigned long) (end.tv_sec - start.tv_sec) * 1000) + ((unsigned long) ((end.tv_nsec / 1000000) - (start.tv_nsec / 1000000)))) / 1000); } long long DiffTimebWithNow(struct timeb ST) { //return milli-second struct timeb ET; long long StartTime, StopTime; ftime(&ET); StartTime = (long long) ST.time; StopTime = (long long) ET.time; return ((StopTime - StartTime) * 1000) + (ET.millitm - ST.millitm); } long long DiffTimeb(struct timeb ST, struct timeb ET) { //return milli-second long long StartTime, StopTime; StartTime = (long long) ST.time; StopTime = (long long) ET.time; return ((StopTime - StartTime) * 1000) + (ET.millitm - ST.millitm); } int DiffTimebWithNowSec(struct timeb ST) { //return milli-second struct timeb ET; unsigned int StartTime, StopTime; ftime(&ET); StartTime = (unsigned int) ST.time; StopTime = (unsigned int) ET.time; return (StopTime - StartTime); } int isOvertNow(uint8_t *start) { int result = YES; struct ParsingResult { int result; int scanedElement; int year; int month; int mday; int hour; int min; int sec; int tz_hour; int tz_min; float minSec; } parsingResult; struct tm tmStart; struct timeb tbStart; memset(&parsingResult, 0x00, sizeof(struct ParsingResult)); if (strstr((char*) start, ".") != NULL) { // Original data with mini second if (strstr((char*) start, "Z") != NULL) { // Original data with Z parsingResult.scanedElement = sscanf((char*) start, "%d-%d-%dT%d:%d:%d.%fZ", &parsingResult.year, &parsingResult.month, &parsingResult.mday, &parsingResult.hour, &parsingResult.min, &parsingResult.sec, &parsingResult.minSec); } else { // Original data without Z parsingResult.scanedElement = sscanf((char*) start, "%d-%d-%dT%d:%d:%d.%f%d:%d", &parsingResult.year, &parsingResult.month, &parsingResult.mday, &parsingResult.hour, &parsingResult.min, &parsingResult.sec, &parsingResult.minSec, &parsingResult.tz_hour, &parsingResult.tz_min); } } else { // Original data without mini second if (strstr((char*) start, "Z") != NULL) { // Original data with Z parsingResult.scanedElement = sscanf((char*) start, "%d-%d-%dT%d:%d:%dZ", &parsingResult.year, &parsingResult.month, &parsingResult.mday, &parsingResult.hour, &parsingResult.min, &parsingResult.sec); } else { // Original data without Z parsingResult.scanedElement = sscanf((char*) start, "%d-%d-%dT%d:%d:%d%d:%d", &parsingResult.year, &parsingResult.month, &parsingResult.mday, &parsingResult.hour, &parsingResult.min, &parsingResult.sec, &parsingResult.tz_hour, &parsingResult.tz_min); } } if (parsingResult.scanedElement >= 6) { tmStart.tm_year = parsingResult.year - 1900; tmStart.tm_mon = parsingResult.month - 1; tmStart.tm_mday = parsingResult.mday; tmStart.tm_hour = parsingResult.hour; tmStart.tm_min = parsingResult.min; tmStart.tm_sec = parsingResult.sec; tmStart.tm_gmtoff = 0; tbStart.time = mktime(&tmStart); tbStart.timezone = 0; tbStart.millitm = 0; tbStart.time -= (parsingResult.tz_hour * 3600) + (parsingResult.tz_min * 60 * (parsingResult.tz_hour >= 0 ? 1 : -1)); if (DiffTimebWithNowSec(tbStart) <= 0) result = NO; else result = YES; } else { DEBUG_WARN("Start date parsing error.\n"); } return result; } void getDateTimeString(char* result) { time_t CurrentTime; struct tm *tm; CurrentTime = time(NULL); tm = localtime(&CurrentTime); sprintf(result, "%04d.%02d.%02d %02d:%02d:%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); } int getCurrentYear() { int result = 0; time_t CurrentTime; struct tm *tm; CurrentTime = time(NULL); tm = localtime(&CurrentTime); result = (tm->tm_year + 1900); return result; } unsigned long long getAvailableMemory() { long pages = sysconf(_SC_AVPHYS_PAGES); long page_size = sysconf(_SC_PAGE_SIZE); return pages * page_size; } unsigned int isKernelSupportNAT() { unsigned int result = NO; unsigned int version = 0; FILE *fp; char cmd[256]; char buf[512]; // Get IP address & net mask strcpy(cmd, "uname -v"); fp = popen(cmd, "r"); if (fp != NULL) { if (fgets(buf, sizeof(buf), fp) != NULL) { sscanf(buf, "#%d", &version); if (version >= 30) result = YES; } } pclose(fp); return result; } int getEth0MacAddress() { int result = PASS; FILE *fp; char cmd[256]; char buf[512]; char tmp[512]; strcpy(cmd, "ifconfig eth0"); fp = popen(cmd, "r"); if (fp != NULL) { while (fgets(buf, sizeof(buf), fp) != NULL) { if (strstr(buf, "eth0") > 0) { result = PASS; } if (strstr(buf, "eth0 Link encap:Ethernet HWaddr") > 0) { sscanf(buf, "%*s%*s%*s%*s%s", tmp); strcpy((char*) ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthMacAddress, tmp); } } } pclose(fp); return result; } int isUap0up(void) { int result = FAIL; FILE *fp; char cmd[256]; char buf[512]; strcpy(cmd, "ifconfig uap0"); ; fp = popen(cmd, "r"); if (fp != NULL) { while (fgets(buf, sizeof(buf), fp) != NULL) { if (strstr(buf, "uap0") > 0) { result = PASS; } } } pclose(fp); return result; } //====================================================== // Get tartget charging info data //====================================================== struct ChargingInfoData* getTargetChargingInfoData(uint8_t gun_index) { struct ChargingInfoData *targetChargingInfoData = NULL; // Get target gun data if (modelnameInfo.ParsingInfo[gun_index].GunType == Gun_Type_Chademo) { for (int index = 0; index < CHAdeMO_QUANTITY; index++) { if ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == gun_index)) { targetChargingInfoData = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index]; break; } } } else if (modelnameInfo.ParsingInfo[gun_index].GunType == Gun_Type_CCS_2) { for (int index = 0; index < CCS_QUANTITY; index++) { if ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == gun_index)) { targetChargingInfoData = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index]; break; } } } else if (modelnameInfo.ParsingInfo[gun_index].GunType == Gun_Type_GB) { for (int index = 0; index < GB_QUANTITY; index++) { if ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == gun_index)) { targetChargingInfoData = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index]; break; } } } else if (modelnameInfo.ParsingInfo[gun_index].GunType == Gun_Type_AC) { for (int index = 0; index < AC_QUANTITY; index++) { if ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == gun_index)) { targetChargingInfoData = &ShmSysConfigAndInfo->SysInfo.AcChargingData[index]; break; } } } if (targetChargingInfoData == NULL) targetChargingInfoData = &ShmSysConfigAndInfo->SysInfo.AcChargingData[0]; return targetChargingInfoData; } //====================================================== // OCPP routine //====================================================== void ocpp_process_start() { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) system("/root/OcppBackend &"); else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) system("/root/OcppBackend20 &"); } uint8_t ocpp_get_isRemoteStartWait() { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->MsMsg.bits.isRemoteStartWaitReq; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->MsMsg.bits.isRemoteStartWaitReq; } return result; } uint8_t ocpp_get_connection_status() { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->OcppConnStatus; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->OcppConnStatus; } return result; } uint16_t ocpp_get_connection_timeout() { uint16_t result = TIMEOUT_SPEC_HANDSHAKING; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strcmp((char *) ShmOCPP16Data->ConfigurationTable.CoreProfile[ConnectionTimeOut].ItemData, "") != 0) { result = atoi((char *) ShmOCPP16Data->ConfigurationTable.CoreProfile[ConnectionTimeOut].ItemData); } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (strcmp( (char *) ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].value,"") != 0) { result = atoi( (char *) ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].value); } } return result; } uint8_t ocpp_get_update_firmware_req() { uint8_t result = NO; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->MsMsg.bits.UpdateFirmwareReq; } return result; } uint8_t ocpp_get_reset_req() { uint8_t result = NO; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->MsMsg.bits.ResetReq; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->MsMsg.bits.ResetReq; } return result; } void ocpp_boot_info_sync() { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { memcpy((char*) ShmOCPP16Data->OcppServerURL, (char*) ShmSysConfigAndInfo->SysConfig.OcppServerURL, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.OcppServerURL)); memcpy((char*) ShmOCPP16Data->ChargeBoxId, (char*) ShmSysConfigAndInfo->SysConfig.ChargeBoxId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ChargeBoxId)); sprintf((char*) ShmOCPP16Data->BootNotification.CpFwVersion, (char*) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev); sprintf((char*) ShmOCPP16Data->BootNotification.CpMeterSerialNumber, "N/A"); switch (ShmSysConfigAndInfo->SysConfig.ModelName[SAFETY_REGULATION]) { case 'M': case 'Z': sprintf((char*) ShmOCPP16Data->BootNotification.CpMeterType, "MID"); break; case 'P': sprintf((char*) ShmOCPP16Data->BootNotification.CpMeterType, "PTB"); break; case 'I': sprintf((char*) ShmOCPP16Data->BootNotification.CpMeterType, "TIC"); break; case 'U': sprintf((char*) ShmOCPP16Data->BootNotification.CpMeterType, "UL"); break; default: sprintf((char*) ShmOCPP16Data->BootNotification.CpMeterType, "N/A"); break; } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { memcpy((char*) ShmOCPP20Data->OcppServerURL, (char*) ShmSysConfigAndInfo->SysConfig.OcppServerURL, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.OcppServerURL)); memcpy((char*) ShmOCPP20Data->ChargeBoxId, (char*) ShmSysConfigAndInfo->SysConfig.ChargeBoxId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ChargeBoxId)); sprintf((char*) ShmOCPP20Data->BootNotification.chargingStation.firmwareVersion, (char*) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev); } } void ocpp_set_remotestart(uint8_t gun_index, uint8_t status) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq != status) ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq = status; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CsMsg.bits[gun_index].RequestStartTransactionReq != status) ShmOCPP20Data->CsMsg.bits[gun_index].RequestStartTransactionReq = status; } } void ocpp_set_remotestop(uint8_t gun_index, uint8_t status) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq != status) ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq = status; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CsMsg.bits[gun_index].RequestStopTransactionReq != status) ShmOCPP20Data->CsMsg.bits[gun_index].RequestStopTransactionReq = status; } } uint8_t ocpp_get_remotestart(uint8_t gun_index) { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->CsMsg.bits[gun_index].RequestStartTransactionReq; } return result; } void ocpp_copy_userid_from_remotestart(uint8_t gun_index) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag, ARRAY_SIZE(ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag)); } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmOCPP20Data->RequestStartTransaction[gun_index].idToken.idToken, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); } } uint8_t ocpp_get_remotestop(uint8_t gun_index) { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->CsMsg.bits[gun_index].RequestStopTransactionReq; } return result; } void ocpp_set_auth_req(uint8_t status, ...) { va_list args; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->SpMsg.bits.AuthorizeReq != status) { if (status == ON) memset(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, 0x00, ARRAY_SIZE(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status)); ShmOCPP16Data->SpMsg.bits.AuthorizeReq = status; } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->SpMsg.bits.AuthorizeReq != status) { if (status == ON) { memset(&ShmOCPP20Data->Authorize.Response_idTokenInfo, 0x00, sizeof(struct IdTokenInfoType)); va_start(args, status); sprintf((char*) ShmOCPP20Data->Authorize.idToken.type, "%s", va_arg(args, char*)); va_end(args); } ShmOCPP20Data->SpMsg.bits.AuthorizeReq = status; } } } uint8_t ocpp_get_auth_req() { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->SpMsg.bits.AuthorizeReq; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->SpMsg.bits.AuthorizeReq; } return result; } void ocpp_set_auth_conf(uint8_t status) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->SpMsg.bits.AuthorizeConf != status) ShmOCPP16Data->SpMsg.bits.AuthorizeConf = status; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->SpMsg.bits.AuthorizeConf != status) ShmOCPP20Data->SpMsg.bits.AuthorizeConf = status; } } uint8_t ocpp_get_auth_conf() { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->SpMsg.bits.AuthorizeConf; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->SpMsg.bits.AuthorizeConf; } return result; } uint8_t ocpp_get_auth_result(uint8_t isValidParent, ...) { uint8_t result = OFF; va_list args; uint8_t gun_index; if (isValidParent) { va_start(args, isValidParent); gun_index = va_arg(args, int); va_end(args); switch (getTargetChargingInfoData(gun_index)->SystemStatus) { case SYS_MODE_AUTHORIZING: if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if ((strcmp((char*) ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted") == 0)) result = PASS; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if ((strcmp((char*) ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted") == 0)) result = PASS; } break; case SYS_MODE_CHARGING: case SYS_MODE_TERMINATING: if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if ((strcmp((char*) ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted") == 0) && (strcmp((char*) ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, (char*) ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.ParentIdTag) == 0)) result = PASS; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if ((strcmp((char*) ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted") == 0) && (strcmp((char*) ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, (char*) ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.groupIdToken.idToken) == 0)) result = PASS; } break; default: break; } } else { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if ((strcmp((char*) ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted") == 0)) result = PASS; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if ((strcmp((char*) ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted") == 0)) result = PASS; } } //DEBUG_INFO("Authorize result : %s \n", ((result == PASS)?"Pass":"Fail")); return result; } uint8_t ocpp_get_unlocker_req(uint8_t gun_index) { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId - 1].isUnlockerConnetor; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmCharger->gun_info[ShmOCPP20Data->UnlockConnector[gun_index].connectorId - 1].isUnlockerConnetor; } return result; } void ocpp_set_unlocker_req(uint8_t gun_index, uint8_t status) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId - 1].isUnlockerConnetor != status) ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId - 1].isUnlockerConnetor = status; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmCharger->gun_info[ShmOCPP20Data->UnlockConnector[gun_index].connectorId - 1].isUnlockerConnetor != status) ShmCharger->gun_info[ShmOCPP20Data->UnlockConnector[gun_index].connectorId - 1].isUnlockerConnetor = status; } } void ocpp_set_starttransaction_req(uint8_t gun_index, uint8_t status) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionReq != status) ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionReq = status; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq != status) ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = status; } if (strcmp((char *) &ShmSysConfigAndInfo->SysConfig.MaintainServerURL, "") != 0) { if (ShmOCPP16DataPH->CpMsg.bits[gun_index].StartTransactionReq != status) ShmOCPP16DataPH->CpMsg.bits[gun_index].StartTransactionReq = status; } } void ocpp_set_starttransaction_conf(uint8_t gun_index, uint8_t status) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionConf != status) ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionConf = status; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventConf != status) ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventConf = status; } if (strcmp((char *) &ShmSysConfigAndInfo->SysConfig.MaintainServerURL, "") != 0) { if (ShmOCPP16DataPH->CpMsg.bits[gun_index].StartTransactionConf != status) ShmOCPP16DataPH->CpMsg.bits[gun_index].StartTransactionConf = status; } } void ocpp_set_stoptransaction_req(uint8_t gun_index, uint8_t status) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq != status) ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = status; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq != status) ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = status; } if (strcmp((char *) &ShmSysConfigAndInfo->SysConfig.MaintainServerURL, "") != 0) { if (ShmOCPP16DataPH->CpMsg.bits[gun_index].StopTransactionReq != status) ShmOCPP16DataPH->CpMsg.bits[gun_index].StopTransactionReq = status; } } void ocpp_set_stoptransaction_conf(uint8_t gun_index, uint8_t status) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionConf != status) { ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionConf = status; } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventConf != status) { ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventConf = status; } } if (strcmp((char *) &ShmSysConfigAndInfo->SysConfig.MaintainServerURL, "") != 0) { if (ShmOCPP16DataPH->CpMsg.bits[gun_index].StopTransactionConf != status) { ShmOCPP16DataPH->CpMsg.bits[gun_index].StopTransactionConf = status; } } } void ocpp_copy_userid_to_starttransaction(uint8_t gun_index) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { memcpy((char*) ShmOCPP16Data->StartTransaction[gun_index].IdTag, (char*) getTargetChargingInfoData(gun_index)->StartUserId, ARRAY_SIZE(ShmOCPP16Data->StartTransaction[gun_index].IdTag)); } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { memcpy((char*) ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*) getTargetChargingInfoData(gun_index)->StartUserId, ARRAY_SIZE(getTargetChargingInfoData(gun_index)->StartUserId)); } if (strcmp((char *) &ShmSysConfigAndInfo->SysConfig.MaintainServerURL, "") != 0) { memcpy((char*) ShmOCPP16DataPH->StartTransaction[gun_index].IdTag, (char*) getTargetChargingInfoData(gun_index)->StartUserId, ARRAY_SIZE(ShmOCPP16DataPH->StartTransaction[gun_index].IdTag)); } } uint8_t ocpp_get_starttransaction_result(uint8_t gun_index) { uint8_t result = PASS; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strstr((char*) ShmOCPP16Data->ConfigurationTable.CoreProfile[StopTransactionOnInvalidId].ItemData, "TRUE")) { if ((strcmp((char*) ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.Status, "Blocked") == 0) || (strcmp((char*) ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.Status, "Expired") == 0) || (strcmp((char*) ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.Status, "Invalid") == 0)) result = NO; } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (strstr((char*) ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].value, "TRUE")) { if ((strcmp((char*) ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Blocked") == 0) || (strcmp((char*) ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Expired") == 0) || (strcmp((char*) ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Invalid") == 0) || (strcmp((char*) ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "NoCredit") == 0) || (strcmp((char*) ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "NotAllowedTypeEVSE") == 0) || (strcmp((char*) ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "NotAtThisLocation") == 0) || (strcmp((char*) ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "NotAtThisTime") == 0) || (strcmp((char*) ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Unknown") == 0)) result = NO; } } return result; } uint8_t ocpp_get_maxcharging_profileId() { uint8_t result = 0; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->MaxChargingProfile.ChargingProfileId; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->MaxChargingProfile.id; } return result; } uint8_t ocpp_get_smartcharging_profileId(uint8_t gun_index) { uint8_t result = 0; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileId; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->SmartChargingProfile[gun_index].id; } return result; } void ocpp_reset_smartcharging_profileId(uint8_t gun_index) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileId = 0; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { ShmOCPP20Data->SmartChargingProfile[gun_index].id = 0; } } uint8_t ocpp_get_profile_req(uint8_t gun_index) { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileReq; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileReq; } return result; } void ocpp_set_profile_req(uint8_t gun_index, uint8_t status) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileReq != status) ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileReq = status; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileReq != status) ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileReq = status; } } uint8_t ocpp_get_profile_conf(uint8_t gun_index) { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileConf; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileConf; } return result; } void ocpp_set_profile_conf(uint8_t gun_index, uint8_t status) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileConf != status) ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileConf = status; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileConf != status) ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileConf = status; } } uint8_t ocpp_get_StopTransactionOnEVSideDisconnect() { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strcmp((char *) ShmOCPP16Data->ConfigurationTable.CoreProfile[StopTransactionOnEVSideDisconnect].ItemData, "TRUE") == 0) result = ON; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (strcmp((char *) ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variableAttribute[0].value, "TRUE") == 0) result = ON; } return result; } uint8_t ocpp_get_cancelreservation_req(uint8_t gun_index) { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationReq; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationReq; } return result; } void ocpp_set_cancelreservation_req(uint8_t gun_index, uint8_t status) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationReq != status) ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationReq = status; if (ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationReq == OFF) ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationConf = ON; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationReq != status) ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationReq = status; if (ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationReq == OFF) ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationConf = ON; } } uint8_t ocpp_compare_reserve_id_with_user(uint8_t gun_index) { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strcmp((char*) ShmSysConfigAndInfo->SysConfig.UserId, (char*) ShmOCPP16Data->ReserveNow[gun_index].IdTag) == 0) result = ON; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (strcmp((char*) ShmSysConfigAndInfo->SysConfig.UserId, (char*) ShmOCPP20Data->ReserveNow[gun_index].idToken.idToken) == 0) result = ON; } return result; } uint8_t ocpp_compare_reserve_id_with_remote_user(uint8_t gun_index) { uint8_t result = OFF; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strcmp((char*) ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag, (char*) ShmOCPP16Data->ReserveNow[gun_index].IdTag) == 0) { result = ON; memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag, ARRAY_SIZE(ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag)); } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (strcmp((char*) ShmOCPP20Data->RequestStartTransaction[gun_index].idToken.idToken, (char*) ShmOCPP20Data->ReserveNow[gun_index].idToken.idToken) == 0) { result = ON; memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmOCPP20Data->RequestStartTransaction[gun_index].idToken.idToken, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); } } return result; } uint8_t ocpp_isAuthorizeRemoteStart() { uint8_t result = NO; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strstr((char*) ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthorizeRemoteTxRequests].ItemData, "TRUE")) { result = YES; } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (strstr( (char*) ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variableAttribute[0].value, "TRUE")) { result = YES; } } return result; } uint8_t ocpp_get_freevend_idtag(uint8_t * userId) { uint8_t result = NO; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { strcpy((char*) userId, (char*) ShmOCPP16Data->ConfigurationTable.CoreProfile[FreeVendIdtag].ItemData); result = YES; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { strcpy((char*) userId, (char*) ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVendIdtag].variableAttribute[0].value); result = YES; } return result; } //====================================================== // Check interface status //====================================================== int isInterfaceUp(const char *interface) { int result = FAIL; FILE *fp; char cmd[256]; char buf[512]; strcpy(cmd, "ifconfig"); ; fp = popen(cmd, "r"); if (fp != NULL) { while (fgets(buf, sizeof(buf), fp) != NULL) { if (strstr(buf, interface) > 0) { result = PASS; } } } pclose(fp); return result; } //====================================================== // Create all share memory //====================================================== int CreatShareMemory() { int result = PASS; int MeterSMId; //creat ShmSysConfigAndInfo if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n"); result = FAIL; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n"); result = FAIL; } memset(ShmSysConfigAndInfo, 0, sizeof(struct SysConfigAndInfo)); //creat ShmStatusCodeData if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmStatusCodeData NG\n"); result = FAIL; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmStatusCodeData NG\n"); result = FAIL; } memset(ShmStatusCodeData, 0, sizeof(struct StatusCodeData)); //creat ShmPsuData if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmPsuData NG\n"); result = FAIL; } else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmPsuData NG\n"); result = FAIL; } memset(ShmPsuData, 0, sizeof(struct PsuData)); //creat ShmCHAdeMOData if ((MeterSMId = shmget(ShmCHAdeMOCommKey, sizeof(struct CHAdeMOData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmCHAdeMOData NG1\n"); result = FAIL; } else if ((ShmCHAdeMOData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmCHAdeMOData NG2\n"); result = FAIL; } memset(ShmCHAdeMOData, 0, sizeof(struct CHAdeMOData)); //creat ShmCcsData if ((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmCcsData NG\n"); result = FAIL; } else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmCcsData NG\n"); result = FAIL; } memset(ShmCcsData, 0, sizeof(struct CcsData)); //creat ShmPrimaryMcuData if ((MeterSMId = shmget(ShmPrimaryMcuKey, sizeof(struct PrimaryMcuData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmPrimaryMcuData NG\n"); result = FAIL; } else if ((ShmPrimaryMcuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmPrimaryMcuData NG\n"); result = FAIL; } memset(ShmPrimaryMcuData, 0, sizeof(struct PrimaryMcuData)); //creat ShmOCPP16Data if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmOCPP16Data NG\n"); result = FAIL; } else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmOCPP16Data NG\n"); result = FAIL; } memset(ShmOCPP16Data, 0, sizeof(struct OCPP16Data)); //creat ShmOCPP20Data if ((MeterSMId = shmget(ShmOcpp20ModuleKey, sizeof(struct OCPP20Data), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget OCPP20Data NG\n"); result = FAIL; } else if ((ShmOCPP20Data = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat OCPP20Data NG\n"); result = FAIL; } memset(ShmOCPP20Data, 0, sizeof(struct OCPP20Data)); //creat ShmCharger if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmCharger NG\n"); result = FAIL; } else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmCharger NG\n"); result = FAIL; } memset(ShmCharger, 0, sizeof(struct Charger)); //creat ShmOCPP16DataPH if ((MeterSMId = shmget(ShmOcppPHModuleKey, sizeof(struct OCPP16Data), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmOCPP16DataPH NG\n"); result = FAIL; } else if ((ShmOCPP16DataPH = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmOCPP16DataPH NG\n"); result = FAIL; } else { } ShmSysConfigAndInfo->SysInfo.InternetConn = OFF; return result; } //====================================================== // Call WEBAPI to mail receipt (Only for CDFA verify) //====================================================== #ifdef CDFA_CERTIFICATE int sendReceiptMail(char *startDateTime, char *stopDateTime, char *receiptInfo) { int result = FAIL; char reciever[128]; char subject[128]; char content[8192]; char priceDetail[4098]={0}; char cmdBuf[8192]; double totalEnergy; double totalPrice; json_object *detailPrice = json_tokener_parse(receiptInfo); if(!is_error(detailPrice)) { if(json_object_object_get(detailPrice, "totalChargedEnergy") != NULL) totalEnergy = json_object_get_double(json_object_object_get(detailPrice, "totalChargedEnergy")); if(json_object_object_get(detailPrice, "totalPrice") != NULL) totalPrice = json_object_get_double(json_object_object_get(detailPrice, "totalPrice")); if(json_object_object_get(detailPrice, "receiptDetail") != NULL) { for(int idx=0;idx\n", priceDetail , json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(detailPrice, "receiptDetail"), idx), "hour")) , json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(detailPrice, "receiptDetail"), idx), "chargedEnergy")) , json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(detailPrice, "receiptDetail"), idx), "unitPrice")) , json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(detailPrice, "receiptDetail"), idx), "periodPrice"))); } } } json_object_put(detailPrice); // Generate mail content sprintf(reciever, "folus_wen@phihong.com.tw"); sprintf(subject, "Charging Receipt From %s", ShmSysConfigAndInfo->SysConfig.chargePointVendor); sprintf(content, "
\n" "

Receipt of charging on %s


\n" "Location Name: CDFA Lab
\n" "Location Address: xxxxxxxxxxx
\n" "EVSE ID: %s
\n" "Maximum Rate of Energy Transfer: 11.5 KW AC
\n" "Charging start date time: %s
\n" "Charging stop date time: %s
\n" "Energy Delivered: %.4f KWH
\n" "Cost of Charging:
\n" "%s" "***Total charged cost: $ %.2f
\n" "
\n" "
\n" "%s
\n" "47800 Fremont Blvd.
\n" "Fremont, CA 94538, USA
\n", startDateTime , ShmSysConfigAndInfo->SysConfig.ChargeBoxId , startDateTime , stopDateTime , totalEnergy , priceDetail , totalPrice , ShmSysConfigAndInfo->SysConfig.chargePointVendor); json_object *post = json_object_new_object(); json_object_object_add(post, "Receiver", json_object_new_string(reciever)); json_object_object_add(post, "Subject", json_object_new_string(subject)); json_object_object_add(post, "Body", json_object_new_string(content)); json_object_object_add(post, "UseHtml", json_object_new_boolean(1)); // Call WEBAPI sprintf(cmdBuf, "curl -X POST -k -d '%s' -H \"Content-Type: application/json\" https://ocpp.phihong.com.tw:5014/api/Notification/ &", json_object_to_json_string_ext(post, JSON_C_TO_STRING_PLAIN)); system(cmdBuf); //DEBUG_INFO("cmdBuf: %s\n", cmdBuf); json_object_put(post); return result; } #endif /* CDFA_CERTIFICATE */ //====================================================== // SQLite3 related routine //====================================================== int getReceiptInfo(uint8_t gun_index, char *receiptInfo) { int result = PASS; double totalEnergy = 0.0; double totalPrice = 0.0; json_object *receipt = json_object_new_object(); json_object *receiptAry = json_object_new_array(); for (uint8_t idxHour = 0; idxHour < ARRAY_SIZE(getTargetChargingInfoData(gun_index)->presentChargedEnergyPeriod); idxHour++) { json_object *receiptDetail = json_object_new_object(); json_object_object_add(receiptDetail, "hour", json_object_new_int(idxHour)); json_object_object_add(receiptDetail, "chargedEnergy", json_object_new_double(getTargetChargingInfoData(gun_index)->presentChargedEnergyPeriod[idxHour])); json_object_object_add(receiptDetail, "unitPrice", json_object_new_double(ShmSysConfigAndInfo->SysConfig.BillingData.Fee[idxHour])); json_object_object_add(receiptDetail, "periodPrice", json_object_new_double(getTargetChargingInfoData(gun_index)->presentChargedEnergyPeriod[idxHour] * ShmSysConfigAndInfo->SysConfig.BillingData.Fee[idxHour])); totalEnergy += getTargetChargingInfoData(gun_index)->presentChargedEnergyPeriod[idxHour]; totalPrice += getTargetChargingInfoData(gun_index)->presentChargedEnergyPeriod[idxHour] * ShmSysConfigAndInfo->SysConfig.BillingData.Fee[idxHour]; json_object_array_add(receiptAry, receiptDetail); } json_object_object_add(receipt, "receiptDetail", receiptAry); json_object_object_add(receipt, "totalChargedEnergy", json_object_new_double(totalEnergy)); json_object_object_add(receipt, "totalPrice", json_object_new_double(totalPrice)); json_object_object_add(receipt, "serviceProvider", json_object_new_string((char*) ShmSysConfigAndInfo->SysConfig.chargePointVendor)); json_object_object_add(receipt, "serviceProviderAddress", json_object_new_string("Address")); json_object_object_add(receipt, "serviceProviderTel", json_object_new_string("TEL")); json_object_object_add(receipt, "chargerBoxId", json_object_new_string((char*) ShmSysConfigAndInfo->SysConfig.ChargeBoxId)); sprintf(receiptInfo, "%s", json_object_to_json_string_ext(receipt, JSON_C_TO_STRING_PLAIN)); json_object_put(receipt); //DEBUG_INFO("receiptInfo: %s\n", receiptInfo); return result; } int DB_Open(sqlite3 *db) { int result = PASS; char* errMsg = NULL; char* createRecordSql = "CREATE TABLE IF NOT EXISTS charging_record(" "idx integer primary key AUTOINCREMENT, " "reservationId text, " "transactionId text, " "startMethod text, " "userId text, " "dateTimeStart text, " "dateTimeStop text," "socStart text, " "socStop text, " "chargeEnergy text, " "stopReason text, " "finalCost text" ");"; char* createRecordBufSql = "CREATE TABLE IF NOT EXISTS charging_record_buffer(" "reservationId text, " "transactionId text, " "startMethod text, " "userId text, " "dateTimeStart text, " "dateTimeStop text," "socStart text, " "socStop text, " "chargeEnergy text, " "stopReason text, " "finalCost text" ");"; char* createCfgSql = "CREATE TABLE IF NOT EXISTS `config` ( " "`idx` INTEGER PRIMARY KEY AUTOINCREMENT, " "`item` TEXT NOT NULL, " "`connector` INTEGER NOT NULL, " "`val` TEXT NOT NULL, unique(item,connector) on conflict replace);"; //sqlite3_config(SQLITE_CONFIG_URI, 1); if (sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_ERROR("Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { DEBUG_INFO("Local charging record database open successfully.\n"); if (sqlite3_exec(db, createRecordSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_ERROR("Create local charging record table error message: %s\n", errMsg); } else { DEBUG_INFO("Opened local charging record table successfully\n"); } if (sqlite3_exec(db, createRecordBufSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_ERROR("Create local charging record buffer table error message: %s\n", errMsg); } else { DEBUG_INFO("Opened local charging record buffer table successfully\n"); } if (sqlite3_exec(db, createCfgSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_ERROR("Create local config table error message: %s\n", errMsg); } else { DEBUG_INFO("Opened local config table successfully\n"); } sqlite3_close(db); } return result; } int DB_Check_Record_Buf(sqlite3 *db, int gun_index) { int result = PASS; char* errMsg = NULL; char sqlStr[4096]; char **rs; int rows, cols; if (sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO("Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { sqlite3_get_table(db, "select * from charging_record_buffer", &rs, &rows, &cols, &errMsg); if (rows > 0) { // Copy record buffer for (int idxRow = 1; idxRow <= rows; idxRow++) { if (strcmp(rs[(idxRow * cols) + 3], "0") == 0) { result = false; } sprintf(sqlStr, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) " "values('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s');", rs[(idxRow * cols) + 0], rs[(idxRow * cols) + 1], rs[(idxRow * cols) + 2], rs[(idxRow * cols) + 3], rs[(idxRow * cols) + 4], rs[(idxRow * cols) + 5], rs[(idxRow * cols) + 6], rs[(idxRow * cols) + 7], rs[(idxRow * cols) + 8], rs[(idxRow * cols) + 9], rs[(idxRow * cols) + 10]); if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO("Copy local charging record buffer error message: %s\n", errMsg); } else { DEBUG_INFO("Copy local charging record buffer successfully\n"); } #ifdef CDFA_CERTIFICATE // Only for CDFA certificate sendReceiptMail(rs[(idxRow*cols)+4], rs[(idxRow*cols)+5], rs[(idxRow*cols)+10]); #endif /* CDFA_CERTIFICATE */ } // Delete buffer if (sqlite3_exec(db, "delete from charging_record_buffer", 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO("Delete local charging record buffer error message: %s\n", errMsg); } else { DEBUG_INFO("Delete local charging record buffer successfully\n"); } } else { DEBUG_INFO("There is not any charging record buffer.\n", gun_index); } sqlite3_free_table(rs); sqlite3_close(db); } return result; } int DB_Update_Record_Buf(sqlite3 *db, int gun_index) { int result = PASS; char* errMsg = NULL; char sqlStr[4096]; char receiptInfo[2048]; getReceiptInfo(gun_index, receiptInfo); if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { sprintf(sqlStr, "insert into charging_record_buffer(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) " "values('%d', '%d', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');", getTargetChargingInfoData(gun_index)->ReservationId, ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId, getTargetChargingInfoData(gun_index)->StartMethod, getTargetChargingInfoData(gun_index)->StartUserId, getTargetChargingInfoData(gun_index)->StartDateTime, getTargetChargingInfoData(gun_index)->StopDateTime, getTargetChargingInfoData(gun_index)->EvBatterySoc, getTargetChargingInfoData(gun_index)->EvBatterySoc, getTargetChargingInfoData(gun_index)->PresentChargedEnergy, "Power Loss", #ifdef CDFA_CERTIFICATE receiptInfo);// Only for CDFA certificate #else ShmOCPP16Data->Cost.FinalCost[gun_index].description); #endif /* CDFA_CERTIFICATE */ } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { sprintf(sqlStr, "insert into charging_record_buffer(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) " #ifdef CDFA_CERTIFICATE "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');", #else "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%f');", #endif /* CDFA_CERTIFICATE */ getTargetChargingInfoData(gun_index)->ReservationId, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId, getTargetChargingInfoData(gun_index)->StartMethod, getTargetChargingInfoData(gun_index)->StartUserId, getTargetChargingInfoData(gun_index)->StartDateTime, getTargetChargingInfoData(gun_index)->StopDateTime, getTargetChargingInfoData(gun_index)->EvBatterySoc, getTargetChargingInfoData(gun_index)->EvBatterySoc, getTargetChargingInfoData(gun_index)->PresentChargedEnergy, "Power Loss", #ifdef CDFA_CERTIFICATE //receiptInfo);// Only for CDFA certificate #else ShmOCPP20Data->CostUpdated.totalCost); #endif /* CDFA_CERTIFICATE */ } if (sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO("Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { // Delete buffer if (sqlite3_exec(db, "delete from charging_record_buffer", 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO("Delete local charging record buffer error message: %s\n", errMsg); } else { //DEBUG_INFO( "Delete local charging record buffer successfully\n"); } // Insert record buffer if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO("Insert local charging record buffer error message: %s\n", errMsg); } else { //DEBUG_INFO( "Insert local charging record buffer successfully\n"); } sqlite3_close(db); } return result; } int DB_Insert_Record(sqlite3 *db, int gun_index) { int result = PASS; char* errMsg = NULL; char sqlStr[4096]; char receiptInfo[2048]; getReceiptInfo(gun_index, receiptInfo); if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { sprintf(sqlStr, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) " "values('%d', '%d', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');", getTargetChargingInfoData(gun_index)->ReservationId, ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId, getTargetChargingInfoData(gun_index)->StartMethod, getTargetChargingInfoData(gun_index)->StartUserId, getTargetChargingInfoData(gun_index)->StartDateTime, getTargetChargingInfoData(gun_index)->StopDateTime, getTargetChargingInfoData(gun_index)->EvBatterySoc, getTargetChargingInfoData(gun_index)->EvBatterySoc, getTargetChargingInfoData(gun_index)->PresentChargedEnergy, ShmOCPP16Data->StopTransaction[gun_index].StopReason, #ifdef CDFA_CERTIFICATE receiptInfo);// Only for CDFA certificate #else ShmOCPP16Data->Cost.FinalCost[gun_index].description); #endif /* CDFA_CERTIFICATE */ } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { sprintf(sqlStr, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) " #ifdef CDFA_CERTIFICATE "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');", #else "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%f');", #endif /* CDFA_CERTIFICATE */ getTargetChargingInfoData(gun_index)->ReservationId, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId, getTargetChargingInfoData(gun_index)->StartMethod, getTargetChargingInfoData(gun_index)->StartUserId, getTargetChargingInfoData(gun_index)->StartDateTime, getTargetChargingInfoData(gun_index)->StopDateTime, getTargetChargingInfoData(gun_index)->EvBatterySoc, getTargetChargingInfoData(gun_index)->EvBatterySoc, getTargetChargingInfoData(gun_index)->PresentChargedEnergy, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, #ifdef CDFA_CERTIFICATE receiptInfo);// Only for CDFA certificate #else ShmOCPP20Data->CostUpdated.totalCost); #endif /* CDFA_CERTIFICATE */ } //DEBUG_INFO("sqlStr= %s\n", sqlStr); if (sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO("Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { // Delete buffer if (sqlite3_exec(db, "delete from charging_record_buffer", 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO("Delete local charging record buffer error message: %s\n", errMsg); } else { DEBUG_INFO("Delete local charging record buffer successfully\n"); } // Insert charging record if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO("Insert local charging record error message: %s\n", errMsg); } else { DEBUG_INFO("Insert local charging record successfully\n"); } sprintf(sqlStr, "delete from charging_record where (idx < (select idx from charging_record order by idx desc limit 1)-2000) and (dateTimeStop < '%04d.01.01 00:00:00');", (getCurrentYear() - 3)); if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO("delete local charging error message: %s\n", errMsg); } else { DEBUG_INFO("delete local charging record successfully\n"); } sqlite3_close(db); } #ifdef CDFA_CERTIFICATE // Only for CDFA certificate sendReceiptMail((char*)getTargetChargingInfoData(gun_index)->StartDateTime, (char*)getTargetChargingInfoData(gun_index)->StopDateTime, receiptInfo); #endif return result; } int DB_Update_Operactive(sqlite3 *db, uint8_t gun_index, uint8_t isOperactive) { uint8_t result = false; char* errMsg = NULL; char sqlStr[1024]; srand(time(NULL)); if (sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO("Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { sprintf(sqlStr, "insert or replace into config (item, connector, val) values('isOperactive', %d, %d);", gun_index, isOperactive); //DEBUG_INFO("sqlStr= %s\n", sqlStr); if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO("update config error message: %s\n", errMsg); } else { DEBUG_INFO("update connector-%d config item isOperactive to %d\n", gun_index, isOperactive); } sqlite3_close(db); } return result; } int DB_Get_Operactive(sqlite3 *db, uint8_t gun_index) { uint8_t result = true; char* errMsg = NULL; char sqlStr[1024]; char **rs; int rows, cols; sprintf(sqlStr, "select * from config where item='isOperactive' and connector=%d;", gun_index); //DEBUG_INFO("sqlStr= %s\n", sqlStr); if (sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO("Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { sqlite3_get_table(db, sqlStr, &rs, &rows, &cols, &errMsg); if (rows > 0) { for (int idxRow = 1; idxRow <= rows; idxRow++) { if (strcmp(rs[(idxRow * cols) + 3], "0") == 0) { result = false; } DEBUG_INFO("Query connector-%d isOperactive: %s\n", gun_index, rs[(idxRow * cols) + 3]); } } else { DEBUG_INFO("Query connector-%d fail, default value as operactive.\n", gun_index); } sqlite3_free_table(rs); sqlite3_close(db); } return result; } //====================================================== // Peripheral initial //====================================================== int InitWatchDog() { int fd; int timeout = 180; system("/usr/bin/fuser -k /dev/watchdog"); sleep(1); system("echo V > /dev/watchdog"); sleep(1); fd = open("/dev/watchdog", O_RDWR); if (fd <= 0) { DEBUG_ERROR("System watch dog initial fail.\n"); } ioctl(fd, _IOWR('W', 6, int), &timeout); return fd; } void InitGPIO() { /*****************0~3, 4 bank, bank x 32+ num*********************/ /***************************************************************/ /*************** INPUT PIN ***************************************/ /***************************************************************/ /***************************************************************/ /*************** OUTPUT PIN ************************************/ /***************************************************************/ /*MCU request:GPIO3_20 => H:ON; L:OFF*/ system("echo 116 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio116/direction"); system("echo 0 > /sys/class/gpio/gpio116/value"); /*Rfid:GPIO0_19 => Reset_PING H:ON; L:OFF*/ system("echo 19 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio19/direction"); system("echo 1 > /sys/class/gpio/gpio19/value"); /*Speaker:GPIO2_1 => H:ON; L:OFF*/ system("echo 65 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio65/direction"); system("echo 0 > /sys/class/gpio/gpio65/value"); /*Ethernet RST:GPIO1_24 => H:ON; L:OFF*/ system("echo 56 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio56/direction"); system("echo 0 > /sys/class/gpio/gpio56/value"); sleep(3); system("echo 1 > /sys/class/gpio/gpio56/value"); /*4G POWER RST:GPIO3_18 => H:ON; L:OFF*/ system("echo 114 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio114/direction"); system("echo 1 > /sys/class/gpio/gpio114/value"); sleep(3); system("echo 0 > /sys/class/gpio/gpio114/value"); /*4G/WIFI POWER RST:GPIO1_27 => H:OFF L:ON*/ system("echo 59 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio59/direction"); system("echo 1 > /sys/class/gpio/gpio59/value"); sleep(3); system("echo 0 > /sys/class/gpio/gpio59/value"); /*RFID ICC:GPIO0_20 => H:ON; L:OFF*/ system("echo 20 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio20/direction"); /*QCA7000 interrupt:GPIO2_00 => H:ON; L:OFF*/ system("echo 64 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio64/direction"); /*QCA7000 Reset:GPIO3_19 => H:ON; L:OFF*/ system("echo 115 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio115/direction"); system("echo 0 > /sys/class/gpio/gpio115/value"); sleep(3); system("echo 1 > /sys/class/gpio/gpio115/value"); /*RFID RST: GPIO1_30 => H:OFF; L:ON*/ system("echo 62 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio62/direction"); system("echo 1 > /sys/class/gpio/gpio62/value"); /*Wake up button GPIO1_31 => H:OFF; L:ON*/ system("echo 63 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio63/direction"); sleep(1); DEBUG_INFO("Initial GPIO OK\n"); } //lwtest uint8_t getAcPhaseCount(void) { uint8_t cnt = 1; if (ShmSysConfigAndInfo->SysConfig.ModelName[INPUT_TYPE] == 'Y' || ShmSysConfigAndInfo->SysConfig.ModelName[INPUT_TYPE] == 'D' || ShmSysConfigAndInfo->SysConfig.ModelName[INPUT_TYPE] == 'W') cnt = 3; else cnt = 1; DEBUG_INFO("Get Phase Count %d\n", cnt); return cnt; } int LoadSysConfigAndInfo(struct SysConfigData *ptr) { int fd, wrd; unsigned char *buf; unsigned int ChkSum, ChkSumOrg; if ((buf = malloc(MtdBlockSize)) == NULL) { DEBUG_ERROR("malloc buffer NG, rebooting..\n"); if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, MtdBlockSize); //================================================ // Load configuration from mtdblock10 //================================================ system("nanddump /dev/mtd10 -f /mnt/EvseConfig.bin"); fd = open("/mnt/EvseConfig.bin", O_RDWR); if (fd < 0) { free(buf); DEBUG_ERROR("open mtdblock10 NG, rebooting..\n"); if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } wrd = read(fd, buf, MtdBlockSize); close(fd); if (wrd < MtdBlockSize) { free(buf); DEBUG_ERROR("read SysConfigData data NG, rebooting..\n"); if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum = 0; for (wrd = ARRAY_SIZE(ptr->CsuBootLoadFwRev); wrd < MtdBlockSize - 4; wrd++) { ChkSum += buf[wrd]; } memcpy(&ChkSumOrg, buf + (MtdBlockSize - 4), sizeof(ChkSumOrg)); memcpy(&ptr->ModelName, buf + (ARRAY_SIZE(ptr->CsuBootLoadFwRev)), ARRAY_SIZE(ptr->ModelName)); memcpy(&ptr->SerialNumber, buf + (ARRAY_SIZE(ptr->CsuBootLoadFwRev) + ARRAY_SIZE(ptr->ModelName) + ARRAY_SIZE(ptr->AcModelName)), ARRAY_SIZE(ptr->SerialNumber)); //================================================ // Load configuration from mtdblock11 //================================================ if (ChkSum != ChkSumOrg) { DEBUG_ERROR("Primary SysConfigData checksum NG, read backup\n"); system("nanddump /dev/mtd11 -f /mnt/EvseConfig.bin"); fd = open("/mnt/EvseConfig.bin", O_RDWR); if (fd < 0) { free(buf); DEBUG_ERROR("open mtdblock11 (backup) NG, rebooting..\n"); if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, MtdBlockSize); wrd = read(fd, buf, MtdBlockSize); close(fd); if (wrd < MtdBlockSize) { free(buf); DEBUG_ERROR("read backup SysConfigData data NG,rebooting..\n"); if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum = 0; for (wrd = ARRAY_SIZE(ptr->CsuBootLoadFwRev); wrd < MtdBlockSize - 4; wrd++) { ChkSum += buf[wrd]; } memcpy(&ChkSumOrg, buf + (MtdBlockSize - 4), sizeof(ChkSumOrg)); //================================================ // Load configuration from mtdblock12 (Factory default) //================================================ if (ChkSum != ChkSumOrg) { DEBUG_WARN("backup SysConfigData checksum NG, read Factory default\n"); system("nanddump /dev/mtd12 -f /mnt/EvseConfig.bin"); fd = open("/mnt/EvseConfig.bin", O_RDWR); if (fd < 0) { DEBUG_ERROR("open mtdblock12 (Factory default) NG,rebooting..\n"); free(buf); if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, MtdBlockSize); wrd = read(fd, buf, MtdBlockSize); close(fd); if (wrd < MtdBlockSize) { DEBUG_ERROR("read factory default SysConfigData data NG, rebooting..\n"); free(buf); if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum = 0; for (wrd = ARRAY_SIZE(ptr->CsuBootLoadFwRev); wrd < MtdBlockSize - 4; wrd++) { ChkSum += buf[wrd]; } memcpy(&ChkSumOrg, buf + (MtdBlockSize - 4), sizeof(ChkSumOrg)); memcpy(buf + (ARRAY_SIZE(ptr->CsuBootLoadFwRev)), &ptr->ModelName, ARRAY_SIZE(ptr->ModelName)); memcpy(buf + (ARRAY_SIZE(ptr->CsuBootLoadFwRev) + ARRAY_SIZE(ptr->ModelName) + ARRAY_SIZE(ptr->AcModelName)), &ptr->SerialNumber, ARRAY_SIZE(ptr->SerialNumber)); if (ChkSum != ChkSumOrg) { DEBUG_WARN("factory default SysConfigData checksum NG, restore factory default\n"); free(buf); system("cd /root;./Module_FactoryConfig -m"); system("rm -f /Storage/OCPP/OCPPConfiguration"); system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); return FAIL; } } } //load OK memcpy((struct SysConfigData *) ptr, buf, sizeof(struct SysConfigData)); free(buf); system("rm -f /mnt/EvseConfig.bin"); // SysConfig in flash is empty (0xffffffff) if ((strlen((char*) ShmSysConfigAndInfo->SysConfig.ModelName) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName)) || (strlen((char*) ShmSysConfigAndInfo->SysConfig.SerialNumber) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)) || (strlen((char*) ShmSysConfigAndInfo->SysConfig.SystemId) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SystemId)) || (ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient == 0xff)) { if (strlen( (char*) ShmSysConfigAndInfo->SysConfig.ModelName) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName)) { memset(ShmSysConfigAndInfo->SysConfig.ModelName, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName)); } if (strlen((char*) ShmSysConfigAndInfo->SysConfig.SerialNumber) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)) { memset(ShmSysConfigAndInfo->SysConfig.SerialNumber, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)); } if (strlen((char*) ShmSysConfigAndInfo->SysConfig.SystemId) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SystemId)) { memset(ShmSysConfigAndInfo->SysConfig.SystemId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SystemId)); } if (ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient == 0xff) { DEBUG_INFO("Ethernet dhcp config is null.\n"); } if (strlen((char*) ShmSysConfigAndInfo->SysConfig.ModelName) == 0x00) { DEBUG_INFO("Model name over length.\n"); } if (strlen((char*) ShmSysConfigAndInfo->SysConfig.SerialNumber) == 0x00) { DEBUG_INFO("Model serial number over length.\n"); } if (strlen((char*) ShmSysConfigAndInfo->SysConfig.SystemId) == 0x00) { DEBUG_INFO("SystemId over length.\n"); } system("cd /root;./Module_FactoryConfig -m"); sleep(3); system("/usr/bin/run_evse_restart.sh"); } DEBUG_INFO("Load SysConfigData OK\n"); ShmCharger->isCcsEnable = OFF; DEBUG_INFO("Is CCS Enable: %s \n", ((ShmCharger->isCcsEnable == ON)?"YES":"NO")); RatedCurrentParsing((char*) ShmSysConfigAndInfo->SysConfig.ModelName, &modelnameInfo); //lwtest if (ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_OUTPUT_TYPE] == 'A') ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent = modelnameInfo.ratedPower / AC_OUTPUT_VOL; else ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent = 0; ShmSysConfigAndInfo->SysConfig.AcPhaseCount = getAcPhaseCount(); DEBUG_INFO("Gun quantity: %d\n", modelnameInfo.GetGunCount); DEBUG_INFO("Model name rated power: %d\n", modelnameInfo.ratedPower); return PASS; } int StoreUsrConfigData(struct SysConfigData *UsrData) { int result = PASS; int fd, wrd; unsigned int i, Chk; unsigned char *ptr, *BufTmp; Chk = 0; ptr = (unsigned char *) UsrData; if ((BufTmp = malloc(MtdBlockSize)) != NULL) { memset(BufTmp, 0, MtdBlockSize); memcpy(BufTmp, ptr, sizeof(struct SysConfigData)); for (i = 0; i < MtdBlockSize - 4; i++) Chk += *(BufTmp + i); memcpy(BufTmp + MtdBlockSize - 4, &Chk, 4); // Output configuration to file. fd = open("/mnt/EvseConfig.bin", O_RDWR | O_CREAT); if (fd < 0) { DEBUG_ERROR("open /mnt/EvseConfig.bin NG\n"); free(BufTmp); return 0; } wrd = write(fd, BufTmp, MtdBlockSize); close(fd); if (wrd < MtdBlockSize) { DEBUG_ERROR("write /mnt/EvseConfig.bin NG\n"); free(BufTmp); return 0; } DEBUG_INFO("EvseConfig write to file in /mnt OK.\n"); DEBUG_INFO("Erase /dev/mtd10.\n"); runShellCmd("flash_erase /dev/mtd10 0 0"); DEBUG_INFO("Write /dev/mtd10.\n"); runShellCmd("nandwrite -p /dev/mtd10 /mnt/EvseConfig.bin"); DEBUG_INFO("Erase /dev/mtd11.\n"); runShellCmd("flash_erase /dev/mtd11 0 0"); DEBUG_INFO("Write /dev/mtd11.\n"); runShellCmd("nandwrite -p /dev/mtd11 /mnt/EvseConfig.bin"); system("rm -f /mnt/EvseConfig.bin"); DEBUG_INFO("EvseConfig write to flash OK\n"); } else { DEBUG_ERROR("alloc BlockSize NG\r\n"); result = FAIL; } if (BufTmp != NULL) free(BufTmp); return result; } void InitEthernet() { uint8_t cnt_pingDNS_Fail; char tmpbuf[256]; unsigned int natInterface = 0; // Detele bridge interface system("/sbin/ifconfig uap0 down"); system("/sbin/ifconfig br0 down"); system("/usr/sbin/brctl delbr br0"); //Init Eth0 for internet memset(tmpbuf, 0, 256); sprintf(tmpbuf, "/sbin/ifconfig eth0 %s netmask %s up &", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress); DEBUG_INFO("eth0 config as ip: %s, netmask: %s\n", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress); system(tmpbuf); memset(tmpbuf, 0, 256); sprintf(tmpbuf, "route add default gw %s eth0 &", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress); system(tmpbuf); system("ifconfig lo up &"); system("/sbin/ifconfig eth0:1 192.168.201.201 netmask 255.255.255.248 up &"); if ((ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_OUTPUT_TYPE] == 'A') && (ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_TYPE] == 'W')) system("/sbin/ethtool -s eth0 speed 10 duplex full autoneg off"); //Run DHCP client if enabled system("killall udhcpc"); system("rm -rf /etc/resolv.conf"); system("echo nameserver 8.8.8.8 >> /etc/resolv.conf"); //Google DNS server system("echo nameserver 180.76.76.76 >> /etc/resolv.conf"); //Baidu DNS server if (ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient == 0) { sprintf(tmpbuf, "/sbin/udhcpc -i eth0 -x hostname:CSU3_%s -s /root/dhcp_script/eth0.script > /dev/null &", ShmSysConfigAndInfo->SysConfig.SystemId); system(tmpbuf); } // Upgrade system id to /etc/hostname sprintf(tmpbuf, "echo %s > /etc/hostname", ShmSysConfigAndInfo->SysConfig.SystemId); system(tmpbuf); // Ethernet MAC address getEth0MacAddress(); // Init for eth1 when model name is DC if (ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_OUTPUT_TYPE] == 'D') { memset(tmpbuf, 0, 256); sprintf(tmpbuf, "/sbin/ifconfig eth1 192.168.0.10 netmask 255.255.255.0 up &"); DEBUG_INFO("eth1 config as ip: 192.168.0.10, netmask: 255.255.255.0\n"); system(tmpbuf); } //check internet status if (fork() == 0) { for (;;) { if (isRouteFail()) { //DEBUG_ERROR("eth0 not in route, restart eth0.\n"); system("/sbin/ifconfig eth0 down;/sbin/ifconfig eth0 up"); if ((ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient == 0)) { system("pgrep -f \"udhcpc -i eth0\" | xargs kill"); sprintf(tmpbuf, "/sbin/udhcpc -i eth0 -x hostname:CSU3_%s -s /root/dhcp_script/eth0.script > /dev/null &", ShmSysConfigAndInfo->SysConfig.SystemId); system(tmpbuf); } else { system("pgrep -f \"udhcpc -i eth0\" | xargs kill"); memset(tmpbuf, 0, 256); sprintf(tmpbuf, "/sbin/ifconfig eth0 %s netmask %s up &", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress); system(tmpbuf); memset(tmpbuf, 0, 256); sprintf(tmpbuf, "route add default gw %s eth0 &", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress); system(tmpbuf); } } if (isReachableInternet() == PASS) { ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = OFF; cnt_pingDNS_Fail = 0; } else { if (cnt_pingDNS_Fail >= 3) { ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON; if (!ShmSysConfigAndInfo->SysInfo.OcppConnStatus) { if ((ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient == 0)) { system("pgrep -f \"udhcpc -i eth0\" | xargs kill"); sprintf(tmpbuf, "/sbin/udhcpc -i eth0 -x hostname:CSU3_%s -s /root/dhcp_script/eth0.script > /dev/null &", ShmSysConfigAndInfo->SysConfig.SystemId); system(tmpbuf); } else { system("pgrep -f \"udhcpc -i eth0\" | xargs kill"); memset(tmpbuf, 0, 256); sprintf(tmpbuf, "/sbin/ifconfig eth0 %s netmask %s up &", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress); system(tmpbuf); memset(tmpbuf, 0, 256); sprintf(tmpbuf, "route add default gw %s eth0 &", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress); system(tmpbuf); } cnt_pingDNS_Fail = 0; } } else { cnt_pingDNS_Fail++; } } if (ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet && ((ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 0) || ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi) && ((ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled == 0) || ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi) && (ShmOCPP16Data->OcppConnStatus != PASS)) { ShmSysConfigAndInfo->SysInfo.InternetConn = OFF; } else { ShmSysConfigAndInfo->SysInfo.InternetConn = ON; } //============================================================ // Priority for internet 0 : First / 1 : Second / 2: Third //============================================================ if (!ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet) { system("/sbin/ifmetric eth0 0"); if ((ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'D')) { system("/sbin/ifmetric mlan0 1"); } if ((ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'D')) { system("/sbin/ifmetric ppp0 2"); } if (isKernelSupportNAT() == YES) { if (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 2) { if (natInterface != 1) { system("/sbin/iptables -t nat -F"); system("/sbin/iptables -A POSTROUTING -t nat -s 192.168.10.0/24 -o eth0 -j MASQUERADE"); natInterface = 1; } } else { system("/sbin/iptables -t nat -F"); } } } else if (!ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi) { if ((ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'D')) { system("/sbin/ifmetric eth0 1"); system("/sbin/ifmetric mlan0 0"); } if ((ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'D')) { system("/sbin/ifmetric ppp0 2"); } } else if (!ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi) { if ((ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'D')) { system("/sbin/ifmetric mlan0 2"); } if ((ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'D')) { system("/sbin/ifmetric eth0 1"); system("/sbin/ifmetric ppp0 0"); } if (isKernelSupportNAT() == YES) { if (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 2) { if (natInterface != 2) { system("/sbin/iptables -t nat -F"); system("/sbin/iptables -A POSTROUTING -t nat -s 192.168.10.0/24 -o ppp0 -j MASQUERADE"); natInterface = 2; } } else { system("/sbin/iptables -t nat -F"); } } } else { if (isKernelSupportNAT() == YES) { if (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 2) { system("/sbin/iptables -t nat -F"); natInterface = 0; } } } // Bridge ethernet to uap0 to get dynamic ip address if (ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharing && (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 2) && (isUap0up() == PASS) && (access("/sys/class/net/br0/address", F_OK) == -1)) { sleep(10); system("/usr/sbin/brctl addbr br0"); system("/usr/sbin/brctl addif br0 eth0"); system("/usr/sbin/brctl addif br0 uap0"); system("/sbin/ifconfig br0 192.168.10.200 up"); system("/bin/sed -i '/interface/d' /etc/udhcpd.conf"); system("/bin/echo 'interface br0' >> /etc/udhcpd.conf"); system("kill udhcpd"); system("/usr/sbin/udhcpd /etc/udhcpd.conf"); DEBUG_INFO("Bridge uap0 & eth0 for local power sharing by ethernet.\n"); } sleep(5); } } DEBUG_INFO("Initial Ethernet OK\n"); } int SpawnTask(uint8_t gun_index) { if (gun_index == 0) { system("pkill Module_"); system("pkill OcppBackend"); system("/root/Module_EventLogging &"); system("/root/Module_Speaker &"); system("/root/Module_ProduceUtils &"); system("/root/Module_LcmControl &"); if (strcmp((char *) &ShmSysConfigAndInfo->SysConfig.OcppServerURL, "") != 0) { ocpp_process_start(); } else { DEBUG_INFO("OCPP URL is empty, need to create a configuration table !!!\n"); ocpp_process_start(); } } return PASS; } int InitQca7000() { int result = PASS; system("/sbin/rmmod qcaspi"); if (isKernelSupportNAT() == YES) system("/sbin/insmod /lib/qcaspi_nat.ko"); else system("/sbin/insmod /lib/qcaspi.ko"); sleep(2); /*+++ vern, for CCS +++*/ //system("/sbin/ifconfig eth1 192.168.253.11 netmask 255.255.255.0 up"); system("/sbin/ifconfig eth1 192.168.0.11 netmask 255.255.255.0 up"); /*--- vern, for CCS ---*/ sleep(1); return result; } int Initialization(uint8_t gun_index) { int result = PASS; if (gun_index == 0) { LoadSysConfigAndInfo(&ShmSysConfigAndInfo->SysConfig); InitGPIO(); InitEthernet(); // Only AX or DC model enable QCA7000 if ((ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_OUTPUT_TYPE] == 'A') && (ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_TYPE] == 'X')) { if (InitQca7000() != PASS) { DEBUG_ERROR("QCA7000 initial fail.\n"); result = FAIL; } } if (DB_Open(localDb) != PASS) { DEBUG_ERROR("Local database initial fail.\n"); result = FAIL; } if ((rfidFd = InitRfidPort()) == FAIL) { DEBUG_ERROR("RFID port initial fail.\n"); result = FAIL; } if ((wtdFd = InitWatchDog()) == FAIL) { DEBUG_ERROR("Watchdog initial fail.\n"); result = FAIL; } if (result == PASS) DEBUG_INFO("Initialization OK.\n"); else DEBUG_INFO("Initialization Fail.\n"); } return result; } //===================================================== // Common routine //===================================================== char* getSystemModeName(unsigned char mode) { char* result; switch (mode) { case SYS_MODE_BOOTING: result = "booting"; break; case SYS_MODE_IDLE: result = "idle"; break; case SYS_MODE_AUTHORIZING: result = "authorizing"; break; case SYS_MODE_PREPARING: result = "preparing"; break; case SYS_MODE_CHARGING: result = "charging"; break; case SYS_MODE_TERMINATING: result = "terminating"; break; case SYS_MODE_COMPLETE: result = "complete"; break; case SYS_MODE_ALARM: result = "alarm"; break; case SYS_MODE_FAULT: result = "fault"; break; case SYS_MODE_MAINTAIN: result = "maintain"; break; case SYS_MODE_RESERVATION: result = "reservation"; break; case SYS_MODE_BOOKING: result = "booking"; break; case SYS_MODE_DEBUG: result = "debug"; break; case SYS_MODE_UPDATE: result = "upgrade"; break; default: result = "unknown"; break; } return result; } void setChargerMode(unsigned char gun_index, unsigned char mode) { getTargetChargingInfoData(gun_index)->PreviousSystemStatus = getTargetChargingInfoData(gun_index)->SystemStatus; getTargetChargingInfoData(gun_index)->SystemStatus = mode; DEBUG_INFO("Gun-%02d mode switch from %s to %s\n", gun_index, getSystemModeName(getTargetChargingInfoData(gun_index)->PreviousSystemStatus), getSystemModeName(getTargetChargingInfoData(gun_index)->SystemStatus)); } unsigned char isMode(unsigned char gun_index, unsigned char mode) { return ((getTargetChargingInfoData(gun_index)->SystemStatus == mode) ? YES : NO); } unsigned char isModeChange(unsigned char gun_index) { unsigned char result = NO; if (!isMode(gun_index, getTargetChargingInfoData(gun_index)->PreviousSystemStatus)) { result = YES; getTargetChargingInfoData(gun_index)->PreviousSystemStatus = getTargetChargingInfoData(gun_index)->SystemStatus; } return result; } void gpio_set_value(unsigned int gpio, unsigned int value) { int fd; char buf[256]; sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio); fd = open(buf, O_WRONLY); if (fd < 0) { DEBUG_ERROR("GPIO-%d set %d fail.\n", gpio, value); return; } if (value) write(fd, "1", 2); else write(fd, "0", 2); close(fd); } int gpio_get_value(unsigned int gpio) { int fd; char buf[256]; char ch; int8_t result = FAIL; sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio); fd = open(buf, O_RDONLY); if (fd < 0) { DEBUG_ERROR("GPIO-%d get fail\n", gpio); return result; } read(fd, &ch, 1); if (ch != '0') result = 1; else result = 0; close(fd); return result; } int presentChargedEnergyClear(unsigned char gun_index) { int result = FAIL; getTargetChargingInfoData(gun_index)->PresentChargedEnergy = 0; memset(getTargetChargingInfoData(gun_index)->presentChargedEnergyPeriod, 0x00, ARRAY_SIZE(getTargetChargingInfoData(gun_index)->presentChargedEnergyPeriod) * sizeof(float)); result = PASS; return result; } float presentChargedEnergyTotal(unsigned char gun_index) { float result = 0.0f; for (int idx = 0; idx < ARRAY_SIZE(getTargetChargingInfoData(gun_index)->presentChargedEnergyPeriod); idx++) { //result += getTargetChargingInfoData(gun_index)->presentChargedEnergyPeriod[idx]; result += (((int) (getTargetChargingInfoData(gun_index)->presentChargedEnergyPeriod[idx] * 10000)) / (float) 10000); } return result; } int presentChargedEnergyUpdate(unsigned char gun_index) { int result = FAIL; time_t CurrentTime; struct tm *tm; CurrentTime = time(NULL); tm = localtime(&CurrentTime); if (ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 1) { // Resolution: 0.0001 kwh getTargetChargingInfoData(gun_index)->presentChargedEnergyPeriod[tm->tm_hour] += (((float) (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption - ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption_at_start)) / 10000.0) - presentChargedEnergyTotal(gun_index); } else { // Resolution: 0.0001 kwh getTargetChargingInfoData(gun_index)->presentChargedEnergyPeriod[tm->tm_hour] += ((((float) (ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption - ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption_at_start)) / 10000.0) + (((float) (ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption - ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption_at_start)) / 10000.0) + (((float) (ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption - ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption_at_start)) / 10000.0)) - presentChargedEnergyTotal(gun_index); } getTargetChargingInfoData(gun_index)->PresentChargedEnergy = presentChargedEnergyTotal(gun_index); return result; } //=============================================== // Get firmware version //=============================================== void get_firmware_version(unsigned char gun_index) { FILE *fp; char cmd[512]; char buf[512]; // Get CSU hardware version sprintf((char*) ShmSysConfigAndInfo->SysInfo.CsuHwRev, "REV.XXXXXXX"); // Get CSU boot loader version memcpy(ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev, ShmSysConfigAndInfo->SysConfig.CsuBootLoadFwRev, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.CsuBootLoadFwRev)); // Get CSU kernel version sprintf(cmd, "/bin/uname -r"); fp = popen(cmd, "r"); if (fp == NULL) sprintf((char*) ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev, "Unknown version"); else { while (fgets(buf, sizeof(buf), fp) != NULL) { memcpy(ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev, buf, strlen(buf) - 1); } } // Get MCU firmware version //lwtest if (modelnameInfo.GetGunCount > 1) { strcpy((char*) ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[0].ver.Version_FW); strcpy((char*) ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[1].ver.Version_FW); } else strcpy((char*) ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[0].ver.Version_FW); // Get CSU root file system version sprintf((char*) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "E0.02.00.0000.00"); // Get AC connector type from model name for (uint8_t idx = 0; idx < 3; idx++) { switch (ShmSysConfigAndInfo->SysConfig.ModelName[CONNECTOR_TYPE1 + idx]) { case '1': // J1772 Plug ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[6] = '4'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[6] = '4'; break; case '2': // J1772 Socket ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[6] = '1'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[6] = '1'; break; case '3': // CE Plug ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[6] = '5'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[6] = '5'; break; case '4': // CE Socket ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[6] = '2'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[6] = '2'; break; case '5': // GB Plug ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[6] = '6'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[6] = '6'; break; case '6': // GB Socket ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[6] = '3'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[6] = '3'; break; } } // Get network option from model name switch (ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE]) { case 'B': case 'U': //Blue tooth ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '3'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[9] = '3'; break; case 'W': // WIFI ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '1'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[9] = '1'; break; case 'T': // 3G/4G ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '2'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[9] = '2'; break; case 'D': // WIFI + 4G ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '5'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[9] = '5'; break; default: // LAN ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '0'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[9] = '0'; break; } // Get rating power from model name memcpy(&ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[10], &ShmSysConfigAndInfo->SysConfig.ModelName[RATING_POWER], 0x03); memcpy(&ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[10], &ShmSysConfigAndInfo->SysConfig.ModelName[RATING_POWER], 0x03); // Get vender code from model name memcpy(&ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[14], &ShmSysConfigAndInfo->SysConfig.ModelName[VENDOR_CODE], 0x02); memcpy(&ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[14], &ShmSysConfigAndInfo->SysConfig.ModelName[VENDOR_CODE], 0x02); //lwtest if ((modelnameInfo.GetGunCount > 1 && gun_index == 0) || modelnameInfo.GetGunCount < 2) { DEBUG_INFO("========================================\n"); DEBUG_INFO("Model: %s\n", ShmSysConfigAndInfo->SysConfig.ModelName); DEBUG_INFO("CSU hardware version: %s\n", ShmSysConfigAndInfo->SysInfo.CsuHwRev); DEBUG_INFO("CSU boot loader version: %s\n", ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev); DEBUG_INFO("CSU kernel version: %s\n", ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev); DEBUG_INFO("CSU root file system version: %s\n", ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev); DEBUG_INFO("CSU MCU-%2d firmware version: %s\n", gun_index, ShmCharger->gun_info[0].ver.Version_FW); DEBUG_INFO("========================================\n"); } } //=============================================== // Upgrade firmware //=============================================== int upgrade_check() { int result = PASS; int fd; DIR *dir; struct dirent *file; char cmd[512]; long int MaxLen = 48 * 1024 * 1024, ImageLen = 0, wrd; if ((dir = opendir("/mnt")) != NULL) { /* print all the files and directories within directory */ while ((file = readdir(dir)) != NULL) { if ((strlen(file->d_name) > 2)) { // Wait for MCU upgrade finish. while (ShmCharger->gun_info[0].mcuFlag.isMcuUpgradeReq || (modelnameInfo.GetGunCount > 1 ? ShmCharger->gun_info[1].mcuFlag.isMcuUpgradeReq : FALSE)) sleep(1); // Wait for LCM upgrade finish. while (ShmCharger->isUpgradeLcmReq) sleep(1); memset(&ShmCharger->fwUpgradeInfo, 0xFF, sizeof(Fw_Upgrade_Info)); DEBUG_INFO("New firmware file: %s\n", file->d_name); sprintf(ShmCharger->fwUpgradeInfo.location, "/mnt/%s", file->d_name); if ((fd = open(ShmCharger->fwUpgradeInfo.location, O_RDONLY)) >= 0) { unsigned char *ptr = malloc(MaxLen); //-48 is take out the header memset(ptr, 0xFF, MaxLen); //-48 is take out the header ImageLen = read(fd, ptr, MaxLen); close(fd); ShmCharger->fwUpgradeInfo.fwType = ((ptr[0x13] << 0) | (ptr[0x12] << 8) | (ptr[0x11] << 16) | (ptr[0x10] << 24)); substr(ShmCharger->fwUpgradeInfo.modelName, (char *) ptr, 0, 0x10); DEBUG_INFO("New firmware type: %X\n", ShmCharger->fwUpgradeInfo.fwType); DEBUG_INFO("New firmware model name: %s, %s\n", ShmCharger->fwUpgradeInfo.modelName, ShmSysConfigAndInfo->SysConfig.ModelName); if ((ShmCharger->fwUpgradeInfo.modelName[0] == ShmSysConfigAndInfo->SysConfig.ModelName[0]) && (ShmCharger->fwUpgradeInfo.modelName[1] == ShmSysConfigAndInfo->SysConfig.ModelName[1]) && (ShmCharger->fwUpgradeInfo.modelName[7] == ShmSysConfigAndInfo->SysConfig.ModelName[7]) && (ShmCharger->fwUpgradeInfo.modelName[8] == ShmSysConfigAndInfo->SysConfig.ModelName[8]) && (ShmCharger->fwUpgradeInfo.modelName[9] == ShmSysConfigAndInfo->SysConfig.ModelName[9]) && (ShmCharger->fwUpgradeInfo.modelName[11] == ShmSysConfigAndInfo->SysConfig.ModelName[11]) && (ShmCharger->fwUpgradeInfo.modelName[12] == ShmSysConfigAndInfo->SysConfig.ModelName[12]) && (ShmCharger->fwUpgradeInfo.modelName[13] == ShmSysConfigAndInfo->SysConfig.ModelName[13]) && (ShmCharger->fwUpgradeInfo.fwType > 0)) { switch (ShmCharger->fwUpgradeInfo.fwType) { //case CSU_MLO: case CSU_BOOTLOADER: case CSU_KERNEL_CONFIGURATION: case CSU_KERNEL_IMAGE: case CSU_ROOT_FILE_SYSTEM: case CSU_USER_CONFIGURATION: case CSU_PRIMARY_CONTROLLER: if (Upgrade_Flash(ShmCharger->fwUpgradeInfo.fwType, ShmCharger->fwUpgradeInfo.location, ShmCharger->fwUpgradeInfo.modelName) != PASS) { result = FAIL; } else { if (ShmCharger->fwUpgradeInfo.fwType == CSU_USER_CONFIGURATION) { DEBUG_INFO("Restore model name & serial number.\n"); memcpy(&SysConfigOrg, &ShmSysConfigAndInfo->SysConfig, sizeof(struct SysConfigData)); if (LoadSysConfigAndInfo(&ShmSysConfigAndInfo->SysConfig) != PASS) { DEBUG_INFO("Re-load configuration fail.\n"); result = FAIL; } else { memcpy(&ShmSysConfigAndInfo->SysConfig.ModelName, &SysConfigOrg.ModelName, ARRAY_SIZE(SysConfigOrg.ModelName)); memcpy(&ShmSysConfigAndInfo->SysConfig.SerialNumber, &SysConfigOrg.SerialNumber, ARRAY_SIZE(SysConfigOrg.SerialNumber)); memcpy(&ShmSysConfigAndInfo->SysConfig.SystemId, &SysConfigOrg.SystemId, ARRAY_SIZE(SysConfigOrg.SystemId)); if (StoreUsrConfigData(&ShmSysConfigAndInfo->SysConfig) != PASS) { DEBUG_INFO("Re-write configuration fail.\n"); result = FAIL; } else DEBUG_INFO("Re-write configuration OK.\n"); } } } sprintf(cmd, "yes|rm %s", ShmCharger->fwUpgradeInfo.location); system(cmd); break; case AC_WALLMOUNT_CONTROLLER: for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) ShmCharger->gun_info[gun_index].mcuFlag.isMcuUpgradeReq = ON; sleep(10); break; case LCM: fd = open("/mnt/lcm.zip", O_RDWR | O_CREAT | O_EXCL); if (fd < 0) { DEBUG_ERROR("Can not create lcm.zip file.\n"); result = FAIL; } else { // Write image to flash DEBUG_INFO("Writing data to lcm.zip file...\n"); wrd = write(fd, ptr + 48, ImageLen - 48); close(fd); DEBUG_INFO(">> lcm.zip Written length: 0x%x\n", wrd); if (wrd != (ImageLen - 48)) { result = FAIL; } else { runShellCmd("mkdir -p /mnt/lcd"); runShellCmd("unzip /mnt/lcm.zip -d /mnt/lcd"); sprintf(cmd, "yes|rm %s", ShmCharger->fwUpgradeInfo.location); system(cmd); system("rm -f /mnt/lcm.zip"); result = PASS; } } ShmCharger->isUpgradeLcmReq = ON; sleep(10); break; default: result = FAIL; DEBUG_WARN("Image file is unknown type.\n"); sprintf(cmd, "yes|rm %s", ShmCharger->fwUpgradeInfo.location); system(cmd); break; } } else { result = FAIL; DEBUG_ERROR("Model name and Firmware type error.\n"); sprintf(cmd, "yes|rm %s", ShmCharger->fwUpgradeInfo.location); system(cmd); } free(ptr); } else { result = FAIL; DEBUG_ERROR("New firmware open error.\n"); } } else { if (strlen(file->d_name) >= 3) { result = FAIL; DEBUG_ERROR("File name error.\n"); } else { DEBUG_ERROR("Searching file.\n"); } } } closedir(dir); } else { result = FAIL; DEBUG_ERROR("/mnt does not valid.\n"); } return result; } //=============================================== // Check RFID is match with start user //=============================================== bool isMatchStartUser(void) { uint8_t tmpUser[32]; uint8_t isPrintLogOut = OFF; bool _matchFlag = FALSE; if (ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian) { // Big endian switch (rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char*) tmpUser, "%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5]); break; case RFID_SN_TYPE_7BYTE: sprintf((char*) tmpUser, "%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6]); break; case RFID_SN_TYPE_8BYTE: sprintf((char *) tmpUser, "%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6], rfid.currentCard[7]); break; case RFID_SN_TYPE_10BYTE: sprintf((char*) tmpUser, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6], rfid.currentCard[7], rfid.currentCard[8], rfid.currentCard[9]); break; case RFID_SN_TYPE_4BYTE: default: sprintf((char*) tmpUser, "%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3]); break; } } else { // Little endian switch (rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char*) tmpUser, "%02X%02X%02X%02X%02X%02X", rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_7BYTE: sprintf((char*) tmpUser, "%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_8BYTE: sprintf((char *) tmpUser, "%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[7], rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_10BYTE: sprintf((char*) tmpUser, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[9], rfid.currentCard[8], rfid.currentCard[7], rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_4BYTE: default: sprintf((char*) tmpUser, "%02X%02X%02X%02X", rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; } } //lwtest for (uint8_t index = 0; index < modelnameInfo.GetGunCount; index++) { DEBUG_INFO("Gun %d start SN compare [%s] \n", index, getTargetChargingInfoData(index)->StartUserId); if (strcmp((char*) tmpUser, (char*) getTargetChargingInfoData(index)->StartUserId) == 0) { _matchFlag = YES; ShmCharger->gun_selectd = index; break; } } if (isPrintLogOut == OFF) { if (_matchFlag == YES) //lwtest { DEBUG_INFO("==== isMatchStartUser(gun %d) ==== \n", ShmCharger->gun_selectd); DEBUG_INFO("tmpUser : %s \n", tmpUser); DEBUG_INFO("StartUserId : %s \n", getTargetChargingInfoData(ShmCharger->gun_selectd)->StartUserId); DEBUG_INFO("========================== \n"); } else DEBUG_INFO("==== Start Card SN none match ==== \n"); isPrintLogOut = ON; } return _matchFlag; } bool isMatchPresentUser() { uint8_t tmpUser[32]; uint8_t isPrintLogOut = OFF; bool _matchFlag = FALSE; if (ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian) { // Big endian switch (rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char*) tmpUser, "%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5]); break; case RFID_SN_TYPE_7BYTE: sprintf((char*) tmpUser, "%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6]); break; case RFID_SN_TYPE_8BYTE: sprintf((char *) tmpUser, "%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6], rfid.currentCard[7]); break; case RFID_SN_TYPE_10BYTE: sprintf((char*) tmpUser, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6], rfid.currentCard[7], rfid.currentCard[8], rfid.currentCard[9]); break; case RFID_SN_TYPE_4BYTE: default: sprintf((char*) tmpUser, "%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3]); break; } } else { // Little endian switch (rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char*) tmpUser, "%02X%02X%02X%02X%02X%02X", rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_7BYTE: sprintf((char*) tmpUser, "%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_8BYTE: sprintf((char *) tmpUser, "%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[7], rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_10BYTE: sprintf((char*) tmpUser, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[9], rfid.currentCard[8], rfid.currentCard[7], rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_4BYTE: default: sprintf((char*) tmpUser, "%02X%02X%02X%02X", rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; } } //lwtest //compare with SN card if already authoraized but not entry the charging session. for (uint8_t index = 0; index < modelnameInfo.GetGunCount; index++) { DEBUG_INFO("Gun %d present SN compare [%s] \n", index, ShmCharger->gun_info[index].AuthAcceptUserId); if (strcmp((char*) tmpUser, (char*) ShmCharger->gun_info[index].AuthAcceptUserId) == 0) { _matchFlag = TRUE; ShmCharger->gun_selectd = index; break; } } if (isPrintLogOut == OFF) { if (_matchFlag == YES) { DEBUG_INFO("==== isMatchPresentUser (%d)==== \n", ShmCharger->gun_selectd); DEBUG_INFO("tmpUser : %s \n", tmpUser); DEBUG_INFO("UserId : %s \n", ShmCharger->gun_info[ShmCharger->gun_selectd].AuthAcceptUserId); DEBUG_INFO("============================ \n"); isPrintLogOut = ON; } else DEBUG_INFO("==== Present Card SN none match ==== \n"); } return _matchFlag; } //=============================================== // Check RFID is need to authorize .. lwtest //=============================================== bool isNeedToAuth(void) { bool result = FALSE; for (uint8_t index = 0; index < modelnameInfo.GetGunCount; index++) { if (getTargetChargingInfoData(index)->SystemStatus == SYS_MODE_IDLE) { result = TRUE; DEBUG_INFO("Need to Authorize (gun %d)\n", index); break; } } return result; } //=============================================== // Read RFID Serial Number //=============================================== int GetCardSerialNumber() { int isSuccess = FAIL; int module_type = MODULE_EWT; if (getRequestCardSN(rfidFd, module_type, &rfid)) { if (rfid.cardType == ISO14443A) { if (rfid.snType == RFID_SN_TYPE_4BYTE) { isSuccess = PASS; } else if (rfid.snType == RFID_SN_TYPE_7BYTE) { isSuccess = PASS; } sethaltCard(rfidFd, module_type); } else if (rfid.cardType == IS014443B) { isSuccess = PASS; } else if (rfid.cardType == FELICA) { isSuccess = PASS; } else { } } else { } return isSuccess; } //=============================================== // Set led motion //=============================================== void setLedMotion(unsigned char gun_index, unsigned char led_mode) { //lwtest if (ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_OUTPUT_TYPE] != 'A') return; switch (led_mode) { case LED_ACTION_INIT: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_INIT; break; case LED_ACTION_IDLE: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_IDLE; break; case LED_ACTION_AUTHED: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_AUTHED; break; case LED_ACTION_CONNECTED: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_CONNECTED; break; case LED_ACTION_CHARGING: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_CHARGING; break; case LED_ACTION_STOP: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_STOP; break; case LED_ACTION_ALARM: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_ALARM; break; case LED_ACTION_MAINTAIN: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_MAINTAIN; break; case LED_ACTION_RFID_PASS: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_RFID_PASS; break; case LED_ACTION_RFID_FAIL: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_RFID_FAIL; break; case LED_ACTION_BLE_CONNECT: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_BLE_CONNECT; break; case LED_ACTION_BLE_DISABLE: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_BLE_DISABLE; break; case LED_ACTION_DEBUG: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_DEBUG; break; case LED_ACTION_ALL_OFF: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_ALL_OFF; break; case LED_RELAY_ON: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_RELAY_ON; break; case LED_RELAY_OFF: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_RELAY_OFF; break; case LED_ACTION_HANDSHAKE_FAIL: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_HANDSHAKE_FAIL; break; case LED_ACTION_INTERNET_DISCONNECT: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_INTERNET_DISCONNECT; break; case LED_ACTION_RESTORE_SETTING: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_RESTORE_SETTING; break; case LED_ACTION_IDLE_BACKEND_CONNECTED: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_IDLE_BACKEND_CONNECTED; break; case LED_ACTION_IDLE_BACKEND_CONNECTED_SLEEP: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_IDLE_BACKEND_CONNECTED_SLEEP; break; case LED_ACTION_IDLE_BACKEND_DISCONNECTED: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_IDLE_BACKEND_DISCONNECTED; break; case LED_ACTION_IDLE_BACKEND_DISCONNECTED_SLEEP: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_IDLE_BACKEND_DISCONNECTED_SLEEP; break; case LED_ACTION_RESERVATION_MODE: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_RESERVATION_MODE; break; } } //=============================================== // Request on/off set //=============================================== void setRequest(unsigned char gun_index, unsigned char isOn) { if (isOn == ON) { if (ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest == OFF) { ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest = ON; DEBUG_INFO("Gun-%d permission request: ON \n", gun_index); } } else { if (ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest == ON) { ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest = OFF; DEBUG_INFO("Gun-%d permission request: OFF \n", gun_index); } } } //=============================================== // Request on/off get //=============================================== int getRequest(unsigned char gun_index) { return ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest; } //=============================================== // Relay on/off set //=============================================== void setRelay(unsigned char gun_index, unsigned char isOn) { if (isOn == ON) { if (ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn == OFF) { switch (ShmCharger->gun_info[gun_index].chargingMode) { case CHARGING_MODE_BS: case CHARGING_MODE_HLC: ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn = ON; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0] = 0x01; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1] = 0x01; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2] = 0x01; if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) DEBUG_INFO("Gun-%d Output relay status: ON. [CHARGING_MODE_BS] \n", gun_index); else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) DEBUG_INFO("Gun-%d Output relay status: ON. [CHARGING_MODE_HLC] \n", gun_index); break; case CHARGING_MODE_SOCKETE: ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn = ON; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][3] = 0x01; DEBUG_INFO("Gun-%d Output relay status: ON. [CHARGING_MODE_SOCKETE] \n", gun_index); break; default: ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn = ON; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0] = 0x01; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1] = 0x01; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2] = 0x01; DEBUG_INFO("Gun-%d Output relay status: ON. [DEFFAULT] \n", gun_index); break; } } } else { if (ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn == ON) { switch (ShmCharger->gun_info[gun_index].chargingMode) { case CHARGING_MODE_BS: case CHARGING_MODE_HLC: ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn = OFF; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0] = 0; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1] = 0; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2] = 0; if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) DEBUG_INFO("Gun-%d Output relay status: OFF. [CHARGING_MODE_BS] \n", gun_index); else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) DEBUG_INFO("Gun-%d Output relay status: OFF. [CHARGING_MODE_HLC] \n", gun_index); break; case CHARGING_MODE_SOCKETE: ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn = OFF; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][3] = 0; DEBUG_INFO("Gun-%d Output relay status: OFF. [CHARGING_MODE_SOCKETE] \n", gun_index); break; default: ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn = OFF; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0] = 0; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1] = 0; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2] = 0; DEBUG_INFO("Gun-%d Output relay status: OFF. [DEFFAULT] \n", gun_index); break; } } } } //=============================================== // Relay on/off get //=============================================== int getRelay(unsigned char gun_index) { return ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn; } //=============================================== // Set speaker on/off request //=============================================== void setSpeaker(unsigned char isOn, unsigned char speaker_mode) { //lwtest if (ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_OUTPUT_TYPE] != 'A') return; if (isOn == ON) { ShmCharger->isSpeakerOn = ON; ShmCharger->speaker_type = speaker_mode; } } //=============================================== // Initialization RFID communication port //=============================================== int InitRfidPort() { int uartO2 = open(rfidPortName, O_RDWR); struct termios tios; if (uartO2 != FAIL) { ioctl(uartO2, TCGETS, &tios); tios.c_cflag = B19200 | CS8 | CLOCAL | CREAD; tios.c_lflag = 0; tios.c_iflag = 0; tios.c_oflag = 0; tios.c_cc[VMIN] = 0; tios.c_cc[VTIME] = (unsigned char) 1; tios.c_lflag = 0; tcflush(uartO2, TCIFLUSH); ioctl(uartO2, TCSETS, &tios); } if (uartO2 < 0) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RfidModuleCommFail = 1; } return uartO2; } //=============================================== // Check internet access status //=============================================== int isReachableInternet() { int result = FAIL; FILE *fp; char cmd[256]; char buf[512]; char tmp[512]; // Get ip address & net mask strcpy(cmd, "ifconfig eth0"); fp = popen(cmd, "r"); if (fp != NULL) { while (fgets(buf, sizeof(buf), fp) != NULL) { if (strstr(buf, "inet addr:") > 0) { sscanf(buf, "%*s%s", tmp); substr((char*) ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, tmp, strspn(tmp, "addr:"), strlen(tmp) - strspn(tmp, "addr:")); sscanf(buf, "%*s%*s%*s%s", tmp); substr((char*) ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress, tmp, strspn(tmp, "Mask:"), strlen(tmp) - strspn(tmp, "Mask:")); } } } pclose(fp); memset(buf, 0x00, sizeof(buf)); // Get gateway fp = popen("ip route", "r"); if (fp == NULL) result = FAIL; else { while (fgets(buf, sizeof(buf), fp) != NULL) { if ((strstr(buf, "default") != NULL) && (strstr(buf, "eth0") != NULL)) break; } if (strstr(buf, "default") != NULL) { sscanf(buf, "%*s%*s%s", tmp); substr((char*) ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress, tmp, 0, strlen(tmp)); } } pclose(fp); memset(buf, 0x00, sizeof(buf)); for (int idx = 0; idx < ARRAY_SIZE(valid_Internet); idx++) { sprintf(cmd, "ping -c 1 -w 3 -I eth0 %s", valid_Internet[idx]); fp = popen(cmd, "r"); if (fp != NULL) { while (fgets(buf, sizeof(buf), fp) != NULL) { if (strstr(buf, "transmitted") > 0) { //sscanf(buf, "%*s%*s%*s%*s%*s%*s%s", tmp); if (strstr(buf, "100%") != NULL) { } else { result = PASS; } //DEBUG_INFO("%s",buf); //DEBUG_INFO("%s\n",tmp); } } } pclose(fp); } return result; } int isRouteFail() { int result = YES; FILE *fp; char buf[512]; fp = popen("route -n", "r"); if (fp != NULL) { while (fgets(buf, sizeof(buf), fp) != NULL) { if (strstr(buf, "eth0") != NULL) result = NO; } } pclose(fp); return result; } //=============================================== // Check reservation date is expired //=============================================== int isReservationExpired(unsigned char gun_index) { int result = NO; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (isOvertNow(ShmOCPP16Data->ReserveNow[gun_index].ExpiryDate)) result = YES; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (isOvertNow(ShmOCPP20Data->ReserveNow[gun_index].expiryDateTime)) result = YES; } return result; } //=============================================== // Check charging profile related date routine //=============================================== int isProfileValid(uint8_t gun_index) { int result = NO; struct tm tmFrom, tmTo; struct timeb tbFrom, tbTo; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if ((sscanf((char*) ShmOCPP16Data->SmartChargingProfile[gun_index].ValidFrom, "%4d-%2d-%2dT%2d:%2d:%2d", &tmFrom.tm_year, &tmFrom.tm_mon, &tmFrom.tm_mday, &tmFrom.tm_hour, &tmFrom.tm_min, &tmFrom.tm_sec) == 6) && (sscanf((char*) ShmOCPP16Data->SmartChargingProfile[gun_index].ValidTo, "%4d-%2d-%2dT%2d:%2d:%2d", &tmTo.tm_year, &tmTo.tm_mon, &tmTo.tm_mday, &tmTo.tm_hour, &tmTo.tm_min, &tmTo.tm_sec) == 6)) { tmFrom.tm_year -= 1900; tmFrom.tm_mon -= 1; tbFrom.time = mktime(&tmFrom); tmTo.tm_year -= 1900; tmTo.tm_mon -= 1; tbTo.time = mktime(&tmTo); DEBUG_INFO("Valid from compare Now: %d\n", DiffTimebWithNow(tbFrom)); DEBUG_INFO("Valid to compare Now: %d\n", DiffTimebWithNow(tbTo)); if ((DiffTimebWithNow(tbFrom) >= 0) && (DiffTimebWithNow(tbTo) <= 0)) { result = YES; } } else { DEBUG_WARN("ValidFrom or ValidTo date parsing error.\n"); } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if ((sscanf((char*) ShmOCPP20Data->SmartChargingProfile[gun_index].validFrom, "%4d-%2d-%2dT%2d:%2d:%2d", &tmFrom.tm_year, &tmFrom.tm_mon, &tmFrom.tm_mday, &tmFrom.tm_hour, &tmFrom.tm_min, &tmFrom.tm_sec) == 6) && (sscanf((char*) ShmOCPP20Data->SmartChargingProfile[gun_index].validTo, "%4d-%2d-%2dT%2d:%2d:%2d", &tmTo.tm_year, &tmTo.tm_mon, &tmTo.tm_mday, &tmTo.tm_hour, &tmTo.tm_min, &tmTo.tm_sec) == 6)) { tmFrom.tm_year -= 1900; tmFrom.tm_mon -= 1; tbFrom.time = mktime(&tmFrom); tmTo.tm_year -= 1900; tmTo.tm_mon -= 1; tbTo.time = mktime(&tmTo); DEBUG_INFO("Valid from compare Now: %d\n", DiffTimebWithNow(tbFrom)); DEBUG_INFO("Valid to compare Now: %d\n", DiffTimebWithNow(tbTo)); if ((DiffTimebWithNow(tbFrom) >= 0) && (DiffTimebWithNow(tbTo) <= 0)) { result = YES; } } else { DEBUG_WARN("ValidFrom or ValidTo date parsing error.\n"); } } return result; } int getMaxScheduleStart() { int result = -1; struct tm tmScheduleStart; struct timeb tbScheduleStart; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if ((sscanf((char*) ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.StartSchedule, "%4d-%2d-%2dT%2d:%2d:%2d", &tmScheduleStart.tm_year, &tmScheduleStart.tm_mon, &tmScheduleStart.tm_mday, &tmScheduleStart.tm_hour, &tmScheduleStart.tm_min, &tmScheduleStart.tm_sec) == 6)) { tmScheduleStart.tm_year -= 1900; tmScheduleStart.tm_mon -= 1; tbScheduleStart.time = mktime(&tmScheduleStart); tbScheduleStart.millitm = 0; result = DiffTimebWithNow(tbScheduleStart) / 1000; //DEBUG_INFO("Max schedule start compare Now(seconds): %d\n", result); } else { DEBUG_WARN("Max schedule start date parsing error.\n"); } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if ((sscanf((char*) ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].startSchedule, "%4d-%2d-%2dT%2d:%2d:%2d", &tmScheduleStart.tm_year, &tmScheduleStart.tm_mon, &tmScheduleStart.tm_mday, &tmScheduleStart.tm_hour, &tmScheduleStart.tm_min, &tmScheduleStart.tm_sec) == 6)) { tmScheduleStart.tm_year -= 1900; tmScheduleStart.tm_mon -= 1; tbScheduleStart.time = mktime(&tmScheduleStart); tbScheduleStart.millitm = 0; result = DiffTimebWithNow(tbScheduleStart) / 1000; //DEBUG_INFO("Max schedule start compare Now(seconds): %d\n", result); } else { DEBUG_WARN("Max schedule start date parsing error.\n"); } } return result; } int getScheduleStart(int gun_index) { int result = -1; struct tm tmScheduleStart; struct timeb tbScheduleStart; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if ((sscanf((char*) ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.StartSchedule, "%4d-%2d-%2dT%2d:%2d:%2d", &tmScheduleStart.tm_year, &tmScheduleStart.tm_mon, &tmScheduleStart.tm_mday, &tmScheduleStart.tm_hour, &tmScheduleStart.tm_min, &tmScheduleStart.tm_sec) == 6)) { tmScheduleStart.tm_year -= 1900; tmScheduleStart.tm_mon -= 1; tbScheduleStart.time = mktime(&tmScheduleStart); tbScheduleStart.millitm = 0; result = DiffTimebWithNow(tbScheduleStart) / 1000; //DEBUG_INFO("Schedule start compare Now(seconds): %d\n", result); } else { DEBUG_WARN("Schedule start date parsing error.\n"); } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if ((sscanf((char*) ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].startSchedule, "%4d-%2d-%2dT%2d:%2d:%2d", &tmScheduleStart.tm_year, &tmScheduleStart.tm_mon, &tmScheduleStart.tm_mday, &tmScheduleStart.tm_hour, &tmScheduleStart.tm_min, &tmScheduleStart.tm_sec) == 6)) { tmScheduleStart.tm_year -= 1900; tmScheduleStart.tm_mon -= 1; tbScheduleStart.time = mktime(&tmScheduleStart); tbScheduleStart.millitm = 0; result = DiffTimebWithNow(tbScheduleStart) / 1000; //DEBUG_INFO("Schedule start compare Now(seconds): %d\n", result); } else { DEBUG_WARN("Schedule start date parsing error.\n"); } } return result; } int getStartSinceToday() { int result = -1; time_t t; struct tm *tmStartToday; struct timeb tbStartToday; t = time(NULL); tmStartToday = localtime(&t); tmStartToday->tm_hour = 0; tmStartToday->tm_min = 0; tmStartToday->tm_sec = 0; tbStartToday.time = mktime(tmStartToday); result = DiffTimebWithNow(tbStartToday) / 1000; //DEBUG_INFO("Start today compare Now(seconds): %d\n", result); return result; } int getStartSinceWeek() { int result = -1; time_t t; struct tm *tmStartWeek; struct timeb tbStartWeek; t = time(NULL); tmStartWeek = localtime(&t); t -= 86400 * tmStartWeek->tm_wday; tmStartWeek = localtime(&t); tmStartWeek->tm_hour = 0; tmStartWeek->tm_min = 0; tmStartWeek->tm_sec = 0; tbStartWeek.time = mktime(tmStartWeek); result = DiffTimebWithNow(tbStartWeek) / 1000; //DEBUG_INFO("Start week compare Now(seconds): %d\n", result); return result; } //=============================================== // Valid from local white list //=============================================== int isValidLocalWhiteCard() { uint8_t result = FAIL; for (uint8_t idx = 0; idx < ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.LocalWhiteCard); idx++) { if (strcmp((char*) ShmSysConfigAndInfo->SysConfig.UserId, (char*) ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[idx]) == 0) { result = PASS; } } return result; } //========================================== // Check routine //========================================== void checkTask() { //lwtest if ((ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'D')) { if (system("pidof -s Module_4g > /dev/null") != 0) { DEBUG_INFO("Module_4g not running, restart it.\n"); system("/root/Module_4g &"); } } if ((ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE] == 'D')) { if (system("pidof -s Module_Wifi > /dev/null") != 0) { DEBUG_INFO("Module_Wifi not running, restart it.\n"); system("/root/Module_Wifi &"); } } if (system("pidof -s Module_EventLogging > /dev/null") != 0) { DEBUG_INFO("Module_EventLogging not running, restart it.\n"); system("/root/Module_EventLogging &"); } if ((strcmp((char *) &ShmSysConfigAndInfo->SysConfig.OcppServerURL, "") != 0)) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if ((time((time_t*) NULL) - ShmOCPP16Data->procDogTime) > 180) { DEBUG_WARN("OcppBackend watch dog timeout task restart.\n"); ShmOCPP16Data->procDogTime = time((time_t*) NULL); system("pkill OcppBackend"); sleep(3); ocpp_process_start(); } if (system("pidof -s OcppBackend > /dev/null") != 0) { DEBUG_INFO("OcppBackend not running, restart it.\n"); ocpp_process_start(); } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if ((time((time_t*) NULL) - ShmOCPP20Data->procDogTime) > 180) { DEBUG_WARN("OcppBackend20 watch dog timeout task restart.\n"); ShmOCPP20Data->procDogTime = time((time_t*) NULL); system("pkill OcppBackend20"); sleep(3); ocpp_process_start(); } if (system("pidof -s OcppBackend20 > /dev/null") != 0) { DEBUG_INFO("OcppBackend20 not running, restart it.\n"); ocpp_process_start(); } } } if (strcmp((char *) &ShmSysConfigAndInfo->SysConfig.MaintainServerURL, "") != 0) { if (system("pidof -s OcppBackendPH > /dev/null") != 0) { DEBUG_INFO("OcppBackendPH not running, restart it.\n"); system("/root/OcppBackendPH &"); } } //lwtest if (ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_OUTPUT_TYPE] == 'A') { if (system("pidof -s Module_Speaker > /dev/null") != 0) { DEBUG_INFO("Module_Speaker not running, restart it.\n"); system("/root/Module_Speaker &"); } } if (system("pidof -s Module_ProduceUtils > /dev/null") != 0) { DEBUG_INFO("Module_ProduceUtils not running, restart it.\n"); system("/root/Module_ProduceUtils &"); } } //=============================================== // Check simulator status ..lwtest //=============================================== bool isTwoGunInChargingMode(void) { bool result = FALSE; if (modelnameInfo.GetGunCount < 2) result = FALSE; else { if (getTargetChargingInfoData(0)->SystemStatus == SYS_MODE_CHARGING && getTargetChargingInfoData(1)->SystemStatus == SYS_MODE_CHARGING) result = TRUE; } return result; } void checkConnectionTimeout() { if ((system("pidof -s OcppBackend > /dev/null") != 0) && (system("pidof -s OcppBackend20 > /dev/null") != 0)) { ShmCharger->timeoutSpec.Present_Timeout_Spec = TIMEOUT_SPEC_HANDSHAKING; //DEBUG_INFO("Handshaking timeout specification follow by initial setting : %d s \n", TIMEOUT_SPEC_HANDSHAKING); } else { ShmCharger->timeoutSpec.Setting_Timeout_Spec = ocpp_get_connection_timeout(); if ((ShmCharger->timeoutSpec.Setting_Timeout_Spec) < TIMEOUT_SPEC_BS_HLC_HANDSHAKE) { ShmCharger->timeoutSpec.Present_Timeout_Spec = (TIMEOUT_SPEC_BS_HLC_HANDSHAKE + 10); //DEBUG_INFO("Handshaking timeout specification follow by OCPP Configuration : Fail. Value can't be zero or less than zero.\n."); } else { ShmCharger->timeoutSpec.Present_Timeout_Spec = ShmCharger->timeoutSpec.Setting_Timeout_Spec; //DEBUG_INFO("Handshaking timeout specification follow by OCPP Configuration : Pass...\n."); } //DEBUG_INFO("Handshaking timeout specification follow by OCPP Configuration : %s s \n.",ShmOCPP16Data->ConfigurationTable.CoreProfile[ConnectionTimeOut].ItemData); } } void checkReset() { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->MsMsg.bits.ResetReq) { if ((!isMode(0, SYS_MODE_CHARGING) && !isMode(0, SYS_MODE_TERMINATING) && !isMode(0, SYS_MODE_COMPLETE)) && (modelnameInfo.GetGunCount > 1 ? (!isMode(1, SYS_MODE_CHARGING) && !isMode(1, SYS_MODE_TERMINATING) && !isMode(1, SYS_MODE_COMPLETE)) : TRUE)) { ShmOCPP16Data->MsMsg.bits.ResetReq = OFF; sprintf((char*) ShmOCPP16Data->Reset.ResponseStatus, "Accepted"); ShmOCPP16Data->MsMsg.bits.ResetConf = ON; DEBUG_INFO("%s reset request by OCPP.\n", ShmOCPP16Data->Reset.Type); for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) setChargerMode(gun_index, SYS_MODE_BOOTING); if (strcmp((char*) ShmOCPP16Data->Reset.Type, "Hard") == 0) { system("sync"); sleep(10); system("reboot -f"); sleep(10); system("reboot -f"); } else { sleep(10); close(wtdFd); system("/usr/bin/run_evse_restart.sh"); } } } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->MsMsg.bits.ResetReq) { if ((!isMode(0, SYS_MODE_CHARGING) && !isMode(0, SYS_MODE_TERMINATING) && !isMode(0, SYS_MODE_COMPLETE)) && (modelnameInfo.GetGunCount > 1 ? (!isMode(1, SYS_MODE_CHARGING) && !isMode(1, SYS_MODE_TERMINATING) && !isMode(0, SYS_MODE_COMPLETE)) : TRUE)) { ShmOCPP20Data->MsMsg.bits.ResetReq = OFF; sprintf((char*) ShmOCPP20Data->Reset.Response_status, "Accepted"); ShmOCPP20Data->MsMsg.bits.ResetConf = ON; DEBUG_INFO("%s reset request by OCPP.\n", ShmOCPP20Data->Reset.type); for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) setChargerMode(gun_index, SYS_MODE_BOOTING); if (strcmp((char*) ShmOCPP20Data->Reset.type, "Immediate") == 0) { system("sync"); sleep(10); system("reboot -f"); sleep(10); system("reboot -f"); } else { sleep(10); close(wtdFd); system("/usr/bin/run_evse_restart.sh"); } } } } } void checkReservation(uint8_t gun_index) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowReq) { ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowReq = OFF; ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowConf = ON; if (isMode(gun_index, SYS_MODE_IDLE) && !isReservationExpired(gun_index)) { sleep(5); getTargetChargingInfoData(gun_index)->ReservationId = ShmOCPP16Data->ReserveNow[gun_index].ReservationId; setChargerMode(gun_index, SYS_MODE_RESERVATION); } DEBUG_INFO("Reservation request on gun-%d.\n", gun_index); } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowReq) { ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowReq = OFF; ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowConf = ON; if (isMode(gun_index, SYS_MODE_IDLE) && !isReservationExpired(gun_index)) { getTargetChargingInfoData(gun_index)->ReservationId = ShmOCPP20Data->ReserveNow[gun_index].id; setChargerMode(gun_index, SYS_MODE_RESERVATION); } DEBUG_INFO("Reservation request on gun-%d.\n", gun_index); } } } void checkUnlocker(uint8_t gun_index) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CsMsg.bits[gun_index].UnlockConnectorReq == ON) { ShmOCPP16Data->CsMsg.bits[gun_index].UnlockConnectorReq = OFF; sprintf( (char*) ShmOCPP16Data->UnlockConnector[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId - 1].ResponseStatus, "Unlocked"); ShmOCPP16Data->CsMsg.bits[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId - 1].UnlockConnectorConf = ON; ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId - 1].isUnlockerConnetor = ON; } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CsMsg.bits[gun_index].UnlockConnectorReq == ON) { ShmOCPP20Data->CsMsg.bits[gun_index].UnlockConnectorReq = OFF; sprintf((char*) ShmOCPP20Data->UnlockConnector[ShmOCPP20Data->UnlockConnector[gun_index].connectorId - 1].Response_status, "UnlockFailed"); ShmOCPP20Data->CsMsg.bits[ShmOCPP20Data->UnlockConnector[gun_index].connectorId - 1].UnlockConnectorConf = ON; ShmCharger->gun_info[ShmOCPP20Data->UnlockConnector[gun_index].connectorId - 1].isUnlockerConnetor = ON; } } } void checkAvailability(uint8_t gun_index) { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CsMsg.bits[gun_index].ChangeAvailabilityReq) { if (strcmp((char*) ShmOCPP16Data->ChangeAvailability[gun_index].Type, "Operative") == 0) { DB_Update_Operactive(localDb, gun_index, true); ShmCharger->gun_info[gun_index].isOperactive = DB_Get_Operactive(localDb, gun_index); } else { DB_Update_Operactive(localDb, gun_index, false); ShmCharger->gun_info[gun_index].isOperactive = DB_Get_Operactive(localDb, gun_index); } ShmOCPP16Data->CsMsg.bits[gun_index].ChangeAvailabilityReq = OFF; } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CsMsg.bits[gun_index].ChangeAvailabilityReq) { if (strcmp((char*) ShmOCPP20Data->ChangeAvailability[gun_index].operationalStatus, "Operative") == 0) { DB_Update_Operactive(localDb, gun_index, true); ShmCharger->gun_info[gun_index].isOperactive = DB_Get_Operactive(localDb, gun_index); } else { DB_Update_Operactive(localDb, gun_index, false); ShmCharger->gun_info[gun_index].isOperactive = DB_Get_Operactive(localDb, gun_index); } ShmOCPP20Data->CsMsg.bits[gun_index].ChangeAvailabilityReq = OFF; } } } void checkChargingProfileLimit(uint8_t gun_index, uint8_t system_mode) { uint16_t MaxChargingProfileChargingCurrent = ShmSysConfigAndInfo->SysConfig.RatingCurrent; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { // Get profile charging profile limit if ((ocpp_get_smartcharging_profileId(gun_index) > 0)) { // Checking profile kind if ((mystrcmp((char*) ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileKind, "Absolute") == PASS)) { // Checking limitation for (uint8_t idx_period = 0; idx_period < ARRAY_SIZE(ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod); idx_period++) { if ((getScheduleStart(gun_index) >= ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) && ((idx_period == 0) || (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod > 0))) { //lwtest ShmCharger->gun_info[gun_index].ChargingProfilePower = AC_OUTPUT_VOL * ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit * ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].NumberPhases; ShmCharger->gun_info[gun_index].ChargingProfileCurrent = ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit; ShmCharger->gun_info[gun_index].targetCurrent = ShmCharger->gun_info[gun_index].ChargingProfileCurrent; } else break; } } } else { //lwtest if (isTwoGunInChargingMode()) ShmCharger->gun_info[gun_index].targetCurrent = ShmSysConfigAndInfo->SysConfig.RatingCurrent * 0.5; else ShmCharger->gun_info[gun_index].targetCurrent = ShmSysConfigAndInfo->SysConfig.RatingCurrent; //printf("Gun %d charging targetCurrent %d\n", gun_index, ShmCharger->gun_info[gun_index].targetCurrent); } // Get max charging profile limit if ((ocpp_get_maxcharging_profileId() > 0)) { // Absolute profile if ((mystrcmp((char*) ShmOCPP16Data->MaxChargingProfile.ChargingProfileKind, "Absolute") == PASS)) { for (uint8_t idx_period = 0; idx_period < ARRAY_SIZE(ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod); idx_period++) { if ((getMaxScheduleStart() >= ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) && ((idx_period == 0) || (ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod > 0))) { //lwtest MaxChargingProfileChargingCurrent = ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit; // printf("Gun %d Get Max Profile limit = %.2f\n", gun_index, // ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit); } else break; } } } // Compare target current is over max current for EVSE limit //lwtest if (isTwoGunInChargingMode() == FALSE) { //AC type or only one connector in charging if (ShmCharger->gun_info[gun_index].targetCurrent > MaxChargingProfileChargingCurrent) ShmCharger->gun_info[gun_index].targetCurrent = MaxChargingProfileChargingCurrent; } else { uint8_t _otherIndex = 0; _otherIndex = (gun_index > 0) ? 0 : 1; if ((ShmCharger->gun_info[_otherIndex].targetCurrent + ShmCharger->gun_info[gun_index].targetCurrent) > MaxChargingProfileChargingCurrent) { ShmCharger->gun_info[gun_index].targetCurrent = (MaxChargingProfileChargingCurrent - ShmCharger->gun_info[_otherIndex].targetCurrent); } } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { // Get profile charging profile limit if ((ocpp_get_smartcharging_profileId(gun_index) > 0)) { // Checking profile kind if ((mystrcmp((char*) ShmOCPP20Data->SmartChargingProfile[gun_index].chargingProfileKind, "Absolute") == PASS)) { // Checking limitation for (uint8_t idx_period = 0; idx_period < ARRAY_SIZE(ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod); idx_period++) { if ((getScheduleStart(gun_index) >= ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod) && ((idx_period == 0) || (ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod > 0))) { ShmCharger->gun_info[gun_index].ChargingProfilePower = AC_OUTPUT_VOL * ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit * ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].numberPhases; ShmCharger->gun_info[gun_index].ChargingProfileCurrent = ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit; ShmCharger->gun_info[gun_index].targetCurrent = ShmCharger->gun_info[gun_index].ChargingProfileCurrent; } else break; } } } else { //lwtest if (isTwoGunInChargingMode()) ShmCharger->gun_info[gun_index].targetCurrent = ShmSysConfigAndInfo->SysConfig.RatingCurrent * 0.5; else ShmCharger->gun_info[gun_index].targetCurrent = ShmSysConfigAndInfo->SysConfig.RatingCurrent; } // Get max charging profile limit if ((ocpp_get_maxcharging_profileId() > 0)) { // Absolute profile if ((mystrcmp((char*) ShmOCPP20Data->MaxChargingProfile.chargingProfileKind, "Absolute") == PASS)) { // Checking limitation for (uint8_t idx_period = 0; idx_period < ARRAY_SIZE(ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod); idx_period++) { if ((getMaxScheduleStart() >= ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod) && ((idx_period == 0) || (ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod > 0))) { //lwtest MaxChargingProfileChargingCurrent = ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].limit; } else break; } } } // Compare target current is over max current for EVSE limit //lwtest if (isTwoGunInChargingMode() == FALSE) { //AC type or only one connector in charging if (ShmCharger->gun_info[gun_index].targetCurrent > MaxChargingProfileChargingCurrent) ShmCharger->gun_info[gun_index].targetCurrent = MaxChargingProfileChargingCurrent; } else { uint8_t _otherIndex = 0; _otherIndex = (gun_index > 0) ? 0 : 1; if ((ShmCharger->gun_info[_otherIndex].targetCurrent + ShmCharger->gun_info[gun_index].targetCurrent) > MaxChargingProfileChargingCurrent) { ShmCharger->gun_info[gun_index].targetCurrent = (MaxChargingProfileChargingCurrent - ShmCharger->gun_info[_otherIndex].targetCurrent); } } } // Charging session target current check if OCPP disconnect and power sharing server connected if (ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharing > 0) { if (ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer) ShmCharger->gun_info[gun_index].targetCurrent = ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent[gun_index] > ShmSysConfigAndInfo->SysConfig.RatingCurrent ? ShmSysConfigAndInfo->SysConfig.RatingCurrent : ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent[gun_index]; else { if (ShmCharger->gun_info[gun_index].targetCurrent != 0) DEBUG_WARN("Disconnect from power sharing server, target current set to 0.\n"); ShmCharger->gun_info[gun_index].targetCurrent = 0; } } switch (system_mode) { case SYS_MODE_IDLE: if (ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.RatingCurrent) ? ShmSysConfigAndInfo->SysConfig.RatingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); if (ShmCharger->isCcsEnable) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_5; } else { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.RatingCurrent) ? ShmSysConfigAndInfo->SysConfig.RatingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5) ? 6 : ((ShmCharger->gun_info[gun_index].targetCurrent == 0) ? 100 : ShmCharger->gun_info[gun_index].targetCurrent)); } } else { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent) ? ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); if (ShmCharger->isCcsEnable) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_5; } else { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent) ? ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5) ? 6 : ((ShmCharger->gun_info[gun_index].targetCurrent == 0) ? 100 : ShmCharger->gun_info[gun_index].targetCurrent)); } } ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; break; case SYS_MODE_PREPARING: if (ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.RatingCurrent) ? ShmSysConfigAndInfo->SysConfig.RatingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.RatingCurrent) ? ShmSysConfigAndInfo->SysConfig.RatingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5) ? 6 : ( (ShmCharger->gun_info[gun_index].targetCurrent == 0) ? 100 : ShmCharger->gun_info[gun_index].targetCurrent)); } else { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent) ? ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent) ? ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5) ? 6 : ( (ShmCharger->gun_info[gun_index].targetCurrent == 0) ? 100 : ShmCharger->gun_info[gun_index].targetCurrent)); } ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; break; case SYS_MODE_CHARGING: case SYS_MODE_TERMINATING: if (ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.RatingCurrent) ? ShmSysConfigAndInfo->SysConfig.RatingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); if ((ShmCharger->gun_info[gun_index].targetCurrent != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current) || (ShmCharger->gun_info[gun_index].primaryMcuState.current_limit != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current)) { if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { if (getDiffSecNow(startTime[gun_index][TMR_IDX_PWN_CHANGE]) > TIMEOUT_SPEC_PWN_CHANGE) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.RatingCurrent) ? ShmSysConfigAndInfo->SysConfig.RatingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5) ? 6 : ((ShmCharger->gun_info[gun_index].targetCurrent == 0) ? 100 : ShmCharger->gun_info[gun_index].targetCurrent)); ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; refreshStartTimer(&startTime[gun_index][TMR_IDX_PWN_CHANGE]); } } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.RatingCurrent) ? ShmSysConfigAndInfo->SysConfig.RatingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].targetCurrent = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5) ? 6 : ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].acCcsInfo.EVSEMaxCurrent = (float) ShmCharger->gun_info[gun_index].targetCurrent; } } } else { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent) ? ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); if ((ShmCharger->gun_info[gun_index].targetCurrent != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current) || (ShmCharger->gun_info[gun_index].primaryMcuState.current_limit != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current)) { if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { if (getDiffSecNow(startTime[gun_index][TMR_IDX_PWN_CHANGE]) > TIMEOUT_SPEC_PWN_CHANGE) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent) ? ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5) ? 6 : ((ShmCharger->gun_info[gun_index].targetCurrent == 0) ? 100 : ShmCharger->gun_info[gun_index].targetCurrent)); ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; refreshStartTimer(&startTime[gun_index][TMR_IDX_PWN_CHANGE]); } } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent) ? ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent : ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].targetCurrent = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5) ? 6 : ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].acCcsInfo.EVSEMaxCurrent = (float) ShmCharger->gun_info[gun_index].targetCurrent; } } } if (ShmCharger->gun_info[gun_index].targetCurrent != previousData[gun_index].targetCurrent) { DEBUG_INFO("==================================================\n"); DEBUG_INFO("Gun-%02d targetCurrent: %d\n", gun_index, ShmCharger->gun_info[gun_index].targetCurrent); DEBUG_INFO("MaxChargingCurrent: %d \n", ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent); DEBUG_INFO("==================================================\n"); previousData[gun_index].targetCurrent = ShmCharger->gun_info[gun_index].targetCurrent; } if (ShmCharger->gun_info[gun_index].primaryMcuState.current_limit != previousData[gun_index].current_limit) { DEBUG_INFO("==================================================\n"); DEBUG_INFO("Gun-%02d mcu current_limit: %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuState.current_limit); DEBUG_INFO("==================================================\n"); previousData[gun_index].current_limit = ShmCharger->gun_info[gun_index].primaryMcuState.current_limit; } //lwtest if (ShmCharger->gun_info[gun_index].ChargingProfileCurrent != previousData[gun_index].ChargingProfileCurrent) { DEBUG_INFO("==================================================\n"); DEBUG_INFO("Gun-%02d Profile limit : %.2f\n", gun_index, ShmCharger->gun_info[gun_index].ChargingProfileCurrent); DEBUG_INFO("Gun-%02d Profile power : %.2f\n", gun_index, ShmCharger->gun_info[gun_index].ChargingProfilePower); DEBUG_INFO("==================================================\n"); previousData[gun_index].ChargingProfileCurrent = ShmCharger->gun_info[gun_index].ChargingProfileCurrent; previousData[gun_index].ChargingProfilePower = ShmCharger->gun_info[gun_index].ChargingProfilePower; } break; } } void checkStopReason(uint8_t gun_index) { sleep(2); if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { memset(ShmOCPP16Data->StopTransaction[gun_index].IdTag, 0x00, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); if (!ocpp_get_starttransaction_result(gun_index)) { sprintf((char*) ShmOCPP16Data->StopTransaction[gun_index].StopReason, "DeAuthorized"); } else if (ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP) { sprintf((char*) ShmOCPP16Data->StopTransaction[gun_index].StopReason, "EmergencyStop"); } else if ((getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_A) || (ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES)) { sprintf((char*) ShmOCPP16Data->StopTransaction[gun_index].StopReason, "EVDisconnected"); memcpy((char*) ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*) ShmOCPP16Data->StartTransaction[gun_index].IdTag, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); } else if (ShmOCPP16Data->MsMsg.bits.ResetReq) { if (strcmp((char*) ShmOCPP16Data->Reset.Type, "Hard") == 0) sprintf((char*) ShmOCPP16Data->StopTransaction[gun_index].StopReason, "HardReset"); else sprintf((char*) ShmOCPP16Data->StopTransaction[gun_index].StopReason, "SoftReset"); } else if (ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop) { sprintf((char*) ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Local"); if (!isMatchStartUser()) { memcpy((char*) ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*) ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); } else { memcpy((char*) ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*) getTargetChargingInfoData(gun_index)->StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); } DEBUG_INFO("Gun-[%d] : IdTag [ %s ].\n", gun_index, ShmOCPP16Data->StopTransaction[gun_index].IdTag); } else if (ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq) { sprintf((char*) ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Remote"); } else if (ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId - 1].isUnlockerConnetor == ON) { sprintf((char*) ShmOCPP16Data->StopTransaction[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId - 1].StopReason, "UnlockCommand"); } else { sprintf((char*) ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Other"); } DEBUG_INFO("Gun-[%d] : StopReason [ %s ].\n", gun_index, ShmOCPP16Data->StopTransaction[gun_index].StopReason); getTargetChargingInfoData(gun_index)->PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption / 10000.0); presentChargedEnergyUpdate(gun_index); DEBUG_INFO("Gun-[%d] : PresentChargedEnergy [ %.4f ].\n", gun_index,getTargetChargingInfoData(gun_index)->PresentChargedEnergy); ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { memset(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, 0x00, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken)); if (!ocpp_get_starttransaction_result(gun_index)) { sprintf((char*) ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "DeAuthorized"); } else if (ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP) { sprintf((char*) ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "EmergencyStop"); } else if ((getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_A) || (ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES)) { sprintf((char*) ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "EVDisconnected"); } else if (ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL) { sprintf((char*) ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "GroundFault"); } else if (ShmOCPP20Data->MsMsg.bits.ResetReq) { if (strcmp((char*) ShmOCPP20Data->Reset.type, "Immediate") == 0) sprintf((char*) ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "ImmediateReset"); else sprintf((char*) ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "OnIdle"); } else if (ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop) { sprintf((char*) ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Local"); if (!isMatchStartUser()) { memcpy((char*) ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*) ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken)); } else { memcpy((char*) ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*) getTargetChargingInfoData(gun_index)->StartUserId, ARRAY_SIZE(getTargetChargingInfoData(gun_index)->StartUserId)); } DEBUG_INFO("Gun-[%d] : idToken [ %s ].\n", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken); } else if ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_CURRENT) || (ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_CURRENT) || (ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_CURRENT)) { sprintf((char*) ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "OvercurrentFault"); } else if (ShmOCPP20Data->CsMsg.bits[gun_index].RequestStopTransactionReq) { sprintf((char*) ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Remote"); } else if (ShmCharger->gun_info[ShmOCPP20Data->UnlockConnector[gun_index].connectorId - 1].isUnlockerConnetor == ON) { sprintf( (char*) ShmOCPP20Data->TransactionEvent[ShmOCPP20Data->UnlockConnector[gun_index].connectorId - 1].transactionInfo.stoppedReason, "UnlockCommand"); } else { sprintf((char*) ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Other"); } DEBUG_INFO("Gun-[%d] : StopReason [ %s ].\n", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason); getTargetChargingInfoData(gun_index)->PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/ 10000.0); presentChargedEnergyUpdate(gun_index); DEBUG_INFO("Gun-[%d] : PresentChargedEnergy [ %.4f ].\n", gun_index, getTargetChargingInfoData(gun_index)->PresentChargedEnergy); ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON; } // Maintain server if (strcmp((char *) &ShmSysConfigAndInfo->SysConfig.MaintainServerURL, "") != 0) { memcpy(ShmOCPP16DataPH->StopTransaction[gun_index].StopReason, ShmOCPP16Data->StopTransaction[gun_index].StopReason, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].StopReason)); memcpy(ShmOCPP16DataPH->StopTransaction[gun_index].IdTag, ShmOCPP16Data->StopTransaction[gun_index].IdTag, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); ShmOCPP16DataPH->CpMsg.bits[gun_index].StopTransactionReq = ON; } } void checkRemoteUpgradeStatus() { if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strcmp((char*) ShmOCPP16Data->FirmwareStatusNotification.Status, "DownloadFailed") == 0) { DEBUG_INFO("Firmware remote upgraded fail...\n"); ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq = OFF; ShmCharger->isUpdateSuccess = NO; } else if (strcmp((char*) ShmOCPP16Data->FirmwareStatusNotification.Status, "Downloaded") == 0) { DEBUG_INFO("Firmware remote upgrading...\n"); sprintf((char*) ShmOCPP16Data->FirmwareStatusNotification.Status, "Installing"); sleep(1); ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq = OFF; int result = upgrade_check(); DEBUG_INFO("Remote update Result: %s... \n", ((result == PASS)?"Pass": "Fail")); if (result == PASS) { if (ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == ON) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = OFF; ShmCharger->isUpdateSuccess = YES; DEBUG_INFO("Remote update success...\n"); } else { if (ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == OFF) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = ON; ShmCharger->isUpdateSuccess = NO; DEBUG_INFO("Remote update unsuccess...\n"); } } else { } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (strcmp((char*) ShmOCPP20Data->FirmwareStatusNotification.status, "DownloadFailed") == 0) { DEBUG_INFO("Firmware remote upgraded fail...\n"); ShmOCPP20Data->MsMsg.bits.UpdateFirmwareReq = OFF; ShmCharger->isUpdateSuccess = NO; } else if (strcmp((char*) ShmOCPP20Data->FirmwareStatusNotification.status, "Downloaded") == 0) { DEBUG_INFO("Firmware remote upgrading...\n"); sprintf((char*) ShmOCPP16Data->FirmwareStatusNotification.Status, "Installing"); ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; ShmOCPP20Data->MsMsg.bits.UpdateFirmwareReq = OFF; int result = upgrade_check(); DEBUG_INFO("Remote update Result: %s... \n", ((result == PASS)?"Pass": "Fail")); if (result == PASS) { if (ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == ON) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = OFF; ShmCharger->isUpdateSuccess = YES; DEBUG_INFO("Remote update success...\n"); } else { if (ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == OFF) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = ON; ShmCharger->isUpdateSuccess = NO; DEBUG_INFO("Remote update unsuccess...\n"); } } else { } } } void checkHandshakeCountdown(uint8_t gun_index) { switch (getTargetChargingInfoData(gun_index)->SystemStatus) { case SYS_MODE_IDLE: if (ShmCharger->gun_info[ShmCharger->gun_selectd].isHandshakeTimerRefresh == YES) refreshStartTimer(&startTime[0][TMR_IDX_GUN_DETECT]); else ShmCharger->timeoutSpec.Handshake_Timeout = ((ocpp_get_connection_timeout()) - (getDiffSecNow(startTime[0][TMR_IDX_GUN_DETECT]))); if (!ShmCharger->isAuthrizing) { if (ocpp_get_isRemoteStartWait()) ShmCharger->timeoutSpec.Handshake_Timeout = ((ocpp_get_connection_timeout()) - (getDiffSecNow(startTime[0][TMR_IDX_GUN_DETECT]))); else refreshStartTimer(&startTime[0][TMR_IDX_GUN_DETECT]); } break; case SYS_MODE_PREPARING: ShmCharger->timeoutSpec.Handshake_Timeout = ((ocpp_get_connection_timeout()) - getDiffSecNow(startTime[gun_index][TMR_IDX_HANDSHAKING])); break; case SYS_MODE_RESERVATION: if (ShmCharger->gun_info[ShmCharger->gun_selectd].isHandshakeTimerRefresh == YES) refreshStartTimer(&startTime[0][TMR_IDX_GUN_DETECT]); else ShmCharger->timeoutSpec.Handshake_Timeout = ((ocpp_get_connection_timeout()) - (getDiffSecNow(startTime[0][TMR_IDX_GUN_DETECT]))); break; } } void checkRfidAuthrize() { static uint8_t isCheckdResult = FALSE; uint8_t isStartByWrongReservation = NO; if (!ShmCharger->isAuthrizing) { // Read RFID if (GetCardSerialNumber() != FAIL) { uint8_t isSnStart = FALSE; uint8_t bufferRFID[ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)]; if (ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian) { // Big endian switch (rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char*) bufferRFID, "%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5]); break; case RFID_SN_TYPE_7BYTE: sprintf((char*) bufferRFID, "%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6]); break; case RFID_SN_TYPE_8BYTE: sprintf((char *) bufferRFID, "%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6], rfid.currentCard[7]); break; case RFID_SN_TYPE_10BYTE: sprintf((char*) bufferRFID, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6], rfid.currentCard[7], rfid.currentCard[8], rfid.currentCard[9]); break; case RFID_SN_TYPE_4BYTE: default: sprintf((char*) bufferRFID, "%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3]); break; } } else { // Little endian switch (rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char*) bufferRFID, "%02X%02X%02X%02X%02X%02X", rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_7BYTE: sprintf((char*) bufferRFID, "%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_8BYTE: sprintf((char *) bufferRFID, "%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[7], rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_10BYTE: sprintf((char*) bufferRFID, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[9], rfid.currentCard[8], rfid.currentCard[7], rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_4BYTE: default: sprintf((char*) bufferRFID, "%02X%02X%02X%02X", rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; } } DEBUG_INFO("Authorize request User Id : %s\n", bufferRFID); for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) ShmCharger->gun_info[gun_index].resultAuthorization = UNKNOW_RFID; // Check SN already start if (isMatchStartUser() || isMatchPresentUser()) //lwtest { //Already entry charging if (strcmp((char*) getTargetChargingInfoData(ShmCharger->gun_selectd)->StartUserId, "") != 0) DEBUG_INFO("%s running on connector-%02d.\n", getTargetChargingInfoData(ShmCharger->gun_selectd)->StartUserId, ShmCharger->gun_selectd); //Already entry preparing else if (strcmp((char*) ShmCharger->gun_info[ShmCharger->gun_selectd].AuthAcceptUserId, "") != 0) DEBUG_INFO("%s ready running on connector-%02d.\n", ShmCharger->gun_info[ShmCharger->gun_selectd].AuthAcceptUserId, ShmCharger->gun_selectd); isSnStart = TRUE; ShmCharger->gun_info[ShmCharger->gun_selectd].rfidReq = ON; ocpp_set_auth_conf(ON); setLedMotion(ShmCharger->gun_selectd, LED_ACTION_RFID_PASS); setSpeaker(ON, SPEAKER_SHORT); sleep(3); //break; } else if (isNeedToAuth() == FALSE) { //lwtest isSnStart = TRUE; ShmCharger->gun_info[ShmCharger->gun_selectd].rfidReq = OFF; ocpp_set_auth_conf(ON); } else { //lwtest .. for GL testing control. for (uint8_t index = 0; index < modelnameInfo.GetGunCount; index++) { if (ShmCharger->gun_info[index].isCmdToPrepareMode == ON) { ShmCharger->gun_info[index].rfidReq = ON; memset(ShmSysConfigAndInfo->SysConfig.UserId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); return; } } } // Request authorize if isSnStart is false if (!isSnStart) { DEBUG_INFO("RFID start. [ %s ]\n", bufferRFID); memcpy(ShmSysConfigAndInfo->SysConfig.UserId, bufferRFID, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); refreshStartTimer(&startTime[ShmCharger->gun_selectd][TMR_IDX_AUTH]); //lwtest ocpp_set_auth_conf(OFF); ocpp_set_auth_req(ON, "ISO14443"); setLedMotion(0, LED_ACTION_AUTHED); ShmCharger->isAuthrizing = TRUE; ShmCharger->isGetAuthResult = FALSE; isCheckdResult = FALSE; } } } else //isAuthrizing = true { // Wait authorize result if (!ocpp_get_auth_conf() && (getDiffSecNow(startTime[ShmCharger->gun_selectd][TMR_IDX_AUTH]) > TIMEOUT_SPEC_AUTH)) { // Authorization timeout process. DEBUG_WARN("Authorize timeout [ %s ]!!!\n", ShmSysConfigAndInfo->SysConfig.UserId); for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) { ShmCharger->gun_info[gun_index].resultAuthorization = UNVALIDATED_RFID; setLedMotion(gun_index, LED_ACTION_RFID_FAIL); } //lwtest memset(ShmSysConfigAndInfo->SysConfig.UserId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); setSpeaker(ON, SPEAKER_INTERVAL_3COUNT); sleep(3); ShmCharger->isAuthrizing = FALSE; } else { if (ocpp_get_auth_conf() || (!ocpp_get_connection_status() && ((ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE) || (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_NOCHARGE))) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (getDiffSecNow(startTime[0][TMR_IDX_AUTH]) > 2))) { if (ocpp_get_auth_result(NO) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) || (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST))) { if (!isCheckdResult) { refreshStartTimer(&startTime[0][TMR_IDX_GUN_DETECT]); ShmCharger->isGetAuthResult = TRUE; isCheckdResult = TRUE; if (strcmp((char *) &ShmSysConfigAndInfo->SysConfig.OcppServerURL, "") == 0) { ocpp_set_auth_conf(ON); } for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) { if ((getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_RESERVATION) && (strcmp((char*) ShmSysConfigAndInfo->SysConfig.UserId, (char*) ShmOCPP16Data->ReserveNow[gun_index].IdTag) != 0)) { sleep(1); ShmCharger->gun_info[gun_index].resultAuthorization = UNVALIDATED_RFID; isStartByWrongReservation = YES; DEBUG_INFO("Not match: UserId = [%s] / Reserve IdTag = [%s] \n", ShmSysConfigAndInfo->SysConfig.UserId, ShmOCPP16Data->ReserveNow[ShmCharger->gun_selectd].IdTag); DEBUG_INFO("Authorize fail.\n"); //lwtest memset(ShmSysConfigAndInfo->SysConfig.UserId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); setSpeaker(ON, SPEAKER_INTERVAL_3COUNT); } else { //lwtest if (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_IDLE) { DEBUG_INFO("Authorize pass (gun %d) [ %s ].\n", gun_index, ShmSysConfigAndInfo->SysConfig.UserId); ShmCharger->gun_info[gun_index].resultAuthorization = VALIDATED_RFID; getTargetChargingInfoData(gun_index)->PilotState = CP_STATE_B; ShmCharger->gun_selectd = gun_index; memcpy(ShmCharger->gun_info[gun_index].AuthAcceptUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); memset(ShmSysConfigAndInfo->SysConfig.UserId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); break; } setSpeaker(ON, SPEAKER_SHORT); } } } for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) checkHandshakeCountdown(gun_index); if ((getDiffSecNow(startTime[0][TMR_IDX_GUN_DETECT]) < (ocpp_get_connection_timeout())) && (isStartByWrongReservation != YES)) { if (GetCardSerialNumber() != FAIL) { if (isMatchPresentUser()) { DEBUG_INFO("Cancel present user.\n"); for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) { setLedMotion(gun_index, LED_ACTION_IDLE); ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID; } setSpeaker(ON, SPEAKER_SHORT); ShmCharger->isAuthrizing = FALSE; } } else { for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) { if (getDiffSecNow(startTime[0][TMR_IDX_GUN_DETECT]) < 3) setLedMotion(gun_index, LED_ACTION_RFID_PASS); else setLedMotion(gun_index, LED_ACTION_AUTHED); if ((((getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_IDLE) || (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_RESERVATION)) && (((getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_B) || (getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_C)) || (ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON))) || ((getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_PREPARING) && (getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_B) && (ShmCharger->gun_selectd == gun_index)) || (((getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_CHARGING) || (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_TERMINATING)) && (ShmCharger->gun_selectd == gun_index))) { DEBUG_INFO("Connector-%02d action detect.\n", gun_index); ShmCharger->isAuthrizing = FALSE; ShmCharger->gun_info[gun_index].rfidReq = ON; break; } } } } else { if (isStartByWrongReservation != YES) DEBUG_INFO("Connector action detect timeout. \n"); else DEBUG_INFO("User Id and reservation IdTag is not match. \n"); ShmCharger->isAuthrizing = FALSE; ShmCharger->isGetAuthResult = TRUE; for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) { if (isStartByWrongReservation != YES) { setLedMotion(gun_index, LED_ACTION_HANDSHAKE_FAIL); sleep(6); } else { setLedMotion(gun_index, LED_ACTION_RFID_FAIL); sleep(3); } setLedMotion(gun_index, LED_ACTION_IDLE); ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID; } } } else { DEBUG_INFO("Authorize fail.\n"); ShmCharger->isAuthrizing = FALSE; ShmCharger->isGetAuthResult = TRUE; //lwtest memset(ShmSysConfigAndInfo->SysConfig.UserId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) { ShmCharger->gun_info[gun_index].resultAuthorization = UNVALIDATED_RFID; setLedMotion(gun_index, LED_ACTION_RFID_FAIL); } setSpeaker(ON, SPEAKER_INTERVAL_3COUNT); sleep(3); for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) { if ((getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_PREPARING)) setLedMotion(gun_index, LED_ACTION_AUTHED); else setLedMotion(gun_index, LED_ACTION_IDLE); } } } } } } //====================================================== // Main process //====================================================== int main(void) { //================================================== // Create all share memory //================================================== if (CreatShareMemory() == 0) { DEBUG_ERROR("CreatShareMemory NG\n"); if (ShmStatusCodeData != NULL) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = TRUE; sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } else { modelnameInfo.GetGunCount = 1; DEBUG_INFO("CreatShareMemory OK\n"); } for (int gun_index = 0; gun_index < MAX_GUN_NUM; gun_index++) { ShmSysConfigAndInfo->SysInfo.ChademoChargingData[gun_index].SystemStatus = 0x00; ShmSysConfigAndInfo->SysInfo.ChademoChargingData[gun_index].PreviousSystemStatus = 0xff; ShmSysConfigAndInfo->SysInfo.ChademoChargingData[gun_index].Index = 0xff; ShmSysConfigAndInfo->SysInfo.CcsChargingData[gun_index].SystemStatus = 0x00; ShmSysConfigAndInfo->SysInfo.CcsChargingData[gun_index].PreviousSystemStatus = 0xff; ShmSysConfigAndInfo->SysInfo.CcsChargingData[gun_index].Index = 0xff; ShmSysConfigAndInfo->SysInfo.GbChargingData[gun_index].SystemStatus = 0x00; ShmSysConfigAndInfo->SysInfo.GbChargingData[gun_index].PreviousSystemStatus = 0xff; ShmSysConfigAndInfo->SysInfo.GbChargingData[gun_index].Index = 0xff; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus = 0x00; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus = 0xff; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].Index = 0xff; } //================================================== // Main loop //================================================== for (;;) { //============================================== // Synchronize share memory from OCPP struct //============================================== ShmSysConfigAndInfo->SysInfo.OcppConnStatus = ocpp_get_connection_status(); //============================================== // Period check for 10 seconds //============================================== if ((getDiffSecNow(startTime[0][TMR_IDX_CHECK_TASK]) > TIMEOUT_SPEC_TASK_CHECK) || (getDiffSecNow(startTime[0][TMR_IDX_CHECK_TASK]) < 0)) { //============================================== // Check task processing //============================================== if (getTargetChargingInfoData(0)->SystemStatus != SYS_MODE_BOOTING && getTargetChargingInfoData(1)->SystemStatus != SYS_MODE_BOOTING) //lwtest checkTask(); //============================================== // Check connection timeout specification //============================================== checkConnectionTimeout(); refreshStartTimer(&startTime[0][TMR_IDX_CHECK_TASK]); } //============================================== // Something need run in Idle mode //============================================== if (((getTargetChargingInfoData(0)->SystemStatus == SYS_MODE_IDLE) || (getTargetChargingInfoData(0)->SystemStatus == SYS_MODE_ALARM) || (getTargetChargingInfoData(0)->SystemStatus == SYS_MODE_DEBUG)) && (modelnameInfo.GetGunCount > 1 ? ((getTargetChargingInfoData(1)->SystemStatus == SYS_MODE_IDLE) || (getTargetChargingInfoData(1)->SystemStatus == SYS_MODE_ALARM) || (getTargetChargingInfoData(1)->SystemStatus == SYS_MODE_DEBUG)) : TRUE)) { // Check restore factory setting request if (ShmSysConfigAndInfo->SysInfo.FactoryConfiguration) { sleep(5); system("cd /root;./Module_FactoryConfig -m"); system("rm -f /Storage/OCPP/OCPPConfiguration"); system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } // Check upgrade firmware request if (ShmSysConfigAndInfo->SysInfo.FirmwareUpdate || ocpp_get_update_firmware_req()) { // If available memory too small, free memory cache first if (getAvailableMemory() < (200 * 1024 * 1024)) { DEBUG_INFO("Available memory (%.2f Bytes) less than 200 MBytes, free cache first.\n", getAvailableMemory() / (1024 * 1024.0)); system("echo 3 > /proc/sys/vm/drop_caches"); } ShmCharger->isUpdateSuccess = NO; for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) { setChargerMode(gun_index, SYS_MODE_UPDATE); } } } //============================================== // Check remote reset request //============================================== checkReset(); //============================================== // Check RFID authorization //============================================== for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) { // The user is not allowed to use RFID when the system change to under those modes. if ((getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_ALARM) || (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_FAULT) || (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_DEBUG) || (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_UPDATE) || (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_BOOTING) || (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_COMPLETE) || (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE)) { } else { checkRfidAuthrize(); } } //============================================== // Connector loop //============================================== for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) { /* * TODO: * 1. Simulate voltage, current, power consumption */ if (ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_OUTPUT_TYPE] == 'A') { static uint64_t tmpPowerConsumption[3]; static long long tsLast[3], tsNow[3]; // Voltage ShmCharger->gun_info[gun_index].inputVoltage.L1N_L12 = (float) (((rand() % 10) + ((AC_OUTPUT_VOL * 10) - SIM_DEVIATION)) / 10.0); if (ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3) { ShmCharger->gun_info[gun_index].inputVoltage.L2N_L23 = (float) (((rand() % 10) + ((AC_OUTPUT_VOL * 10) - SIM_DEVIATION)) / 10.0); ShmCharger->gun_info[gun_index].inputVoltage.L3N_L31 = (float) (((rand() % 10) + ((AC_OUTPUT_VOL * 10) - SIM_DEVIATION)) / 10.0); } getTargetChargingInfoData(gun_index)->PresentChargingVoltage = ShmCharger->gun_info[gun_index].inputVoltage.L1N_L12; ShmSysConfigAndInfo->SysInfo.InputVoltageR = ShmCharger->gun_info[gun_index].inputVoltage.L1N_L12; if (ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3) { getTargetChargingInfoData(gun_index)->PresentChargingVoltageL2 = ShmCharger->gun_info[gun_index].inputVoltage.L2N_L23; getTargetChargingInfoData(gun_index)->PresentChargingVoltageL3 = ShmCharger->gun_info[gun_index].inputVoltage.L3N_L31; ShmSysConfigAndInfo->SysInfo.InputVoltageS = ShmCharger->gun_info[gun_index].inputVoltage.L2N_L23; ShmSysConfigAndInfo->SysInfo.InputVoltageT = ShmCharger->gun_info[gun_index].inputVoltage.L3N_L31; } else { ShmSysConfigAndInfo->SysInfo.InputVoltageS = 0; ShmSysConfigAndInfo->SysInfo.InputVoltageT = 0; } //lwtest // if (ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3) // printf("=== AC 3 phase R=%.2f v | S=%.2f v | T%.2f v\n", ShmSysConfigAndInfo->SysInfo.InputVoltageR, // ShmSysConfigAndInfo->SysInfo.InputVoltageS, ShmSysConfigAndInfo->SysInfo.InputVoltageT); // else // printf("=== AC 1 phase R=%.2f v\n", ShmSysConfigAndInfo->SysInfo.InputVoltageR); //------------------------------------------------------------------------------------ // Current uint16_t _targetCurrent = ShmCharger->gun_info[gun_index].targetCurrent/ShmSysConfigAndInfo->SysConfig.AcPhaseCount; getTargetChargingInfoData(gun_index)->PresentChargingCurrent = (float) (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_CHARGING ? (((rand() % 10) + ((_targetCurrent * 10) - SIM_DEVIATION)) / 10.0) : 0); if (ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3) { getTargetChargingInfoData(gun_index)->PresentChargingCurrentL2 = (float) (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_CHARGING ? (((rand() % 10) + ((_targetCurrent * 10) - SIM_DEVIATION)) / 10.0) : 0); getTargetChargingInfoData(gun_index)->PresentChargingCurrentL3 = (float) (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_CHARGING ? (((rand() % 10) + ((_targetCurrent * 10) - SIM_DEVIATION)) / 10.0) : 0); } //lwtest if (getTargetChargingInfoData(gun_index)->PresentChargingCurrent < 0.0) { //lwtest for debug DEBUG_INFO("LW debug message : PresentChargingCurrent < 0, value = %.2f A\n", getTargetChargingInfoData(gun_index)->PresentChargingCurrent); getTargetChargingInfoData(gun_index)->PresentChargingCurrent = 0; } //lwtest // if (ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3) // printf("=== AC 3 phase Gun %d Current I1=%.2f A| I2=%.2f A| I3=%.2f A\n", gun_index, // getTargetChargingInfoData(gun_index)->PresentChargingCurrent, // getTargetChargingInfoData(gun_index)->PresentChargingCurrentL2, // getTargetChargingInfoData(gun_index)->PresentChargingCurrentL3); // else // printf("=== AC 1 phase Gun %d Current=%.2f A\n", gun_index, // getTargetChargingInfoData(gun_index)->PresentChargingCurrent); //------------------------------------------------------------------------------------ // Energy tsNow[gun_index] = current_timestamp(); tmpPowerConsumption[gun_index] += (uint64_t) ((getTargetChargingInfoData(gun_index)->PresentChargingVoltage * getTargetChargingInfoData(gun_index)->PresentChargingCurrent) * ((tsNow[gun_index] - tsLast[gun_index]) / 360000.0)); if (ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3) { tmpPowerConsumption[gun_index] += (uint64_t) ((getTargetChargingInfoData(gun_index)->PresentChargingVoltageL2 * getTargetChargingInfoData(gun_index)->PresentChargingCurrentL2) * ((tsNow[gun_index] - tsLast[gun_index]) / 360000.0)); tmpPowerConsumption[gun_index] += (uint64_t) ((getTargetChargingInfoData(gun_index)->PresentChargingVoltageL3 * getTargetChargingInfoData(gun_index)->PresentChargingCurrentL3) * ((tsNow[gun_index] - tsLast[gun_index]) / 360000.0)); } ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption = tmpPowerConsumption[gun_index]; tsLast[gun_index] = tsNow[gun_index]; // Connector temperature getTargetChargingInfoData(gun_index)->ConnectorTemp = (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_CHARGING ? ((rand() % 3) + ((50) - 3)) : ((rand() % 3) + ((25) - 3))); } else { //DC type static uint64_t tmpPowerConsumption[3]; static long long tsLast[3], tsNow[3]; // Input Voltage ShmSysConfigAndInfo->SysInfo.InputVoltageR = (float) (((rand() % 10) + ((AC_OUTPUT_VOL * 10) - SIM_DEVIATION)) / 10.0); ShmSysConfigAndInfo->SysInfo.InputVoltageS = (float) (((rand() % 10) + ((AC_OUTPUT_VOL * 10) - SIM_DEVIATION)) / 10.0); ShmSysConfigAndInfo->SysInfo.InputVoltageT = (float) (((rand() % 10) + ((AC_OUTPUT_VOL * 10) - SIM_DEVIATION)) / 10.0); //lwtest // printf("=== DC input Voltage R=%.2f v| S=%.2f v| T=%.2f v\n", // ShmSysConfigAndInfo->SysInfo.InputVoltageR, ShmSysConfigAndInfo->SysInfo.InputVoltageS, // ShmSysConfigAndInfo->SysInfo.InputVoltageT); //------------------------------------------------------------------------------------ // Output Voltage getTargetChargingInfoData(gun_index)->PresentChargingVoltage = (float) (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_CHARGING ? (((rand() % 10) + ((DC_SIMULATE_OUTPUT_VOL * 10) - 100)) / 10.0) : 0); //lwtest // printf("=== DC Gun %d Present Charging Voltage %.2f v\n", gun_index, // getTargetChargingInfoData(gun_index)->PresentChargingVoltage); //------------------------------------------------------------------------------------ // Current getTargetChargingInfoData(gun_index)->PresentChargingCurrent = (float) (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_CHARGING ? (((rand() % 10) + ((ShmCharger->gun_info[gun_index].targetCurrent * 10) - SIM_DEVIATION)) / 10.0) : 0); //lwtest if (getTargetChargingInfoData(gun_index)->PresentChargingCurrent < 0.0) { //lwtest for debug DEBUG_INFO("LW debug message : PresentChargingCurrent < 0, value = %.2f A\n", getTargetChargingInfoData(gun_index)->PresentChargingCurrent); getTargetChargingInfoData(gun_index)->PresentChargingCurrent = 0; } // //lwtest // printf("=== DC Gun %d Present Charging Current %.2f A\n", gun_index, // getTargetChargingInfoData(gun_index)->PresentChargingCurrent); //------------------------------------------------------------------------------------ // Energy tsNow[gun_index] = current_timestamp(); tmpPowerConsumption[gun_index] += (uint64_t) ((getTargetChargingInfoData(gun_index)->PresentChargingVoltage * getTargetChargingInfoData(gun_index)->PresentChargingCurrent) * ((tsNow[gun_index] - tsLast[gun_index]) / 360000.0)); ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption = tmpPowerConsumption[gun_index]; tsLast[gun_index] = tsNow[gun_index]; //lwtest // printf("=== DC Gun %d power_consumption %.2lld v\n", gun_index, ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption); //------------------------------------------------------------------------------------ //Power Offered , Current Offered //lwtest if (isTwoGunInChargingMode()) { getTargetChargingInfoData(gun_index)->CurrentOffered = 120 * 10 * 0.5; getTargetChargingInfoData(gun_index)->PowerOffered = (modelnameInfo.ratedPower / 100.0) * 0.5; } else { getTargetChargingInfoData(gun_index)->CurrentOffered = 120 * 10; getTargetChargingInfoData(gun_index)->PowerOffered = (modelnameInfo.ratedPower / 100.0); } //------------------------------------------------------------------------------------ // SOC if (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_IDLE) getTargetChargingInfoData(gun_index)->EvBatterySoc = 0; else { if (getDiffSecNow(startTime[gun_index][TMR_IDX_SIMULATION]) > TIMEOUT_SPEC_SIMULATION) { if (getTargetChargingInfoData(gun_index)->EvBatterySoc < 100) getTargetChargingInfoData(gun_index)->EvBatterySoc += 1; refreshStartTimer(&startTime[gun_index][TMR_IDX_SIMULATION]); } } //------------------------------------------------------------------------------------ // Connector temperature getTargetChargingInfoData(gun_index)->ConnectorTemp = (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_CHARGING ? ((rand() % 3) + ((80) - 3)) : ((rand() % 3) + ((25) - 3))); //------------------------------------------------------------------------------------ // System fan RPM getTargetChargingInfoData(gun_index)->ConnectorTemp = (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_CHARGING ? ((rand() % 3) + ((50) - 3)) : ((rand() % 3) + ((25) - 3))) + 60; //------------------------------------------------------------------------------------ // Remain charging time getTargetChargingInfoData(gun_index)->RemainChargingDuration = (100 - getTargetChargingInfoData(gun_index)->EvBatterySoc) * 10; //------------------------------------------------------------------------------------ // EV battery max voltage getTargetChargingInfoData(gun_index)->EvBatteryMaxVoltage = DC_SIMULATE_OUTPUT_VOL; // EV battery target voltage getTargetChargingInfoData(gun_index)->EvBatterytargetVoltage = DC_SIMULATE_OUTPUT_VOL - SIM_DEVIATION; } /* * TODO: * 1. Synchronize current rating value from MCU */ if (ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_OUTPUT_TYPE] == 'A') { if (ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_TYPE] == 'X' && strncmp((char*) &ShmSysConfigAndInfo->SysConfig.ModelName[RATING_POWER], "111", 3) == 0) ShmSysConfigAndInfo->SysConfig.RatingCurrent = 48; else if (ShmSysConfigAndInfo->SysConfig.ModelName[EVSE_TYPE] == 'X' && strncmp((char*) &ShmSysConfigAndInfo->SysConfig.ModelName[RATING_POWER], "221", 3) == 0) ShmSysConfigAndInfo->SysConfig.RatingCurrent = 32; else ShmSysConfigAndInfo->SysConfig.RatingCurrent = modelnameInfo.ratedPower / AC_OUTPUT_VOL; } else ShmSysConfigAndInfo->SysConfig.RatingCurrent = modelnameInfo.ratedPower / DC_SIMULATE_OUTPUT_VOL; //lwtest // printf("=== Rating Current %d, ratedPower = %d\n", ShmSysConfigAndInfo->SysConfig.RatingCurrent, // modelnameInfo.ratedPower); //========================================== // Synchronize present charging power //========================================== if (ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 1) { if (getRelay(gun_index) == ON) { getTargetChargingInfoData(gun_index)->PresentChargingPower = (getTargetChargingInfoData(gun_index)->PresentChargingVoltage * getTargetChargingInfoData(gun_index)->PresentChargingCurrent) / 1000; //min power //lwtest if (getTargetChargingInfoData(gun_index)->PresentChargingPower <= (ShmSysConfigAndInfo->SysConfig.RatingCurrent * 0.01)) getTargetChargingInfoData(gun_index)->PresentChargingPower = ShmSysConfigAndInfo->SysConfig.RatingCurrent * 0.01; // printf("===Gun %d 1 Phase relay ON Rating Pow %.2f w\n", gun_index, // getTargetChargingInfoData(gun_index)->PresentChargingPower); } else getTargetChargingInfoData(gun_index)->PresentChargingPower = 0; } else { if (getRelay(gun_index) == ON) { getTargetChargingInfoData(gun_index)->PresentChargingPower = (((getTargetChargingInfoData(gun_index)->PresentChargingVoltage * getTargetChargingInfoData(gun_index)->PresentChargingCurrent) / 1000) + ((getTargetChargingInfoData(gun_index)->PresentChargingVoltageL2 * getTargetChargingInfoData(gun_index)->PresentChargingCurrentL2) / 1000) + ((getTargetChargingInfoData(gun_index)->PresentChargingVoltageL3 * getTargetChargingInfoData(gun_index)->PresentChargingCurrentL3) / 1000)); //lwtest //min power if (getTargetChargingInfoData(gun_index)->PresentChargingPower <= (ShmSysConfigAndInfo->SysConfig.RatingCurrent * 0.01)) getTargetChargingInfoData(gun_index)->PresentChargingPower = ShmSysConfigAndInfo->SysConfig.RatingCurrent * 0.01; //lwtest // printf("===Gun %d 3 Phase relay ON Rating Pow %.2f\n", gun_index, // getTargetChargingInfoData(gun_index)->PresentChargingPower); } else { getTargetChargingInfoData(gun_index)->PresentChargingPower = 0; } } //========================================== // Check initialization "PASS" or "FAIL" //========================================== if (ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING) { // Alarm event check if ((ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode > 0) || (ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode > 0) || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CCSboardStestFail) { if (getTargetChargingInfoData(gun_index)->SystemStatus != SYS_MODE_ALARM) { if (getTargetChargingInfoData(gun_index)->SystemStatus != SYS_MODE_UPDATE) { setChargerMode(gun_index, SYS_MODE_ALARM); } } } } //========================================== // Reservation request check //========================================== checkReservation(gun_index); //========================================== // Change availability check //========================================== //lwtest if (getTargetChargingInfoData(gun_index)->SystemStatus == SYS_MODE_BOOTING) { ShmCharger->gun_info[gun_index].isOperactive = DB_Get_Operactive(localDb, gun_index); DEBUG_INFO("connector-0 %d operative state %d\n", gun_index, ShmCharger->gun_info[gun_index].isOperactive); } checkAvailability(gun_index); if (ShmCharger->gun_info[gun_index].isOperactive) { if (isMode(gun_index, SYS_MODE_MAINTAIN)) setChargerMode(gun_index, SYS_MODE_IDLE); } else { if (isMode(gun_index, SYS_MODE_IDLE)) setChargerMode(gun_index, SYS_MODE_MAINTAIN); } //========================================== // Unlock Connector signal check //========================================== checkUnlocker(gun_index); //========================================== // Clean isRemoteStartWait flag //========================================== if (ocpp_get_isRemoteStartWait()) { if (ShmCharger->gun_info[gun_index].isRemoteStartWait == OFF) { ShmCharger->gun_info[gun_index].isRemoteStartWait = ON; DEBUG_INFO("Remote start without connector id... \n"); } refreshStartTimer(&startTime[gun_index][TMR_IDX_CLEAN_REMOTE_START_WAIT]); } else { if ((getDiffSecNow(startTime[gun_index][TMR_IDX_CLEAN_REMOTE_START_WAIT]) > 5)) { if (ShmCharger->gun_info[gun_index].isRemoteStartWait == ON) { ShmCharger->gun_info[gun_index].isRemoteStartWait = OFF; DEBUG_INFO("Clean isRemoteStartWait flag... \n"); } } if ((getDiffSecNow(startTime[gun_index][TMR_IDX_CLEAN_REMOTE_START_WAIT]) > 10)) refreshStartTimer(&startTime[gun_index][TMR_IDX_CLEAN_REMOTE_START_WAIT]); } //========================================== // Connector process //========================================== switch (getTargetChargingInfoData(gun_index)->SystemStatus) { case SYS_MODE_BOOTING: if (isModeChange(gun_index)) { uint8_t idxCHAdeMO = 0; uint8_t idxCCS = 0; uint8_t idxGB = 0; uint8_t idxAC = 0; DEBUG_INFO("========== SYS_MODE_BOOTING (%d) ========== \n", gun_index); //CSU Initialization & task spawn if ((Initialization(gun_index) != PASS) || (SpawnTask(gun_index) != PASS)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = ON; refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_LCD]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_RFID]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_METER]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_STATE_B]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_LED_STATUS]); refreshStartTimer(&startTime[gun_index][TMR_IDX_LCM_POWER_CONSUMPTION]); for (int gun_index = 0; gun_index < modelnameInfo.GetGunCount; gun_index++) { if (modelnameInfo.ParsingInfo[gun_index].GunType == Gun_Type_Chademo) { ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].Index = gun_index; idxCHAdeMO ++; } else if (modelnameInfo.ParsingInfo[gun_index].GunType == Gun_Type_CCS_2) { ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].Index = gun_index; idxCCS ++; } else if (modelnameInfo.ParsingInfo[gun_index].GunType == Gun_Type_GB) { ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGB].Index = gun_index; idxGB ++; } else if (modelnameInfo.ParsingInfo[gun_index].GunType == Gun_Type_AC) { ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].Index = gun_index; idxAC ++; } } } if (gun_index == 0)//lwtest { ShmCharger->gun_selectd = 0; // Firmware version get_firmware_version(gun_index); // OCPP BootNotification info set DEBUG_INFO("==========================================\n"); DEBUG_INFO("System ID: %s\n", ShmSysConfigAndInfo->SysConfig.SystemId); DEBUG_INFO("==========================================\n"); DEBUG_INFO("=== OCPP BootNotification information ====\n"); ocpp_boot_info_sync(); DEBUG_INFO("OcppServerURL: %s\n", ShmSysConfigAndInfo->SysConfig.OcppServerURL); DEBUG_INFO("ChargeBoxId: %s\n", ShmSysConfigAndInfo->SysConfig.ChargeBoxId); DEBUG_INFO("ChargePointVendor: %s\n", ShmSysConfigAndInfo->SysConfig.chargePointVendor); DEBUG_INFO("==========================================\n"); // Set max current to rating current if (modelnameInfo.GetGunCount > 1) { ShmCharger->gun_info[0].primaryMcuCp_Pwn_Duty.max_current = ShmSysConfigAndInfo->SysConfig.RatingCurrent; ShmCharger->gun_info[1].primaryMcuCp_Pwn_Duty.max_current = ShmSysConfigAndInfo->SysConfig.RatingCurrent; } else { ShmCharger->gun_info[0].primaryMcuCp_Pwn_Duty.max_current = ShmSysConfigAndInfo->SysConfig.RatingCurrent; } // Default Ethernet / Wifi / 4G to 1:disconnected ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = OFF; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = OFF; //lwtest switch (ShmSysConfigAndInfo->SysConfig.ModelName[INTERNET_TYPE]) { case 'E': ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = OFF; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = OFF; break; case 'W': ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = OFF; break; case 'T': ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = OFF; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = ON; break; case 'D': ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = ON; break; } // If Web Server OPCC URL is empty kill Module_OcppBackend if ((strcmp((char *) &ShmSysConfigAndInfo->SysConfig.OcppServerURL, "") == 0)) { if (strcmp((char *) &ShmSysConfigAndInfo->SysConfig.OcppServerURL, "") == 0) DEBUG_INFO("URL is empty kill Module_OcppBackend...\n"); system("pkill OcppBackend"); } // The system identifies 1 phase or 3 phases depending on the model name ShmSysConfigAndInfo->SysConfig.AcPhaseCount = getAcPhaseCount(); } setChargerMode(gun_index, SYS_MODE_IDLE); //lwtest .. for GL testing control. ShmCharger->gun_info[gun_index].isCmdToPrepareMode = OFF; break; case SYS_MODE_IDLE: if (isModeChange(gun_index)) { DEBUG_INFO("========== SYS_MODE_IDLE (%d) ========== \n", gun_index); setLedMotion(gun_index, LED_ACTION_IDLE); setRelay(gun_index, OFF); setRequest(gun_index, OFF); ShmCharger->gun_info[gun_index].isGunPlugged = NO; ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = NO; ShmCharger->gun_info[gun_index].rfidReq = OFF; ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart = OFF; ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop = OFF; ShmCharger->gun_info[gun_index].isGetEvCCID = OFF; ocpp_set_remotestart(gun_index, OFF); ocpp_set_remotestop(gun_index, OFF); ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode = 0x00; getTargetChargingInfoData(gun_index)->PresentChargedDuration = 0; presentChargedEnergyClear(gun_index); ShmCharger->gun_info[gun_index].targetCurrent = 0xFF; ocpp_set_unlocker_req(gun_index, OFF); getTargetChargingInfoData(gun_index)->ReservationId = -1; // Response StopTransactionConf ocpp_set_stoptransaction_conf(gun_index, OFF); memset(getTargetChargingInfoData(gun_index)->StartUserId, 0x00, ARRAY_SIZE(getTargetChargingInfoData(gun_index)->StartUserId)); memset(ShmSysConfigAndInfo->SysConfig.UserId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); //lwtest memset(ShmCharger->gun_info[gun_index].AuthAcceptUserId, 0x00, ARRAY_SIZE(ShmCharger->gun_info[gun_index].AuthAcceptUserId)); ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_IDLE; ShmCharger->gun_info[gun_index].chargingMode = CHARGING_MODE_BS; ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].isDoEvReadyOnce = OFF; ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID; //if(ShmCharger->isCcsEnable)system("pkill Module_CCS"); DB_Check_Record_Buf(localDb, gun_index); ShmCharger->gun_info[gun_index].isEmergencyStopReport = OFF; // Default previousData every time previousData[gun_index].primaryMcuCp_Pwn_Duty = 0; previousData[gun_index].targetCurrent = 0; previousData[gun_index].current_limit = 0; previousData[gun_index].current_limit = 0; getTargetChargingInfoData(gun_index)->PilotState = CP_STATE_A; getTargetChargingInfoData(gun_index)->ConnectorPlugIn = 0; sleep(5); getTargetChargingInfoData(gun_index)->PilotState = CP_STATE_B; getTargetChargingInfoData(gun_index)->ConnectorPlugIn = 1; } if (((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) && (getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_B)) || ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) && (getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_C)) || ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) && (ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON)) || (ShmCharger->gun_info[gun_index].rfidReq == ON) || (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart == ON) || (ocpp_get_remotestart(gun_index) == ON) || (getTargetChargingInfoData(gun_index)->schedule.isTriggerStart == ON) || (ShmCharger->gun_info[gun_index].isGetEvCCID == ON) || (ShmCharger->gun_info[gun_index].isCmdToPrepareMode == ON)) //lwtest { if ((ShmCharger->gun_info[gun_index].rfidReq == ON)) { getTargetChargingInfoData(gun_index)->StartMethod = START_METHOD_RFID; getTargetChargingInfoData(gun_index)->StartIdType = IdTokenType_ISO14443; DEBUG_INFO("Start Method : RFID...\n"); } else if (ocpp_get_remotestart(gun_index)) { getTargetChargingInfoData(gun_index)->StartMethod = START_METHOD_BACKEND; getTargetChargingInfoData(gun_index)->StartIdType = IdTokenType_Central; ocpp_copy_userid_from_remotestart(gun_index); setSpeaker(ON, SPEAKER_SHORT); DEBUG_INFO("Start Method : BACKEND...\n"); } else if (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart == ON) { getTargetChargingInfoData(gun_index)->StartMethod = START_METHOD_BLE; getTargetChargingInfoData(gun_index)->StartIdType = IdTokenType_Local; memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmCharger->gun_info[gun_index].bleLoginCentralId.id, ARRAY_SIZE(ShmCharger->gun_info[gun_index].bleLoginCentralId.id)); setSpeaker(ON, SPEAKER_SHORT); DEBUG_INFO("Start Method : BLE...\n"); } else if (ShmCharger->gun_info[gun_index].isGetEvCCID == ON) { getTargetChargingInfoData(gun_index)->StartMethod = START_METHOD_EVCCID; getTargetChargingInfoData(gun_index)->StartIdType = IdTokenType_MacAddress; setSpeaker(ON, SPEAKER_SHORT); DEBUG_INFO("Start Method : EVCCID...\n"); } else if (ShmCharger->gun_info[gun_index].isCmdToPrepareMode == ON)//lwtest .. for GL testing control { getTargetChargingInfoData(gun_index)->StartMethod = START_METHOD_CMD; getTargetChargingInfoData(gun_index)->PilotState = CP_STATE_B; DEBUG_INFO("Start Method : COMMAND...\n"); } else { getTargetChargingInfoData(gun_index)->StartMethod = START_METHOD_FREE; getTargetChargingInfoData(gun_index)->StartIdType = IdTokenType_NoAuthorization; ocpp_get_freevend_idtag(ShmSysConfigAndInfo->SysConfig.UserId); setSpeaker(ON, SPEAKER_SHORT); DEBUG_INFO("Start Method : FREE...\n"); } ShmCharger->gun_info[gun_index].rfidReq = OFF; ocpp_set_remotestart(gun_index, OFF); ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart = OFF; ShmCharger->gun_info[gun_index].isGunPlugged = NO; ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = NO; getTargetChargingInfoData(gun_index)->schedule.isTriggerStart = OFF; ShmCharger->gun_info[gun_index].isGetEvCCID = OFF; // Get target current ocpp_set_profile_req(gun_index, ON); sleep(1); checkChargingProfileLimit(gun_index, getTargetChargingInfoData(gun_index)->SystemStatus); setChargerMode(gun_index, SYS_MODE_AUTHORIZING); } else { } break; case SYS_MODE_AUTHORIZING: if (isModeChange(gun_index)) { DEBUG_INFO("========== SYS_MODE_AUTHORIZING (%d)========== \n", gun_index); refreshStartTimer(&startTime[gun_index][TMR_IDX_AUTH]); if (ocpp_isAuthorizeRemoteStart() && (getTargetChargingInfoData(gun_index)->StartMethod == START_METHOD_BACKEND)) { DEBUG_INFO("Remote start request authorize.\n"); ocpp_set_auth_req(ON, "ISO14443"); } else if ((getTargetChargingInfoData(gun_index)->StartMethod == START_METHOD_EVCCID)) { DEBUG_INFO("EVCCID request authorize.\n"); ocpp_set_auth_req(ON, "MacAddress"); } } if (getDiffSecNow(startTime[gun_index][TMR_IDX_AUTH]) > TIMEOUT_SPEC_AUTH) { // Authorization timeout process. setSpeaker(ON, SPEAKER_INTERVAL_3COUNT); setLedMotion(gun_index, LED_ACTION_RFID_FAIL); sleep(3); setChargerMode(gun_index, SYS_MODE_IDLE); DEBUG_WARN("Authorize timeout !!!\n"); } else { switch (getTargetChargingInfoData(gun_index)->StartMethod) { case START_METHOD_BACKEND: if (ocpp_isAuthorizeRemoteStart()) { if (ocpp_get_auth_conf()) { if (ocpp_get_auth_result(gun_index)) { memcpy((char*) getTargetChargingInfoData(gun_index)->StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); DEBUG_INFO("Authorize pass.\n"); setSpeaker(ON, SPEAKER_SHORT); setLedMotion(gun_index, LED_ACTION_RFID_PASS); sleep(4); setChargerMode(gun_index, SYS_MODE_PREPARING); } else { DEBUG_INFO("Authorize fail.\n"); setSpeaker(ON, SPEAKER_INTERVAL_3COUNT); setLedMotion(gun_index, LED_ACTION_RFID_FAIL); sleep(3); setChargerMode(gun_index, SYS_MODE_IDLE); } ocpp_set_auth_conf(OFF); } } else { setChargerMode(gun_index, SYS_MODE_PREPARING); } break; case START_METHOD_EVCCID: ShmCharger->gun_info[gun_index].resultAuthorization = UNKNOW_RFID; if (ocpp_get_auth_conf() || (!ocpp_get_connection_status() && ((ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE) || (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_NOCHARGE))) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (getDiffSecNow(startTime[0][TMR_IDX_AUTH]) > 2))) { if (ocpp_get_auth_result(gun_index) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) || (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST))) { memcpy((char*) getTargetChargingInfoData(gun_index)->StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); ShmCharger->gun_info[gun_index].resultAuthorization = VALIDATED_RFID; DEBUG_INFO("Authorize pass [EVCCID].\n"); setSpeaker(ON, SPEAKER_SHORT); setLedMotion(gun_index, LED_ACTION_RFID_PASS); sleep(1); setChargerMode(gun_index, SYS_MODE_PREPARING); ShmCharger->gun_info[gun_index].isEvCCIDAuthorizeFail = NO; } else { ShmCharger->gun_info[gun_index].resultAuthorization = UNVALIDATED_RFID; DEBUG_INFO("Authorize fail [EVCCID].\n"); setSpeaker(ON, SPEAKER_INTERVAL_3COUNT); setLedMotion(gun_index, LED_ACTION_RFID_FAIL); sleep(3); setChargerMode(gun_index, SYS_MODE_IDLE); ShmCharger->gun_info[gun_index].isEvCCIDAuthorizeFail = YES; ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; } ocpp_set_auth_conf(OFF); } break; case START_METHOD_RFID: case START_METHOD_BLE: case START_METHOD_FREE: case START_METHOD_CMD: default: setChargerMode(gun_index, SYS_MODE_PREPARING); break; } } break; case SYS_MODE_PREPARING: if (isModeChange(gun_index)) { DEBUG_INFO("========== SYS_MODE_PREPARING (%d)========== \n", gun_index); //lwtest .. for GL testing control if (ShmCharger->gun_info[gun_index].isCmdToPrepareMode != ON) getTargetChargingInfoData(gun_index)->PilotState = CP_STATE_C; refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]); ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID; ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_CP_STATE_E; ShmCharger->gun_info[gun_index].chargingMode = CHARGING_MODE_BS; setRequest(gun_index, ON); sleep(3); } // If control pilot detect Bx, skip watch dog time out. if ((getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_B) || (getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_C)) { ShmCharger->gun_info[gun_index].isGunPlugged = YES; ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = NO; switch (ShmCharger->gun_info[gun_index].ccsHandshakeState) { case HANDSHAKE_CP_STATE_E: DEBUG_INFO("Determine max charging current to MCU.\n"); ocpp_set_profile_req(gun_index, ON); sleep(1); checkChargingProfileLimit(gun_index, getTargetChargingInfoData(gun_index)->SystemStatus); ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_SET_MAX_CURRENT; refreshStartTimer(&startTime[gun_index][TMR_IDX_BS_HLC_HANDSHAKE]); sleep(1); break; case HANDSHAKE_SET_MAX_CURRENT: ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_BS_MODE; DEBUG_INFO("Enter BS Mode charging.\n"); //for EV READY 30 secs didn't start charging to STATE E refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]); sleep(1); break; case HANDSHAKE_BS_MODE: refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]); checkChargingProfileLimit(gun_index, getTargetChargingInfoData(gun_index)->SystemStatus); if (ShmCharger->gun_info[gun_index].targetCurrent != 0 && ShmCharger->gun_info[gun_index].isCmdToPrepareMode == OFF) setRelay(gun_index, ON); //---------------LW test for GL test platform start----------------- else if (ShmCharger->gun_info[gun_index].isCmdToPrepareMode == ON) { //Plugin state and wait trigger start. if (ShmCharger->gun_info[gun_index].isCmdToPrepareMode == ON && (ocpp_get_remotestart(gun_index) == ON || ShmCharger->gun_info[gun_index].rfidReq == ON)) { if (ocpp_get_remotestart(gun_index)) { getTargetChargingInfoData(gun_index)->StartIdType = IdTokenType_Central; ocpp_copy_userid_from_remotestart(gun_index); DEBUG_INFO("LW debug Message : GL Remote Start.\n"); /////////////// if (ocpp_isAuthorizeRemoteStart()) { DEBUG_INFO("LW debug Message : GL Remote Start request authorize.\n"); ocpp_set_auth_req(ON, "ISO14443"); if (ocpp_get_auth_conf()) { if (ocpp_get_auth_result(gun_index)) { memcpy( (char*) getTargetChargingInfoData(gun_index)->StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); DEBUG_INFO("LW debug Message : GL Authorize pass.\n"); } else { DEBUG_INFO("LW debug Message : GL Authorize fail.\n"); setChargerMode(gun_index, SYS_MODE_TERMINATING); } ocpp_set_auth_conf(OFF); } } } setRelay(gun_index, ON); ShmCharger->gun_info[gun_index].isCmdToPrepareMode = OFF; ShmCharger->gun_info[gun_index].rfidReq = OFF; getTargetChargingInfoData(gun_index)->PilotState = CP_STATE_C; } //---------------LW test for GL test platform end----------------- } if ((getRelay(gun_index) == ON) || (ShmCharger->gun_info[gun_index].targetCurrent == 0)) { ocpp_set_unlocker_req(gun_index, OFF); presentChargedEnergyClear(gun_index); getDateTimeString((char*) getTargetChargingInfoData(gun_index)->StartDateTime); ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption; ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption; ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption; ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption; if (ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 1) getTargetChargingInfoData(gun_index)->PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption / 10000.0); else { getTargetChargingInfoData(gun_index)->PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption / 10000.0); } //lwtest if (ocpp_get_remotestart(gun_index)) { memcpy((char*) getTargetChargingInfoData(gun_index)->StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); } else { memcpy((char*) getTargetChargingInfoData(gun_index)->StartUserId, ShmCharger->gun_info[gun_index].AuthAcceptUserId, ARRAY_SIZE(ShmCharger->gun_info[gun_index].AuthAcceptUserId)); } ocpp_copy_userid_to_starttransaction(gun_index); ocpp_set_starttransaction_req(gun_index, ON); refreshStartTimer(&startChargingTime[gun_index]); setChargerMode(gun_index, SYS_MODE_CHARGING); } sleep(1); break; default: break; } } // Unplug charging gun to Idle mode if ((getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_A) && (ShmCharger->gun_info[gun_index].isGunPlugged == YES)) { DEBUG_INFO("The connector was connected to the EV before.\n"); //Cancel CCS task negotiating ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = ON; } // Use RFID card to stop handshaking if ((ShmCharger->gun_info[gun_index].rfidReq == ON) && isMatchPresentUser()) { DEBUG_INFO("Use RFID card to stop handshaking.\n"); //Cancel CCS task negotiating ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = ON; //lwtest setChargerMode(gun_index, SYS_MODE_TERMINATING); } else { ShmCharger->gun_info[gun_index].rfidReq = OFF; } //lwtest if (getTargetChargingInfoData(gun_index)->schedule.isTriggerStop == ON) { setChargerMode(gun_index, SYS_MODE_TERMINATING); } checkHandshakeCountdown(gun_index); if (getDiffSecNow(startTime[gun_index][TMR_IDX_HANDSHAKING]) > ShmCharger->timeoutSpec.Present_Timeout_Spec) { setLedMotion(gun_index, LED_ACTION_HANDSHAKE_FAIL); if (getDiffSecNow(startTime[gun_index][TMR_IDX_HANDSHAKING]) > (ShmCharger->timeoutSpec.Present_Timeout_Spec + 5)) { DEBUG_INFO("Handshaking timeout...\n"); //Cancel CCS task negotiating ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = ON; } } break; case SYS_MODE_CHARGING: if (isModeChange(gun_index)) { DEBUG_INFO("========== SYS_MODE_CHARGING (%d) ========== \n", gun_index); ShmCharger->gun_info[gun_index].rfidReq = OFF; refreshStartTimer(&startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]); refreshStartTimer(&startTime[gun_index][TMR_IDX_PROFILE_PREPARE]); refreshStartTimer(&startTime[gun_index][TMR_IDX_PWN_CHANGE]); ocpp_set_auth_req(OFF); ocpp_reset_smartcharging_profileId(gun_index); ocpp_set_profile_req(gun_index, ON); ShmCharger->gun_info[gun_index].isChargerStopByCondition = NO; ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID; } if ((ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES) || (ShmCharger->gun_info[gun_index].rfidReq == ON) || (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop == ON) || ocpp_get_remotestop(gun_index) || (ocpp_get_connection_status() && !ocpp_get_starttransaction_result(gun_index)) || ((ShmCharger->gun_info[gun_index].chargingMode != CHARGING_MODE_SOCKETE) && getTargetChargingInfoData(gun_index)->PilotState != CP_STATE_C) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) && !ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn) || ocpp_get_reset_req() || ocpp_get_unlocker_req(gun_index) || (getTargetChargingInfoData(gun_index)->schedule.isTriggerStop == ON) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress == HLC_STOP_MODE)) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress == HLC_RENEGOTIATE_MODE)) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress == HLC_STANDBY_MODE)) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && ((49 <= ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus) && (ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus <= 255)))) { setChargerMode(gun_index, SYS_MODE_TERMINATING); } else { // Charging session info calculation if (ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 1) getTargetChargingInfoData(gun_index)->PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption / 10000.0); else { getTargetChargingInfoData(gun_index)->PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption / 10000.0); } refreshStartTimer(&endChargingTime[gun_index]); getTargetChargingInfoData(gun_index)->PresentChargedDuration = getDiffSecBetween(startChargingTime[gun_index], endChargingTime[gun_index]); presentChargedEnergyUpdate(gun_index); // Response StartTransactionConf ocpp_set_starttransaction_conf(gun_index, OFF); // Charging profile preparation if ((getDiffSecNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) > TIMEOUT_SPEC_PROFILE_PREPARE) || (getDiffSecNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) < 0)) { if (!ocpp_get_profile_conf(gun_index)) { ocpp_set_profile_req(gun_index, ON); refreshStartTimer(&startTime[gun_index][TMR_IDX_PROFILE_PREPARE]); } else { ocpp_set_profile_conf(gun_index, OFF); } } // Checking profile id > 0 and current time is between charging profile validFrom & validTo checkChargingProfileLimit(gun_index, getTargetChargingInfoData(gun_index)->SystemStatus); // Charging session local limit condition check if (ocpp_get_connection_status()) { // On-line max condition check if ((ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (getTargetChargingInfoData(gun_index)->PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration * 60))) { if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isChargerStopByCondition = YES; } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { setRelay(gun_index, OFF); } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { setRelay(gun_index, OFF); } else { } setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO("Connector-%d charging duration(%d) already over max duration(%d) in second.\n", gun_index, getTargetChargingInfoData(gun_index)->PresentChargedDuration, (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration * 60)); } else if ((ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (getTargetChargingInfoData(gun_index)->PresentChargedEnergy >= ((float) ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy))) { if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isChargerStopByCondition = YES; } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { setRelay(gun_index, OFF); } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { setRelay(gun_index, OFF); } else { } setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO("Connector-%d charging energy(%.2f) already over max energy(%.2f) in KWH.\n", gun_index, getTargetChargingInfoData(gun_index)->PresentChargedEnergy, ((float )ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy)); } else { if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { ShmCharger->gun_info[gun_index].isChargerStopByCondition = NO; if (ShmCharger->gun_info[gun_index].targetCurrent > 0) setRelay(gun_index, ON); else setRelay(gun_index, OFF); } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { if (getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_C) setRelay(gun_index, ON); } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { if (ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON) setRelay(gun_index, ON); else setRelay(gun_index, OFF); } else { } } } else { // Off-line max condition check if ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) || ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy != OFF_POLICY_NOCHARGE))) { if (((ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration > 0) ? (getTargetChargingInfoData(gun_index)->PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration * 60)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (getTargetChargingInfoData(gun_index)->PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration * 60)))) { if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isChargerStopByCondition = YES; } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { setRelay(gun_index, OFF); } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { setRelay(gun_index, OFF); } else { } setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO( "Connector-%d charging duration(%d) already over off-line max duration(%d) in second.\n", gun_index, getTargetChargingInfoData(gun_index)->PresentChargedDuration, (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration * 60)); } else if (((ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy > 0) ? (getTargetChargingInfoData(gun_index)->PresentChargedEnergy >= ((float) ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (getTargetChargingInfoData(gun_index)->PresentChargedEnergy >= ((float) ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy)))) { if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isChargerStopByCondition = YES; } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { setRelay(gun_index, OFF); } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { setRelay(gun_index, OFF); } else { } setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO( "Connector-%d charging energy(%.2f) already over off-line max energy(%.2f) in KWH.\n", gun_index, getTargetChargingInfoData(gun_index)->PresentChargedEnergy, ((float )ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy)); } else { if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { ShmCharger->gun_info[gun_index].isChargerStopByCondition = NO; if (ShmCharger->gun_info[gun_index].targetCurrent > 0) setRelay(gun_index, ON); else setRelay(gun_index, OFF); } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { if (getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_C) setRelay(gun_index, ON); } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { if (ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON) setRelay(gun_index, ON); else setRelay(gun_index, OFF); } else { } } } else { if (ShmCharger->gun_info[gun_index].primaryMcuState.relay_state > 0) DEBUG_INFO("Connector-%d can not charging in off line\n", gun_index); setRelay(gun_index, OFF); } } // Debug information if ((getDiffSecNow(startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]) > TIMEOUT_SPEC_LOGPPRINTOUT) || (getDiffSecNow(startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]) < 0)) { refreshStartTimer(&startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]); getDateTimeString((char*) getTargetChargingInfoData(gun_index)->StopDateTime); DB_Update_Record_Buf(localDb, gun_index); } } break; case SYS_MODE_TERMINATING: if (isModeChange(gun_index)) { DEBUG_INFO("========== SYS_MODE_TERMINATING (%d)========== \n", gun_index); if (!ShmCharger->gun_info[gun_index].primaryMcuState.relay_state) { setLedMotion(gun_index, LED_ACTION_STOP); } else { } getDateTimeString((char*) getTargetChargingInfoData(gun_index)->StopDateTime); ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID; if (ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES) setRelay(gun_index, OFF); } refreshStartTimer(&endChargingTime[gun_index]); getTargetChargingInfoData(gun_index)->PresentChargedDuration = getDiffSecBetween( startChargingTime[gun_index], endChargingTime[gun_index]); // End authorize pass if (((ShmCharger->gun_info[gun_index].rfidReq == ON) && isMatchStartUser()) || ((ShmCharger->gun_info[gun_index].rfidReq == ON) && ocpp_get_auth_result(YES, gun_index)) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE) && (ShmCharger->gun_info[gun_index].rfidReq == ON)) || (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (ShmCharger->gun_info[gun_index].rfidReq == ON)) || (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop == ON) || ocpp_get_remotestop(gun_index) || (ocpp_get_connection_status() && !ocpp_get_starttransaction_result(gun_index)) || ((ShmCharger->gun_info[gun_index].chargingMode != CHARGING_MODE_SOCKETE) && ((getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_A) || (ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES)) && ocpp_get_StopTransactionOnEVSideDisconnect()) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) && ((!ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn) || (ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES))) || ocpp_get_reset_req() || ocpp_get_unlocker_req(gun_index) || (getTargetChargingInfoData(gun_index)->schedule.isTriggerStop == ON) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress == HLC_STOP_MODE))) { setLedMotion(gun_index, LED_ACTION_STOP); if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; sleep(1); checkStopReason(gun_index); setChargerMode(gun_index, SYS_MODE_COMPLETE); } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { //setChargerMode(gun_index, SYS_MODE_COMPLETE); //Cancel CCS task negotiating ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = ON; } else { setChargerMode(gun_index, SYS_MODE_COMPLETE); } } else { // If the charger stops charging, the led should be stoped blink if (!ShmCharger->gun_info[gun_index].primaryMcuState.relay_state) { setLedMotion(gun_index, LED_ACTION_STOP); } // Charging profile preparation if ((getDiffSecNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) > TIMEOUT_SPEC_PROFILE_PREPARE) || (getDiffSecNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) < 0)) { if (!ocpp_get_profile_conf(gun_index)) { ocpp_set_profile_req(gun_index, ON); refreshStartTimer(&startTime[gun_index][TMR_IDX_PROFILE_PREPARE]); } else { ocpp_set_profile_conf(gun_index, OFF); } } // Checking profile id > 0 and current time is between charging profile validFrom & validTo checkChargingProfileLimit(gun_index, getTargetChargingInfoData(gun_index)->SystemStatus); setRelay(gun_index, OFF); // Debug information if ((getDiffSecNow(startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]) > TIMEOUT_SPEC_LOGPPRINTOUT) || (getDiffSecNow(startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]) < 0)) { refreshStartTimer(&startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]); } if (!ocpp_get_auth_result(YES, gun_index)) ShmCharger->gun_info[gun_index].rfidReq = OFF; if ((ShmCharger->gun_info[gun_index].isGunUnpluggedBefore != YES) && (((ShmCharger->gun_info[gun_index].chargingMode != CHARGING_MODE_SOCKETE) && (getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_C)) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) && ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn)) && (ShmCharger->gun_info[gun_index].rfidReq != ON) && (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop != ON) && !ocpp_get_remotestop(gun_index) && (getTargetChargingInfoData(gun_index)->schedule.isTriggerStop != ON) && !ocpp_get_reset_req() && ocpp_get_starttransaction_result(gun_index) && !(ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (getTargetChargingInfoData(gun_index)->PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration * 60))) && !(ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (getTargetChargingInfoData(gun_index)->PresentChargedEnergy >= ((float) ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy))) && !(!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy != OFF_POLICY_NOCHARGE) && ((ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration > 0) ? (getTargetChargingInfoData(gun_index)->PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration * 60)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (getTargetChargingInfoData(gun_index)->PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration * 60)))) && !(!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy != OFF_POLICY_NOCHARGE) && ((ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy > 0) ? (getTargetChargingInfoData(gun_index)->PresentChargedEnergy >= ((float) ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (getTargetChargingInfoData(gun_index)->PresentChargedEnergy >= ((float) ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy)))) && (((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress == HLC_START_MODE)) || (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) || (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE))) { sleep(1); setChargerMode(gun_index, SYS_MODE_CHARGING); } } if ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty == ON) && (ShmCharger->gun_info[gun_index].acCcsInfo.CpSetPWMDuty == CCS_PWM_DUTY_100)) { DEBUG_INFO("Set PWM duty 100%% go to SYS_MODE_TERMINATING.\n"); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = OFF; sleep(1); checkStopReason(gun_index); setChargerMode(gun_index, SYS_MODE_COMPLETE); } break; case SYS_MODE_COMPLETE: if (isModeChange(gun_index)) { DEBUG_INFO("========== SYS_MODE_COMPLETE (%d)========== \n", gun_index); setLedMotion(gun_index, LED_ACTION_STOP); sleep(6); setRelay(gun_index, OFF); setRequest(gun_index, OFF); getTargetChargingInfoData(gun_index)->PilotState = CP_STATE_A; } if (((ShmCharger->gun_info[gun_index].chargingMode != CHARGING_MODE_SOCKETE) && (getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_A)) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) && (!ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn)) || ocpp_get_reset_req()) { sleep(2); ShmCharger->gun_info[gun_index].rfidReq = OFF; ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop = OFF; ocpp_set_remotestop(gun_index, OFF); getTargetChargingInfoData(gun_index)->schedule.isTriggerStop = OFF; ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = NO; DB_Insert_Record(localDb, gun_index); setChargerMode(gun_index, SYS_MODE_IDLE); } break; case SYS_MODE_ALARM: setLedMotion(gun_index, LED_ACTION_ALARM); setRelay(gun_index, OFF); DEBUG_INFO("========== SYS_MODE_ALARM ========== \n"); if ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) || (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC)) { if ((getTargetChargingInfoData(gun_index)->PilotState == CP_STATE_A)) { setRequest(gun_index, OFF); ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = YES; } } else if (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { if (ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn != ON) { setRequest(gun_index, OFF); ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = YES; } } else { } /* * 1. Customize emergency stop and report stop transaction then return to idle mode if error recover. * 2. Customer: Bambang */ if (((ShmSysConfigAndInfo->SysConfig.ModelName[VENDOR_CODE] == 'B') && (ShmSysConfigAndInfo->SysConfig.ModelName[VENDOR_CODE + 1] == 'B')) && (ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode == ALARM_EMERGENCY_STOP)) { if (((getTargetChargingInfoData(gun_index)->PreviousSystemStatus == SYS_MODE_CHARGING) || (getTargetChargingInfoData(gun_index)->PreviousSystemStatus == SYS_MODE_TERMINATING)) && !ShmCharger->gun_info[gun_index].isEmergencyStopReport) { checkStopReason(gun_index); ShmCharger->gun_info[gun_index].isEmergencyStopReport = ON; } } if ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode == 0) && !ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CCSboardStestFail) { if (((getTargetChargingInfoData(gun_index)->PreviousSystemStatus == SYS_MODE_CHARGING) || (getTargetChargingInfoData(gun_index)->PreviousSystemStatus == SYS_MODE_TERMINATING)) && (!ShmCharger->gun_info[gun_index].isEmergencyStopReport)) { setChargerMode(gun_index, getTargetChargingInfoData(gun_index)->PreviousSystemStatus); } else { setChargerMode(gun_index, SYS_MODE_IDLE); } } break; case SYS_MODE_FAULT: if (isModeChange(gun_index)) { DEBUG_INFO("========== SYS_MODE_FAULT (%d) ========== \n", gun_index); } break; case SYS_MODE_MAINTAIN: if (isModeChange(gun_index)) { setLedMotion(gun_index, LED_ACTION_MAINTAIN); DEBUG_INFO("========== SYS_MODE_MAINTAIN (%d) ========== \n", gun_index); } break; case SYS_MODE_UPDATE: if (isModeChange(gun_index)) { DEBUG_INFO("========== SYS_MODE_UPDATE (%d) ========== \n", gun_index); setLedMotion(gun_index, LED_ACTION_MAINTAIN); } //====================================== // Check local upgrade firmware request //====================================== if (ShmSysConfigAndInfo->SysInfo.FirmwareUpdate) { DEBUG_INFO("Firmware local upgrading...\n"); ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = OFF; int value = upgrade_check(); DEBUG_INFO("Local update Value: %s... \n", ((value == PASS)?"Pass": "Fail")); if (value == PASS) { if (ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == ON) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = OFF; ShmCharger->isUpdateSuccess = YES; DEBUG_INFO("Local update success...\n"); } else { if (ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == OFF) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = ON; ShmCharger->isUpdateSuccess = NO; DEBUG_INFO("Local update unsuccess...\n"); } } else if (ocpp_get_update_firmware_req()) { //====================================== // Check remote upgrade firmware request //====================================== checkRemoteUpgradeStatus(); } else { //====================================== // Upgrade complete reboot system //====================================== if (!ShmCharger->gun_info[gun_index].mcuFlag.isMcuUpgradeReq && ((modelnameInfo.GetGunCount > 1) ? !ShmCharger->gun_info[gun_index ^ 1].mcuFlag.isMcuUpgradeReq : YES) && !ShmCharger->isUpgradeLcmReq) { if (ShmCharger->isUpdateSuccess == YES) { sprintf((char*) ShmOCPP16Data->FirmwareStatusNotification.Status, "Installed"); ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; sprintf((char*) ShmOCPP20Data->FirmwareStatusNotification.status, "Installed"); ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; DEBUG_WARN("Firmware upgrade success.\n"); sleep(5); DEBUG_INFO("Firmware upgraded, reboot...\n"); system("reboot -f"); sleep(5); system("reboot -f"); } else { sprintf((char*) ShmOCPP16Data->FirmwareStatusNotification.Status, "InstallationFailed"); ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; sprintf((char*) ShmOCPP20Data->FirmwareStatusNotification.status, "InstallationFailed"); ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; DEBUG_WARN("Firmware upgrade fail.\n"); sleep(5); system("rm -rvf /mnt/* "); close(wtdFd); system("/usr/bin/run_evse_restart.sh"); } } } break; case SYS_MODE_RESERVATION: if (isModeChange(gun_index)) { DEBUG_INFO("========== SYS_MODE_RESERVATION (%d)========== \n", gun_index); } setLedMotion(gun_index, LED_ACTION_RESERVATION_MODE); if (isReservationExpired(gun_index)) { DEBUG_INFO("Reservation: Time's up...\n"); setChargerMode(gun_index, SYS_MODE_IDLE); } else if (ocpp_get_cancelreservation_req(gun_index)) { DEBUG_INFO("Reservation: Cancel reservation...\n"); setChargerMode(gun_index, SYS_MODE_IDLE); ocpp_set_cancelreservation_req(gun_index, OFF); } else { // Check is there RFID or back end request start if ((ShmCharger->gun_info[gun_index].rfidReq == ON) || ocpp_get_remotestart(gun_index)) { if ((ShmCharger->gun_info[gun_index].rfidReq == ON)) { if (ocpp_compare_reserve_id_with_user(gun_index)) { DEBUG_INFO("Start Method in reservation : RFID...\n"); DEBUG_INFO("Start request User Id : %s\n", ShmSysConfigAndInfo->SysConfig.UserId); getTargetChargingInfoData(gun_index)->StartMethod = START_METHOD_RFID; getTargetChargingInfoData(gun_index)->StartIdType = IdTokenType_ISO14443; setChargerMode(gun_index, SYS_MODE_AUTHORIZING); } else { DEBUG_INFO("It's not reserve user id.\n"); ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID; } ShmCharger->gun_info[gun_index].rfidReq = OFF; } else if (ocpp_get_remotestart(gun_index)) { if (ocpp_compare_reserve_id_with_remote_user(gun_index)) { DEBUG_INFO("Start Method in reservation: BACKEND...\n"); getTargetChargingInfoData(gun_index)->StartMethod = START_METHOD_BACKEND; getTargetChargingInfoData(gun_index)->StartIdType = IdTokenType_Central; setChargerMode(gun_index, SYS_MODE_AUTHORIZING); } ocpp_set_remotestop(gun_index, OFF); } } } break; case SYS_MODE_BOOKING: if (isModeChange(gun_index)) { DEBUG_INFO("========== SYS_MODE_BOOKING (%d)========== \n", gun_index); } break; case SYS_MODE_DEBUG: if (isModeChange(gun_index)) { setLedMotion(gun_index, LED_ACTION_DEBUG); DEBUG_INFO("========== SYS_MODE_DEBUG (%d)========== \n", gun_index); } break; } } // System watch dog reset write(wtdFd, "a", 1); usleep(50000); } return FAIL; }