#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_4 4 #define TMR_IDX_5 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 MtdBlockSize 0x600000 #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 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 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; 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); if((ShmSysConfigAndInfo->SysConfig.ModelName != NULL) && (ShmSysConfigAndInfo->SysConfig.SerialNumber != NULL) && (strlen((char*)ShmSysConfigAndInfo->SysConfig.ModelName) >= 14)) { sprintf(Buf,"echo \"[%04d.%02d.%02d %02d:%02d:%02d] - %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, buffer, tm->tm_year+1900,tm->tm_mon+1, ShmSysConfigAndInfo->SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.SerialNumber); } else { sprintf(Buf,"echo \"[%04d.%02d.%02d %02d:%02d:%02d] - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec, buffer, tm->tm_year+1900,tm->tm_mon+1); } #ifdef SystemLogMessage system(Buf); #endif #ifdef ConsloePrintLog printf("[%04d.%02d.%02d %02d:%02d:%02d] - %s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec, 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); } 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); } //====================================================== // 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\r\n"); result = FAIL; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\r\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\r\n"); result = FAIL; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmStatusCodeData NG\r\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\r\n"); result = FAIL; } else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmPsuData NG\r\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\r\n"); result = FAIL; } else if ((ShmCHAdeMOData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmCHAdeMOData NG2\r\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\r\n"); result = FAIL; } else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmCcsData NG\r\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\r\n"); result = FAIL; } else if ((ShmPrimaryMcuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmPrimaryMcuData NG\r\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\r\n"); result = FAIL; } else if ((ShmFanModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmFanModuleData NG\r\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\r\n"); result = FAIL; } else if ((ShmRelayModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmRelayModuleData NG\r\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\r\n"); result = FAIL; } else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmOCPP16Data NG\r\n"); result = FAIL; } memset(ShmOCPP16Data,0,sizeof(struct OCPP16Data)); //creat ShmCharger if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmCharger NG\r\n"); result = FAIL; } else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmCharger NG\r\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_INFO( "Can't open database: %s\r\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { DEBUG_INFO( "Local charging record database open successfully.\r\n"); if (sqlite3_exec(db, createRecordSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO( "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_INFO( "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 insertSql[1024]; sprintf(insertSql, "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); if(sqlite3_open("/Storage/ChargeLog/localCgargingRecord.db", &db)) { result = FAIL; DEBUG_INFO( "Can't open database: %s\r\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { DEBUG_INFO( "Local charging record database open successfully.\r\n"); if (sqlite3_exec(db, insertSql, 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"); } 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\r\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { DEBUG_INFO( "Local charging record database open successfully.\r\n"); sprintf(sqlStr, "insert or replace into config (item, connector, val) values('isOperactive', %d, %d);", gun_index, isOperactive); DEBUG_INFO("sqlStr= %s\r\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\r\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\r\n", sqlStr); if(sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO( "Can't open database: %s\r\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { DEBUG_INFO( "Local config query database open successfully.\r\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\r\n", gun_index, rs[(idxRow*cols)+3]); } } else { DEBUG_INFO("Query connector-%d fail, set default value to operactive.\r\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.\r\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\r\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..\r\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 //================================================ fd = open("/dev/mtdblock10", O_RDWR); if (fd < 0) { free(buf); DEBUG_ERROR("open mtdblock10 NG,rebooting..\r\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=0;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=0;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=0;wrd0) { wrd=write(fd, BufTmp, MtdBlockSize); close(fd); if(wrd>=MtdBlockSize) { fd = open("/dev/mtdblock11", O_RDWR); if (fd>0) { wrd=write(fd, BufTmp, MtdBlockSize); close(fd); if(wrdSysConfig.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"); } 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); //check internet status pid = fork(); if(pid == 0) { for(;;) { if(isReachableInternet() == PASS) { ShmSysConfigAndInfo->SysInfo.InternetConn = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet=OFF; cnt_pingDNS_Fail = 0; } else { if(++cnt_pingDNS_Fail > 3) { ShmSysConfigAndInfo->SysInfo.InternetConn = OFF; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet=ON; } } sleep(5); } } DEBUG_INFO("Initial Ethernet OK\r\n"); } int SpawnTask() { system ("pkill Module_4g"); system ("pkill Module_Wifi"); system ("pkill Module_EventLogging"); system ("pkill OcppBackend"); system ("pkill Module_AlarmDetect"); system ("pkill Module_InternalComm"); system ("pkill Module_Speaker"); system ("pkill Module_ProduceUtils"); if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') { system("/root/Module_4g &"); } else if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') { system("/root/Module_Wifi &"); } system("/root/Module_EventLogging &"); if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") != 0) { system("/root/OcppBackend &"); } else { DEBUG_INFO("OCPP URL is empty, need to create a configuration table !!!\r\n"); system("/root/OcppBackend &"); } 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) 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); rfidFd = InitRfidPort(); wtdFd = InitWatchDog(); if((wtdFd < 0) || (rfidFd < 0)) result = FAIL; if(result == PASS) DEBUG_INFO("Initialization OK.\r\n"); else DEBUG_INFO("Initialization Fail.\r\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\r\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; } //=============================================== // 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) { strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev, buf); } } // 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, "B0.34.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; 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("====================================================================\r\n"); DEBUG_INFO("Model: %s\r\n", ShmSysConfigAndInfo->SysConfig.ModelName); DEBUG_INFO("CSU hardware version: %s\r\n", ShmSysConfigAndInfo->SysInfo.CsuHwRev); DEBUG_INFO("CSU boot loader version: %s\r\n", ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev); DEBUG_INFO("CSU kernel version: %s\r\n", ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev); DEBUG_INFO("CSU root file system version: %s\r\n", ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev); DEBUG_INFO("CSU MCU-%2d firmware version: %s\r\n", gun_index, ShmCharger->gun_info[gun_index].ver.Version_FW); DEBUG_INFO("====================================================================\r\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\r\n", ShmCharger->fwUpgradeInfo.fwType); DEBUG_INFO("New firmware model name: %s, %s\r\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.\r\n"); memcpy(&SysConfigOrg, &ShmSysConfigAndInfo->SysConfig, sizeof(struct SysConfigData)); if(LoadSysConfigAndInfo(&ShmSysConfigAndInfo->SysConfig) != PASS) { DEBUG_INFO("Re-load configuration fail.\r\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.\r\n"); result = FAIL; } else DEBUG_INFO("Re-write configuration OK.\r\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.\r\n"); sprintf(cmd, "yes|rm %s", ShmCharger->fwUpgradeInfo.location); system(cmd); break; } } else { result = FAIL; DEBUG_ERROR("Model name and Firmware type error.\r\n"); } free(ptr); } else { result = FAIL; DEBUG_ERROR("New firmware open error.\r\n"); } } else { if(strlen(file->d_name) >= 3) { result = FAIL; DEBUG_ERROR("File name error.\r\n"); } else { DEBUG_ERROR("Searching file.\r\n"); } } } closedir (dir); } else { result = FAIL; DEBUG_ERROR("/mnt does not valid.\r\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; } } else if(rfid.cardType == IS014443B) { isSuccess = PASS; } else if(rfid.cardType == FELICA) { isSuccess = PASS; } else {} } else {} return isSuccess; } //=============================================== // Calculation CRC32 function //=============================================== unsigned int CRC32(uint8_t const * p_data, uint32_t size) { uint32_t crc; crc = 0xFFFFFFFF; for (uint32_t i = 0; i < size; i++) { if( (i<0x22) || (i>0x2f)) { crc = crc ^ p_data[i]; for (uint32_t j = 8; j > 0; j--) { crc = (crc >> 1) ^ (0xEDB88320U & ((crc & 1) ? 0xFFFFFFFF : 0)); } } } return ~crc; } //=============================================== // Check PH RFID //=============================================== int isValidPHCard() { int isSuccess = FAIL; int module_type = MODULE_EWT; uint8_t data_read[16]; uint32_t crc_result; uint8_t sn_len; uint8_t *buf; if(getBlockRead(rfidFd,module_type,2,0,data_read)) { if(rfid.snType == RFID_SN_TYPE_4BYTE) { // SN length: 4 sn_len = 4; } else if(rfid.snType == RFID_SN_TYPE_7BYTE) { // SN length: 7 sn_len = 7; } else { // SN length: 10 sn_len = 10; } buf = malloc(25 + sn_len); memcpy(buf, ShmSysConfigAndInfo->SysConfig.SystemId, 25); memcpy(&buf[25], rfid.currentCard, sn_len); crc_result = CRC32(buf, 25 + sn_len); if(((data_read[0] << 8) | (data_read[1] << 0) | (data_read[2] << 24) | (data_read[3] << 16)) == ~crc_result) { isSuccess = PASS; DEBUG_INFO("PH logic checked pass.\r\n"); } else { DEBUG_INFO("PH logic checked fail.\r\n"); } free(buf); } 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; } } //=============================================== // Relay on/off request set //=============================================== void setRelay(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 Output relay sts: ON \r\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 Output relay sts: OFF \r\n",gun_index); } } } //=============================================== // Relay on/off request get //=============================================== int getRelay(unsigned char gun_index) { return ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest; } //=============================================== // 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]; 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 reservation date is expired //=============================================== int isReservationExpired(unsigned char gun_index) { int result = NO; struct tm expiredDate; struct timeb expiredTime; if(sscanf((char*)ShmOCPP16Data->ReserveNow[gun_index].ExpiryDate, "%4d-%2d-%2dT%2d:%2d:%2d", &expiredDate.tm_year, &expiredDate.tm_mon, &expiredDate.tm_mday, &expiredDate.tm_hour, &expiredDate.tm_min, &expiredDate.tm_sec) == 6) { expiredDate.tm_year -= 1900; expiredDate.tm_mon -= 1; expiredTime.time = mktime(&expiredDate); if(DiffTimebWithNow(expiredTime)>=0) { result = YES; } } else { DEBUG_WARN("Expired date parsing error.\r\n"); DEBUG_INFO("Date expired.\r\n"); 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((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\r\n", DiffTimebWithNow(tbFrom)); DEBUG_INFO("Valid to compare Now: %d\r\n", DiffTimebWithNow(tbTo)); if((DiffTimebWithNow(tbFrom)>=0) && (DiffTimebWithNow(tbTo)<=0)) { result = YES; } } else { DEBUG_WARN("ValidFrom or ValidTo date parsing error.\r\n"); } return result; } int getScheduleStart(int gun_index) { int result = -1; struct tm tmScheduleStart;; struct timeb tbScheduleStart; 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\r\n", result); } else { DEBUG_WARN("Schedule start date parsing error.\r\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\r\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\r\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; } //========================================== // Get Ethernet MAC address //========================================== int getEth0MacAddress() { int result = PASS; FILE *fp; char cmd[256]; char buf[512]; char tmp[512]; strcpy(cmd, "ifconfig");; 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; } //========================================== // Check task processing //========================================== void checkTask() { if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') { if(system("pidof -s Module_4g > /dev/null") != 0) { DEBUG_INFO("Module_4g not running, restart it.\r\n"); system("/root/Module_4g &"); } } else if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') { if(system("pidof -s Module_Wifi > /dev/null") != 0) { DEBUG_INFO("Module_Wifi not running, restart it.\r\n"); system("/root/Module_Wifi &"); } } if(system("pidof -s Module_EventLogging > /dev/null") != 0) { DEBUG_INFO("Module_EventLogging not running, restart it.\r\n"); system("/root/Module_EventLogging &"); } if(system("pidof -s OcppBackend > /dev/null") != 0) { DEBUG_INFO("OcppBackend not running, restart it.\r\n"); system("/root/OcppBackend &"); } if(system("pidof -s Module_AlarmDetect > /dev/null") != 0) { DEBUG_INFO("Module_AlarmDetect not running, restart it.\r\n"); system("/root/Module_AlarmDetect &"); } if(system("pidof -s Module_InternalComm > /dev/null") != 0) { DEBUG_INFO("Module_InternalComm not running, restart it.\r\n"); system("/root/Module_InternalComm &"); } if(system("pidof -s Module_Speaker > /dev/null") != 0) { DEBUG_INFO("Module_Speaker not running, restart it.\r\n"); system("/root/Module_Speaker &"); } if(system("pidof -s Module_ProduceUtils > /dev/null") != 0) { DEBUG_INFO("Module_ProduceUtils not running, restart it.\r\n"); system ("/root/Module_ProduceUtils &"); } } //=============================================== // Check Connection Timeout //=============================================== void checkConnectionTimeout() { if(system("pidof -s OcppBackend > /dev/null") != 0) { ShmCharger->timeoutSpec.Present_Timeout_Spec = TIMEOUT_SPEC_HANDSHAKING; //DEBUG_INFO("Handshaking timeout specification follow by initial setting : %d s \r\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.\r\n."); } else { ShmCharger->timeoutSpec.Present_Timeout_Spec = (ShmCharger->timeoutSpec.Setting_Timeout_Spec*1000); //DEBUG_INFO("Handshaking timeout specification follow by OCPP Configuration : Pass...\r\n."); } //DEBUG_INFO("Handshaking timeout specification follow by OCPP Configuration : %s s \r\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...\r\n."); } //DEBUG_INFO("Present timeout spec : %d \r\n", ShmCharger->timeoutSpec.Present_Timeout_Spec); } } //=============================================== // Main process //=============================================== int main(void) { //Create all share memory if(CreatShareMemory()==0) { DEBUG_ERROR("CreatShareMemory NG\r\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\r\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 = ShmOCPP16Data->OcppConnStatus; //========================================== // Ethernet MAC address //========================================== getEth0MacAddress(); //========================================== // Check task processing //========================================== checkTask(); //========================================== // Check connection timeout specification //========================================== checkConnectionTimeout(); //========================================== // 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 || ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq) { ShmCharger->isUpdateSuccess = NO; for(int gun_index = 0;gun_indexMsMsg.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; if(strcmp((char*)ShmOCPP16Data->Reset.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"); } } } //========================================== // Check RFID //========================================== if(!ShmCharger->gun_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; // The system switch to Booting mode if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == 0XFF) { setChargerMode(gun_index, SYS_MODE_BOOTING); } // Check initialization "PASS" or "FAIL" if(ShmCharger->gun_info[gun_index].isInitialPass == YES) { // 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) { } else { setChargerMode(gun_index, SYS_MODE_ALARM); } } } else { if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_ALARM) { } } } // Reservation request check 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.\r\n", gun_index); ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowConf = ON; } // Change availability check 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; } 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 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; } // 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 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"); sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterType, "AC"); DEBUG_INFO("==========================================\r\n"); DEBUG_INFO("System ID: %s\r\n",ShmSysConfigAndInfo->SysConfig.SystemId); DEBUG_INFO("==========================================\r\n"); DEBUG_INFO("========== OCPP BootNotification information ==========\r\n"); DEBUG_INFO("OCPP OcppServerURL: %s\r\n",ShmSysConfigAndInfo->SysConfig.OcppServerURL); DEBUG_INFO("OCPP ChargeBoxId: %s\r\n",ShmSysConfigAndInfo->SysConfig.ChargeBoxId); DEBUG_INFO("OCPP ChargePointVendor: %s\r\n",ShmSysConfigAndInfo->SysConfig.chargePointVendor); DEBUG_INFO("OCPP CpFwVersion: %s\r\n",ShmOCPP16Data->BootNotification.CpFwVersion); DEBUG_INFO("OCPP CpMeterSerialNumber: %s\r\n",ShmOCPP16Data->BootNotification.CpMeterSerialNumber); DEBUG_INFO("OCPP CpMeterType: %s\r\n",ShmOCPP16Data->BootNotification.CpMeterType); DEBUG_INFO("=======================================================\r\n"); DEBUG_INFO("========== Set Wifi information ==========\r\n"); DEBUG_INFO("Wifi mode: %d\r\n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode); DEBUG_INFO("Wifi SSID: %s\r\n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSsid); DEBUG_INFO("Wifi password: %s\r\n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiPassword); DEBUG_INFO("==========================================\r\n"); // Flag for initialization system success ShmCharger->gun_info[gun_index].isInitialPass = YES; // Set max current to rating current ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current; // 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); 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; ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq = OFF; ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq = 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; ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = (ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent > 0) ? ((ShmSysConfigAndInfo->SysConfig.MaxChargingCurrentgun_info[gun_index].primaryMcuState.rating_current)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].primaryMcuState.rating_current) : ShmCharger->gun_info[gun_index].primaryMcuState.rating_current; ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].isUnlockerConnetor = OFF; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId = -1; // Response StopTransactionConf if(ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionConf == ON) { ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionConf = OFF; } ShmCharger->gun_info[gun_index].isHandshakeTimeOn = 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) || (ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq == 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...\r\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\r\n", ShmSysConfigAndInfo->SysConfig.UserId); } else if(ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_BACKEND; memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag, ARRAY_SIZE(ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag)); DEBUG_INFO("Start Method : BACKEND...\r\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...\r\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..\r\n"); } ShmCharger->gun_info[gun_index].rfidReq = OFF; ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq = OFF; ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart = OFF; ShmCharger->gun_info[gun_index].isGunPlugged = NO; 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(ShmOCPP16Data->OcppConnStatus) { // On line ShmOCPP16Data->SpMsg.bits.AuthorizeReq = ON; } else { // Off line switch(ShmSysConfigAndInfo->SysConfig.OfflinePolicy) { case OFF_POLICY_LOCALLIST: ShmOCPP16Data->SpMsg.bits.AuthorizeReq = ON; 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; } } ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; } if(ShmCharger->gun_info[gun_index].isHandshakeTimeOn == OFF) { if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > TIMEOUT_SPEC_AUTH) { // Authorization timeout process. ShmCharger->gun_info[gun_index].rfidReq = OFF; setChargerMode(gun_index, SYS_MODE_IDLE); DEBUG_WARN("Authorize timeout !!!\r\n"); } else { switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod) { case START_METHOD_RFID: if(ShmOCPP16Data->SpMsg.bits.AuthorizeConf || (!ShmOCPP16Data->OcppConnStatus)) { if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted") == 0) || ((!ShmOCPP16Data->OcppConnStatus) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) || ((!ShmOCPP16Data->OcppConnStatus) && ((isValidLocalWhiteCard() == PASS)||(isValidPHCard() == 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("Start Authorize pass.\r\n"); setLedMotion(gun_index,LED_ACTION_RFID_PASS); sleep(3); setLedMotion(gun_index,LED_ACTION_AUTHED); ftime(&startTime[gun_index][TMR_IDX_HANDSHAKING]); ShmCharger->gun_info[gun_index].isHandshakeTimeOn = ON; } else { DEBUG_INFO("Authorize fail.\r\n"); setLedMotion(gun_index,LED_ACTION_RFID_FAIL); sleep(3); setChargerMode(gun_index, SYS_MODE_IDLE); } sethaltCard(rfidFd,MODULE_EWT); ShmCharger->gun_info[gun_index].rfidReq = OFF; ShmOCPP16Data->SpMsg.bits.AuthorizeConf = OFF; } break; case START_METHOD_BACKEND: case START_METHOD_BLE: case START_METHOD_FREE: default: setLedMotion(gun_index,LED_ACTION_AUTHED); ftime(&startTime[gun_index][TMR_IDX_HANDSHAKING]); ShmCharger->gun_info[gun_index].isHandshakeTimeOn = ON; break; } } } else { // 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)) { ftime(&startTime[gun_index][TMR_IDX_HANDSHAKING]); ShmCharger->gun_info[gun_index].isGunPlugged = YES; } if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C))&& (ShmCharger->gun_info[gun_index].isGunPlugged == YES)) { setChargerMode(gun_index, SYS_MODE_PREPARING); } // 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.\r\n"); setChargerMode(gun_index, SYS_MODE_IDLE); sethaltCard(rfidFd,MODULE_EWT); } 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); sleep(5); DEBUG_INFO("Handshaking timeout..."); setChargerMode(gun_index, SYS_MODE_IDLE); } } break; case SYS_MODE_PREPARING: if(isModeChange(gun_index)) { setRelay(gun_index, ON); setLedMotion(gun_index,LED_ACTION_CONNECTED); } if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) && (ShmCharger->gun_info[gun_index].isGunPlugged == YES)) { DEBUG_INFO("Charging gun is plugged before.\r\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.\r\n"); setChargerMode(gun_index, SYS_MODE_IDLE); sethaltCard(rfidFd,MODULE_EWT); } else { ShmCharger->gun_info[gun_index].rfidReq = OFF; } if((ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON)) { ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].isUnlockerConnetor = 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); memcpy((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); memcpy((char*)ShmOCPP16Data->StartTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StartTransaction[gun_index].IdTag)); ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionReq = 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]); } if((ShmCharger->gun_info[gun_index].rfidReq == ON) || (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop == ON) || (ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq == ON)|| (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState != CP_STATE_C) || (ShmOCPP16Data->MsMsg.bits.ResetReq) || (ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].isUnlockerConnetor == ON)) { setChargerMode(gun_index, SYS_MODE_TERMINATING); } else { setLedMotion(gun_index,LED_ACTION_CHARGING); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100); ftime(&endChargingTime[gun_index]); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration = DiffTimeb(startChargingTime[gun_index], endChargingTime[gun_index])/1000; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy = ((float)(ShmCharger->gun_info[gun_index].powerConsumption.power_consumption - ShmCharger->gun_info[gun_index].powerConsumption.power_consumption_at_start))/100; // Response StartTransactionConf if(ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionConf == ON) { ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionConf = OFF; } // Charging profile preparation if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) > TIMEOUT_SPEC_PROFILE_PREPARE) { if(!ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileConf) { ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileReq = ON; ftime(&startTime[gun_index][TMR_IDX_PROFILE_PREPARE]); } else { ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileConf = OFF; } } // Checking profile id > 0 and current time is between charging profile validFrom & validTo if((ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileId>0) && (ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileReq != 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\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileId); DEBUG_INFO("Valid from: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ValidFrom); DEBUG_INFO("Valid to: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ValidTo); DEBUG_INFO("Start schedule: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.StartSchedule); DEBUG_INFO("Profile kind: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileKind); DEBUG_INFO("RecurrencyKind: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].RecurrencyKind); DEBUG_INFO("Profile purpose: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose); DEBUG_INFO("Transaction ID: %d\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].TransactionId); DEBUG_INFO("ChargingRateUnit: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit); } // 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) && (((ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod == 0) && (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit != 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].Limit); DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\r\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent); } else break; } } } else if((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileKind, "Relative") == PASS)) { // Relative 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((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration > ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) && (((ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod == 0) && (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit != 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].Limit); DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\r\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent); } else break; } } } else { // Recurring 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)) { if((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].RecurrencyKind, "Daily") == PASS)) { // Checking limitation for(uint8_t idx_period=0;idx_periodSmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod);idx_period++) { if((getStartSinceToday() > ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) && (((ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod == 0) && (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit != 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].Limit); DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\r\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent); } else break; } } else { // Checking limitation for(uint8_t idx_period=0;idx_periodSmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod);idx_period++) { if((getStartSinceWeek() > ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) && (((ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod == 0) && (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit != 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].Limit); DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\r\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent); } else break; } } } } } // 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) { 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); ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; } } else { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); if(ShmCharger->gun_info[gun_index].targetCurrent != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current) { ShmCharger->gun_info[gun_index].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; } } // Debug information if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_LOGPPRINTOUT]) > TIMEOUT_SPEC_LOGPPRINTOUT) { DEBUG_INFO("=======================================================================\r\n"); DEBUG_INFO("ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent: %d \r\n", ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent); DEBUG_INFO("ShmCharger->gun_info[%d].primaryMcuCp_Pwn_Duty.max_current: %d\r\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current); DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent: %d\r\n", gun_index, ShmCharger->gun_info[gun_index].targetCurrent); DEBUG_INFO("=======================================================================\r\n"); ftime(&startTime[gun_index][TMR_IDX_LOGPPRINTOUT]); } if(ShmOCPP16Data->OcppConnStatus) { // On-line max condition check if((ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60))) { setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO("Connector-%d charging duration(%d) already over max duration(%d) in second.\r\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))) { setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO("Connector-%d charging energy(%.2f) already over max energy(%.2f) in KWH.\r\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy, ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy)); } else { setRelay(gun_index, ON); } } 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)) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_BLE)) { 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)))) { setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO("Connector-%d charging duration(%d) already over off-line max duration(%d) in second.\r\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)))) { setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO("Connector-%d charging energy(%.2f) already over off-line max energy(%.2f) in KWH.\r\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy, ((float)ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy)); } else { setRelay(gun_index, ON); } } else { setRelay(gun_index, OFF); DEBUG_INFO("Connector-%d can not charging in off line\r\n", gun_index); } } } break; case SYS_MODE_TERMINATING: if(isModeChange(gun_index)) { if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration != 0) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration = DiffTimeb(startChargingTime[gun_index], endChargingTime[gun_index])/1000; } if(!ShmCharger->gun_info[gun_index].primaryMcuState.relay_state) { setLedMotion(gun_index, LED_ACTION_STOP); } else {} getDateTimeString((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime); } // 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) && !ShmOCPP16Data->SpMsg.bits.AuthorizeReq) { // 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\r\n", ShmSysConfigAndInfo->SysConfig.UserId); DEBUG_INFO("Start method : %d...\r\n ", ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod); if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_RFID) { switch(ShmSysConfigAndInfo->SysConfig.AuthorisationMode) { case AUTH_MODE_ENABLE: if(ShmOCPP16Data->OcppConnStatus) { // On line ShmOCPP16Data->SpMsg.bits.AuthorizeReq = ON; } else { // Off line switch(ShmSysConfigAndInfo->SysConfig.OfflinePolicy) { case OFF_POLICY_LOCALLIST: ShmOCPP16Data->SpMsg.bits.AuthorizeReq = ON; 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) { ShmCharger->gun_info[gun_index].rfidReq = OFF; DEBUG_INFO("Need to match with start method : START_METHOD_BACKEND...\r\n"); setChargerMode(gun_index, SYS_MODE_CHARGING); } else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_BLE) { ShmCharger->gun_info[gun_index].rfidReq = OFF; DEBUG_INFO("Need to match with start method : START_METHOD_BLE...\r\n"); setChargerMode(gun_index, SYS_MODE_CHARGING); } else {} } else { if(((ShmOCPP16Data->SpMsg.bits.AuthorizeConf) || (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) || (!ShmOCPP16Data->OcppConnStatus&&(ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE))) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod != START_METHOD_BLE)) { if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0) || (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) || (!ShmOCPP16Data->OcppConnStatus&&(ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE))) { ShmCharger->gun_info[gun_index].isAuthPassEnd = ON; } else { ShmCharger->gun_info[gun_index].rfidReq = OFF; DEBUG_INFO("Authorize fail.\r\n"); setLedMotion(gun_index,LED_ACTION_RFID_FAIL); sleep(3); } ShmOCPP16Data->SpMsg.bits.AuthorizeConf = OFF; } } } // 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) || (ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq == ON) || ((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) && (strcmp((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[StopTransactionOnEVSideDisconnect].ItemData, "TRUE") == 0)) || (ShmOCPP16Data->MsMsg.bits.ResetReq) || (ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].isUnlockerConnetor == ON)) { if(ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest == ON) { if(((ShmCharger->gun_info[gun_index].rfidReq == ON) && isMatchStartUser(gun_index)) || (ShmCharger->gun_info[gun_index].isAuthPassEnd)) { DEBUG_INFO("End Authorize pass.\r\n"); setLedMotion(gun_index,LED_ACTION_RFID_PASS); sleep(3); } } else {} setRelay(gun_index, OFF); setLedMotion(gun_index, LED_ACTION_STOP); if(!ShmCharger->gun_info[gun_index].primaryMcuState.relay_state) { setChargerMode(gun_index, SYS_MODE_COMPLETE); } } else { 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) && (ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq != ON) && !ShmOCPP16Data->MsMsg.bits.ResetReq && !(ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60))) && !(ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy))) && !(!ShmOCPP16Data->OcppConnStatus && (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)))) && !(!ShmOCPP16Data->OcppConnStatus && (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); } 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(ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq) { sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Remote"); } else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop) { sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Local"); } else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) { sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "EVDisconnected"); } 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 ]...\r\n.",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason); memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100); ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON; ShmCharger->gun_info[gun_index].rfidReq = OFF; ShmCharger->gun_info[gun_index].isAuthPassEnd = OFF; ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop = OFF; ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq = OFF; DB_Insert_Record(localDb, gun_index); setChargerMode(gun_index, SYS_MODE_IDLE); break; case SYS_MODE_ALARM: if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus == SYS_MODE_TERMINATING)) { } else { 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); } } setLedMotion(gun_index,LED_ACTION_ALARM); 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...\r\n"); ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = OFF; int value = upgrade_check(); DEBUG_INFO("Local update Value: %d...\r\n",value); if(value == PASS) { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == ON) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = OFF; ShmCharger->isUpdateSuccess = YES; DEBUG_INFO("Local update success...\r\n"); } else { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == OFF) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = ON; ShmCharger->isUpdateSuccess = NO; DEBUG_INFO("Local update unsuccess...\r\n"); } } else if(ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq) { //====================================== // Check remote upgrade firmware request //====================================== if(strcmp((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "DownloadFailed")==0) { DEBUG_INFO("Firmware remote upgraded fail...\r\n"); ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq = OFF; ShmCharger->isUpdateSuccess = NO; } else if(strcmp((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "Downloaded")==0) { DEBUG_INFO("Firmware remote upgrading...\r\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: %d...\r\n",result); if(result == PASS) { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == ON) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = OFF; ShmCharger->isUpdateSuccess = YES; DEBUG_INFO("Remote update success...\r\n"); } else { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == OFF) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = ON; ShmCharger->isUpdateSuccess = NO; DEBUG_INFO("Remote update unsuccess...\r\n"); } } else {} } 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; DEBUG_WARN("Firmware upgrade success.\r\n"); sleep(5); DEBUG_INFO("Firmware upgraded, reboot...\r\n"); system("reboot -f"); sleep(5); system("reboot -f"); } else { sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "InstallationFailed"); ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; DEBUG_WARN("Firmware upgrade fail.\r\n"); 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...\r\n"); setChargerMode(gun_index, SYS_MODE_IDLE); } else if(ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationReq) { DEBUG_INFO("Reservation: Cancel reservation...\r\n"); setChargerMode(gun_index, SYS_MODE_IDLE); ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationReq = OFF; ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationConf = ON; } else { // Check is there RFID or back end request start if((ShmCharger->gun_info[gun_index].rfidReq == ON) || (ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq == ON)) { 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(strcmp((char*)ShmSysConfigAndInfo->SysConfig.UserId, (char*)ShmOCPP16Data->ReserveNow[gun_index].IdTag) == 0) { DEBUG_INFO("Start Method in reservation : RFID...\r\n"); DEBUG_INFO("Start request User Id : %s\r\n", ShmSysConfigAndInfo->SysConfig.UserId); DEBUG_INFO("Reservation User Id : %s\r\n", ShmOCPP16Data->ReserveNow[gun_index].IdTag); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_RFID; setChargerMode(gun_index, SYS_MODE_AUTHORIZING); } ShmCharger->gun_info[gun_index].rfidReq = OFF; } else if(ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq) { if(strcmp((char*)ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag, (char*)ShmOCPP16Data->ReserveNow[gun_index].IdTag) == 0) { DEBUG_INFO("Start Method in reservation: BACKEND...\r\n"); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_BACKEND; memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag, ARRAY_SIZE(ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag)); setChargerMode(gun_index, SYS_MODE_AUTHORIZING); } ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq = 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; }