#include /*標準輸入輸出定義*/ #include /*標準函數庫定義*/ #include #include #include "../Config.h" #include "../Log/log.h" #include "../Define/define.h" #include "../ShareMemory/shmMem.h" #include "../SelectGun/SelectGun.h" #include "../DataBase/DataBase.h" #include #include "main.h" #include "../timeout.h" static DcCommonInfo *ShmDcCommonData = NULL; static SelectGunInfo *ShmSelectGunInfo = NULL; static struct SysInfoData *pSysInfo = NULL; #define PREAUTHMONEY 888 bool isDb_ready; static RecordTransactionInfo LocalTransactionInfo; //------------------------------------------------------------------------------ static char *rfidPortName = "/dev/ttyS2"; static bool isCardScan = false; //------------------------------------------------------------------------------ int checkRemoteStart(int gunIndex) { if (ShmDcCommonData->is_RemoteStart[gunIndex] || ShmDcCommonData->TransactionInfo[gunIndex].LineStatus == _LINE_PAY_INVOICE || ShmDcCommonData->TransactionInfo[gunIndex].LineStatus == _LINE_PAY_DONATE) { return TRUE; } return FALSE; } static bool canStartCharging(void) { uint8_t index = 0; char buf2[16] = ""; memset(buf2, 0, ARRAY_SIZE(buf2)); struct OCPP16Data *ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data(); for (index = 0; index < strlen((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status); index++) { sprintf(buf2 + (index - 1) * 2, "%02X", ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status[index]); } sprintf(buf2, "%s", ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status); // 因為無法得知實際的長度,所以只能用搜尋的方式 if (strcmp(buf2, "Accepted") == EQUAL) { return true; } return false; } bool isAutorCompleteHandle(/*uint8_t *authorizeIndex*/) { // uint8_t i = 0; struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData(); //struct ChargingInfoData *pDcChargingInfo = NULL; //struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData(); // 透過後臺停止充電的判斷 if (isAuthorizedComplete()) { // 判斷後台回覆狀態 if (canStartCharging() == false) { strcpy((char *)pSysConfig->UserId, ""); ClearAuthorizedFlag(); } return true; } return false; /* if (*(authorizeIndex) != NO_DEFINE) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(*(authorizeIndex)); if (pSysConfig->OfflinePolicy == _OFFLINE_POLICY_LOCAL_LIST && strcmp((char *)pDcChargingInfo->StartUserId, "") != EQUAL) { // 先找 AC if (*(authorizeIndex) == DEFAULT_AC_INDEX) { AcChargingTerminalProcess(); } else { ChargingTerminalProcess(*(authorizeIndex)); } } strcpy((char *)pSysConfig->UserId, ""); *(authorizeIndex) = NO_DEFINE; } ClearAuthorizedFlag(); } else if (pSysConfig->OfflinePolicy == _OFFLINE_POLICY_LOCAL_LIST) { // 白名單驗證 for (i = 0; i < 10; i++) { if (strcmp((char *)pSysConfig->LocalWhiteCard[i], "") == EQUAL) { continue; } if (strcmp((char *)pSysConfig->LocalWhiteCard[i], (char *)pSysConfig->UserId) == EQUAL) { ChargingTerminalProcess(*(authorizeIndex)); strcpy((char *)pSysConfig->UserId, ""); ClearAuthorizedFlag(); break; } } }*/ } void showDeductInfo(RecordTransactionInfo* transactionInfo) { char ApprovalNo[10]; char vemdata[65]; char cardno[21]; char sn[37]; memset(ApprovalNo,'\0',sizeof(ApprovalNo)); memset(vemdata,'\0',sizeof(vemdata)); memset(cardno,'\0',sizeof(cardno)); memset(sn,'\0',sizeof(sn)); memcpy(ApprovalNo,&transactionInfo->pCreditCard.ApprovalNo[0],9); memcpy(vemdata,&transactionInfo->pCreditCard.VemData[0],64); memcpy(cardno,&transactionInfo->pCreditCard.CardNo[0],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, ApprovalNo, vemdata, cardno); } bool RfidStopCharging(void) { //當前沒有選槍 struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData(); struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData(); if (getConfirmSelectedGun(pSysInfo->CurGunSelected) == FAIL ) { strcpy((char *)pSysConfig->UserId, ""); return false; } struct ChargingInfoData *pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected); if (pDcChargingInfo->isRemoteStart) { } else { if (strcmp((char *)pSysConfig->UserId, (char *)pDcChargingInfo->StartUserId) == EQUAL) { ChargingTerminalProcess(pSysInfo->CurGunSelected); strcpy((char *)pSysConfig->UserId, ""); log_info("index = %d, card number = %s, UserId = %s ", pSysInfo->CurGunSelected, pDcChargingInfo->StartUserId, pSysConfig->UserId); return true; } else { strcpy((char *)pSysConfig->UserId, ""); return false; } } return false; } static void UserScanFunction(int gunIndex) { struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData(); struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData(); //struct ChargingInfoData *pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); struct ChargingInfoData *pDcChargingInfo = NULL; ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData(); // 當前非驗證的狀態 if (IsAuthorizingMode()) { isAutorCompleteHandle(/*&_authorizeIndex*/); } // 先判斷現在是否可以提供刷卡 // 1. 如果當前沒有槍是閒置狀態,則無提供刷卡功能 // 2. 停止充電 //if (pSysInfo->PageIndex == _LCM_ERROR) { if (pSysInfo->SystemPage == _PAGE_MAINTAIN) { strcpy((char *)pSysConfig->UserId, ""); return; } if (strlen((char *)pSysConfig->UserId) <= 0) { return; } pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if ( (pSysInfo->SystemPage == _PAGE_AUTHORIZE || pSysInfo->SystemPage == _PAGE_SENSING)) { log_info("// LCM => Authorizing"); confirmSelGun(gunIndex); setSelGunWaitToAuthor(gunIndex); StartSystemTimeoutDet(Timeout_Authorizing); AuthorizingStart(); pDcChargingInfo->SystemStatus = S_AUTHORIZING; // LCM => Authorizing //pSysInfo->SystemPage = _PAGE_AUTHORIZE; // 進入確認卡號狀態 } else { //strcpy((char *)pSysConfig->UserId, ""); } return; } bool GetIsCardScan(void) { return isCardScan; } void SetIsCardScan(bool value) { isCardScan = value; } void AuthorizeToCharge(int gunIndex) { struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData(); struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData(); struct ChargingInfoData* pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex); ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData(); if (pDcChargingInfo->SystemStatus == S_RESERVATION) { if (strcmp((char*)pSysConfig->UserId, (char*)ShmDcCommonData->pGunInfo[gunIndex].ReservationID) != EQUAL) { log_info("LCM => Authorize fail"); ShmDcCommonData->TradeCancel = TRUE; ShmDcCommonData->PreAuth_Config = _CREDITCARD_CANCEL; ShmDcCommonData->PreAuth_Result = 0; pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL; strcpy((char*)pSysConfig->UserId, ""); ClearAuthorizedFlag(); return; } } if(isAuthorizedComplete()) { if (canStartCharging()) { DetectPluginStart(gunIndex); if (ShmDcCommonData->AuthPass_flag[gunIndex] == TRUE && ShmDcCommonData->TradeCancel == FALSE) { pSysInfo->SystemPage = _PAGE_PLUGIN; } } else { struct ChargingInfoData* pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex); log_info("LCM => Authorize fail"); ShmDcCommonData->TradeCancel = TRUE; ShmDcCommonData->PreAuth_Config = _CREDITCARD_CANCEL; ShmDcCommonData->PreAuth_Result = 0; if (!pDcChargingInfo->RemoteStartFlag || !pDcChargingInfo->isRemoteStart) pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL; strcpy((char *)pSysConfig->UserId, ""); } ClearAuthorizedFlag(); } } void ScannerCardProcess(int gunIndex) { //struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData(); struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData(); struct WARNING_CODE_INFO *pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo(); struct ChargingInfoData *pDcChargingInfo = NULL; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (!isDetectPlugin(gunIndex) && (pSysInfo->SystemPage == _PAGE_SENSING || pSysInfo->SystemPage == _PAGE_AUTHORIZE ) && (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION )&& pSysWarning->Level != WARN_LV_ER ) { //setSelGunWaitToAuthor(gunIndex); isCardScan = true; // 處理刷卡及驗證卡號的動作 UserScanFunction(gunIndex); } if (pDcChargingInfo->SystemStatus == S_AUTHORIZING && pSysInfo->SystemPage == _PAGE_SENSING && !ShmDcCommonData->is_RemoteStart[gunIndex] ) { AuthorizeToCharge(gunIndex); } else if (pSysInfo->SystemPage == _PAGE_AUTHORIZE_FAIL) { StartSystemTimeoutDet(Timeout_VerifyFail); isCardScan = false; } else { isCardScan = false; } } void storePayResult(uint8_t gunIndex) { memset(&LocalTransactionInfo, 0x00, sizeof(RecordTransactionInfo)); memcpy(&LocalTransactionInfo, &ShmDcCommonData->TransactionInfo[gunIndex] ,sizeof(RecordTransactionInfo)); } void getPayResult(uint8_t gunIndex) { memcpy(&ShmDcCommonData->TransactionInfo[gunIndex], &LocalTransactionInfo, sizeof(RecordTransactionInfo)); } void storeParkingPayResult(uint8_t gunIndex) { memset(&LocalTransactionInfo, 0x00, sizeof(RecordTransactionInfo)); memcpy(&LocalTransactionInfo, &ShmDcCommonData->ParkingInfo[gunIndex] ,sizeof(RecordTransactionInfo)); } void getParkingPayResult(uint8_t gunIndex) { //memcpy(&ShmDcCommonData->ParkingInfo[gunIndex], &LocalTransactionInfo, sizeof(RecordTransactionInfo)); memcpy( ShmDcCommonData->ParkingInfo[gunIndex].OccupancySN, LocalTransactionInfo.OccupancySN, 36); } void WritePayResult(int result ,uint8_t gunIndex) { if (result == TRUE) ShmDcCommonData->TransactionInfo[gunIndex].DeductResult = _DEDUCT_COMPLETE_PASS; else ShmDcCommonData->TransactionInfo[gunIndex].DeductResult = _DEDUCT_COMPLETE_FAIL; log_info("Gun[%d] TransactionId:%d DeductResult:%d IsDonateInvoice:%d Amount:%f VemData:%s Approve No:%s", gunIndex, ShmDcCommonData->TransactionInfo[gunIndex].TransactionId, ShmDcCommonData->TransactionInfo[gunIndex].DeductResult, ShmDcCommonData->TransactionInfo[gunIndex].IsDonateInvoice, ShmDcCommonData->TransactionInfo[gunIndex].Amount, ShmDcCommonData->TransactionInfo[gunIndex].pCreditCard.VemData, ShmDcCommonData->TransactionInfo[gunIndex].pCreditCard.ApprovalNo); } void PreAuthCompleteToCardReader(int fd,uint8_t gunIndex) { struct SysConfigData* pSysConfig = (struct SysConfigData*)GetShmSysConfigData(); int result = 0; storePayResult(gunIndex); if (ShmDcCommonData->TransactionInfo[gunIndex].Amount > 0 && ShmDcCommonData->TransactionInfo[gunIndex].Amount < 1 && ShmDcCommonData->pGunInfo[gunIndex].ParkingStatus == 0) { log_info("final cost less 1 : %f", ShmDcCommonData->TransactionInfo[gunIndex].Amount); ShmDcCommonData->TransactionInfo[gunIndex].Amount = 1; } result = CreditCardPreAuthComplete(fd,(int)LocalTransactionInfo.Amount, &pSysConfig->ModelName[0], &ShmDcCommonData->TransactionInfo[gunIndex].pCreditCard.VemData[0], &ShmDcCommonData->TransactionInfo[gunIndex]); getPayResult(gunIndex); //sleep(10); if (result > 0 ) { log_info("Credit Card Spend Money:%.1f", ShmDcCommonData->TransactionInfo[gunIndex].Amount); pSysInfo->SystemPage = _PAGE_COMPLETE; ShmDcCommonData->TransactionInfo[gunIndex].DeductResult = _DEDUCT_COMPLETE_PASS; WritePayResult(TRUE,gunIndex); ShmDcCommonData->PayPass_flag[gunIndex] = TRUE; } else { log_info("PAYING FAIL"); ShmDcCommonData->PayPass_flag[gunIndex] = FALSE; pSysInfo->SystemPage = _PAGE_PAYFAIL; ShmDcCommonData->TransactionInfo[gunIndex].DeductResult = _DEDUCT_COMPLETE_FAIL; WritePayResult(FALSE,gunIndex); } ShmDcCommonData->TransactionInfo[gunIndex].IsUpload = FALSE; //getPayResult(gunIndex); UpdateDeductInfoStatus(gunIndex, &ShmDcCommonData->TransactionInfo[gunIndex]); ShmDcCommonData->PreAuth_Result = result; } int CreditCardCancelPreAuth(int fd, uint8_t gunIndex) { if (ShmDcCommonData->pGunInfo[gunIndex].ParkingStatus) { return; } struct SysConfigData* pSysConfig = (struct SysConfigData*)GetShmSysConfigData(); storePayResult(gunIndex); ShmDcCommonData->PreAuth_Result = CreditCardPreAuthCancel(fd, PREAUTHMONEY, &pSysConfig->ModelName[0], &LocalTransactionInfo.pCreditCard.ApprovalNo[0], &LocalTransactionInfo.pCreditCard.CardNo[0], &LocalTransactionInfo.pCreditCard.VemData[0]); //sleep(10); if (ShmDcCommonData->PreAuth_Result >= 0) { strcpy((char*)pSysConfig->UserId, ""); //ShmDcCommonData->PayFinish[gunIndex] = TRUE; log_info("Gun%d Card Reader PreAuth Cancel Success",gunIndex); LocalTransactionInfo.DeductResult = _DEDUCT_CANCEL; } else if (ShmDcCommonData->PreAuth_Result < 0) { log_info("Gun%d Card Reader PreAuth Cancel Failure",gunIndex); LocalTransactionInfo.DeductResult = _DEDUCT_PREAUTH; } LocalTransactionInfo.IsUpload = FALSE; getPayResult(gunIndex); UpdateDeductInfoStatus(gunIndex, &LocalTransactionInfo); memset(&ShmDcCommonData->TransactionInfo[gunIndex], 0x00, sizeof(RecordTransactionInfo)); ShmDcCommonData->PreAuth_Config = _CREDITCARD_IDLE; return ShmDcCommonData->PreAuth_Result; } void ReDeductProcess(int fd) { struct SysConfigData* pSysConfig = (struct SysConfigData*)GetShmSysConfigData(); int j; int result; int rededuct_gunIndex[128]; RecordTransactionInfo deductInfo[128]; int rededuct_num = 0; // 充電費補扣款 rededuct_num = DB_GetMultiReDeductInfo(&rededuct_gunIndex[0], &deductInfo[0]); if (rededuct_num == 0) { //log_info("No Rededuct Information"); } else { ShmDcCommonData->CreditCardUpload = TRUE; pSysInfo->SystemPage = _PAGE_PAYING; log_info("Rededuct Total Number:%d", rededuct_num); for (j = rededuct_num-1; j >= 0 ; j--) { sleep(10); log_info("Start Rededuct item [%d]",j); if (deductInfo[j].isIntoCharge == FALSE || (deductInfo[j].Energy == 0 && deductInfo[j].Amount == 0) || (deductInfo[j].LineStatus == _LINE_PAY_DONATE || deductInfo[j].LineStatus == _LINE_PAY_INVOICE)) { // 未進入充電或度數等於零 result = CreditCardPreAuthCancel(fd, PREAUTHMONEY, &pSysConfig->ModelName[0], &deductInfo[j].pCreditCard.ApprovalNo[0], &deductInfo[j].pCreditCard.CardNo[0], &deductInfo[j].pCreditCard.VemData[0]); sleep(10); if (result > 0) { deductInfo[j].DeductResult = _DEDUCT_CANCEL; log_info("Backgroud PreAuthCancel OK"); } } else { // 度數大於零 if (deductInfo[j].Amount == 0 && deductInfo[j].Energy > 0) { log_info("Error Close Charging recount amount:%.1f",deductInfo[j].Amount); continue; } result = CreditCardPreAuthComplete(fd, (int)deductInfo[j].Amount, &pSysConfig->ModelName[0], &deductInfo[j].pCreditCard.VemData[0], &ShmDcCommonData->TransactionInfo[0].pCreditCard); if (result > 0) { deductInfo[j].DeductResult = _DEDUCT_COMPLETE_PASS; log_info("Backgroud PreAuthComplete OK"); } else if (result < 0) { deductInfo[j].DeductResult = _DEDUCT_COMPLETE_FAIL; log_info("Backgroud ID:%d Amount:%d VemData:%s PreAuthComplete fail", deductInfo[j].TransactionId, (int)deductInfo[j].Amount, deductInfo[j].pCreditCard.VemData); } } deductInfo[j].IsUpload = FALSE; deductInfo[j].RedeductTime++; UpdateDeductInfoStatus(rededuct_gunIndex[j], &deductInfo[j]); } } // 佔位費補扣款 /* rededuct_num = DB_GetParkingDeductResult(&rededuct_gunIndex[0], &deductInfo[0]); if (rededuct_num == 0) { log_info("No Parking Rededuct Information"); } else { ShmDcCommonData->CreditCardUpload = TRUE; pSysInfo->SystemPage = _PAGE_PAYING; log_info("Parking Rededuct Total Number:%d", rededuct_num); for (j = rededuct_num-1; j >= 0 ; j--) { sleep(3); log_info("Start Parking Rededuct item [%d]",j); result = CreditCardPreAuthComplete(fd, (int)deductInfo[j].Amount, &pSysConfig->ModelName[0], &deductInfo[j].pCreditCard.VemData[0], &ShmDcCommonData->ParkingInfo[0].pCreditCard); if (result > 0) { deductInfo[j].DeductResult = _DEDUCT_COMPLETE_PASS; log_info("Backgroud Parking PreAuthComplete OK"); } else if (result < 0) { deductInfo[j].DeductResult = _DEDUCT_COMPLETE_FAIL; log_info("Backgroud Parking ID:%d Amount:%d VemData:%s PreAuthComplete fail", deductInfo[j].TransactionId, (int)deductInfo[j].Amount, deductInfo[j].pCreditCard.VemData); } deductInfo[j].IsUpload = FALSE; deductInfo[j].RedeductTime++; UpdateParkingDeductInfo(rededuct_gunIndex[j], &deductInfo[j]); } } */ ShmDcCommonData->RoutineReduct = TRUE; } static int InitialRfidPort(void) { int fd = open(rfidPortName, O_RDWR); struct termios tios; struct AlarmCodeData *pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData(); if (fd != FAIL) { ioctl (fd, TCGETS, &tios); tios.c_cflag = B115200 | CS8 | CLOCAL | CREAD; tios.c_lflag = 0; tios.c_iflag = 0; tios.c_oflag = 0; tios.c_cc[VMIN] = 0; tios.c_cc[VTIME] = (uint8_t) 1; tios.c_lflag = 0; tcflush(fd, TCIFLUSH); ioctl(fd, TCSETS, &tios); } if (fd < 0) { pAlarmCode->AlarmEvents.bits.RfidModuleCommFail = 1; } return fd; } void RemoteStartCancelPreAuth(int sel_gun) { log_info("Remote start need to cancel PreAuth"); memcpy(&ShmDcCommonData->RedeductBill, &ShmDcCommonData->TransactionInfo[sel_gun], sizeof(RecordTransactionInfo)); memset(&ShmDcCommonData->TransactionInfo[sel_gun], 0x00, sizeof(RecordTransactionInfo)); ShmDcCommonData->TransactionInfo[sel_gun].LineStatus = ShmDcCommonData->RedeductBill.LineStatus; } void PreAuthCreditCard(int fd, uint8_t gunIndex) { struct SysConfigData* pSysConfig = (struct SysConfigData*)GetShmSysConfigData(); struct ChargingInfoData *pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);; int result = 0; storePayResult(gunIndex); if (ShmDcCommonData->pGunInfo[gunIndex].ParkingStatus) result = CreditCardPreAuth(fd, LocalTransactionInfo.Amount,&pSysConfig->ModelName[0], &LocalTransactionInfo.pCreditCard); else result = CreditCardPreAuth(fd, PREAUTHMONEY,&pSysConfig->ModelName[0], &LocalTransactionInfo.pCreditCard); ShmDcCommonData->PreAuth_Result = result; pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex); { if (!checkRemoteStart(gunIndex)) { if (!ShmDcCommonData->TradeCancel) StopSystemTimeoutDet(); if (ShmDcCommonData->TradeCancel == FALSE && result > 0) { pSysInfo->SystemPage = _PAGE_SENSING; } } if (result > 0 && strcmp((char*)LocalTransactionInfo.pCreditCard.CardNo, "") != 0) { log_info("Gun%d PreAuth card:%s", gunIndex, LocalTransactionInfo.pCreditCard.CardNo); LocalTransactionInfo.DeductResult = _DEDUCT_PREAUTH; LocalTransactionInfo.IsUpload = FALSE; LocalTransactionInfo.ConnectorID = ShmDcCommonData->ConnectorID[gunIndex]; //log_info("Gun%d Line Status:%d", LocalTransactionInfo.LineStatus); if (ShmDcCommonData->pGunInfo[gunIndex].ParkingStatus) InsertParkingDeductInfo(ShmDcCommonData->ConnectorID[gunIndex], &LocalTransactionInfo); else { ShmDcCommonData->AuthPass_flag[gunIndex] = TRUE; strncpy((char*)pSysConfig->UserId, (char*)LocalTransactionInfo.pCreditCard.CardNo, 20); InsertDeductInfo(ShmDcCommonData->ConnectorID[gunIndex], &LocalTransactionInfo); } getPayResult(gunIndex); //log_info("Gun%d PreAuth OK",gunIndex); } else if (result < 0) { if (ShmDcCommonData->TradeCancel == FALSE && !checkRemoteStart(gunIndex)) pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL; ShmDcCommonData->AuthPass_flag[gunIndex] = FALSE; memset(&LocalTransactionInfo.pCreditCard, 0, sizeof(TransInfo)); log_info("Gun%d PreAuth Fail",gunIndex); } ShmDcCommonData->PreAuth_Config = _CREDITCARD_IDLE; } } void CreateRfidFork(void) { pid_t rfidRecPid; int donate = 0; rfidRecPid = fork(); int sel_gun = 0; int linestatus = 0; if (rfidRecPid == 0) { //char localTime[128] = {0}; struct timeb SeqEndTime; struct tm *tm; pSysInfo = (struct SysInfoData *)GetShmSysInfoData(); int fd = -1; int isContinue = 1; //RFID rfid = {0}; //RecordTransactionInfo deduct; fd = InitialRfidPort(); struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData(); ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData(); ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo(); struct ChargingInfoData *pDcChargingInfo = NULL; if (DeductDB_Open() != PASS) { isDb_ready = false; log_info("DeductDB_Open Fail"); return; } else { isDb_ready = true; //InsertDeductInfo(0, &ShmDcCommonData->TransactionInfo); } if (ParkingDB_Open() != PASS) { isDb_ready = false; log_info("ParkingDB_Open Fail"); return; } else { isDb_ready = true; //InsertDeductInfo(0, &ShmDcCommonData->TransactionInfo); } int gunIndex; //int uploadIndex = 0; //int ReAuthComplete_Index = 0; //log_info("RFID fork Child's PID is %d", getpid()); int result; int is_idle = TRUE; while (isContinue) { result = 0; usleep(500000); ftime(&SeqEndTime); SeqEndTime.time = time(NULL); tm = localtime(&SeqEndTime.time); if (ShmDcCommonData->DebugFlag == TRUE || ShmDcCommonData->is_RemoteStart[pSysInfo->CurGunSelected] == TRUE || ShmDcCommonData->is_AutoStart[pSysInfo->CurGunSelected] == TRUE) { ShmDcCommonData->PreAuth_Config = _CREDITCARD_IDLE; ShmDcCommonData->PreAuth_Result = 0; } is_idle = TRUE; for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); // 檢查電樁狀態是否為idle狀態 if (pDcChargingInfo->SystemStatus != S_IDLE ) { is_idle = FALSE; } // 檢查使用者是否進行線上支付操作並且線下支付已完成 // 需進行取消預授權 if (checkRemoteStart(gunIndex) && ShmDcCommonData->AuthPass_flag[gunIndex] && !ShmDcCommonData->PayPass_flag[gunIndex]) { RemoteStartCancelPreAuth(gunIndex); ShmDcCommonData->AuthPass_flag[gunIndex] = FALSE; } if (ShmDcCommonData->StopCharge[gunIndex] == TRUE && pDcChargingInfo->Replug_flag == TRUE) { // Remote Start of AutoStart ByPass Credit Card Reader if (ShmDcCommonData->DebugFlag == TRUE || ShmDcCommonData->is_RemoteStart[gunIndex] == TRUE || ShmDcCommonData->is_AutoStart[gunIndex] == TRUE) { continue; } log_info("Gun %d Not Into Charging cancel Trade",gunIndex); StopGunInfoTimeoutDet(gunIndex); ShmDcCommonData->TradeCancel = TRUE; pSysInfo->SystemPage = _PAGE_SENSING; StartSystemTimeoutDet(Timeout_TradeCancel); CreditCardCancelPreAuth(fd, gunIndex); pSysInfo->CurGunSelected = gunIndex; pSysInfo->SystemPage = _PAGE_PLUGOUT; StopSystemTimeoutDet(); ShmDcCommonData->StopCharge[gunIndex] = FALSE; } else { if (ShmDcCommonData->StopCharge[gunIndex] && ShmDcCommonData->finalcost_flag[gunIndex] && ShmDcCommonData->PreAuth_Config != _CREDITCARD_CANCEL) { pSysInfo->CurGunSelected = gunIndex; StopGunInfoTimeoutDet(gunIndex); //Timeout_FinalCost // Remote Start of AutoStart ByPass Credit Card Reader if (ShmDcCommonData->DebugFlag == TRUE || checkRemoteStart(gunIndex) || ShmDcCommonData->is_AutoStart[gunIndex]) { if (ShmDcCommonData->is_AutoStart[gunIndex]) { ShmDcCommonData->PayPass_flag[gunIndex] = TRUE; } ShmDcCommonData->StopCharge[gunIndex] = FALSE; continue; } // 實際扣款 if (ShmDcCommonData->TransactionInfo[gunIndex].Amount < 1) { log_info("Final Cost less 1 , Cancel Trade!!"); if (CreditCardCancelPreAuth(fd, gunIndex) > 0) { pSysInfo->SystemPage = _PAGE_COMPLETE; ShmDcCommonData->PayPass_flag[gunIndex] = TRUE; } else { pSysInfo->SystemPage = _PAGE_PAYFAIL; ShmDcCommonData->PayPass_flag[gunIndex] = FALSE; } } else { ShmDcCommonData->PreAuth_Config = _CREDITCARD_PREAUTHCOMPLETE; PreAuthCompleteToCardReader(fd, gunIndex); ShmDcCommonData->PreAuth_Config = _CREDITCARD_IDLE; } ShmDcCommonData->StopCharge[gunIndex] = FALSE; } } } // for if (ShmDcCommonData->PreAuth_Config == _CREDITCARD_SALE /*&& ShmDcCommonData->pGunInfo[pSysInfo->CurGunSelected].isParking*/) { sel_gun = pSysInfo->CurGunSelected; ShmDcCommonData->PreAuth_Result = 0; storeParkingPayResult(sel_gun); ShmDcCommonData->PreAuth_Result = CreditCardSale(fd,(int)ShmDcCommonData->ParkingInfo[sel_gun].Amount, &pSysConfig->ModelName[0], &ShmDcCommonData->ParkingInfo[sel_gun].pCreditCard); StopSystemTimeoutDet(); //Timeout_ScanCard getParkingPayResult(sel_gun); if (ShmDcCommonData->PreAuth_Result > 0 ) { log_info("Gun%d Parking Fee Sale Success",sel_gun); pSysInfo->SystemPage = _PAGE_PLUGIN; ShmDcCommonData->ParkingInfo[sel_gun].IsUpload = FALSE; //ShmDcCommonData->pGunInfo[sel_gun].GetParkingBill = FALSE; ShmDcCommonData->ParkingInfo[sel_gun].DeductResult = _DEDUCT_SALE_PASS; InsertParkingDeductInfo(ShmDcCommonData->ConnectorID[sel_gun], &ShmDcCommonData->ParkingInfo[sel_gun]); } else { log_info("Gun%d Parking Fee Sale Fail",sel_gun); if (!ShmDcCommonData->TradeCancel) { pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL; } } ShmDcCommonData->PreAuth_Result = 0; ShmDcCommonData->PreAuth_Config = _CREDITCARD_IDLE; } else if(ShmDcCommonData->PreAuth_Config == _CREDITCARD_CANCEL) { // 取消預授權 CreditCardCancelPreAuth(fd,pSysInfo->CurGunSelected); } else if (ShmDcCommonData->PreAuth_Config == _CREDITCARD_PREAUTH ) { // 預授權 sel_gun = pSysInfo->CurGunSelected; if (ShmDcCommonData->pGunInfo[sel_gun].isParking) { log_info("In Parking Status can't enable PreAuth function"); pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL; ShmDcCommonData->AuthPass_flag[gunIndex] = FALSE; ShmDcCommonData->PreAuth_Config = _CREDITCARD_IDLE; } else PreAuthCreditCard(fd,sel_gun); // 佔位費預授權並扣款 /* if (ShmDcCommonData->PreAuth_Result > 0 ) { log_info("Gun%d Parking Fee PreAuthComplete Success",sel_gun); pSysInfo->SystemPage = _PAGE_PLUGIN; StartSystemTimeoutDet(Timeout_ReturnViewPage); } else { log_info("Gun%d Parking Fee PreAuthComplete Fail",sel_gun); if (!ShmDcCommonData->TradeCancel) { pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL; StartSystemTimeoutDet(Timeout_VerifyFail); } } if (ShmDcCommonData->pGunInfo[sel_gun].ParkingStatus && ShmDcCommonData->PreAuth_Result > 0 && !ShmDcCommonData->TradeCancel && ShmDcCommonData->PreAuth_Config != _CREDITCARD_CANCEL ) { ShmDcCommonData->PreAuth_Result = 0; sleep(10); PreAuthCompleteToCardReader(fd, sel_gun); if (ShmDcCommonData->PreAuth_Result > 0 ) { log_info("Gun%d Parking Fee PreAuthComplete Success",sel_gun); pSysInfo->SystemPage = _PAGE_PLUGIN; StartSystemTimeoutDet(Timeout_ReturnViewPage); } else { log_info("Gun%d Parking Fee PreAuthComplete Fail",sel_gun); if (!ShmDcCommonData->TradeCancel) { pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL; StartSystemTimeoutDet(Timeout_VerifyFail); } } ShmDcCommonData->PreAuth_Result = 0; }*/ } // 每30分鐘檢查補扣款 if (tm->tm_min %30 == 0 && tm->tm_sec == 0) { ShmDcCommonData->RoutineReduct = FALSE; } if ((is_idle == TRUE && pSysInfo->SystemPage == _PAGE_IDLE && ShmDcCommonData->RoutineReduct == FALSE) || ShmDcCommonData->Exe_ReDeduct) { ReDeductProcess(fd); pSysInfo->SystemPage = _PAGE_IDLE; ShmDcCommonData->CreditCardUpload = FALSE; ShmDcCommonData->Exe_ReDeduct = 0; } // 每日晚上11點30分結帳 if (is_idle == TRUE && pSysInfo->SystemPage == _PAGE_IDLE && ((tm->tm_hour == 15 && tm->tm_min > 30 && ShmDcCommonData->RoutineSettlement == FALSE) || ShmDcCommonData->UnionSettlement)) { StopSystemTimeoutDet(); if (ShmDcCommonData->UnionSettlement) ShmDcCommonData->UnionSettlement = 0; else ShmDcCommonData->RoutineSettlement = TRUE; ShmDcCommonData->CreditCardUpload = TRUE; pSysInfo->SystemPage = _PAGE_PAYING; result = CreditCardUnionSettlement(fd, &pSysConfig->ModelName[0], &LocalTransactionInfo.pCreditCard); if (result > 0) { log_info("CreditCardUnionSettlement OK"); } else log_info("CreditCardUnionSettlement FAIL"); sleep(90); pSysInfo->SystemPage = _PAGE_IDLE; ShmDcCommonData->CreditCardUpload = FALSE; } if (tm->tm_hour == 16 && tm->tm_min == 0) { ShmDcCommonData->RoutineSettlement = FALSE; } } } }