#include "define.h" #include "main.h" //========================== // System basic sample constant //========================== #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 //========================== // Timer interval //========================== #define TMR_IDX_HANDSHAKING 0 #define TMR_IDX_AUTH 1 #define TMR_IDX_LOGPPRINTOUT 2 #define TMR_IDX_PROFILE_PREPARE 3 #define TMR_IDX_PWN_CHANGE 4 #define TMR_IDX_CHECK_TASK 5 #define TMR_IDX_6 6 #define TMR_IDX_7 7 #define TMR_IDX_8 8 #define TMR_IDX_9 9 #define TIMEOUT_SPEC_HANDSHAKING 180000 #define TIMEOUT_SPEC_AUTH 15000 #define TIMEOUT_SPEC_HANDSHAKING_LED 185000 #define TIMEOUT_SPEC_LOGPPRINTOUT 30000 #define TIMEOUT_SPEC_PROFILE_PREPARE 5000 #define TIMEOUT_SPEC_PWN_CHANGE 5000 #define SPEC_TEMPERATURE_WARN 71 #define SPEC_TEMPERATURE_RECOVER 63 #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 setRelay(unsigned char gun_index,unsigned char isOn); void setSpeaker(unsigned char isOn, unsigned char speaker_mode); //========================== // 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 Charger *ShmCharger; struct timeb startTime[AC_QUANTITY][10]; struct timeb startChargingTime[AC_QUANTITY]; struct timeb endChargingTime[AC_QUANTITY]; sqlite3 *localDb; struct SysConfigData SysConfigOrg; //================================= // Common routine //================================= 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; } 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); } 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); //DEBUG_INFO("Kernel version: %d\n", 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; } //====================================================== // 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_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/1000); 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[3]) { 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 gun_index) { uint8_t result = OFF; switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[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) { DEBUG_INFO("==========================================\n"); DEBUG_INFO("=== OCPP GETTING AUTHORIZE RESULT 1.6 ====\n"); DEBUG_INFO("==========================================\n"); DEBUG_INFO("Authorize.ResponseIdTagInfo.ParentIdTag : %s \n", ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag); DEBUG_INFO("StartTransaction[%d].ResponseIdTagInfo.ParentIdTag : %s \n", gun_index ,ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.ParentIdTag); 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) { DEBUG_INFO("==========================================\n"); DEBUG_INFO("=== OCPP GETTING AUTHORIZE RESULT 2.0 ====\n"); DEBUG_INFO("==========================================\n"); DEBUG_INFO("Authorize.Response_idTokenInfo.groupIdToken.idToken : %s \n", ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken); DEBUG_INFO("TransactionEvent[%d].Response_idTokenInfo.groupIdToken.idToken : %s \n", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.groupIdToken.idToken); 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; } 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; } } 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; } } 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; } } 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; } } } 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*)ShmSysConfigAndInfo->SysInfo.AcChargingData[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*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId)); } } 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_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; } //====================================================== // 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 ShmFanModuleData if ((MeterSMId = shmget(ShmFanBdKey, sizeof(struct FanModuleData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmFanModuleData NG\n"); result = FAIL; } else if ((ShmFanModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmFanModuleData NG\n"); result = FAIL; } memset(ShmFanModuleData,0,sizeof(struct FanModuleData)); //creat ShmRelayModuleData if ((MeterSMId = shmget(ShmRelayBdKey, sizeof(struct RelayModuleData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmRelayModuleData NG\n"); result = FAIL; } else if ((ShmRelayModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmRelayModuleData NG\n"); result = FAIL; } memset(ShmRelayModuleData,0,sizeof(struct RelayModuleData));*/ //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)); return result; } //=============================================== // SQLite3 related routine //=============================================== 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" ");"; 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, 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_Insert_Record(sqlite3 *db, int gun_index) { int result = PASS; char* errMsg = NULL; char sqlStr[1024]; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { sprintf(sqlStr, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason) " "values('%d', '%d', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s');", ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId, ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy, ShmOCPP16Data->StopTransaction[gun_index].StopReason); } 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) " "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s');", ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason); } if(sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO( "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, 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;"); 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); } 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 { DEBUG_INFO( "Local charging record database open successfully.\n"); 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 { DEBUG_INFO( "Local config query database open successfully.\n"); 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"); /*4G/Wifi RST:GPIO3_14 => H:ON; L:OFF*/ system("echo 110 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio110/direction"); system("echo 1 > /sys/class/gpio/gpio110/value"); sleep(3); system("echo 0 > /sys/class/gpio/gpio110/value"); DEBUG_INFO("Initial GPIO OK\n"); } 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(wrdAlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum=0; for(wrd=ARRAY_SIZE(ptr->CsuBootLoadFwRev);wrdModelName,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(wrdAlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum=0; for(wrd=ARRAY_SIZE(ptr->CsuBootLoadFwRev);wrdAlarmCode.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(wrdAlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum=0; for(wrd=ARRAY_SIZE(ptr->CsuBootLoadFwRev);wrdCsuBootLoadFwRev)), &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("System id over length.\n"); } system("cd /root;./Module_FactoryConfig -m"); sleep(3); system("/usr/bin/run_evse_restart.sh"); } DEBUG_INFO("Load SysConfigData OK\n"); 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;iSysConfig.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("/sbin/ifconfig eth0:1 192.168.201.201 netmask 255.255.255.248 up &"); system("ifconfig lo up &"); system("/sbin/ethtool -s eth0 speed 10 duplex full autoneg off"); if(isInterfaceUp("eth1")==PASS) { //Init Eth1 for administrator tool memset(tmpbuf,0,256); sprintf(tmpbuf,"/sbin/ifconfig eth1 %s netmask %s up &", ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthIpAddress, ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthSubmaskAddress); system(tmpbuf); } //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(); //check internet status pid = fork(); if(pid == 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->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[10] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { system("/sbin/ifmetric mlan0 1"); } if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { system("/sbin/ifmetric ppp0 2"); } } else if(!ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi) { if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { system("/sbin/ifmetric eth0 1"); system("/sbin/ifmetric mlan0 0"); } if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { system("/sbin/ifmetric ppp0 2"); } } else if(!ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi) { if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { system("/sbin/ifmetric mlan0 2"); } if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { system("/sbin/ifmetric eth0 1"); system("/sbin/ifmetric ppp0 0"); } } sleep(5); } } DEBUG_INFO("Initial Ethernet OK\n"); } int SpawnTask() { system ("pkill Module_"); system ("pkill OcppBackend"); if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { system("/root/Module_4g &"); } else if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { system("/root/Module_Wifi &"); } system("/root/Module_EventLogging &"); 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(); } system ("/root/Module_AlarmDetect &"); system ("/root/Module_InternalComm &"); system ("/root/Module_Speaker &"); system ("/root/Module_ProduceUtils &"); return PASS; } int Initialization() { int result = PASS; LoadSysConfigAndInfo(&ShmSysConfigAndInfo->SysConfig); InitGPIO(); InitEthernet(); if(DB_Open(localDb) != PASS) { DEBUG_ERROR("Local database initial fail.\n"); result = FAIL; } for(int gun_index=0;gun_index< AC_QUANTITY;gun_index++) ShmCharger->gun_info[gun_index].isOperactive = DB_Get_Operactive(localDb, gun_index); 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) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus = ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus = mode; DEBUG_INFO("Gun-%02d mode switch from %s to %s\n", gun_index, getSystemModeName(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus), getSystemModeName(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus)); } unsigned char isMode(unsigned char gun_index, unsigned char mode) { return ((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == mode)?YES:NO); } unsigned char isModeChange(unsigned char gun_index) { unsigned char result = NO; if(!isMode(gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus)) { result = YES; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus = ShmSysConfigAndInfo->SysInfo.AcChargingData[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; } //=============================================== // 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 strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[gun_index].ver.Version_FW); // Get CSU root file system version sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "V0.69.00.0000.00"); // Get AC connector type from model name for(uint8_t idx=0;idx<3;idx++) { switch(ShmSysConfigAndInfo->SysConfig.ModelName[7+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[10]) { 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[4], 0x03); memcpy(&ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[10], &ShmSysConfigAndInfo->SysConfig.ModelName[4], 0x03); // Get vender code from model name memcpy(&ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[14], &ShmSysConfigAndInfo->SysConfig.ModelName[12], 0x02); memcpy(&ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[14], &ShmSysConfigAndInfo->SysConfig.ModelName[12], 0x02); 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[gun_index].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; if ((dir = opendir ("/mnt")) != NULL) { /* print all the files and directories within directory */ while ((file = readdir (dir)) != NULL) { if(strlen(file->d_name)>2) { 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 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((strcmp(ShmCharger->fwUpgradeInfo.modelName, (char*)ShmSysConfigAndInfo->SysConfig.ModelName)==0) && (ShmCharger->fwUpgradeInfo.fwType>0)) { switch(ShmCharger->fwUpgradeInfo.fwType) { 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_indexgun_info[gun_index].mcuFlag.isMcuUpgradeReq = ON; 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"); } 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 //=============================================== int isMatchStartUser(unsigned char gun_index) { uint8_t tmpUser[32]; 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_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_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; } } return ((strcmp((char*)tmpUser, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId)==0)?YES:NO); } //=============================================== // 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) { 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; } } //=============================================== // Request on/off set (PWM) //=============================================== 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 (PWM) //=============================================== int getRequest(unsigned char gun_index) { return ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest; } //=============================================== // Relay on/off set (Relay) //=============================================== void setRelay(unsigned char gun_index,unsigned char isOn) { if(isOn == ON) { if(ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn == OFF) { 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. \n",gun_index); } } else { if(ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn == ON) { 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. \n",gun_index); } } } //=============================================== // Relay on/off get (Relay) //=============================================== 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) { 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]; 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(tmp, tmp, strspn(tmp, "addr:"), strlen(buf)-strspn(tmp, "addr:")); if (strcmp(tmp, (char *)ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress) != 0) { strcpy((char *) ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, tmp); } sscanf(buf, "%*s%*s%*s%s", tmp); substr(tmp, tmp, strspn(tmp, "Mask:"), strlen(buf)-strspn(tmp, "Mask:")); if (strcmp(tmp, (char *)ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress) != 0) { strcpy((char *) ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress, tmp); } } } } 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 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; } //=============================================== // Check route for eth0 //=============================================== 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 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;idxSysConfig.LocalWhiteCard);idx++) { if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.UserId, (char*)ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[idx]) == 0) { result = PASS; } } return result; } //========================================== // Check routine //========================================== void checkTask() { if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == '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[10] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == '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(system("pidof -s Module_AlarmDetect > /dev/null") != 0) { DEBUG_INFO("Module_AlarmDetect not running, restart it.\n"); system("/root/Module_AlarmDetect &"); } if(system("pidof -s Module_InternalComm > /dev/null") != 0) { DEBUG_INFO("Module_InternalComm not running, restart it.\n"); system("/root/Module_InternalComm &"); } 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 &"); } /* if((system("pidof -s Module_InitUpgrade > /dev/null") != 0) && ShmSysConfigAndInfo->SysConfig.isReqFirstUpgrade) { DEBUG_INFO("Module_InitUpgrade not running, restart it.\n"); system ("/root/Module_InitUpgrade &"); }*/ } 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/1000); } else { if(strcmp((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[ConnectionTimeOut].ItemData,"") != 0) { ShmCharger->timeoutSpec.Setting_Timeout_Spec = atoi((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[ConnectionTimeOut].ItemData); if(ShmCharger->timeoutSpec.Setting_Timeout_Spec <= 0) { ShmCharger->timeoutSpec.Present_Timeout_Spec = TIMEOUT_SPEC_HANDSHAKING; //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*1000); //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); } else { ShmCharger->timeoutSpec.Present_Timeout_Spec = TIMEOUT_SPEC_HANDSHAKING; //DEBUG_INFO("Handshaking timeout specification follow by OCPP Configuration : Fail. Table is blank...\n."); } //DEBUG_INFO("Present timeout spec : %d \n", ShmCharger->timeoutSpec.Present_Timeout_Spec); } } 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)) && (AC_QUANTITY>1?(!isMode(1, SYS_MODE_CHARGING) && !isMode(1, SYS_MODE_TERMINATING) && !isMode(0, 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_indexReset.Type, "Hard") == 0) { system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } else { sleep(5); 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)) && (AC_QUANTITY>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_indexReset.type, "Immediate") == 0) { system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } else { sleep(5); 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; if(isMode(gun_index, SYS_MODE_IDLE) && !isReservationExpired(gun_index)) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId = ShmOCPP16Data->ReserveNow[gun_index].ReservationId; setChargerMode(gun_index, SYS_MODE_RESERVATION); } DEBUG_INFO("Reservation request on connector-%d.\n", gun_index); ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowConf = ON; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowReq) { ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowReq = OFF; if(isMode(gun_index, SYS_MODE_IDLE) && !isReservationExpired(gun_index)) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId = ShmOCPP20Data->ReserveNow[gun_index].id; setChargerMode(gun_index, SYS_MODE_RESERVATION); } DEBUG_INFO("Reservation request on connector-%d.\n", gun_index); ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowConf = ON; } } } 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, "NotSupported"); 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, "NotSupported"); 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) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if((ocpp_get_smartcharging_profileId(gun_index) > 0) && (ocpp_get_profile_req(gun_index) != ON) && (((strlen((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ValidFrom)>0) && (strlen((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ValidTo)>0)) ? isProfileValid(gun_index) : ON)) { // Debug information if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_LOGPPRINTOUT]) > TIMEOUT_SPEC_LOGPPRINTOUT) { DEBUG_INFO("Profile ID found: %d\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileId); DEBUG_INFO("Valid from: %s\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ValidFrom); DEBUG_INFO("Valid to: %s\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ValidTo); DEBUG_INFO("Start schedule: %s\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.StartSchedule); DEBUG_INFO("Profile kind: %s\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileKind); DEBUG_INFO("RecurrencyKind: %s\n", ShmOCPP16Data->SmartChargingProfile[gun_index].RecurrencyKind); DEBUG_INFO("Profile purpose: %s\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose); DEBUG_INFO("Transaction ID: %d\n", ShmOCPP16Data->SmartChargingProfile[gun_index].TransactionId); DEBUG_INFO("ChargingRateUnit: %s\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit); DEBUG_INFO("========================================\n"); } // Checking profile kind if((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileKind, "Absolute") == PASS)) { // Absolute profile if(((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose, "TxProfile") == PASS) && (ShmOCPP16Data->SmartChargingProfile[gun_index].TransactionId == ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId)) || (mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose, "TxProfile") == FAIL)) { // Checking limitation for(uint8_t idx_period=0;idx_periodSmartChargingProfile[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)) ) { ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit,"W")==PASS?ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit/(220*ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].NumberPhases):ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit); //DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent); } else break; } } } } else if((ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileId == 0) && (ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileReq != ON)) { ShmCharger->gun_info[gun_index].targetCurrent = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if((ocpp_get_smartcharging_profileId(gun_index) > 0) && (ocpp_get_profile_req(gun_index) != ON) && (((strlen((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].validFrom)>0) && (strlen((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].validTo)>0)) ? isProfileValid(gun_index) : ON)) { // Debug information if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_LOGPPRINTOUT]) > TIMEOUT_SPEC_LOGPPRINTOUT) { DEBUG_INFO("Profile ID found: %d\n", ShmOCPP20Data->SmartChargingProfile[gun_index].id); DEBUG_INFO("Valid from: %s\n", ShmOCPP20Data->SmartChargingProfile[gun_index].validFrom); DEBUG_INFO("Valid to: %s\n", ShmOCPP20Data->SmartChargingProfile[gun_index].validTo); DEBUG_INFO("Start schedule: %s\n", ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].startSchedule); DEBUG_INFO("Profile kind: %s\n", ShmOCPP20Data->SmartChargingProfile[gun_index].chargingProfileKind); DEBUG_INFO("RecurrencyKind: %s\n", ShmOCPP20Data->SmartChargingProfile[gun_index].recurrencyKind); DEBUG_INFO("Profile purpose: %s\n", ShmOCPP20Data->SmartChargingProfile[gun_index].chargingProfilePurpose); DEBUG_INFO("Transaction ID: %d\n", ShmOCPP20Data->SmartChargingProfile[gun_index].transactionId); DEBUG_INFO("ChargingRateUnit: %s\n", ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingRateUnit); DEBUG_INFO("=======================================\n"); } // Checking profile kind if((mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingProfileKind, "Absolute") == PASS)) { // Absolute profile if(((mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingProfilePurpose, "TxProfile") == PASS) && (ShmOCPP20Data->SmartChargingProfile[gun_index].transactionId == ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId)) || (mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingProfilePurpose, "TxProfile") == FAIL)) { // Checking limitation for(uint8_t idx_period=0;idx_periodSmartChargingProfile[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].targetCurrent = (mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingRateUnit,"W")==PASS?ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit/(220*ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].numberPhases):ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit); //DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent); } else break; } } } } else if((ShmOCPP20Data->SmartChargingProfile[gun_index].id == 0) && (ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileReq != ON)) { ShmCharger->gun_info[gun_index].targetCurrent = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current; } } } void checkStopReason(uint8_t gun_index) { 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(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) { sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "EVDisconnected"); } 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(gun_index)) { 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*)ShmSysConfigAndInfo->SysInfo.AcChargingData[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); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0); 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(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) { 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(gun_index)) { 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*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[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_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); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0); ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = 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"); 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 {} } } //=============================================== // 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=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } else { DEBUG_INFO("CreatShareMemory OK\n"); } for(int gun_index = 0;gun_indexSysInfo.AcChargingData[gun_index].PreviousSystemStatus = 0xff; ShmCharger->gun_info[gun_index].primaryMcuState.rotatory_switch = 0xff; ShmCharger->gun_info[gun_index].mcuResetRequest.isMcuResetRequest = ON; ShmCharger->gun_info[gun_index].isInitialPass = NO; ShmCharger->gun_info[gun_index].isSetBreatheLedTiming = OFF; ShmCharger->gun_info[gun_index].isSetLedBrightness = OFF; } // Main loop for(;;) { //========================================== // Synchronize share memory from OCPP struct //========================================== ShmSysConfigAndInfo->SysInfo.OcppConnStatus = ocpp_get_connection_status(); //============================================== // Period check for 10 seconds //============================================== if((DiffTimebWithNow(startTime[0][TMR_IDX_CHECK_TASK]) > 10000) || (DiffTimebWithNow(startTime[0][TMR_IDX_CHECK_TASK]) < 0)) { //============================================== // Check task processing //============================================== if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING) checkTask(); //============================================== // Check connection timeout specification //============================================== checkConnectionTimeout(); ftime(&startTime[0][TMR_IDX_CHECK_TASK]); } //========================================== // Something need run in Idle mode //========================================== if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus==SYS_MODE_IDLE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus==SYS_MODE_ALARM)) && (AC_QUANTITY>1?((ShmSysConfigAndInfo->SysInfo.AcChargingData[1].SystemStatus==SYS_MODE_IDLE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[1].SystemStatus==SYS_MODE_ALARM)):true)) { //====================================== // Check restore factory setting request //====================================== if(ShmSysConfigAndInfo->SysInfo.FactoryConfiguration) { // Set led to initial for(int gun_index = 0;gun_indexSysInfo.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_indexgun_info[ShmCharger->gun_selectd].rfidReq) { if(GetCardSerialNumber()!= FAIL) { ShmCharger->gun_info[ShmCharger->gun_selectd].rfidReq = ON; } } //========================================== // Connector loop //========================================== for(int gun_index = 0;gun_indexSysConfig.RatingCurrent = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current; // Assign connector location index for OCPP ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].Index = gun_index; // Synchronize present charging power if(ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON) ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = (ShmSysConfigAndInfo->SysInfo.InputVoltageR* ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrent)/1000; else ShmSysConfigAndInfo->SysInfo.AcChargingData[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)) { if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus != SYS_MODE_ALARM) { if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus != SYS_MODE_UPDATE) { setChargerMode(gun_index, SYS_MODE_ALARM); } } } } // Reservation request check checkReservation(gun_index); // Change availability check 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); // Connector process switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus) { case SYS_MODE_BOOTING: if(isModeChange(gun_index)) { setLedMotion(gun_index,LED_ACTION_INIT); //CSU Initialization & task spawn if((Initialization() != PASS) || (SpawnTask() != PASS)) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = ON; } } if(ShmCharger->gun_info[gun_index].mcuFlag.isReadFwVerPass && ShmCharger->gun_info[gun_index].mcuFlag.isSetModelNamePass && ShmCharger->gun_info[gun_index].mcuFlag.isSetSerialNumberPass) { 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"); DEBUG_INFO("========== Set Wifi information ==========\n"); DEBUG_INFO("Wifi mode: %d\n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode); DEBUG_INFO("Wifi SSID: %s\n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSsid); DEBUG_INFO("Wifi password: %s\n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiPassword); DEBUG_INFO("==========================================\n"); // Set max current to rating current ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current; // Default Ethernet / Wifi / 4G to 1:disconnected ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = ON; // If Web Server OPCC URL is empty kill Module_OcppBackend if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0) { DEBUG_INFO("URL is empty kill Module_OcppBackend...\n"); system ("pkill OcppBackend"); LoadSysConfigAndInfo(&ShmSysConfigAndInfo->SysConfig); } // If rotate switch equal zero, the system needs to change Debug mode if(ShmCharger->gun_info[gun_index].primaryMcuState.rotatory_switch == 0) setChargerMode(gun_index, SYS_MODE_DEBUG); else setChargerMode(gun_index, SYS_MODE_IDLE); } break; case SYS_MODE_IDLE: if(isModeChange(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].rfidReq = OFF; ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart = OFF; ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop = OFF; ocpp_set_remotestart(gun_index, OFF); ocpp_set_remotestop(gun_index, OFF); ocpp_set_auth_conf(OFF); ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode = 0x00; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration = 0; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy = 0; ShmCharger->gun_info[gun_index].targetCurrent = 0xFF; ocpp_set_unlocker_req(gun_index, OFF); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId = -1; // Response StopTransactionConf ocpp_set_stoptransaction_conf(gun_index, OFF); } if(((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B)) || ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C)) || (ShmCharger->gun_info[gun_index].rfidReq == ON) || (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart == ON) || (ocpp_get_remotestart(gun_index) == ON) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStart == ON)) { // Clean User id & Card Number memset(ShmSysConfigAndInfo->SysConfig.UserId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); if((ShmCharger->gun_info[gun_index].rfidReq == ON)) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_RFID; DEBUG_INFO("Start Method : RFID...\n"); if(ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian) { // Big endian switch(rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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_10BYTE: sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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_10BYTE: sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X", rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; } } DEBUG_INFO("Start request User Id : %s\n", ShmSysConfigAndInfo->SysConfig.UserId); } else if(ocpp_get_remotestart(gun_index)) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_BACKEND; ocpp_copy_userid_from_remotestart(gun_index); DEBUG_INFO("Start Method : BACKEND...\n"); } else if(ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart == ON) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_BLE; memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmCharger->gun_info[gun_index].bleLoginCentralId.id, ARRAY_SIZE(ShmCharger->gun_info[gun_index].bleLoginCentralId.id)); DEBUG_INFO("Start Method : BLE...\n"); } else { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_FREE; memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmSysConfigAndInfo->SysConfig.SerialNumber, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)); 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; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStart = OFF; // Get target current ocpp_set_profile_req(gun_index, ON); sleep(1); checkChargingProfileLimit(gun_index); if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current: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].mcuFlag.isSetCpPwmDuty = YES; setChargerMode(gun_index, SYS_MODE_AUTHORIZING); } else {} break; case SYS_MODE_AUTHORIZING: if(isModeChange(gun_index)) { ftime(&startTime[gun_index][TMR_IDX_AUTH]); if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_RFID) { switch(ShmSysConfigAndInfo->SysConfig.AuthorisationMode) { case AUTH_MODE_ENABLE: if(ocpp_get_connection_status()) { // On line ocpp_set_auth_req(ON, "ISO14443"); } else { // Off line switch(ShmSysConfigAndInfo->SysConfig.OfflinePolicy) { case OFF_POLICY_LOCALLIST: ocpp_set_auth_req(ON, "ISO14443"); break; case OFF_POLICY_PH_RFID: break; case OFF_POLICY_FREE: break; case OFF_POLICY_NOCHARGE: default: break; } } break; case AUTH_MODE_DISABLE: default: break; } } else if(ocpp_isAuthorizeRemoteStart() && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_BACKEND)) { DEBUG_INFO("Remote start request authorize.\n"); ocpp_set_auth_req(ON, "ISO14443"); } } if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > TIMEOUT_SPEC_AUTH) { // Authorization timeout process. ShmCharger->gun_info[gun_index].rfidReq = OFF; 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(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod) { case START_METHOD_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) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > 2000))) { 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*)ShmSysConfigAndInfo->SysInfo.AcChargingData[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(3); 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); } ShmCharger->gun_info[gun_index].rfidReq = OFF; ocpp_set_auth_conf(OFF); } break; case START_METHOD_BACKEND: if(ocpp_isAuthorizeRemoteStart()) { if(ocpp_get_auth_conf()) { if(ocpp_get_auth_result(gun_index)) { memcpy((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[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(3); 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 { setSpeaker(ON,SPEAKER_SHORT); setChargerMode(gun_index, SYS_MODE_PREPARING); } break; case START_METHOD_BLE: case START_METHOD_FREE: default: setSpeaker(ON,SPEAKER_SHORT); setChargerMode(gun_index, SYS_MODE_PREPARING); break; } } break; case SYS_MODE_PREPARING: if(isModeChange(gun_index)) { ftime(&startTime[gun_index][TMR_IDX_HANDSHAKING]); setLedMotion(gun_index,LED_ACTION_CONNECTED); } // If control pilot detect Bx, skip watch dog time out. if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C)) { setRequest(gun_index,ON); ftime(&startTime[gun_index][TMR_IDX_HANDSHAKING]); ShmCharger->gun_info[gun_index].isGunPlugged = YES; } // Unplug charging gun to Idle mode if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) && (ShmCharger->gun_info[gun_index].isGunPlugged == YES)) { DEBUG_INFO("Charging gun is plugged before.\n"); setChargerMode(gun_index, SYS_MODE_IDLE); } // Use RFID card to stop handshaking if((ShmCharger->gun_info[gun_index].rfidReq == ON) && isMatchStartUser(gun_index)) { DEBUG_INFO("Use RFID card to stop handshaking.\n"); setSpeaker(ON,SPEAKER_SHORT); setChargerMode(gun_index, SYS_MODE_IDLE); } else { ShmCharger->gun_info[gun_index].rfidReq = OFF; } if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_HANDSHAKING]) > ShmCharger->timeoutSpec.Present_Timeout_Spec) { setLedMotion(gun_index, LED_ACTION_HANDSHAKE_FAIL); if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_HANDSHAKING]) > (ShmCharger->timeoutSpec.Present_Timeout_Spec+5000)) { DEBUG_INFO("Handshaking timeout...\n"); setChargerMode(gun_index, SYS_MODE_IDLE); } } else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C)) { // Set relay on when the system is state C setRelay(gun_index,ON); if((ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON)) { ocpp_set_unlocker_req(gun_index, OFF); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy = 0; getDateTimeString((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime); ShmCharger->gun_info[gun_index].powerConsumption.power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption.power_consumption; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0); memcpy((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); ocpp_copy_userid_to_starttransaction(gun_index); ocpp_set_starttransaction_req(gun_index, ON); setChargerMode(gun_index, SYS_MODE_CHARGING); } } break; case SYS_MODE_CHARGING: if(isModeChange(gun_index)) { ShmCharger->gun_info[gun_index].rfidReq = OFF; ftime(&startChargingTime[gun_index]); ftime(&startTime[gun_index][TMR_IDX_LOGPPRINTOUT]); ftime(&startTime[gun_index][TMR_IDX_PROFILE_PREPARE]); ftime(&startTime[gun_index][TMR_IDX_PWN_CHANGE]); startTime[gun_index][TMR_IDX_AUTH].time -= TIMEOUT_SPEC_AUTH; 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; } if((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)) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState != CP_STATE_C) || ocpp_get_reset_req() || ocpp_get_unlocker_req(gun_index) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStop == ON)) { if(ShmCharger->gun_info[gun_index].rfidReq) { DEBUG_INFO("Certified in charging mode... \n"); // If RFID SN different with start user, it need to authorize ID if((ShmCharger->gun_info[gun_index].rfidReq == ON) && !isMatchStartUser(gun_index)) { if((DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > TIMEOUT_SPEC_AUTH) && !ocpp_get_auth_req()) { // Request authorization ftime(&startTime[gun_index][TMR_IDX_AUTH]); memset(ShmSysConfigAndInfo->SysConfig.UserId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); if(ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian) { // Big endian switch(rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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_10BYTE: sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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_10BYTE: sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X", rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; } } DEBUG_INFO("End request User Id : %s\n", ShmSysConfigAndInfo->SysConfig.UserId); DEBUG_INFO("Start method : %d\n ", ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod); if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_RFID) || //(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_BACKEND) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_BLE)) { switch(ShmSysConfigAndInfo->SysConfig.AuthorisationMode) { case AUTH_MODE_ENABLE: if(ocpp_get_connection_status()) { // On line ocpp_set_auth_req(ON, "ISO14443"); } else { // Off line switch(ShmSysConfigAndInfo->SysConfig.OfflinePolicy) { case OFF_POLICY_LOCALLIST: ocpp_set_auth_req(ON, "ISO14443"); break; case OFF_POLICY_PH_RFID: break; case OFF_POLICY_FREE: break; case OFF_POLICY_NOCHARGE: default: break; } } break; case AUTH_MODE_DISABLE: default: break; } } else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_BACKEND) { DEBUG_INFO("Should be remote stop charger... \n"); ShmCharger->gun_info[gun_index].rfidReq = OFF; } } else { if(ocpp_get_auth_conf() || (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > 2000)) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE))) { if(ocpp_get_auth_result(gun_index) || (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) || (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE))) { ShmCharger->gun_info[gun_index].isAuthPassEnd = ON; } else { ShmCharger->gun_info[gun_index].rfidReq = OFF; ocpp_set_auth_req(OFF); DEBUG_INFO("Authorize fail.\n"); setSpeaker(ON,SPEAKER_INTERVAL_3COUNT); setLedMotion(gun_index,LED_ACTION_RFID_FAIL); sleep(3); } startTime[gun_index][TMR_IDX_AUTH].time -= TIMEOUT_SPEC_AUTH; ocpp_set_auth_conf(OFF); } } } // If Authorize is accpted or Rfid card match with start User, The system should terminating to the end if(ShmCharger->gun_info[gun_index].isAuthPassEnd || isMatchStartUser(gun_index)) setChargerMode(gun_index, SYS_MODE_TERMINATING); } else setChargerMode(gun_index, SYS_MODE_TERMINATING); } else { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0); ftime(&endChargingTime[gun_index]); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration = DiffTimeb(startChargingTime[gun_index], endChargingTime[gun_index])/1000; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption - ShmCharger->gun_info[gun_index].powerConsumption.power_consumption_at_start)/100.0; // Response StartTransactionConf ocpp_set_starttransaction_conf(gun_index, OFF); // Charging profile preparation if((DiffTimebWithNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) > TIMEOUT_SPEC_PROFILE_PREPARE) || (DiffTimebWithNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) < 0)) { if(!ocpp_get_profile_conf(gun_index)) { ocpp_set_profile_req(gun_index, ON); ftime(&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); // If temperature warning derating PWM duty 20% if(ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp >= SPEC_TEMPERATURE_WARN) { ShmCharger->gun_info[gun_index].tempCoefficient = 0.8; } else if(ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp <= SPEC_TEMPERATURE_RECOVER) { ShmCharger->gun_info[gun_index].tempCoefficient = 1.0; } ShmCharger->gun_info[gun_index].targetCurrent = (ShmCharger->gun_info[gun_index].targetCurrent==0?ShmCharger->gun_info[gun_index].targetCurrent:(((ShmCharger->gun_info[gun_index].targetCurrent*ShmCharger->gun_info[gun_index].tempCoefficient)>=6) ? (ShmCharger->gun_info[gun_index].targetCurrent*ShmCharger->gun_info[gun_index].tempCoefficient):6)); // Determine max charging current to MCU if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); if(ShmCharger->gun_info[gun_index].targetCurrent != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current) { if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_PWN_CHANGE]) > TIMEOUT_SPEC_PWN_CHANGE) { if((6 <= ShmCharger->gun_info[gun_index].targetCurrent)) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); } else if((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent < 6)) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 6; } else { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 100; } ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; ftime(&startTime[gun_index][TMR_IDX_PWN_CHANGE]); } else {} } } 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) { if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_PWN_CHANGE]) > TIMEOUT_SPEC_PWN_CHANGE) { if((6 <= 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); } else if((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent < 6)) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 6; } else { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 100; } ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; ftime(&startTime[gun_index][TMR_IDX_PWN_CHANGE]); } else {} } } // Debug information if((DiffTimebWithNow(startTime[gun_index][TMR_IDX_LOGPPRINTOUT]) > TIMEOUT_SPEC_LOGPPRINTOUT) || (DiffTimebWithNow(startTime[gun_index][TMR_IDX_LOGPPRINTOUT]) < 0)) { DEBUG_INFO("=============================================================\n"); DEBUG_INFO("ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent: %d\n", ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent); DEBUG_INFO("ShmCharger->gun_info[%d].primaryMcuCp_Pwn_Duty.max_current: %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current); DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent: %d\n", gun_index, ShmCharger->gun_info[gun_index].targetCurrent); DEBUG_INFO("=============================================================\n"); ftime(&startTime[gun_index][TMR_IDX_LOGPPRINTOUT]); } if(ocpp_get_connection_status()) { // On-line max condition check if((ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60))) { setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isChargerStopByCondition = YES; setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO("Connector-%d charging duration(%d) already over max duration(%d) in second.\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration, (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60)); } else if((ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy))) { setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isChargerStopByCondition = YES; setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO("Connector-%d charging energy(%.2f) already over max energy(%.2f) in KWH.\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy, ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy)); } else { ShmCharger->gun_info[gun_index].isChargerStopByCondition = NO; if(ShmCharger->gun_info[gun_index].targetCurrent > 0) { setLedMotion(gun_index,LED_ACTION_CHARGING); setRelay(gun_index, ON); } else { setLedMotion(gun_index, LED_ACTION_STOP); setRelay(gun_index, OFF); } } } 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) ? (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration*60)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60)))) { setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isChargerStopByCondition = YES; 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, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration, (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60)); } else if(((ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy > 0) ? (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy)))) { setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isChargerStopByCondition = YES; 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, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy, ((float)ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy)); } else { ShmCharger->gun_info[gun_index].isChargerStopByCondition = NO; if(ShmCharger->gun_info[gun_index].targetCurrent > 0) { setLedMotion(gun_index,LED_ACTION_CHARGING); setRelay(gun_index, ON); } else { setLedMotion(gun_index, LED_ACTION_STOP); setRelay(gun_index, OFF); } } } else { setRelay(gun_index, OFF); DEBUG_INFO("Connector-%d can not charging in off line\n", gun_index); } } } break; case SYS_MODE_TERMINATING: if(isModeChange(gun_index)) { setLedMotion(gun_index, LED_ACTION_STOP); if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration != 0) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration = DiffTimeb(startChargingTime[gun_index], endChargingTime[gun_index])/1000; } getDateTimeString((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime); startTime[gun_index][TMR_IDX_AUTH].time -= TIMEOUT_SPEC_AUTH; sleep(3); } // End authorize pass if(((ShmCharger->gun_info[gun_index].rfidReq == ON) && isMatchStartUser(gun_index)) || (ShmCharger->gun_info[gun_index].isAuthPassEnd) || (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop == ON) || ocpp_get_remotestop(gun_index) || (ocpp_get_connection_status() && !ocpp_get_starttransaction_result(gun_index)) || ((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) && ocpp_get_StopTransactionOnEVSideDisconnect()) || ocpp_get_reset_req() || ocpp_get_unlocker_req(gun_index) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStop == ON)) { if(((ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest == ON) || (ShmCharger->gun_info[gun_index].isChargerStopByCondition == YES)) && (ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current != 100)) { if(((ShmCharger->gun_info[gun_index].rfidReq == ON) && isMatchStartUser(gun_index)) || (ShmCharger->gun_info[gun_index].isAuthPassEnd)) { DEBUG_INFO("Authorize pass.\n"); setSpeaker(ON,SPEAKER_SHORT); setLedMotion(gun_index,LED_ACTION_RFID_PASS); sleep(3); } } else {} ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 100; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; setLedMotion(gun_index, LED_ACTION_STOP); checkStopReason(gun_index); sleep(6); setChargerMode(gun_index, SYS_MODE_COMPLETE); /* // If relay is off, the system should change to complete mode if(!ShmCharger->gun_info[gun_index].primaryMcuState.relay_state) { checkStopReason(gun_index); 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); } if(ShmCharger->gun_info[gun_index].rfidReq) { DEBUG_INFO("Certified in terminating mode... \n"); // If RFID SN different with start user, it need to authorize ID if((ShmCharger->gun_info[gun_index].rfidReq == ON) && !isMatchStartUser(gun_index)) { if((DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > TIMEOUT_SPEC_AUTH) && !ocpp_get_auth_req()) { // Request authorization ftime(&startTime[gun_index][TMR_IDX_AUTH]); memset(ShmSysConfigAndInfo->SysConfig.UserId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); if(ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian) { // Big endian switch(rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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_10BYTE: sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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_10BYTE: sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X", rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; } } DEBUG_INFO("End request User Id : %s... \n", ShmSysConfigAndInfo->SysConfig.UserId); DEBUG_INFO("Start method : %d... \n ", ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod); if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_RFID) || //(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_BACKEND) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_BLE)) { switch(ShmSysConfigAndInfo->SysConfig.AuthorisationMode) { case AUTH_MODE_ENABLE: if(ocpp_get_connection_status()) { // On line ocpp_set_auth_req(ON, "ISO14443"); } else { // Off line switch(ShmSysConfigAndInfo->SysConfig.OfflinePolicy) { case OFF_POLICY_LOCALLIST: ocpp_set_auth_req(ON, "ISO14443"); break; case OFF_POLICY_PH_RFID: break; case OFF_POLICY_FREE: break; case OFF_POLICY_NOCHARGE: default: break; } } break; case AUTH_MODE_DISABLE: default: break; } } else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_BACKEND) { DEBUG_INFO("Should be remote stop charger... \n"); ShmCharger->gun_info[gun_index].rfidReq = OFF; } } else { if(ocpp_get_auth_conf() || (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > 2000)) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE))) { if(ocpp_get_auth_result(gun_index) || (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) || (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE))) { ShmCharger->gun_info[gun_index].isAuthPassEnd = ON; } else { ShmCharger->gun_info[gun_index].rfidReq = OFF; ocpp_set_auth_req(OFF); DEBUG_INFO("Authorize fail... \n"); setSpeaker(ON,SPEAKER_INTERVAL_3COUNT); setLedMotion(gun_index,LED_ACTION_RFID_FAIL); sleep(3); } startTime[gun_index][TMR_IDX_AUTH].time -= TIMEOUT_SPEC_AUTH; ocpp_set_auth_conf(OFF); } } } } // Charging profile preparation if((DiffTimebWithNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) > TIMEOUT_SPEC_PROFILE_PREPARE) || (DiffTimebWithNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) < 0)) { if(!ocpp_get_profile_conf(gun_index)) { ocpp_set_profile_req(gun_index, ON); ftime(&startTime[gun_index][TMR_IDX_PROFILE_PREPARE]); } else { ocpp_set_profile_conf(gun_index, OFF); } } // Check target current if charging profile limit > 0 checkChargingProfileLimit(gun_index); // Determine max charging current to MCU if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); if(ShmCharger->gun_info[gun_index].targetCurrent != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current) { if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_PWN_CHANGE]) > TIMEOUT_SPEC_PWN_CHANGE) { if((6 <= ShmCharger->gun_info[gun_index].targetCurrent)) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); } else if((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent < 6)) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 6; } else { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 100; } ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; ftime(&startTime[gun_index][TMR_IDX_PWN_CHANGE]); } else {} } } 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) { if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_PWN_CHANGE]) > TIMEOUT_SPEC_PWN_CHANGE) { if((6 <= 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); } else if((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent < 6)) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 6; } else { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 100; } ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; ftime(&startTime[gun_index][TMR_IDX_PWN_CHANGE]); } else {} } } // Debug information if((DiffTimebWithNow(startTime[gun_index][TMR_IDX_LOGPPRINTOUT]) > TIMEOUT_SPEC_LOGPPRINTOUT) || (DiffTimebWithNow(startTime[gun_index][TMR_IDX_LOGPPRINTOUT]) < 0)) { DEBUG_INFO("=============================================================\n"); DEBUG_INFO("ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent: %d\n", ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent); DEBUG_INFO("ShmCharger->gun_info[%d].primaryMcuCp_Pwn_Duty.max_current: %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current); DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent: %d\n", gun_index, ShmCharger->gun_info[gun_index].targetCurrent); DEBUG_INFO("=============================================================\n"); ftime(&startTime[gun_index][TMR_IDX_LOGPPRINTOUT]); } if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C) && (ShmCharger->gun_info[gun_index].rfidReq != ON) && (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop != ON) && !ocpp_get_remotestop(gun_index) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStop != ON) && !ocpp_get_reset_req() && ocpp_get_starttransaction_result(gun_index) && !(ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60))) && !(ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy))) && !(!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy != OFF_POLICY_NOCHARGE) && ((ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration > 0) ? (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration*60)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60)))) && !(!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy != OFF_POLICY_NOCHARGE) && ((ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy > 0) ? (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy))))) { setChargerMode(gun_index, SYS_MODE_CHARGING); } } break; case SYS_MODE_COMPLETE: if(isModeChange(gun_index)) { setLedMotion(gun_index, LED_ACTION_STOP); setRequest(gun_index, OFF); setRelay(gun_index, OFF); sleep(3); } ShmCharger->gun_info[gun_index].rfidReq = OFF; ShmCharger->gun_info[gun_index].isAuthPassEnd = OFF; ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop = OFF; ocpp_set_remotestop(gun_index, OFF); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStop = OFF; 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); if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode == 0)) { if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus == SYS_MODE_TERMINATING)) { setChargerMode(gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus); } else { setChargerMode(gun_index, SYS_MODE_IDLE); } } break; case SYS_MODE_FAULT: if(isModeChange(gun_index)) {} break; case SYS_MODE_MAINTAIN: if(isModeChange(gun_index)) { setLedMotion(gun_index,LED_ACTION_MAINTAIN); } break; case SYS_MODE_UPDATE: if(isModeChange(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 && ((AC_QUANTITY>1)?!ShmCharger->gun_info[gun_index^1].mcuFlag.isMcuUpgradeReq:YES)) { 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)) { setLedMotion(gun_index,LED_ACTION_MAINTAIN); } 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)) { memset(ShmSysConfigAndInfo->SysConfig.UserId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); if(ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian) { // Big endian switch(rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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_10BYTE: sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%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_10BYTE: sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%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*)ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X", rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; } } 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); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_RFID; setChargerMode(gun_index, SYS_MODE_AUTHORIZING); } 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"); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_BACKEND; setChargerMode(gun_index, SYS_MODE_AUTHORIZING); } ocpp_set_remotestop(gun_index, OFF); } } } break; case SYS_MODE_BOOKING: if(isModeChange(gun_index)) {} break; case SYS_MODE_DEBUG: if(isModeChange(gun_index)) { setLedMotion(gun_index,LED_ACTION_DEBUG); } break; } } // System watch dog reset write(wtdFd, "a", 1); usleep(50000); } return FAIL; }