#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../Log/log.h" #include "../ShareMemory/shmMem.h" #include "../Define/define.h" #include "../Config.h" #include "../SelectGun/SelectGun.h" #include "../timeout.h" #include "../DataBase/DataBase.h" #include "DoComm.h" //------------------------------------------------------------------------------ static DoCommGblData gDoCommGblData = {0}; static MoreInfoReq gMoreInfoReq[2] = {0}; //static ChangePageReq gPageReq[2] = {0}; static ConnectorActReqVar gConnectorActReq[2] = {0}; static struct SysConfigData *pSysConfig = NULL; static struct SysInfoData *pSysInfo = NULL; static struct WARNING_CODE_INFO *pSysWarning = NULL; static struct AlarmCodeData *pAlarmCode = NULL; static struct PsuData *ShmPsuData = NULL; static struct OCPP16Data *ShmOCPP16Data = NULL; static struct PrimaryMcuData *ShmPrimaryMcuData = NULL; static SelectGunInfo *ShmSelectGunInfo = NULL; static DcCommonInfo *ShmDcCommonData = NULL; //static struct ChargingInfoData *ChargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY] static struct ChargingInfoData *pDcChargingInfo = NULL; static struct timeb gRegTimeUp[2][MAX_REGISTER_NUM] = {0}; static struct WARNING_CODE_INFO gPreSysWarningInfo = {0}; // Hexdump char old_Hexdump[10240]; static uint8_t RemoteStartNoIDState = NO; static uint8_t ReservationState[2] = {0}; static char ReservationIdTag[2][32]; //static uint8_t DeductResultReq[2] = {0}; static int LineStatusCode[2] = {0}; static unsigned int LedIntensity = 0; static int TimeZoneOffset = 0; int RxLen; char Rxdata[1024]; uint8_t _isplugin = 0; int gunstatus[2]; //------------------------------------------------------------------------------ static void removeFaultCodeToBuf(uint8_t *Code); static void addFaultCodeToBuf(uint8_t *Code); static int readMiscCommand(int fd, uint8_t id); static int writeCsuModuleVersion(int fd); static int writeGroundFaultDetection(int fd, uint8_t status, uint8_t id); //------------------------------------------------------------------------------ //--- Common function --- //------------------------------------------------------------------------------ void GetClockTime(struct timespec *_now_time, void *null) { clock_gettime(CLOCK_MONOTONIC, _now_time); } static int DiffTimeb(struct timeb ST, struct timeb ET) { //return milli-second unsigned int StartTime, StopTime; StartTime = (unsigned int)ST.time; StopTime = (unsigned int)ET.time; return (StopTime - StartTime) * 1000 + ET.millitm - ST.millitm; } /** * [hexdump : check data] * @Author Jerry * @DateTime 2018-12-21 * @param p [description] * @param size [description] */ static void Hexdump(const void *p, size_t size) { const uint8_t *c = p; char message[10240] = {0}; uint32_t i = 0; uint32_t message_len = 0; assert(p); //printf("Dumping %u bytes from %p:\n", size, p); message_len += sprintf(&message[message_len], "\nDumping %u bytes from %p:\n", (unsigned int)size, p); while (size > 0) { for (i = 0; i < 16; i++) { if (i < size) { //printf("%02x ", c[i]); message_len += sprintf(&message[message_len], "%02x ", c[i]); } else { //printf(" "); message_len += sprintf(&message[message_len], " "); } } for (i = 0; i < 16; i++) { if (i < size) { //printf("%c", c[i] >= 32 && c[i] < 127 ? c[i] : '.'); message_len += sprintf(&message[message_len], "%c", c[i] >= 32 && c[i] < 127 ? c[i] : '.'); } else { //printf(" "); message_len += sprintf(&message[message_len], " "); } } //printf("\n"); message_len += sprintf(&message[message_len], "\n"); c += 16; if (size <= 16) { break; } size -= 16; } //message_len += sprintf(&message[message_len], "\n"); if( strcmp(old_Hexdump,message) != EQUAL ) { log_info("%s", message); strcpy(old_Hexdump,message); } } static int string2ByteArray(char *input, uint8_t *output) { int loop = 0; int i = 0; while (input[loop] != '\0') { output[i++] = input[loop++]; } output[loop] = '\0'; return loop + 1; } int string2Date(char* input, uint8_t* output) { int loop = 0; int i = 0; while (input[loop] != '\0') { loop++; } loop++; while (input[loop] != '\0') { output[i++] = input[loop++]; } output[loop] = '\0'; return loop + 1; } static void unixSocketSigPipeHandle(int sig) { log_error("socket packet error %x", sig); } static void InitSocketSigPipe(void) { struct sigaction action; action.sa_handler = unixSocketSigPipeHandle; sigemptyset(&action.sa_mask); action.sa_flags = 0; sigaction(SIGPIPE, &action, NULL); } //------------------------------------------------------------------------------ static void setTcpStatus(uint8_t setValue) { pAlarmCode->AlarmEvents.bits.DisconnectedFromDo = setValue; } //------------------------------------------------------------------------------ //--- TCP socket function --- //------------------------------------------------------------------------------ static int sendTcpSocket(int fd, uint8_t *data, uint16_t dataLen) { int size = -1; int i; char _info[1024]; int len = 0; // ReadCmdline show network package if (ShmDcCommonData->showNetPackage) { len = 0; len += sprintf(&_info[len], "Net Tx[%d]:", dataLen); for (i = 0; i < dataLen; i++) { if (i == 0) len += sprintf(&_info[len], "[%X]\t", data[i]); else len += sprintf(&_info[len], "%X ", data[i]); } len += sprintf(&_info[len], "\n"); printf("%s", _info); } size = send(fd, data, dataLen , 0); if ((size < 0) || (errno == EAGAIN)) { if (size < 0) { log_error("Send Socket Size = %d, EAGAIN error %d:%s", size, errno, strerror(errno)); } } return size; } static int recvTcpSocket(int fd, uint8_t *data, uint16_t dataLen,uint8_t ishead) { int size = -1; int i; uint8_t *pdata = (uint8_t *)data; size = recv(fd, pdata, dataLen, MSG_WAITALL); if ((errno == EAGAIN) || (size < 0)) { log_error("Receive Socket Size = %d, EAGAIN error %d:%s", size, errno, strerror(errno)); } // ReadCmdline show network package if (ShmDcCommonData->showNetPackage) { if (ishead) { RxLen = 0; RxLen += sprintf(&Rxdata[RxLen], "Net Rx[%d]:", size); } for (i = 0; i < dataLen; i++) { if (ishead && i == 0) RxLen += sprintf(&Rxdata[RxLen], "[%X]\t", data[i]); else RxLen += sprintf(&Rxdata[RxLen], "%X ", data[i]); } if (!ishead) { RxLen += sprintf(&Rxdata[RxLen], "\n"); printf("%s", Rxdata); strcpy(Rxdata,""); } } return size; } static int getSO_ERROR(int fd) { int err = 1; socklen_t len = sizeof err; if (-1 == getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&err, &len)) { log_error("getSO_ERROR"); } if (err) { errno = err; // set errno to the socket SO_ERROR } return err; } static void closeSocket(int fd) // *not* the Windows closesocket() { if (fd < 0) { return; } getSO_ERROR(fd); // first clear any errors, which can cause close to fail if (shutdown(fd, SHUT_RDWR) < 0) { // secondly, terminate the 'reliable' delivery if (errno != ENOTCONN && errno != EINVAL) { // SGI causes EINVAL log_info("shutdown"); } } if (close(fd) < 0) { // finally call close() log_info("client socket close"); } } static int doCommConnToServer(void) { struct sockaddr_in dest; struct timeval tv; int flag; int TcpSock = 0; //if (TcpSock > 0) { // close(TcpSock); //} if ((TcpSock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { log_error("Open TCP socket NG"); return -1; } //flag = fcntl (TcpSock, F_GETFL, 0); //if (flag >= 0) { // flag |= O_NONBLOCK; // fcntl(TcpSock, F_SETFL, flag ); //} tv.tv_sec = 3; tv.tv_usec = 0; setsockopt(TcpSock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)); //設定等待3s setsockopt(TcpSock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval)); //設定傳送3s flag = 1; setsockopt(TcpSock, SOL_SOCKET, MSG_NOSIGNAL, &flag, sizeof(flag)); memset(&dest, 0, sizeof(dest)); dest.sin_family = AF_INET; dest.sin_port = htons(DoTcpPort); inet_aton(DoIPAddress, (struct in_addr *) &dest.sin_addr.s_addr); if (connect(TcpSock, (struct sockaddr *) &dest, sizeof(dest)) != 0) { close(TcpSock); return -1; } return TcpSock; } //------------------------------------------------------------------------------ //--- Audi select gun --- //------------------------------------------------------------------------------ static void clearPricesInfo(uint8_t id) { memset(&ShmSelectGunInfo->PricesInfo[id], 0, sizeof(PricesInfo)); ShmSelectGunInfo->PricesInfo[id].Balance = FAIL_BALANCE_PRICES; } static void ClearAuthorizedFlag(void) { ShmOCPP16Data->SpMsg.bits.AuthorizeConf = NO; pSysInfo->AuthorizeFlag = NO; } static void ClearDetectPluginFlag(int gunIndex) { if (pSysConfig->TotalConnectorCount > 1 && gunIndex == RIGHT_GUN_NUM) return; ShmDcCommonData->pGunInfo[gunIndex].WaitForPlugit = NO; } static bool isDetectPlugin(int gunIndex) { if (pSysConfig->TotalConnectorCount == 1 && gunIndex == RIGHT_GUN_NUM) return false; if (ShmDcCommonData->pGunInfo[gunIndex].WaitForPlugit == YES) { return true; } /* if (pSysInfo->WaitForPlugit == YES) { return true; } */ return false; } static void destroySelectGun(uint8_t curGun) { uint8_t i = 0; uint8_t totalGun = pSysConfig->TotalConnectorCount; if (curGun == DESTROY_ALL_SEL) { ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_RELEASE; ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_RELEASE; for (i = 0; i < totalGun; i++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i); pDcChargingInfo->TimeoutFlag = Timeout_None; clearPricesInfo(i); } pSysInfo->CurGunSelected = 0; strcpy((char *)pSysConfig->UserId, ""); } //for charging timeout or complete if ((curGun == LEFT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.LeftGun != SEL_GUN_RELEASE)) { ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_RELEASE; if (ShmOCPP16Data->SpMsg.bits.AuthorizeConf != NO) { ClearAuthorizedFlag(); } clearPricesInfo(curGun); } if ((curGun == RIGHT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.RightGun != SEL_GUN_RELEASE)) { if (ShmOCPP16Data->SpMsg.bits.AuthorizeConf != NO) { ClearAuthorizedFlag(); } clearPricesInfo(curGun); } } static int getConfirmSelectedGun(uint8_t curSel) { if (((curSel == LEFT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.LeftGun >= SEL_GUN_CONFIRM)) || ((curSel == RIGHT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.RightGun >= SEL_GUN_CONFIRM))) { return PASS; } return FAIL; } static int getSelGunWaitToAuthor(uint8_t curGun) { if (curGun == LEFT_GUN_NUM && ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_ATHOR) { return FAIL; } if (curGun == RIGHT_GUN_NUM && ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_ATHOR) { return FAIL; } return PASS; } static void setConfirmSelGun(uint8_t selGun) { if (selGun == LEFT_GUN_NUM && ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_RELEASE) { ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_CONFIRM; //printf("confirmSelGun left"); } else if (selGun == RIGHT_GUN_NUM && ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_RELEASE) { ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_CONFIRM; //printf("confirmSelGun right"); } } //------------------------------------------------------------------------------ //--- DoComm function --- //------------------------------------------------------------------------------ static int compareOpcode(uint8_t opCode) { if (opCode != OP_WAIT_RESPONSE) { //log_error("response operative code fail"); return FAIL; } return PASS; } static int compareResult(uint8_t result) { if (result != COMMAND_RESULT_OK) { //log_error("response result fail"); return FAIL; } return PASS; } static int compareRegister(uint8_t srcReg, uint8_t destReg) { if (srcReg != destReg) { //log_error("response register fail"); return FAIL; } return PASS; } static float transPricesUnit(int prices) { //printf("prices = %.2f", prices * PRICES_UNIT); return (prices * PRICES_UNIT); } static void clearMiscCommand(void) { gDoCommGblData.MiscCmd = 0; } int timecmp(uint8_t* time1, uint8_t* time2) { for (int i = 0; i < strlen(time1); i++) { if (time1[i] != time2[i]) { return FALSE; } } return TRUE; } static int qrCodeUrlInfoHandle(uint8_t *data) { //int len = 0; //char cmdBuf[128] = {0}; char localTime[128] = {0}; uint16_t timeLen = 0; struct timeb SeqEndTime; struct tm *tm; char _setTime[50]; uint8_t cmdBuf[128]; if ((char *)&data[0] == '\0') { log_error("QR code date error"); return FAIL; } //get local system time ftime(&SeqEndTime); SeqEndTime.time = time(NULL); tm = localtime(&SeqEndTime.time); timeLen = sprintf(localTime, "%04d-%02d-%02d %02d:%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min); //copy QR code string memset(ShmDcCommonData->QRCodeString, '\0', sizeof(ShmDcCommonData->QRCodeString)); //printf("data = %s", data); //len = string2ByteArray((char *)data, (uint8_t *)ShmDcCommonData->QRCodeString); string2Date((char*)data, (uint8_t*)_setTime); //printf("SystemId = %s", pSysConfig->SystemId); if (!timecmp(localTime, _setTime)) { //log_info("Set Timer:%s", _setTime); sprintf((char*)cmdBuf, "date -u -s \"%s\" >> /dev/null &", _setTime); system((char*)cmdBuf); system("hwclock -w -u"); system("hwclock -s"); } //if ((char *)&data[len] == '\0') { // log_error("power cabinet system date error"); // return FAIL; //} //set system date //if (strncmp((char *)localTime, (char *)&data[len], timeLen) != 0) { // sprintf(cmdBuf, "date -s \"%s\" >> /dev/null", (char *)&data[len]); // system(cmdBuf); // log_info("local time = %s, data time = %s", localTime, (char *)&data[len]); // ShmOCPP16Data->MsMsg.bits.ResetReq = YES; // strcpy((char *)ShmOCPP16Data->Reset.Type, "Soft"); // sleep(3); // //gDoCommGblData.DisConnCount = CHECK_NETWORK_FAIL_COUNT; //} return PASS; } static int updateFirmwareHandle(uint8_t *imgName) { int ret = PASS; char cmdBuf[1024] = {0}; sprintf(cmdBuf, "/mnt/%s", imgName); log_info("Program ready to check file %s", cmdBuf); if ( access(cmdBuf, F_OK) != -1) { log_info("File '%s' exist.", cmdBuf); pSysInfo->FirmwareUpdate = YES; } else { log_info("File '%s' doesn't exist.", cmdBuf); ret = FAIL; } #if 0 char cmdBuf[1024] = {0}; int status = 0; system("touch ./tftpUpdate.sh"); //創建shell sprintf(cmdBuf, "echo tftp -gr %s -l %s/%s %s; > ./tftpUpdate.sh", imgName, IMAGE_FILE_PATH, imgName, DoIPAddress); system("chmod +x ./tftpUpdate.sh"); //修改權限 status = system("sh tftpUpdate.sh"); //執行shell if (-1 == status) { printf("system error!"); } else { printf("exit status value = [0x%x]", status); if (WIFEXITED(status)) { if (0 == WEXITSTATUS(status)) { printf("run shell script successfully."); pSysInfo->FirmwareUpdate = YES; } else { printf("run shell script fail, script exit code: %d", WEXITSTATUS(status)); } } else { printf("exit status = [%d]", WEXITSTATUS(status)); } } system("rm -rf ./tftpUpdate.sh"); //刪除shell #endif //0 return ret; } static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data) { int ret = PASS; uint8_t i = 0, j = 0; uint8_t cmdCount = (dataLen / 6); uint16_t cmd = 0; uint32_t value = 0; float prices = 0; MiscCommand *pMiscCmd = NULL; if (cmdCount < 1) { gDoCommGblData.MiscCmd = 0; //printf("cmdCount fail = %d, data len = %d", cmdCount, dataLen); return FAIL; } for (i = 0; i < cmdCount; i++) { pMiscCmd = (MiscCommand *)data + i; cmd = ntohs(pMiscCmd->CMD); value = ntohl(*((uint32_t *)&pMiscCmd->Value[0])); //log_info("misc command = %x, value = %d", cmd, value); switch (cmd) { //--- Execute parameter --- case MISC_CMD_CONNECOTOR_TIMEOUT: ShmSelectGunInfo->RemoteSetup.ConnectionTimeout = value; log_info("connection timeout = %d", ShmSelectGunInfo->RemoteSetup.ConnectionTimeout); clearMiscCommand(); break; case MISC_CMD_OPERATIVE_STATE: if ((value > YES) || (value < NO)) { if (plugNum == 1) { clearMiscCommand(); } break; } log_info("change availability plugNum = %d, value = %d", plugNum, value); ShmOCPP16Data->CsMsg.bits[plugNum].ChangeAvailabilityReq = YES; if (value == YES) { strcpy((char *)ShmOCPP16Data->ChangeAvailability[plugNum].Type, "Operative"); } else if (value == NO) { strcpy((char *)ShmOCPP16Data->ChangeAvailability[plugNum].Type, "Inoperative"); } if (plugNum == 1) { clearMiscCommand(); } break; case MISC_CMD_DEFAULT_PRICES: prices = transPricesUnit((int)value); log_info("default prices = %.2f", prices); ShmDcCommonData->ChargingRate = prices; pSysConfig->BillingData.isBilling = YES; for (j = 0; j < 24; j++) { pSysConfig->BillingData.Fee[j] = prices; } clearMiscCommand(); break; case MISC_CMD_DEFAULT_CURRENCY: if (value < 0) { clearMiscCommand(); return FAIL; } //log_info("default currency = %s%c", (uint8_t *)Currency[value]); log_info("default currency = %s", (uint8_t *)GetCurrency(value)); pSysConfig->BillingData.Currency = value; clearMiscCommand(); break; case MISC_CMD_ACCOUNT_BALANCE: if (pSysInfo->CurGunSelected != (plugNum)) { clearMiscCommand(); break; } #if defined DD360Audi if (getConfirmSelectedGun(plugNum) == FAIL) { log_info("Remote start not select gun"); break; } #endif //DD360Audi ShmSelectGunInfo->PricesInfo[plugNum].Balance = transPricesUnit((int)value); log_info("%d misc balance = %.2f", plugNum, ShmSelectGunInfo->PricesInfo[plugNum].Balance); clearMiscCommand(); break; case MISC_CMD_BACKEND_STATUS : ShmSelectGunInfo->EthDevStatus.Backend = value; break; case MISC_CMD_ETHERNET_STATUS : ShmSelectGunInfo->EthDevStatus.Ethernet = value; break; case MISC_CMD_WIFI_STATUS : ShmSelectGunInfo->EthDevStatus.Wifi = value; break; case MISC_CMD_4G_STATUS : ShmSelectGunInfo->EthDevStatus.FourG = value; break; case MISC_CMD_BILLING_INFO: pSysConfig->BillingData.isBilling = value; break; case MISC_CMD_WEB_STOP_CHARGING: pSysConfig->StopChargingByButton = value; break; //--- Control Dispenser --- case MISC_CMD_HARDWARE_REBOOT: if (value != YES) { clearMiscCommand(); break; } log_info("Hardware reboot"); ShmOCPP16Data->MsMsg.bits.ResetReq = YES; strcpy((char *)ShmOCPP16Data->Reset.Type, "Hard"); clearMiscCommand(); break; case MISC_CMD_SOFTWARE_RESTART: if (value != YES) { clearMiscCommand(); break; } clearMiscCommand(); log_info("Software reboot"); ShmOCPP16Data->MsMsg.bits.ResetReq = YES; strcpy((char *)ShmOCPP16Data->Reset.Type, "Soft"); break; case MISC_CMD_REMOTE_START_CHARGING: if (value != YES) { if (plugNum == 1) { clearMiscCommand(); } break; } log_info("Remote start charging plugNum = %d", plugNum); #if defined DD360Audi if (getSelGunWaitToAuthor(plugNum) == FAIL) { log_error("Remote start gun already charging"); break; } if (pSysInfo->CurGunSelected != (plugNum)) { if (plugNum == LEFT_GUN_NUM && (ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_CONFIRM || ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_ATHOR)) { ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_RELEASE; strcpy((char *)pSysConfig->UserId, ""); pSysInfo->WaitForPlugit = NO; sleep(1); //Jerry add pSysInfo->SystemPage = _LCM_SELECT_GUN; GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL); pSysInfo->SystemTimeoutFlag = Timeout_None; } if (plugNum == RIGHT_GUN_NUM && (ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_CONFIRM || ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_ATHOR)) { ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_RELEASE; strcpy((char *)pSysConfig->UserId, ""); pSysInfo->WaitForPlugit = NO; sleep(1); //Jerry add pSysInfo->SystemPage = _LCM_SELECT_GUN; GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL); pSysInfo->SystemTimeoutFlag = Timeout_None; } pSysInfo->CurGunSelected = (plugNum); pSysInfo->CurGunSelectedByAc = NO_DEFINE; } #else pSysInfo->CurGunSelected = (plugNum); pSysInfo->CurGunSelectedByAc = NO_DEFINE; #endif //DD360Audi setConfirmSelGun(pSysInfo->CurGunSelected); ShmOCPP16Data->CsMsg.bits[plugNum].RemoteStartTransactionReq = YES; ShmSelectGunInfo->PricesInfo[plugNum].Balance = 0.00; clearMiscCommand(); break; case MISC_CMD_REMOTE_STOP_CHARGING: if (value != YES) { if (plugNum == 1) { clearMiscCommand(); } break; } strcpy((char *)pSysConfig->UserId, ""); //pSysInfo->WaitForPlugit = NO; ClearDetectPluginFlag(plugNum); #ifdef DD360Audi pSysInfo->SystemPage = _LCM_SELECT_GUN; #endif GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL); pSysInfo->SystemTimeoutFlag = Timeout_None; destroySelectGun(plugNum); clearMiscCommand(); break; case MISC_CMD_REMOTE_UNLOCK: if (value != YES) { if (plugNum == 1) { clearMiscCommand(); } break; } if (isDetectPlugin(plugNum) == YES) { ClearDetectPluginFlag(plugNum); strcpy((char *)pSysConfig->UserId, ""); #ifdef DD360Audi pSysInfo->SystemPage = _LCM_SELECT_GUN; #endif GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL); pSysInfo->SystemTimeoutFlag = Timeout_None; destroySelectGun(plugNum); } else { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum); pDcChargingInfo->StopChargeFlag = POWER_CABINET_STOP_CHARGING; } break; case MISC_CMD_AUTH_DISABLE: pSysConfig->AuthorisationMode = value; log_info("Auto Authorize Disable:%d", pSysConfig->AuthorisationMode); //clearMiscCommand(); break; case MISC_CMD_EVCCID_ENABLE: pSysConfig->isAuthrizeByEVCCID = value; log_info("Authorize By EVCCID:%d",pSysConfig->isAuthrizeByEVCCID); //clearMiscCommand(); break; case MISC_CMD_RESERVATION: if(value != YES) { break; } gMoreInfoReq[plugNum].bits.ReservationReq = YES; break; case MISC_CMD_CHANGE_LCM_PAGE: if(value == LCM_PAGE_REMOTE_START_NO_ID) { gMoreInfoReq[plugNum].bits.RemoteStartNoID = YES; } /* if(value == LCM_PAGE_JOIN_LINE) { if(!gPageReq[plugNum].bits.JoinLine) { log_info("Gun %d JoinLine page is trigger", plugNum); } gPageReq[plugNum].bits.JoinLine = YES; } if(value == LCM_PAGE_PAYMENT_SWITCH) { if(!gPageReq[plugNum].bits.PaymentSwitch) { log_info("Gun %d PaymentSwitch page is trigger", plugNum); } gPageReq[plugNum].bits.PaymentSwitch = YES; }*/ break; case MISC_CMD_QR_CODE_REQ: break; case MISC_CMD_STATION_INFO_REQ: if(value != YES) { break; } gMoreInfoReq[plugNum].bits.StationInfoReq = YES; break; case MISC_CMD_FINAL_COST_REQ: if(value != YES) { break; } gMoreInfoReq[plugNum].bits.FinalCostReq = YES; break; case MISC_CMD_LINE_STATUS_REQ: LineStatusCode[plugNum] = value; //ShmDcCommonData->LineStatus[plugNum] = value; log_info("Gun %d Line Status Code: %d", plugNum, LineStatusCode[plugNum]); break; case MISC_CMD_LED_INTENSITY: LedIntensity = value; log_info("Led Intensity: %d", LedIntensity); break; case MISC_CMD_TIME_OFFSET: TimeZoneOffset = value; log_info("Time Zone Offset: %d", TimeZoneOffset); ShmDcCommonData->TZOffset = TimeZoneOffset; /* if (TimeZoneOffset == 480) { system("export TZ=CST-8"); log_info("Set Time Zone CST 8"); } */ break; case MISC_CMD_DEFAULT_PRICE_REQ: if (value != YES) { break; } gMoreInfoReq[plugNum].bits.DefaultPriceReq = YES; break; case MISC_CMD_USER_PRICE_REQ: if (value != YES) { break; } gMoreInfoReq[plugNum].bits.UserPriceReq = YES; break; case MISC_CMD_RECEIPT_REQ: if (value != YES) { break; } gMoreInfoReq[plugNum].bits.ReceiptReq = YES; break; case MISC_CMD_RFIDCARD_ENDIAN: if (pSysConfig->RfidCardNumEndian != value) { pSysConfig->RfidCardNumEndian = value; log_info("Set RFID CARD %s endian", value ? "Big" : "Little"); } break; default: clearMiscCommand(); break; } usleep(128); } return ret; } void AddDispenserReq(uint8_t* buff, MiscCommand* req) { buff[0] = (req->CMD >> 8) & 0xFF; buff[1] = req->CMD & 0xFF; buff[2] = req->Value[0]; buff[3] = req->Value[1]; buff[4] = req->Value[2]; buff[5] = req->Value[3]; } static int chargingcapabilityHandle(uint8_t *data, uint8_t plugNum) { uint8_t addr = 0; float MaxVolt, MaxCurrent, MaxPower; static PricesInfo pricesInfo[2] = {0}; CapabilityInfo *pCapabilityInfo = NULL; AccountInfo *pAccountInfo = NULL; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum); //--- charging capability information -------------------------------------- pCapabilityInfo = (CapabilityInfo *)&data[0]; MaxVolt = (float)(ntohs(pCapabilityInfo->OutputVoltage)); if (MaxVolt >= 0) { if (MaxVolt > MAX_VOLTAGE) { MaxVolt = MAX_VOLTAGE; } pDcChargingInfo->MaximumChargingVoltage = MaxVolt; } MaxCurrent = (float)(ntohs(pCapabilityInfo->OutputCurrent)); if (MaxCurrent >= 0) { if (MaxCurrent > MAX_CURRENCY) { MaxCurrent = MAX_CURRENCY; } pDcChargingInfo->AvailableChargingCurrent = MaxCurrent; } MaxPower = (float)(ntohs(pCapabilityInfo->OutputPower)); if (MaxPower >= 0) { if (MaxPower > MAX_POWER) { MaxPower = MAX_POWER; } pDcChargingInfo->AvailableChargingPower = MaxPower; } //MaxVolt = (float)(data[0] << 8 |data[1]); //MaxCurrent = (float)(data[2] << 8 | data[3]); //MaxPower = (float)(data[4] << 8 | data[5]); //printf("MaxVolt=%f, MaxCurrent=%f, MaxPower=%f,", MaxVolt, MaxCurrent, MaxPower); //--- user prices information ---------------------------------------------- addr = (sizeof(CapabilityInfo) - 2); //2 byte reserved pAccountInfo = (AccountInfo *)&data[addr]; pSysConfig->BillingData.Currency = pAccountInfo->Currency; ShmSelectGunInfo->PricesInfo[plugNum].UserPrices = transPricesUnit(ntohl(pAccountInfo->UserPrices)); pDcChargingInfo->ChargingFee = transPricesUnit(ntohl(pAccountInfo->TotalCost)); ShmSelectGunInfo->PricesInfo[plugNum].Balance = transPricesUnit(ntohl(pAccountInfo->Balance)); ShmSelectGunInfo->PricesInfo[plugNum].Discount = transPricesUnit(ntohl(pAccountInfo->Discount)); ShmSelectGunInfo->PricesInfo[plugNum].TransactionId = ntohl(pAccountInfo->Transaction); ShmSelectGunInfo->PricesInfo[plugNum].EnergyCost = transPricesUnit(ntohl(pAccountInfo->EnergyCost)); ShmSelectGunInfo->PricesInfo[plugNum].ParkingFee = transPricesUnit(ntohl(pAccountInfo->ParkingFee)); pAccountInfo->RemainAmount = ntohl(pAccountInfo->RemainAmount); memcpy((char*)&ShmSelectGunInfo->PricesInfo[plugNum].RemainAmount, (char*)&pAccountInfo->RemainAmount, sizeof(uint32_t)); if ((pricesInfo[plugNum].UserPrices != ShmSelectGunInfo->PricesInfo[plugNum].UserPrices) || (pricesInfo[plugNum].Balance != ShmSelectGunInfo->PricesInfo[plugNum].Balance) || (pricesInfo[plugNum].Discount != ShmSelectGunInfo->PricesInfo[plugNum].Discount) || (pricesInfo[plugNum].TransactionId != ShmSelectGunInfo->PricesInfo[plugNum].TransactionId) || (pricesInfo[plugNum].EnergyCost != ShmSelectGunInfo->PricesInfo[plugNum].EnergyCost) || (pricesInfo[plugNum].ParkingFee != ShmSelectGunInfo->PricesInfo[plugNum].ParkingFee) || (pricesInfo[plugNum].RemainAmount != ShmSelectGunInfo->PricesInfo[plugNum].RemainAmount)) { pricesInfo[plugNum].UserPrices = ShmSelectGunInfo->PricesInfo[plugNum].UserPrices; pricesInfo[plugNum].Balance = ShmSelectGunInfo->PricesInfo[plugNum].Balance; pricesInfo[plugNum].Discount = ShmSelectGunInfo->PricesInfo[plugNum].Discount; pricesInfo[plugNum].TransactionId = ShmSelectGunInfo->PricesInfo[plugNum].TransactionId; pricesInfo[plugNum].ParkingFee = ShmSelectGunInfo->PricesInfo[plugNum].ParkingFee; pricesInfo[plugNum].EnergyCost = ShmSelectGunInfo->PricesInfo[plugNum].EnergyCost; pricesInfo[plugNum].RemainAmount = ShmSelectGunInfo->PricesInfo[plugNum].RemainAmount; if (ShmSelectGunInfo->PricesInfo[plugNum].TransactionId != 0) { //ShmDcCommonData->TransactionInfo[plugNum].TransactionId = ShmSelectGunInfo->PricesInfo[plugNum].TransactionId; //UpdateDeductInfoStatus(plugNum, &ShmDcCommonData->TransactionInfo[plugNum]); log_info("id = %d, transaction id = %d, user prices = %.2f, Discount = %.2f, Account balances = %.2f, currency = %s", plugNum, ShmSelectGunInfo->PricesInfo[plugNum].TransactionId, ShmSelectGunInfo->PricesInfo[plugNum].UserPrices, ShmSelectGunInfo->PricesInfo[plugNum].Discount, ShmSelectGunInfo->PricesInfo[plugNum].Balance, (uint8_t*)GetCurrency(pSysConfig->BillingData.Currency) ); log_info("Total Cost:%.2f", pDcChargingInfo->ChargingFee); log_info("Parking Fee:%.2f", ShmSelectGunInfo->PricesInfo[plugNum].ParkingFee); log_info("Energy Cost:%.2f", ShmSelectGunInfo->PricesInfo[plugNum].EnergyCost); log_info("Remain Amount:%.2f", ShmSelectGunInfo->PricesInfo[plugNum].RemainAmount); } } return PASS; } static void addFaultCodeToBuf(uint8_t *Code) { uint8_t warningCount = pSysWarning->WarningCount; if (warningCount < 10) { memcpy(&pSysWarning->WarningCode[warningCount][0], Code, strlen((char *)Code)); pSysWarning->WarningCount++; log_info("Warning Code:%s",Code); } } static void removeFaultCodeToBuf(uint8_t *Code) { uint8_t find = 0x01; uint8_t i = 0; char _code[7] = {0}; sprintf(_code, "%s", Code); // 把相關的錯誤碼一次移除,避免重複顯示 while (find) { usleep(128); find = 0x00; for (i = 0; i < pSysWarning->WarningCount; i++) { usleep(128); if (find == 0x00) { if (memcmp(&pSysWarning->WarningCode[i][0], _code, 7) == 0) { find = 0x01; } } else { memcpy(&pSysWarning->WarningCode[i - 1][0], &pSysWarning->WarningCode[i][0], 7); } } if (find) { pSysWarning->WarningCount--; } } } bool CompareArrayIsZero(uint8_t *array, unsigned int array_size) { uint8_t i; if (array != NULL) { for (i = 0; i < array_size; i++) { if (array[i] != 0) { return false; } } } return true; } static int powerCabinetStatusProcess(uint8_t dataLen, uint8_t *data) { uint8_t ret = 0; uint8_t i = 0; uint8_t count = 0; uint8_t EventCodeTmp[7] = {0}; uint8_t StatusArray[MAX_REGISTER_NUM][WARNING_CODE_SIZE] = {0}; uint8_t remaindLen = 0; //uint8_t statusCodeError = 0; if (dataLen > 0) { //Hexdump((uint8_t *)data, dataLen); remaindLen = dataLen % WARNING_CODE_SIZE; if (remaindLen != 0) { log_info("fail status code length = %d", dataLen); dataLen -= remaindLen; } if (dataLen < WARNING_CODE_SIZE) { log_error("fail status code length = %d", dataLen); //Hexdump(data, dataLen); if (pSysWarning->WarningCount > 0) { for (i = 0; i < pSysWarning->WarningCount; i++) { usleep(128); if (pSysWarning->WarningCode[i][1] >= '3' || //from backend or power cabinet (pSysWarning->WarningCode[i][0] >= 'B' && pSysWarning->WarningCode[i][1] >= '4')) { memset(EventCodeTmp, 0, sizeof(EventCodeTmp)); memcpy(EventCodeTmp, pSysWarning->WarningCode[i], sizeof(EventCodeTmp)); removeFaultCodeToBuf(EventCodeTmp); } } } return FAIL; } for (count = 0; count < dataLen; count += WARNING_CODE_SIZE) { usleep(128); if (strncmp((char *)&data[count + 1], "1", 1) != 0 && strncmp((char *)&data[count + 1], "2", 1) != 0 && strncmp((char *)&data[count + 1], "3", 1) != 0 && (strncmp((char *)&data[count], "B", 1) != 0 && strncmp((char *)&data[count + 1], "4", 1) != 0) ) { log_error("error status code = %s", (char *)&data[count]); continue; } // misc command status code handle if (strncmp((char *)&data[count], MISC_ST_MISC_CMD, WARNING_CODE_SIZE) == 0) { gDoCommGblData.MiscCmd = REG_MISC_CONTROL; memset((char *)&data[count], 0, WARNING_CODE_SIZE); continue; } else if (strncmp((char *)&data[count], MISC_ST_VERSION, WARNING_CODE_SIZE) == 0) { gDoCommGblData.MiscCmd = REG_REPORT_CSU_VERSION; memset((char *)&data[count], 0, WARNING_CODE_SIZE); continue; } if (CompareArrayIsZero((uint8_t *)&data[count], WARNING_CODE_SIZE) == true) { memset(EventCodeTmp, 0, sizeof(EventCodeTmp)); memcpy(EventCodeTmp, (char *)&data[count], sizeof(EventCodeTmp)); log_error("error status = %s", EventCodeTmp); continue; } strncpy((char *)&StatusArray[count / WARNING_CODE_SIZE], (char *)&data[count], WARNING_CODE_SIZE); ret = 0; for (i = 0; i < pSysWarning->WarningCount; i++) { usleep(128); if (memcmp(&pSysWarning->WarningCode[i][0], StatusArray[count / WARNING_CODE_SIZE], WARNING_CODE_SIZE) == 0) { ret = 1; break; } } if (ret == 0) { addFaultCodeToBuf(StatusArray[count / WARNING_CODE_SIZE]); } //Rtn=StatusCodeProcessing(StatusArray[count/6]); } } else { if (CompareArrayIsZero(data, WARNING_CODE_SIZE) == false) { log_error("power cabinet status code data length is zero, but have data"); //Hexdump((uint8_t *)data, WARNING_CODE_SIZE); } } for (i = 0; i < pSysWarning->WarningCount; i++) { usleep(128); if (pSysWarning->WarningCode[i][1] >= '3' || //from backend or power cabinet 0x33 (pSysWarning->WarningCode[i][0] >= 'B' && pSysWarning->WarningCode[i][1] >= '4')) { ret = 0; for (count = 0; count < (dataLen / WARNING_CODE_SIZE); count++) { usleep(128); if (memcmp(&pSysWarning->WarningCode[i][0], StatusArray[count], WARNING_CODE_SIZE) == 0) { ret = 1; break; } } if (ret == 0) { memset(EventCodeTmp, 0, sizeof(EventCodeTmp)); memcpy(EventCodeTmp, pSysWarning->WarningCode[i], sizeof(EventCodeTmp)); removeFaultCodeToBuf(EventCodeTmp); } } } return PASS; } static int responsePackeHandle(int fd, uint8_t *pResult, uint8_t plugNum, uint8_t reg) { int ret = PASS; uint8_t rawDataLen = 0; CsuResultPkt *pCsuResult = (CsuResultPkt *)pResult; SoftwareUpdInfo *pSoftwareUpd = NULL; PcPsuOutput *pPcPsuOutput = NULL; //Hexdump((uint8_t *)pCsuResult, sizeof(CmdHead) + pCsuResult->Head.DataLen); if (compareOpcode(pCsuResult->Head.OP) == FAIL || compareResult(pCsuResult->Data.Result) == FAIL || compareRegister(pCsuResult->Data.Register, reg) == FAIL) { if (reg != REG_CHARGING_PERMISSION) { return FAIL; } } rawDataLen = (pCsuResult->Head.DataLen - 2); //2 byte = register and result byte switch (pCsuResult->Data.Register) { case REG_MODEL_NAME: break; case REG_CONNECTOR_ID: gDoCommGblData.ConnectorID[0] = pCsuResult->Data.Data[0]; gDoCommGblData.ConnectorID[1] = pCsuResult->Data.Data[1]; log_info("OK (Left connector ID = %d, Right connector ID = %d)", pCsuResult->Data.Data[0], pCsuResult->Data.Data[1]); ShmDcCommonData->pGunInfo[0].ConnectorID = pCsuResult->Data.Data[0]; ShmDcCommonData->pGunInfo[1].ConnectorID = pCsuResult->Data.Data[1]; break; case REG_POWER_CABINET_STATUS: ret = powerCabinetStatusProcess(rawDataLen, pCsuResult->Data.Data); break; case REG_DISPENSER_STATUS: memset(&gPreSysWarningInfo, 0, sizeof(struct WARNING_CODE_INFO)); memcpy((uint8_t *)&gPreSysWarningInfo, pSysWarning, sizeof(struct WARNING_CODE_INFO)); break; case REG_CHARGING_CAP: chargingcapabilityHandle(pCsuResult->Data.Data, plugNum); break; case REG_CHARGING_TARGET: break; case REG_SOFTWARE_UPDATE: pSoftwareUpd = (SoftwareUpdInfo *)&pCsuResult->Data.Data[0]; if ((strcmp((char *)pSoftwareUpd->ImgName, "") == 0) || (rawDataLen == 0) || pSoftwareUpd->UpdateState != 1) { ret = FAIL; break; } ret = FAIL; ret = updateFirmwareHandle(pSoftwareUpd->ImgName); break; case REG_PLUG_IN_STATE: break; case REG_CONNECTOR_STATE: break; case REG_USER_ID: //log_info("USER ID:%s", pCsuResult->Data.Data[0] == 1 ? "Accept" : "Reject" ); //if (pCsuResult->Data.Data[0] <= 0) { // return FAIL; //} if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } ShmSelectGunInfo->AuthorStateFromCabinet[plugNum] = pCsuResult->Data.Data[0]; return pCsuResult->Data.Data[0]; break; case REG_CHARGING_PERMISSION: //log_info("id = %d, result = %s, action = %s", // pCsuResult->Head.ID, // pCsuResult->Data.Result == 1 ? "OK" : "NG", // pCsuResult->Data.Data[0] == 1 ? "Permitted" : "NOT permitted"); if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } ShmSelectGunInfo->WaitDoCommPermission[plugNum] = pCsuResult->Data.Data[0]; return pCsuResult->Data.Data[0]; break; case REG_MISC_CONTROL: miscCommandHandle(rawDataLen, plugNum, pCsuResult->Data.Data); break; case REG_REPORT_CSU_VERSION: case REG_REPORT_OTHER_VERSION: break; case REG_PRESENT_CHARGING_INFO: pPcPsuOutput = (PcPsuOutput *)&pCsuResult->Data.Data[0]; ShmDcCommonData->PcPsuOutput[plugNum].Voltage = ntohs((uint16_t)pPcPsuOutput->Voltage); ShmDcCommonData->PcPsuOutput[plugNum].Current = ntohs((uint16_t)pPcPsuOutput->Current); //log_info("%d power cabinet PSU output vol = %f, cur = %f", // plugNum, // (float)ShmDcCommonData->PcPsuOutput[plugNum].Voltage, // (float)ShmDcCommonData->PcPsuOutput[plugNum].Current); break; case REG_QRCODE_URL_INFO: ret = qrCodeUrlInfoHandle(pCsuResult->Data.Data); break; case REG_WAIT_PLUG_IT_STATE: break; case REG_Ground_Fault_Detection: if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } //集電弓relay 不打開才能進入動作 pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum); if(pDcChargingInfo->PantographFlag == YES) { GroundFaultDetection *gfd = (GroundFaultDetection *)&pCsuResult->Data.Data[0]; if(pDcChargingInfo->GroundFaultStatus != gfd->Status) { log_info("id = %d, GFD Result = %d", pCsuResult->Head.ID, gfd->Status); } pDcChargingInfo->GroundFaultStatus = gfd->Status; } break; case REG_RESERVATION_IDTAG: if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } uint8_t reservationState = pCsuResult->Data.Data[0] == YES ? YES : NO; memset(&ReservationIdTag[plugNum][0], 0x00, 32); if(reservationState) { strcpy(&ReservationIdTag[plugNum][0], (char *)&pCsuResult->Data.Data[1]); } if(reservationState != ReservationState[plugNum] || (strcmp((char*)ShmDcCommonData->pGunInfo[plugNum].ReservationID, (char*)ReservationIdTag[plugNum]) != EQUAL) ) { log_info("id = %d reservation is %s", pCsuResult->Head.ID, reservationState ? "trigger" : "expired"); if(reservationState) { log_info("id = %d reservation idTag: %s", pCsuResult->Head.ID, (char *)&ReservationIdTag[plugNum][0]); pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(plugNum); strcpy(&ShmDcCommonData->pGunInfo[plugNum].ReservationID[0], (char*)&pCsuResult->Data.Data[1]); pDcChargingInfo->SystemStatus = S_RESERVATION; } else { if (pDcChargingInfo->SystemStatus == S_RESERVATION && pSysInfo->WaitForPlugit == NO) pDcChargingInfo->SystemStatus = S_IDLE; } } ReservationState[plugNum] = reservationState; ShmDcCommonData->pGunInfo[plugNum].ReservationStatus = reservationState; break; case REG_REMOTE_START_NO_ID: if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } uint8_t remoteStartNoIdState = pCsuResult->Data.Data[0] == YES ? YES : NO; if(remoteStartNoIdState != RemoteStartNoIDState) { log_info("RemoteStartNoID is %s", remoteStartNoIdState ? "trigger" : "expired"); } RemoteStartNoIDState = remoteStartNoIdState; break; case REG_STATION_INFO: if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } StationVar _stationInfo; memset((char *)&_stationInfo, 0x00, sizeof(StationVar)); _stationInfo.StationID = (pCsuResult->Data.Data[0] << 24) + (pCsuResult->Data.Data[1] << 16) + (pCsuResult->Data.Data[2] << 8) + pCsuResult->Data.Data[3]; memcpy(_stationInfo.StationName, (char *)&pCsuResult->Data.Data[4], 64); _stationInfo.WeatherID |= (pCsuResult->Data.Data[68] << 24); _stationInfo.WeatherID |= (pCsuResult->Data.Data[69] << 16); _stationInfo.WeatherID |= (pCsuResult->Data.Data[70] << 8); _stationInfo.WeatherID |= pCsuResult->Data.Data[71]; uint8_t *pFloat = (uint8_t *)&_stationInfo.Temperature; *(pFloat + 3) = pCsuResult->Data.Data[72]; *(pFloat + 2) = pCsuResult->Data.Data[73]; *(pFloat + 1) = pCsuResult->Data.Data[74]; *(pFloat) = pCsuResult->Data.Data[75]; ShmDcCommonData->WeatherID = _stationInfo.WeatherID; ShmDcCommonData->Temperature = _stationInfo.Temperature; ShmDcCommonData->Location = atoi(_stationInfo.StationName); log_info("Station Name: %s, ID: %d, Weather: %d, Temperature: %.1f", _stationInfo.StationName, _stationInfo.StationID, _stationInfo.WeatherID, _stationInfo.Temperature); break; case REG_DEDUCT_INFO: if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } break; case REG_READ_CABINET_SYSTEMID: if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } if (strcmp((char*)pSysConfig->SystemId, (char*)pCsuResult->Data.Data) != 0) { strcpy((char*)pSysConfig->SystemId, (char*)pCsuResult->Data.Data); log_info("System ID:%s", pSysConfig->SystemId); } break; case REG_READ_DEFAULT_PRICE: if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } gMoreInfoReq[plugNum].bits.DefaultPriceReq = NO; if (strcmp((char*)ShmDcCommonData->DefaultPriceString, (char*)pCsuResult->Data.Data) != EQUAL) { strcpy((char*)ShmDcCommonData->DefaultPriceString, (char*)pCsuResult->Data.Data); log_info("Default Price:%s", ShmDcCommonData->DefaultPriceString); } break; case REG_READ_USER_PRICE: if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } gMoreInfoReq[plugNum].bits.UserPriceReq = NO; if (strcmp((char*)ShmDcCommonData->pGunInfo[plugNum].UserPriceString, (char*)pCsuResult->Data.Data) != EQUAL) { strcpy((char*)ShmDcCommonData->pGunInfo[plugNum].UserPriceString, (char*)pCsuResult->Data.Data); log_info("User Price:%s", ShmDcCommonData->pGunInfo[plugNum].UserPriceString); } break; case REG_RECEIPT_INFO: if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } gMoreInfoReq[plugNum].bits.ReceiptReq = NO; if (strcmp((char*)ShmDcCommonData->pGunInfo[plugNum].ReceiptInfo, (char*)pCsuResult->Data.Data) != EQUAL) { strcpy((char*)ShmDcCommonData->pGunInfo[plugNum].ReceiptInfo, (char*)pCsuResult->Data.Data); log_info("Gun%d Receipt:%s", plugNum, ShmDcCommonData->pGunInfo[plugNum].ReceiptInfo); } break; case REG_READ_CHARGING_TIMESTAMP: if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } if (rawDataLen <= 2) { log_info("No Charging timestamp"); break; } strcpy((char*)ShmDcCommonData->pGunInfo[plugNum].ChargeStartTime, (char*)&pCsuResult->Data.Data[0]); int timelen = strlen((char*)ShmDcCommonData->pGunInfo[plugNum].ChargeStartTime); if (timelen != 0) { timelen = strcpy((char*)ShmDcCommonData->pGunInfo[plugNum].ChargeStopTime, (char*)&pCsuResult->Data.Data[timelen+1]); } break; case REG_POWER_CONSUMPTION_INFO: if (pCsuResult->Data.Result == COMMAND_RESULT_NG) { return COMMAND_RESULT_NG; } PowConsumValue* pValue =NULL; pValue = (PowConsumValue*)&pCsuResult->Data.Data[0]; pValue->Gun1_Consumption = ntohl(pValue->Gun1_Consumption); pValue->Gun2_Consumption = ntohl(pValue->Gun2_Consumption); pValue->Gun3_Consumption = ntohl(pValue->Gun3_Consumption); pValue->Gun4_Consumption = ntohl(pValue->Gun4_Consumption); memcpy((char*)&ShmDcCommonData->pConsumption.Gun1_Consumption, (char*)&pValue->Gun1_Consumption, sizeof(uint32_t)); memcpy((char*)&ShmDcCommonData->pConsumption.Gun2_Consumption, (char*)&pValue->Gun2_Consumption, sizeof(uint32_t)); memcpy((char*)&ShmDcCommonData->pConsumption.Gun3_Consumption, (char*)&pValue->Gun3_Consumption, sizeof(uint32_t)); memcpy((char*)&ShmDcCommonData->pConsumption.Gun4_Consumption, (char*)&pValue->Gun4_Consumption, sizeof(uint32_t)); /* log_info("Gun1_Consumption:%f", ShmDcCommonData->pConsumption.Gun1_Consumption); log_info("Gun2_Consumption:%f", ShmDcCommonData->pConsumption.Gun2_Consumption); log_info("Gun3_Consumption:%f", ShmDcCommonData->pConsumption.Gun3_Consumption); log_info("Gun4_Consumption:%f", ShmDcCommonData->pConsumption.Gun4_Consumption); */ break; default: break; } return ret; } static int composeSocketData(int fd, uint8_t id, uint8_t opCode, uint8_t reg, uint8_t dataLen, uint8_t *data) { int ret = PASS; int size = 0; int sendPktLen = 0; uint8_t i = 0; uint8_t plugNum = 0; CsuCmdPkt csuCmdPkt = {0}; CsuResultPkt csuResult = {0}; csuCmdPkt.Head.SeqNum = gDoCommGblData.SeqNum++; csuCmdPkt.Head.ID = id; csuCmdPkt.Head.OP = opCode; csuCmdPkt.Head.DataLen = dataLen + 1; //+1 for register byte csuCmdPkt.Data.Register = reg; if ((data != NULL) && (dataLen > 0)) { memcpy(csuCmdPkt.Data.Data, data, dataLen); } sendPktLen = csuCmdPkt.Head.DataLen + sizeof(csuCmdPkt.Head); //Hexdump((uint8_t *)&csuCmdPkt, sendPktLen); //send command packet if ((size = sendTcpSocket(fd, (uint8_t *)&csuCmdPkt, sendPktLen)) < 0) { log_error("TCP socket send packet fail = %d", size); gDoCommGblData.DisConnCount++; return FAIL; } //receive result head if ((size = recvTcpSocket(fd, (uint8_t *)&csuResult.Head, sizeof(csuResult.Head), 1)) < 0) { log_error("TCP socket RX head fail = %d", size); gDoCommGblData.DisConnCount++; return FAIL; } //receive result raw data if ((size = recvTcpSocket(fd, (uint8_t *)&csuResult.Data, csuResult.Head.DataLen, 0)) < 0) { log_error("TCP socket RX data fail = %d", size); gDoCommGblData.DisConnCount++; return FAIL; } for (i = 0; i < sizeof(gDoCommGblData.ConnectorID); i++) { if (id == gDoCommGblData.ConnectorID[i]) { plugNum = i; break; } } ret = responsePackeHandle(fd, (uint8_t *)&csuResult, plugNum, csuCmdPkt.Data.Register); gDoCommGblData.DisConnCount = 0; //送收資料沒有問題, 清除中斷網路計數 return ret; } static int writeDispenserRequest(int fd, uint8_t id, uint8_t gunIndex) { int ret = PASS; int count = 0; MiscCommand dispenserReq; uint8_t data[6] = { 0 }; if (gConnectorActReq[gunIndex].bits.ChargingCancel) { dispenserReq.CMD = DISPENSER_REQ_CHARGING_CANCEL; dispenserReq.Value[0] = 0; dispenserReq.Value[1] = 0; dispenserReq.Value[2] = 0; dispenserReq.Value[3] = 1; AddDispenserReq(data, &dispenserReq); count++; //log_info("Write Gun %d CHARGING_CANCEL", gunIndex); } if ((ret = composeSocketData(fd, id, OP_WRITE_DATA, REG_DISPENSER_REQUEST, (count * 6), &data[0])) == FAIL) { return ret; } return ret; } static int readReservationState(int fd, uint8_t id) { int ret = PASS; if ((ret = composeSocketData(fd, id, OP_READ_DATA, REG_RESERVATION_IDTAG, 0, NULL)) == FAIL) { return ret; } return ret; } static int readRemoteStartNoIDState(int fd) { int ret = PASS; if ((ret = composeSocketData(fd, ID_REGISTER, OP_READ_DATA, REG_REMOTE_START_NO_ID, 0, NULL)) == FAIL) { return ret; } return ret; } static int readChargerStationInfo(int fd) { int ret = PASS; if ((ret = composeSocketData(fd, ID_REGISTER, OP_READ_DATA, REG_STATION_INFO, 0, NULL)) == FAIL) { return ret; } return ret; } /* static int writeDeductInfo(int fd, uint8_t id,uint8_t gunIndex, RecordTransactionInfo *transactionInfo) { int ret = PASS; uint8_t dataBuf[104] = {0}; //int i; memset((char *)dataBuf, 0x00, sizeof(dataBuf)); dataBuf[0] = transactionInfo->DeductResult; dataBuf[1] = transactionInfo->IsDonateInvoice; dataBuf[2] = (transactionInfo->TransactionId >> 24) & 0xFF; dataBuf[3] = (transactionInfo->TransactionId >> 16) & 0xFF; dataBuf[4] = (transactionInfo->TransactionId >> 8) & 0xFF; dataBuf[5] = (transactionInfo->TransactionId & 0xFF); int amount = (int)(transactionInfo->Amount * 100); dataBuf[6] = (amount >> 24) & 0xFF; dataBuf[7] = (amount >> 16) & 0xFF; dataBuf[8] = (amount >> 8) & 0xFF; dataBuf[9] = (amount & 0xFF); memcpy((char *)&dataBuf[10], transactionInfo->pCreditCard.ApprovalNo,9); memcpy((char *)&dataBuf[19], transactionInfo->pCreditCard.VemData, 64); memcpy((char*)&dataBuf[83], transactionInfo->pCreditCard.CardNo, 20); log_info("Gun[%d] TransactionId:%d DeductResult:%d IsDonateInvoice:%d Amount:%f Approva Num:'%s' VemData:'%s' CardNo:'%s'", transactionInfo->ConnectorID, transactionInfo->TransactionId, transactionInfo->DeductResult, transactionInfo->IsDonateInvoice, transactionInfo->Amount, transactionInfo->pCreditCard.ApprovalNo, transactionInfo->pCreditCard.VemData, transactionInfo->pCreditCard.CardNo); // copy deduct result to dataBuf here if ((ret = composeSocketData(fd, id, OP_WRITE_DATA, REG_DEDUCT_INFO, 104, &dataBuf[0])) == FAIL) { return ret; } return ret; } */ static int readChargingTimeStamp(int fd, uint8_t id) { int ret = PASS; if ((ret = composeSocketData(fd, id, OP_READ_DATA, REG_READ_CHARGING_TIMESTAMP, 0, NULL)) == FAIL) { return ret; } return ret; } static int writeWaitPlugItState(int fd, uint8_t id, uint8_t gunIndex) { int ret = PASS; uint8_t data[2] = { ShmDcCommonData->pGunInfo[gunIndex].WaitForPlugit, 0 }; if (_isplugin != ShmDcCommonData->pGunInfo[gunIndex].WaitForPlugit) { //log_info("Wait Gun%d for plug:%s", gunIndex, ShmDcCommonData->pGunInfo[gunIndex].WaitForPlugit == 0 ? "disable" : "enable"); _isplugin = ShmDcCommonData->pGunInfo[gunIndex].WaitForPlugit; } //printf("WaitForPlugit = %d", pSysInfo->WaitForPlugit); if ((ret = composeSocketData(fd, id, OP_WRITE_DATA, REG_WAIT_PLUG_IT_STATE, 1, &data[0])) == FAIL) { return ret; } return ret; } static int readQRcodeURLAndSystemDate(int fd) { int ret = PASS; ret = composeSocketData(fd, ID_REGISTER, OP_READ_DATA, REG_QRCODE_URL_INFO, 0, NULL); return ret; } static int writePresentChargingInfo(int fd, uint8_t plugNum, uint8_t id) { int ret = PASS; uint8_t dataBuf[16] = {0}; PreChargingInfo *pPreChargingInfo = (PreChargingInfo *)dataBuf; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum); if(pDcChargingInfo->PantographFlag == NO) { pPreChargingInfo->PresentChargingVoltage = htons((uint16_t)(pDcChargingInfo->PresentChargingVoltage * 10)); pPreChargingInfo->PresentChargingCurrent = htons((uint16_t)(pDcChargingInfo->PresentChargingCurrent * 10)); } else { pPreChargingInfo->PresentChargingVoltage = htons((uint16_t)(ShmDcCommonData->PcPsuOutput[plugNum].Voltage)); pPreChargingInfo->PresentChargingCurrent = htons((uint16_t)(ShmDcCommonData->PcPsuOutput[plugNum].Current)); } pPreChargingInfo->RemainChargingDuration = htonl(pDcChargingInfo->RemainChargingDuration); pPreChargingInfo->EvBatterySoc = pDcChargingInfo->EvBatterySoc; ret = composeSocketData(fd, id, OP_WRITE_DATA, REG_PRESENT_CHARGING_INFO, sizeof(PreChargingInfo), (uint8_t *)pPreChargingInfo); return ret; } static int writeOtherModuleVersion(int fd) { int ret = PASS; uint8_t data[255] = {0}; uint8_t dataLen = 0; //report other module version message memcpy(&data[dataLen], pSysInfo->FanModuleFwRev, VERSION_BUF_SIZE); dataLen += VERSION_BUF_SIZE; memcpy(&data[dataLen], pSysInfo->RelayModuleFwRev, VERSION_BUF_SIZE); dataLen += VERSION_BUF_SIZE; memcpy(&data[dataLen], pSysInfo->Connector1FwRev, VERSION_BUF_SIZE); dataLen += VERSION_BUF_SIZE; memcpy(&data[dataLen], pSysInfo->Connector2FwRev, VERSION_BUF_SIZE); dataLen += VERSION_BUF_SIZE; memcpy(&data[dataLen], pSysInfo->LedModuleFwRev, VERSION_BUF_SIZE); dataLen += VERSION_BUF_SIZE; ret = composeSocketData(fd, ID_REGISTER, OP_WRITE_DATA, REG_REPORT_OTHER_VERSION, dataLen, &data[0]); return ret; } static int writeCsuModuleVersion(int fd) { int ret = PASS; uint8_t data[255] = {0}; uint8_t dataLen = 0; //report CSU platform version message memcpy(&data[dataLen], pSysInfo->CsuBootLoadFwRev, VERSION_BUF_SIZE); dataLen += VERSION_BUF_SIZE; memcpy(&data[dataLen], pSysInfo->CsuKernelFwRev, VERSION_BUF_SIZE); dataLen += VERSION_BUF_SIZE; memcpy(&data[dataLen], pSysInfo->CsuRootFsFwRev, VERSION_BUF_SIZE); dataLen += VERSION_BUF_SIZE; memcpy(&data[dataLen], pSysInfo->CsuPrimFwRev, VERSION_BUF_SIZE); dataLen += VERSION_BUF_SIZE; ret = composeSocketData(fd, ID_REGISTER, OP_WRITE_DATA, REG_REPORT_CSU_VERSION, dataLen, &data[0]); return ret; } static int readMiscCommand(int fd, uint8_t id) { int ret = PASS; ret = composeSocketData(fd, id, OP_READ_DATA, REG_MISC_CONTROL, 0, NULL); return ret; } static int readChargePermission(int fd, uint8_t id) { return composeSocketData(fd, id, OP_READ_DATA, REG_CHARGING_PERMISSION, 0, NULL); } static int writeGroundFaultDetection(int fd, uint8_t status, uint8_t id) { int ret = PASS; uint8_t dataBuf[1] = {status}; ret = composeSocketData(fd, id, OP_WRITE_DATA, REG_Ground_Fault_Detection, 1, &dataBuf[0]); return ret; } static int writeUserID(int fd, uint8_t id, uint8_t *pUserID) { if ((strlen((char *)pUserID) <= 0) || (pUserID == NULL)) { return FAIL; } uint8_t data[50]; int datalen = strlen((char*)pUserID); memcpy((uint8_t*)data, pUserID, datalen); data[datalen] = '\0'; data[datalen+1] = ShmDcCommonData->AuthroizeType; datalen += 2; return composeSocketData(fd, id, OP_WRITE_DATA, REG_USER_ID, datalen, &data[0]); } static int writeConnectorState(int fd, uint8_t plugNum, uint8_t id) { uint8_t dataBuf[16] = {'\0'}; uint32_t _consumption; ConnectorState *pConnState = (ConnectorState *)dataBuf; static char vendorErrorCodeTmp[2][WARNING_CODE_SIZE] = {0}; int ret = PASS; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum); pConnState->ConnectorTemp = pDcChargingInfo->ConnectorTemp; pConnState->ChillerTemp = pDcChargingInfo->ChillerTemp; pConnState->PlugIn = pDcChargingInfo->ConnectorPlugIn; pConnState->ConnectMode = pDcChargingInfo->SystemStatus; if (pDcChargingInfo->SystemStatus <= S_AUTHORIZING) { pConnState->State = CONN_ST_IDLE; //idle strncpy((char *)ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode, "", sizeof(ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode)); strncpy(&vendorErrorCodeTmp[plugNum][0], "", WARNING_CODE_SIZE); } else if ((pDcChargingInfo->SystemStatus <= S_PREPARING_FOR_EVSE) || (pDcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST0) || (pDcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST1)) { pConnState->State = CONN_ST_PREPARING; //preparing } else if (pDcChargingInfo->SystemStatus == S_CHARGING) { pConnState->State = CONN_ST_CHARGING; //charging } else if (pDcChargingInfo->SystemStatus == S_TERMINATING || pDcChargingInfo->SystemStatus == S_COMPLETE) { if (pSysConfig->ModelName[3] == 'P') { if (!ShmDcCommonData->pGunInfo[plugNum].isMeterStop) { return FAIL; } } else { if (pDcChargingInfo->RelayK1K2Status == YES) { return FAIL; } } pConnState->State = CONN_ST_TERMINATING; //terminating } else if ((pDcChargingInfo->SystemStatus == S_ALARM) || (pDcChargingInfo->SystemStatus == S_FAULT)) { if (pSysConfig->ModelName[3] == 'P') { if (!ShmDcCommonData->pGunInfo[plugNum].isMeterStop && pDcChargingInfo->SystemStatus == S_ALARM) { return FAIL; } } else { if (pDcChargingInfo->RelayK1K2Status == YES && pDcChargingInfo->SystemStatus == S_ALARM) { return FAIL; } } pConnState->State = CONN_ST_ALARM; strncpy((char *)pConnState->WarningCode, (char *)ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode, WARNING_CODE_SIZE); if (strncmp(&vendorErrorCodeTmp[plugNum][0], "", WARNING_CODE_SIZE) == 0) { strncpy(&vendorErrorCodeTmp[plugNum][0], (char *)ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode, WARNING_CODE_SIZE); vendorErrorCodeTmp[plugNum][6] = '\0'; /* log_info("1 ID = %d, VendorErrorCode = %s", plugNum, (char *)ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode); */ } else { if (strncmp(&vendorErrorCodeTmp[plugNum][0], (char *)ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode, WARNING_CODE_SIZE) != 0 ) { strncpy(&vendorErrorCodeTmp[plugNum][0], (char *)ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode, WARNING_CODE_SIZE); vendorErrorCodeTmp[plugNum][6] = '\0'; /* log_info("2 ID = %d, VendorErrorCode = %s", plugNum, (char *)ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode); */ } } } if (gunstatus[plugNum] != pConnState->State) { log_info("Gun%d Status[%d] to OCPP Backend",plugNum,pConnState->State); gunstatus[plugNum] = pConnState->State; } #ifdef DD360 memcpy((char*)&_consumption, (char*)&ShmDcCommonData->pGunInfo[plugNum].PowerConsumption, sizeof(float)); pConnState->consumption = ntohl(_consumption); #endif ret = composeSocketData(fd, id, OP_WRITE_DATA, REG_CONNECTOR_STATE, sizeof(dataBuf) - 1, &dataBuf[0]); return ret; } /** * * @param data * @param length * @return */ uint32_t crc32(uint8_t *data, uint32_t length) { uint32_t crc=0xFFFFFFFF; for(size_t i=0;i>=1; if(b) crc=crc^0xEDB88320; ch>>=1; } } return ~crc; } /** * * @param filename * @return */ uint32_t getFileCrc32(char *filename) { uint32_t result = 0; int fd = open(filename, O_RDONLY); if(fd < 0) { log_error("Can not open file %s\n", filename); } else { struct stat st; stat(filename, &st); uint8_t *data; data = malloc(st.st_size); if(read(fd,data,st.st_size) == st.st_size) { result = crc32(data, st.st_size); close(fd); } else { log_error("Read file Error %d\n", st.st_size); } free(data); } return result; } static int wrtieOcmpInfo(int fd, uint8_t plugNum, uint8_t id) { int ret = PASS; uint8_t dataBuf[241]; OcmfInfoData* pOcmf = (OcmfInfoData*)dataBuf; pOcmf->CRC = htonl(getFileCrc32(ShmDcCommonData->pGunInfo[plugNum].OcmfFileName)); if (pOcmf->CRC == 0) { log_info("CRC is Zero! Not transmit to Cabinet"); return FAIL; } //memcpy((char*)pOcmf->TxId,pSysInfo->DcMeterReadTransactionRecord[plugNum].head.transactionId,sizeof(pSysInfo->DcMeterReadTransactionRecord[plugNum].head.transactionId)); sprintf((char*)pOcmf->TxId,"%d",ShmDcCommonData->ocmfTridRecord[plugNum]); memcpy((char*)pOcmf->OcmfPublicKey, (char*)pSysInfo->DcMeterStatusInfo[plugNum].publicKeyOcmf,sizeof(pSysInfo->DcMeterStatusInfo[plugNum].publicKeyOcmf)); log_info("txid:[%s], crc:[%X], publicKey:[%s]",pOcmf->TxId,htonl(pOcmf->CRC),pSysInfo->DcMeterStatusInfo[plugNum].publicKeyOcmf); ret = composeSocketData(fd, id, OP_WRITE_DATA, REG_OCMF_INFO, sizeof(dataBuf) - 1, &dataBuf[0]); return ret; } static int writePlugInStatus(int fd, uint8_t plugNum, uint8_t id) { int ret = PASS; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum); uint8_t dataBuf[2] = {pDcChargingInfo->ConnectorPlugIn, 0}; ret = composeSocketData(fd, id, OP_WRITE_DATA, REG_PLUG_IN_STATE, 1, &dataBuf[0]); return ret; } static int readSoftwareUpdate(int fd, uint8_t gunID) { int ret = PASS; uint8_t dataBuf[2] = {pSysInfo->FirmwareUpdate, 0}; ret = composeSocketData(fd, gunID, OP_READ_DATA, REG_SOFTWARE_UPDATE, 1, &dataBuf[0]); return ret; } static int writeChargingTarget(int fd, uint8_t plugNum, uint8_t id) { int ret = PASS; float ChargingVolt, ChargingAmp; uint8_t dataBuf[4] = {0}; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum); if ((pDcChargingInfo->SystemStatus <= S_PREPARING_FOR_EV || pDcChargingInfo->SystemStatus >= S_TERMINATING) && pDcChargingInfo->SystemStatus != S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus != S_CCS_PRECHARGE_ST1) { pDcChargingInfo->EvBatterytargetVoltage = 0; pDcChargingInfo->EvBatterytargetCurrent = 0; } ChargingVolt = pDcChargingInfo->EvBatterytargetVoltage; ChargingAmp = pDcChargingInfo->EvBatterytargetCurrent; ChargingVolt *= 10; ChargingAmp *= 10; dataBuf[0] = ((uint16_t)ChargingVolt >> 8) & 0xFF; dataBuf[1] = ((uint16_t)ChargingVolt) & 0xFF; dataBuf[2] = ((uint16_t)ChargingAmp >> 8) & 0xFF; dataBuf[3] = ((uint16_t)ChargingAmp) & 0xFF; ret = composeSocketData(fd, id, OP_WRITE_DATA, REG_CHARGING_TARGET, sizeof(dataBuf), &dataBuf[0]); return ret; } static int readChargingCapability(int fd, uint8_t id) { int ret = PASS; ret = composeSocketData(fd, id, OP_READ_DATA, REG_CHARGING_CAP, 0, NULL); return ret; } static int readReceiptInfo(int fd, uint8_t id) { int ret = PASS; ret = composeSocketData(fd, id, OP_READ_DATA, REG_RECEIPT_INFO, 0, NULL); return ret; } static int writeDispenserStatus(int fd, uint8_t gunID) { uint8_t warningCount = 0; uint8_t count = 0; uint8_t CurWarnCodeTmp[10][6] = {0}; uint8_t PreWarnCodeTmp[10][6] = {0}; int ret = PASS; if ((pSysWarning->WarningCount <= 0) && (gPreSysWarningInfo.WarningCount <= 0)) { return FAIL; } warningCount = pSysWarning->WarningCount; for (count = 0; count < warningCount; count++) { memcpy(CurWarnCodeTmp[count], pSysWarning->WarningCode[count], WARNING_CODE_SIZE); } warningCount = gPreSysWarningInfo.WarningCount; for (count = 0; count < warningCount; count++) { memcpy(PreWarnCodeTmp[count], gPreSysWarningInfo.WarningCode[count], WARNING_CODE_SIZE); } if (strcmp((char *)&CurWarnCodeTmp[0], (char *)&PreWarnCodeTmp[0]) == 0) { return FAIL; } ret = composeSocketData(fd, gunID, OP_WRITE_DATA, REG_DISPENSER_STATUS, strlen((char *)CurWarnCodeTmp), &CurWarnCodeTmp[0][0]); return ret; } static int readPowerCabinetStatus(int fd, uint8_t gunID) { int ret = PASS; ret = composeSocketData(fd, gunID, OP_READ_DATA, REG_POWER_CABINET_STATUS, 0, NULL); return ret; } static int readConnectorID(int fd) { int ret = PASS; ret = composeSocketData(fd, ID_REGISTER, OP_READ_DATA, REG_CONNECTOR_ID, 0, NULL); return ret; } static int readSystemID(int fd) { int ret = PASS; ret = composeSocketData(fd, ID_REGISTER, OP_READ_DATA, REG_READ_CABINET_SYSTEMID, 0, NULL); return ret; } static int readDefaultPrice(int fd) { int ret = PASS; ret = composeSocketData(fd, ID_REGISTER, OP_READ_DATA, REG_READ_DEFAULT_PRICE, 0, NULL); return ret; } static int readUserPrice(int fd, uint8_t gunID) { int ret = PASS; ret = composeSocketData(fd, gunID, OP_READ_DATA, REG_READ_USER_PRICE, 0, NULL); return ret; } static int readConsumptionInfo(int fd) { int ret = PASS; ret = composeSocketData(fd, ID_REGISTER, OP_READ_DATA, REG_POWER_CONSUMPTION_INFO, 0, NULL); return ret; } static int WriteModelName(int fd) { int ret = PASS; uint8_t Tmp = 0; uint8_t TmpBuf[255] = {0}; memcpy(TmpBuf, pSysConfig->ModelName, strlen((char *)pSysConfig->ModelName)); Tmp = (uint8_t)(ShmPrimaryMcuData->InputDet.bits.Key2 << 2 | ShmPrimaryMcuData->InputDet.bits.Key1 << 1 | ShmPrimaryMcuData->InputDet.bits.Key0); TmpBuf[strlen((char *)pSysConfig->ModelName)] = Tmp; //Dispenser switch value ret = composeSocketData(fd, ID_REGISTER, OP_WRITE_DATA, REG_MODEL_NAME, strlen((char *)pSysConfig->ModelName) + 1, &TmpBuf[0]); return ret; } static void calDisconnectCount(uint8_t *pValue, uint8_t maxCount) { sleep(3); //wait 1 second if ((*pValue) >= maxCount) { setTcpStatus(ABNORMAL); } else { (*pValue)++; } } static int CheckNetworkStatus(void) { char *ipAddr = (char *)&pSysConfig->Eth0Interface.EthIpAddress; //printf("Check network IP Header = %s\n", ipAddr); if (strstr(ipAddr, CMP_ETH_IP_HEAD) != NULL) { return 1; } return 0; } static void updateFirmwareProcess(int fd, uint8_t gunID, uint8_t totalConnCount) { bool canUpdateFirmware = true; uint8_t plugNum = 0; uint8_t ackCount = 5; struct timeb updateTime; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum); if (pSysWarning->Level != 2) { for (plugNum = 0; plugNum < totalConnCount; plugNum++) { if (pDcChargingInfo->SystemStatus != S_IDLE && pDcChargingInfo->SystemStatus != S_RESERVATION && pDcChargingInfo->SystemStatus != S_MAINTAIN) { canUpdateFirmware = false; } } } if (canUpdateFirmware) { ftime(&updateTime); if (DiffTimeb(gRegTimeUp[0][REG_SOFTWARE_UPDATE], updateTime) > LOOP_RETRY_TIME * 5) { readSoftwareUpdate(fd, gunID); ftime(&gRegTimeUp[0][REG_SOFTWARE_UPDATE]); } if (pSysInfo->FirmwareUpdate == YES) { while (ackCount != 0) { ftime(&updateTime); if (DiffTimeb(gRegTimeUp[0][REG_SOFTWARE_UPDATE], updateTime) > LOOP_RETRY_TIME / 2) { readSoftwareUpdate(fd, gunID); ftime(&gRegTimeUp[0][REG_SOFTWARE_UPDATE]); if (pSysInfo->FirmwareUpdate == NO) { ackCount--; } } usleep(128); } } } } static void checkAuthorProcess(int fd, uint8_t plugNum) { int ret = 0; uint8_t gunID = 0; struct timeb AuthNowTime; #if defined DD360Audi gunID = gDoCommGblData.ConnectorID[pSysInfo->CurGunSelected]; //gunID = gDoCommGblData.ConnectorID[plugNum]; if (pSysConfig->AuthorisationMode) { gunID = ID_REGISTER; ShmSelectGunInfo->PricesInfo[pSysInfo->CurGunSelected].Balance = 0.0; } #else gunID = ID_REGISTER; ShmSelectGunInfo->PricesInfo[pSysInfo->CurGunSelected].Balance = 0.0; //非Audi 不需要等待主櫃回報餘額 #endif // DD360Audi if ((ShmOCPP16Data->SpMsg.bits.AuthorizeReq == YES) || (pSysInfo->AuthorizeFlag == YES)) { ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_USER_ID], AuthNowTime) > LOOP_RETRY_TIME) { ret = writeUserID(fd, gunID, pSysConfig->UserId); if (ret >= 0) { memset(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, 0, sizeof(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status)); if (ret == 0) { strcpy((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Invalid"); } else { strcpy((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted"); } //printf("%d Balance = %.2f, %.2f\n", // plugNum, // ShmSelectGunInfo->PricesInfo[plugNum].Balance, // FAIL_BALANCE_PRICES); if (ShmSelectGunInfo->PricesInfo[plugNum].Balance != FAIL_BALANCE_PRICES) { ShmOCPP16Data->SpMsg.bits.AuthorizeConf = YES; //isAuthorizedComplete ShmOCPP16Data->SpMsg.bits.AuthorizeReq = NO; pSysInfo->AuthorizeFlag = NO; ShmPsuData->SystemAvailablePower = NO; ShmPsuData->SystemPresentPsuQuantity = NO; } } ftime(&gRegTimeUp[plugNum][REG_USER_ID]); } } } static int messageTrigger(int fd, uint8_t plugNum, uint8_t gunID, uint8_t curReg) { int ret = DISPENSER_INIT_SUCC; int isContinue = 1; struct timeb NowTime; while (isContinue) { usleep(128); ftime(&NowTime); switch (curReg) { case REG_MODEL_NAME: if (WriteModelName(fd) == PASS) { gDoCommGblData.DisConnCount = 0; curReg = REG_CONNECTOR_ID; } else { sleep(1); } break; case REG_CONNECTOR_ID: if (readConnectorID(fd) == PASS) { gDoCommGblData.DisConnCount = 0; curReg = REG_REPORT_CSU_VERSION; } else { sleep(1); } break; case REG_POWER_CABINET_STATUS: if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { readPowerCabinetStatus(fd, gunID); ftime(&gRegTimeUp[plugNum][curReg]); } curReg = REG_DISPENSER_STATUS; break; case REG_DISPENSER_STATUS: if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { writeDispenserStatus(fd, gunID); ftime(&gRegTimeUp[plugNum][curReg]); } curReg = REG_CHARGING_CAP; break; case REG_CHARGING_CAP: if(gMoreInfoReq[plugNum].bits.FinalCostReq) { if (readChargingCapability(fd, gunID) == PASS && readChargingTimeStamp(fd, gunID) == PASS) { gMoreInfoReq[plugNum].bits.FinalCostReq = false; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum); //ShmDcCommonData->TransactionInfo[plugNum].Amount = pDcChargingInfo->ChargingFee; ShmDcCommonData->pGunInfo[plugNum].finalcost_flag = TRUE; log_info("Gun %d get final cost %f", plugNum, pDcChargingInfo->ChargingFee); } } curReg = REG_PLUG_IN_STATE; break; //case REG_CHARGING_TARGET: // writeChargingTarget(fd, plugNum, gunID); // break; //case REG_SOFTWARE_UPDATE: // if (ChargingData[plugNum]->SystemStatus == S_IDLE) { // if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > L OOP_RETRY_TIME|| //DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0 * 1) { // readSoftwareUpdate(fd); // ftime(&gRegTimeUp[plugNum][curReg]); // } // while (pSysInfo->FirmwareUpdate == YES) { // ftime(&NowTime); // if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowT ime) > LOOP_RETRY_TIME|| //DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { // readSoftwareUpdate(fd); // } // usleep(128); // } // } // isContinue = 0; // break; case REG_PLUG_IN_STATE: if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { writePlugInStatus(fd, plugNum, gunID); ftime(&gRegTimeUp[plugNum][curReg]); } curReg = REG_CONNECTOR_STATE; break; case REG_CONNECTOR_STATE: if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { writeConnectorState(fd, plugNum, gunID); ftime(&gRegTimeUp[plugNum][curReg]); } curReg = REG_OCMF_INFO; break; case REG_OCMF_INFO: if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { if (ShmDcCommonData->pGunInfo[plugNum].SendOcmfDataReq) { if (wrtieOcmpInfo(fd,plugNum,gunID) == PASS) { DB_Upload_ocmf(plugNum,ShmDcCommonData->ocmfTridRecord[plugNum]); ShmDcCommonData->pGunInfo[plugNum].SendOcmfDataReq = FALSE; char cmd[500]; sprintf(cmd,"rm -f %s",ShmDcCommonData->pGunInfo[plugNum].OcmfFileName); system(cmd); ShmDcCommonData->ocmfTridRecord[plugNum] = 0; } else { ShmDcCommonData->pGunInfo[plugNum].SendOcmfDataReq = FALSE; } } ftime(&gRegTimeUp[plugNum][curReg]); } curReg = REG_DISPENSER_REQUEST; break; case REG_DISPENSER_REQUEST: /* gConnectorActReq[plugNum].bits.ChargingCancel = ShmDcCommonData->OperateIDLE[plugNum]; if (gConnectorActReq[plugNum].Value != 0) { if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { if (writeDispenserRequest(fd, gunID, plugNum) == PASS) { gConnectorActReq[plugNum].Value = 0; log_info("Gun %d CHARGING_CANCEL OK", plugNum); ShmDcCommonData->OperateIDLE[plugNum] = 0; } ftime(&gRegTimeUp[plugNum][curReg]); } } */ curReg = REG_QRCODE_URL_INFO; break; case REG_QRCODE_URL_INFO: if (gunID == 1) { if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > (LOOP_RETRY_TIME * 10) || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0 ) { readQRcodeURLAndSystemDate(fd); ftime(&gRegTimeUp[plugNum][curReg]); } } #ifdef DD360Audi curReg = REG_POWER_CONSUMPTION_INFO; #else curReg = REG_READ_CABINET_SYSTEMID; #endif break; //case REG_USER_ID: // writeUserID(fd, gunID, uint8_t *pUserID); // break; //case REG_CHARGING_PERMISSION: // readChargePermission(fd, gunID); // break; case REG_MISC_CONTROL: readMiscCommand(fd, gunID); if(gMoreInfoReq[plugNum].Value == 0) { isContinue = 0; } else { curReg = REG_RESERVATION_IDTAG; } break; case REG_REPORT_CSU_VERSION: case REG_REPORT_OTHER_VERSION: if (gDoCommGblData.MiscCmd != 0) { writeCsuModuleVersion(fd); writeOtherModuleVersion(fd); clearMiscCommand(); isContinue = 0; } else { //power up write dispenser version and get power cabinet system ID if ((writeCsuModuleVersion(fd) == PASS) && (writeOtherModuleVersion(fd) == PASS) && (readQRcodeURLAndSystemDate(fd) == PASS) ) { //gDoCommGblData.DisConnCount = 0; isContinue = 0; } } break; case REG_READ_CABINET_SYSTEMID: if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > (LOOP_RETRY_TIME * 10) || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { readSystemID(fd); ftime(&gRegTimeUp[plugNum][curReg]); } curReg = REG_RESERVATION_IDTAG; /* //check misc command from power cabinet if (gDoCommGblData.MiscCmd != 0) { if (gDoCommGblData.MiscCmd != REG_MISC_CONTROL) { log_error("misc command failed = %x", gDoCommGblData.MiscCmd); } curReg = gDoCommGblData.MiscCmd; } else if (gMoreInfoReq[plugNum].Value != 0) { curReg = REG_RESERVATION_IDTAG; } else { isContinue = 0; } */ break; case REG_RESERVATION_IDTAG: if (gMoreInfoReq[plugNum].bits.ReservationReq) { if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { if (readReservationState(fd, gunID) == PASS) { gMoreInfoReq[plugNum].bits.ReservationReq = ReservationState[plugNum] == NO ? NO : YES; } ftime(&gRegTimeUp[plugNum][curReg]); } } curReg = REG_POWER_CONSUMPTION_INFO; break; case REG_POWER_CONSUMPTION_INFO: if (pSysConfig->ShowInformation || ShmDcCommonData->debugflag) { if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { readConsumptionInfo(fd); ftime(&gRegTimeUp[plugNum][curReg]); } } //check misc command from power cabinet if (gDoCommGblData.MiscCmd != 0) { if (gDoCommGblData.MiscCmd != REG_MISC_CONTROL) { log_error("misc command failed = %x", gDoCommGblData.MiscCmd); } curReg = gDoCommGblData.MiscCmd; } else if (gMoreInfoReq[plugNum].Value != 0) { curReg = REG_REMOTE_START_NO_ID; } else { isContinue = 0; } break; case REG_REMOTE_START_NO_ID: if (gMoreInfoReq[plugNum].bits.RemoteStartNoID) { if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { if (readRemoteStartNoIDState(fd) == PASS) { gMoreInfoReq[plugNum].bits.RemoteStartNoID = RemoteStartNoIDState == NO ? NO : YES; } ftime(&gRegTimeUp[plugNum][curReg]); } } curReg = REG_STATION_INFO; break; case REG_STATION_INFO: if (gMoreInfoReq[plugNum].bits.StationInfoReq) { if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { if (readChargerStationInfo(fd) == PASS) { gMoreInfoReq[plugNum].bits.StationInfoReq = NO; } ftime(&gRegTimeUp[plugNum][curReg]); } } //isContinue = 0; curReg = REG_READ_DEFAULT_PRICE; break; case REG_READ_DEFAULT_PRICE: if (gMoreInfoReq[plugNum].bits.DefaultPriceReq) { if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { readDefaultPrice(fd); ftime(&gRegTimeUp[plugNum][curReg]); } } curReg = REG_READ_USER_PRICE; break; case REG_READ_USER_PRICE: if (gMoreInfoReq[plugNum].bits.UserPriceReq) { if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { readUserPrice(fd,gunID); ftime(&gRegTimeUp[plugNum][curReg]); } } curReg = REG_RECEIPT_INFO; break; case REG_RECEIPT_INFO: if (gMoreInfoReq[plugNum].bits.ReceiptReq) { if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) { readReceiptInfo(fd, gunID); ftime(&gRegTimeUp[plugNum][curReg]); } } curReg = REG_REFUND_AMOUNT; break; case REG_REFUND_AMOUNT: curReg = REG_PREPAYMENT_INFO; break; case REG_PREPAYMENT_INFO: curReg = REG_PAYMENT_FAIL_REASON; break; case REG_PAYMENT_FAIL_REASON: curReg = REG_CONNECTOR_QR_CODE; break; case REG_CONNECTOR_QR_CODE: isContinue = 0; break; default: log_error("error curReg = %x", curReg); gDoCommGblData.MiscCmd = 0; gDoCommGblData.DisConnCount = CHECK_NETWORK_FAIL_COUNT; isContinue = 0; break; } if (gDoCommGblData.DisConnCount >= CHECK_NETWORK_FAIL_COUNT) { return DISPENSER_SOCKET_RECONN; } }//for return ret; } //static bool isDetectPlugin() //{ // if (pSysInfo->WaitForPlugit == YES) { // return YES; // } // // return NO; //} static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8_t gunID) { uint8_t i = 0; int j; struct timeb AuthNowTime = {0}; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum); \ struct timeb SeqEndTime; struct tm* tm; switch (pDcChargingInfo->SystemStatus) { case S_IDLE: case S_RESERVATION: case S_MAINTAIN: case S_ALARM: case S_AUTHORIZING: if(pDcChargingInfo->SystemStatus == S_ALARM) { ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) < 0 ) { writePresentChargingInfo(fd, plugNum, gunID); ftime(&gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO]); } } checkAuthorProcess(fd, plugNum); //authorization complete, write wait plug it state if (ShmSelectGunInfo->PricesInfo[plugNum].Balance == FAIL_BALANCE_PRICES) { break; } ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_WAIT_PLUG_IT_STATE], AuthNowTime) > (LOOP_RETRY_TIME / 10) || DiffTimeb(gRegTimeUp[plugNum][REG_WAIT_PLUG_IT_STATE], AuthNowTime) < 0 ) { writeWaitPlugItState(fd, gunID, plugNum); ftime(&gRegTimeUp[plugNum][REG_WAIT_PLUG_IT_STATE]); } /* ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_MISC_CONTROL], AuthNowTime) > (LOOP_RETRY_TIME / 10) || DiffTimeb(gRegTimeUp[plugNum][REG_MISC_CONTROL], AuthNowTime) < 0 ) { readMiscCommand(fd, gunID); ftime(&gRegTimeUp[plugNum][REG_MISC_CONTROL]); } */ ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) < 0 ) { readChargingCapability(fd, gunID); if (pDcChargingInfo->PantographFlag) writeGroundFaultDetection(fd, 0, gunID); ftime(&gRegTimeUp[plugNum][REG_CHARGING_CAP]); } break; case S_PREPARNING: //get permission ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_CONNECTOR_STATE], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_CONNECTOR_STATE], AuthNowTime) < 0 ) { writeConnectorState(fd, plugNum, gunID); ftime(&gRegTimeUp[plugNum][REG_CONNECTOR_STATE]); } ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_PERMISSION], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_PERMISSION], AuthNowTime) < 0 ) { if (readChargePermission(fd, gunID) && readChargingCapability(fd, gunID)) { for (i = 0; i < totalGun; i++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i); ShmPsuData->SystemAvailablePower += pDcChargingInfo->AvailableChargingPower; } ShmPsuData->SystemPresentPsuQuantity = (ShmPsuData->SystemAvailablePower / 30); } ftime(&gRegTimeUp[plugNum][REG_CHARGING_PERMISSION]); } ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) < 0 ) { writePresentChargingInfo(fd, plugNum, gunID); if (pDcChargingInfo->PantographFlag) writeGroundFaultDetection(fd, 0, gunID); ftime(&gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO]); } break; case S_PREPARING_FOR_EV://wait connector lock ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) < 0 ) { readChargingCapability(fd, gunID); ftime(&gRegTimeUp[plugNum][REG_CHARGING_CAP]); } ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_PERMISSION], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_PERMISSION], AuthNowTime) < 0 ) { if (readChargePermission(fd, gunID) == 0) { log_info("S_PREPARING_FOR_EV Stop charging by power cabinet's permission = %d, %d", plugNum, REG_CHARGING_PERMISSION); pDcChargingInfo->StopChargeFlag = POWER_CABINET_STOP_CHARGING; } ftime(&gRegTimeUp[plugNum][REG_CHARGING_PERMISSION]); } ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) < 0 ) { writePresentChargingInfo(fd, plugNum, gunID); if (pDcChargingInfo->PantographFlag) writeGroundFaultDetection(fd, 0, gunID); ftime(&gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO]); } break; case S_PREPARING_FOR_EVSE: //insaulation test case S_CCS_PRECHARGE_ST0: case S_CCS_PRECHARGE_ST1: writeChargingTarget(fd, plugNum, gunID); if (pDcChargingInfo->PantographFlag) writeGroundFaultDetection(fd, 1, gunID); ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) < 0 ) { readChargingCapability(fd, gunID); ftime(&gRegTimeUp[plugNum][REG_CHARGING_CAP]); } ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_PERMISSION], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_PERMISSION], AuthNowTime) < 0 ) { if (readChargePermission(fd, gunID) == 0) { log_info("S_PREPARING_FOR_EVSE Stop charging by power cabinet's permission = %d, %d", plugNum, REG_CHARGING_PERMISSION); pDcChargingInfo->StopChargeFlag = POWER_CABINET_STOP_CHARGING; } ftime(&gRegTimeUp[plugNum][REG_CHARGING_PERMISSION]); } ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) < 0 ) { writePresentChargingInfo(fd, plugNum, gunID); ftime(&gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO]); } break; case S_CHARGING: //charging case S_TERMINATING: if(pDcChargingInfo->Type == _Type_GB || pDcChargingInfo->Type == _Type_Chademo) { if (pDcChargingInfo->PantographFlag) writeGroundFaultDetection(fd, 0, gunID); } else { if (pDcChargingInfo->PantographFlag) writeGroundFaultDetection(fd, 1, gunID); } ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) < 0 ) { readChargingCapability(fd, gunID); ftime(&gRegTimeUp[plugNum][REG_CHARGING_CAP]); } ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_PERMISSION], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_PERMISSION], AuthNowTime) < 0 ) { if (readChargePermission(fd, gunID) == 0) { if (pDcChargingInfo->StopChargeFlag != POWER_CABINET_STOP_CHARGING) { log_info("Stop charging by power cabinet's permission = %d, %d", plugNum, REG_CHARGING_PERMISSION); pDcChargingInfo->StopChargeFlag = POWER_CABINET_STOP_CHARGING; } //printf("%d StopChargeFlag = %d\n", plugNum, pDcChargingInfo->StopChargeFlag); } ftime(&gRegTimeUp[plugNum][REG_CHARGING_PERMISSION]); } writeChargingTarget(fd, plugNum, gunID); ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) < 0 ) { writePresentChargingInfo(fd, plugNum, gunID); ftime(&gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO]); } // 獲得Charging時間 ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_READ_CHARGING_TIMESTAMP], AuthNowTime) > (LOOP_RETRY_TIME*5) || DiffTimeb(gRegTimeUp[plugNum][REG_READ_CHARGING_TIMESTAMP], AuthNowTime) < 0 ) { readChargingTimeStamp(fd, gunID); ftime(&gRegTimeUp[plugNum][REG_READ_CHARGING_TIMESTAMP]); } break; case S_COMPLETE: ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) < 0 ) { readChargingCapability(fd, gunID); if (pDcChargingInfo->PantographFlag) writeGroundFaultDetection(fd, 0, gunID); ftime(&gRegTimeUp[plugNum][REG_CHARGING_CAP]); } ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) > LOOP_RETRY_TIME || DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) < 0 ) { writePresentChargingInfo(fd, plugNum, gunID); ftime(&gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO]); } // 獲得Charging時間 /* ftime(&AuthNowTime); if (DiffTimeb(gRegTimeUp[plugNum][REG_READ_CHARGING_TIMESTAMP], AuthNowTime) > (LOOP_RETRY_TIME / 10) || DiffTimeb(gRegTimeUp[plugNum][REG_READ_CHARGING_TIMESTAMP], AuthNowTime) < 0 ) { readChargingTimeStamp(fd, gunID); ftime(&gRegTimeUp[plugNum][REG_READ_CHARGING_TIMESTAMP]); } */ break; default: break; } } static int networkCreatePorcess(void) { int fd = 0; uint8_t discount = 0; while (pSysInfo->SelfTestSeq != _STEST_COMPLETE) { usleep(128); } setTcpStatus(ABNORMAL); /**************** Check Network **********/ //log_info("Check Dispenser Network Information"); while (pSysInfo->SelfTestSeq != _STEST_COMPLETE) { usleep(125); } while (!CheckNetworkStatus()) { calDisconnectCount(&gDoCommGblData.DisConnCount, CHECK_NETWORK_FAIL_COUNT); if( gDoCommGblData.DisConnCount != discount ) { discount = gDoCommGblData.DisConnCount; log_error("disconnect count = % d", gDoCommGblData.DisConnCount); } } log_info("Dispenser Network Information checked: IP = % s Netmask = % s, Gateway = % s", pSysConfig->Eth0Interface.EthIpAddress, pSysConfig->Eth0Interface.EthSubmaskAddress, pSysConfig->Eth0Interface.EthGatewayAddress); gDoCommGblData.DisConnCount = 0; discount = 0; /**************** Power cabinet connection **********/ log_info("Connect to Power Cabinet"); while ((fd = doCommConnToServer()) <= 0) { calDisconnectCount(&gDoCommGblData.DisConnCount, CONNECT_SERVER_FAIL_COUNT); if( gDoCommGblData.DisConnCount != discount && fd == -1) { discount = gDoCommGblData.DisConnCount; log_error("disconnect count = %d, fd = %d", gDoCommGblData.DisConnCount, fd); } } log_info("Power cabinet connected(fd = % d): IP = % s Netmask = % s, Gateway = % s", fd, pSysConfig->Eth0Interface.EthIpAddress, pSysConfig->Eth0Interface.EthSubmaskAddress, pSysConfig->Eth0Interface.EthGatewayAddress); gDoCommGblData.DisConnCount = 0; destroySelectGun(DESTROY_ALL_SEL); sleep(3); setTcpStatus(NORMAL); return fd; } int main(int argc, char *argv[]) { uint8_t plugNum = 0, gunID = 0; uint8_t index = 0; uint8_t totalConnCount = 0; uint8_t initDone = DISPENER_INIT_FAIL; char tmpbuf[256] = {0}; int fd = 0; int isContinue = 1; InitSocketSigPipe(); /**************** Initialization **********/ if (CreateAllCsuShareMemory() == FAIL) { log_error("create share memory error"); return FAIL; } MappingGunChargingInfo("DoComm Task"); pSysConfig = (struct SysConfigData *)GetShmSysConfigData(); pSysInfo = (struct SysInfoData *)GetShmSysInfoData(); pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo(); pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData(); ShmPsuData = (struct PsuData *)GetShmPsuData(); ShmPrimaryMcuData = (struct PrimaryMcuData *)GetShmPrimaryMcuData(); ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data(); ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo(); ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData(); totalConnCount = pSysConfig->TotalConnectorCount; for (index = 0; index < totalConnCount; index++) { clearPricesInfo(index); } //initial trigger message timer for (index = 0; index < MAX_REGISTER_NUM; index++) { ftime(&gRegTimeUp[0][index]); usleep(128); ftime(&gRegTimeUp[1][index]); usleep(50000); } setTcpStatus(NORMAL); while (isContinue) { if (initDone == DISPENER_INIT_FAIL) { fd = networkCreatePorcess(); initDone = messageTrigger(fd, 0, 0, REG_MODEL_NAME); //first trigger model name and connector id } else { plugNum = 0; gunID = 0; for (plugNum = 0; plugNum < totalConnCount; plugNum++) { //checkAuthorProcess(fd, plugNum); //plugNum : setup chargingData value for bottom layer //gunID : connector Id from power cabinet, 1 = left gun, 2 = right gun, gunID = gDoCommGblData.ConnectorID[plugNum]; systemStatusProcess(fd, totalConnCount, plugNum, gunID); initDone = messageTrigger(fd, plugNum, gunID, REG_POWER_CABINET_STATUS); if (initDone == DISPENSER_SOCKET_RECONN) { break; } } } if (initDone != DISPENSER_SOCKET_RECONN) { //update dispenser firmware updateFirmwareProcess(fd, gDoCommGblData.ConnectorID[0], totalConnCount); usleep(100000); continue; } //Ethernet error recovery handle log_info("Disconnected from power cabinet...re-connecting"); setTcpStatus(ABNORMAL); if (pSysConfig->Eth0Interface.EthDhcpClient == 0) { system("pgrep -f \"udhcpc -i eth0\" | xargs kill"); sprintf(tmpbuf, "/sbin/udhcpc -i eth0 -x hostname:CSU3_%s -s /root/dhcp_script/eth0.script > /dev/null &", pSysConfig->SystemId); system(tmpbuf); } gDoCommGblData.DisConnCount = 0; gDoCommGblData.SeqNum = 0; closeSocket(fd); fd = 0; initDone = DISPENER_INIT_FAIL; } }