/* * Module_Cabinet.c * * Created on: 2021/10/25 * Author: folus */ #include "Module_Cabinet.h" //#define DEBUG #define is_error(ptr) ((unsigned long)ptr > (unsigned long)-4000L) #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define PASS 1 #define FAIL -1 #define YES 1 #define NO 0 #define ON 1 #define OFF 0 struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct PrimaryMcuData *ShmPrimaryMcuData; struct Charger *ShmCharger; struct CABINET *ShmCabinet; struct DISPENSER *ShmDispenser; /** * * @param fmt * @return */ int StoreLogMsgServer(const char *fmt, ...) { char Buf[4096+256]; char buffer[4096]; time_t CurrentTime; struct tm *tm; struct timeval tv; va_list args; va_start(args, fmt); int rc = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); memset(Buf,0,sizeof(Buf)); CurrentTime = time(NULL); tm=localtime(&CurrentTime); gettimeofday(&tv, NULL); // get microseconds, 10^-6 sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]CabinetServerLog", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer, tm->tm_year+1900,tm->tm_mon+1); #ifdef SystemLogMessage system(Buf); #endif #ifdef ConsloePrintLog printf("[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer); #endif return rc; } /** * * @param fmt * @return */ int StoreLogMsgCient(const char *fmt, ...) { char Buf[4096+256]; char buffer[4096]; time_t CurrentTime; struct tm *tm; struct timeval tv; va_list args; va_start(args, fmt); int rc = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); memset(Buf,0,sizeof(Buf)); CurrentTime = time(NULL); tm=localtime(&CurrentTime); gettimeofday(&tv, NULL); // get microseconds, 10^-6 sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]CabinetClinetLog", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer, tm->tm_year+1900,tm->tm_mon+1); #ifdef SystemLogMessage system(Buf); #endif #ifdef ConsloePrintLog printf("[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer); #endif return rc; } /** * Init all share memory * @return */ int InitShareMemory() { int result = PASS; int MeterSMId; //Initial ShmSysConfigAndInfo if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0) { DEBUG_SERVER_ERROR("shmget ShmSysConfigAndInfo NG\n"); result = FAIL; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_SERVER_ERROR("shmat ShmSysConfigAndInfo NG\n"); result = FAIL; } else {} //Initial ShmStatusCodeData if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0) { DEBUG_SERVER_ERROR("shmget ShmStatusCodeData NG\n"); result = FAIL; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_SERVER_ERROR("shmat ShmStatusCodeData NG\n"); result = FAIL; } else {} //Initial ShmCharger if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), 0777)) < 0) { DEBUG_SERVER_ERROR("shmget ShmCharger NG\n"); result = FAIL; } else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_SERVER_ERROR("shmat ShmCharger NG\n"); result = FAIL; } //Initial ShmSDispenser if ((MeterSMId = shmget(ShmDispenserKey, sizeof(struct DISPENSER), 0777)) < 0) { DEBUG_SERVER_ERROR("shmget ShmSDispenser NG\n"); result = FAIL; } else if ((ShmDispenser = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_SERVER_ERROR("shmat ShmSDispenser NG\n"); result = FAIL; } //Create ShmCabinet if ((MeterSMId = shmget(ShmCabinetKey, sizeof(struct CABINET), IPC_CREAT | 0777)) < 0) { DEBUG_SERVER_ERROR("shmget ShmCabinet NG\n"); result = FAIL; } else if ((ShmCabinet = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_SERVER_ERROR("shmat ShmCabinet NG\n"); result = FAIL; } memset(ShmCabinet,0,sizeof(struct CABINET)); for(uint8_t idx=0;idxConnection_Info[idx].socketFd = (idx+1); return result; } /** * Cabinet socket server * @param data * @param len * @param isRX */ void dM_Server(uint8_t *data, uint16_t len, uint8_t isRX) { #ifdef DEBUG uint8_t output[16384]; if(isRX) { DEBUG_SERVER_INFO("= RX ===========================================\n"); } else { DEBUG_SERVER_INFO("= TX ===========================================\n"); } memset(output, 0x00, ARRAY_SIZE(output)); for(uint16_t idx=0;idx<16;idx++) sprintf((char*)output, "%s %02X", output, idx); DEBUG_SERVER_INFO("%s\n", output); DEBUG_SERVER_INFO("================================================\n"); for(uint16_t idx = 0;idx0) { sprintf((char*)output, "%s %02X", output, data[idx]); } else { if(idx != 0) DEBUG_SERVER_INFO("%s\n", output); memset(output, 0x00, ARRAY_SIZE(output)); sprintf((char*)output, "%s %02X", output, data[idx]); } } DEBUG_SERVER_INFO("%s\n", output); DEBUG_SERVER_INFO("------------------------------------------------\n"); #endif } /** * Cabinet socket server * @param data * @param len * @param isRX */ void dM_Client(uint8_t *data, uint16_t len, uint8_t isRX) { #ifdef DEBUG uint8_t output[16384]; if(isRX) { DEBUG_CLIENT_INFO("= RX ===========================================\n"); } else { DEBUG_CLIENT_INFO("= TX ===========================================\n"); } memset(output, 0x00, ARRAY_SIZE(output)); for(uint16_t idx=0;idx<16;idx++) sprintf((char*)output, "%s %02X", output, idx); DEBUG_CLIENT_INFO("%s\n", output); DEBUG_CLIENT_INFO("================================================\n"); for(uint16_t idx = 0;idx0) { sprintf((char*)output, "%s %02X", output, data[idx]); } else { if(idx != 0) DEBUG_CLIENT_INFO("%s\n", output); memset(output, 0x00, ARRAY_SIZE(output)); sprintf((char*)output, "%s %02X", output, data[idx]); } } DEBUG_CLIENT_INFO("%s\n", output); DEBUG_CLIENT_INFO("------------------------------------------------\n"); #endif } /** * * @param message * @return */ int isValidCheckSum(struct CABINET_Message *message) { uint8_t chksum = 0x00; for(uint16_t idx=0;idx<((((message->buffer[1]<<8) | message->buffer[2])+4)>ARRAY_SIZE(message->buffer)?ARRAY_SIZE(message->buffer):(((message->buffer[1]<<8) | message->buffer[2])+4));idx++) { chksum ^= message->buffer[idx]; } return ((chksum == message->buffer[((((message->buffer[1]<<8) | message->buffer[2])+4)>ARRAY_SIZE(message->buffer)?ARRAY_SIZE(message->buffer):(((message->buffer[1]<<8) | message->buffer[2])+4))]) ? PASS : FAIL); } /** * * @param message * @return */ uint8_t chksumCal(struct CABINET_Message *message) { uint8_t chksum=0; for(uint16_t idx=0;idx<((((message->buffer[1]<<8) | message->buffer[2])+4)>ARRAY_SIZE(message->buffer)?ARRAY_SIZE(message->buffer):(((message->buffer[1]<<8) | message->buffer[2])+4));idx++) { chksum ^= message->buffer[idx]; } return chksum & 0xff; } /** * * @return */ int conn_getConectedQuantity(void) { int result = 0; for(uint8_t idx=0;idxConnection_Info[idx].isSocketConnected) { result += 1; } } DEBUG_SERVER_INFO("Connection quantity: %d\n", result); ShmCabinet->connectedQty = result; return result; } /** * * @return */ int conn_getDupFd(void) { int result = 0; for(uint8_t idx=0;idxConnection_Info[idx].isSocketConnected) { result = ShmCabinet->Connection_Info[idx].socketFd; break; } } return result; } /** * * @param socketFd * @return */ int conn_register(int socketFd) { int result = FAIL; for(uint8_t idx=0;idxConnection_Info[idx].isSocketConnected) { DEBUG_SERVER_INFO("Dupfd-%d register to conn-%d.\n", socketFd, idx); ShmCabinet->Connection_Info[idx].isSocketConnected = TRUE; ShmCabinet->Connection_Info[idx].socketFd = socketFd; ShmCabinet->Connection_Info[idx].lastHeartBeatTime = time((time_t*)NULL); result = PASS; break; } } return result; } /** * * @param socketFd * @return */ int conn_reject(int socketFd) { int result = FAIL; for(uint8_t idx=0;idxConnection_Info[idx].socketFd == socketFd) { DEBUG_SERVER_INFO("Dupfd-%d register from conn_info-%d.\n", socketFd, idx); ShmCabinet->Connection_Info[idx].isSocketConnected = FALSE; result = PASS; break; } } return result; } /** * * @param socketFd * @return */ int conn_updateHeartBeatTime(int socketFd) { int result = FAIL; for(uint8_t idx=0;idxConnection_Info[idx].socketFd == socketFd) { //DEBUG_INFO("Dupfd-%d register from conn_info-%d update heart beat time.\n", socketFd, idx); ShmCabinet->Connection_Info[idx].lastHeartBeatTime = time((time_t*)NULL); result = PASS; break; } } return result; } /** * * @param socketFd * @param gun_index * @param infoData * @return */ int conn_updateGunInfo(int socketFd, int gun_index, Gun_Info *infoData) { int result = FAIL; Gun_Info gunInfo; for(uint8_t idx=0;idxConnection_Info[idx].socketFd == socketFd) { memcpy(&gunInfo, infoData, sizeof(Gun_Info)); ShmCabinet->Connection_Info[idx].gun_index = gun_index; memcpy(&ShmCharger->gun_info[gun_index].primaryMcuLed, &gunInfo.primaryMcuLed, sizeof(Ac_Primary_Mcu_Led)); memcpy(&ShmCharger->gun_info[gun_index].systemAlarmCode, &gunInfo.systemAlarmCode, sizeof(System_Alarm_Code)); memcpy(&ShmCharger->gun_info[gun_index].primaryMcuAlarm, &gunInfo.primaryMcuAlarm, sizeof(Ac_Primary_Mcu_Alarm)); memcpy(&ShmCharger->gun_info[gun_index].GPIO_Input, &gunInfo.GPIO_Input, sizeof(Gpio_in)); memcpy(&ShmCharger->gun_info[gun_index].powerConsumptionTotal, &gunInfo.powerConsumptionTotal, sizeof(Power_Consumption)); memcpy(&ShmCharger->gun_info[gun_index].powerConsumption[0], &gunInfo.powerConsumption[0], ARRAY_SIZE(gunInfo.powerConsumption)*sizeof(Power_Consumption)); memcpy(&ShmCharger->gun_info[gun_index].inputVoltage, &gunInfo.inputVoltage, sizeof(PresentInputVoltage)); memcpy(&ShmCharger->gun_info[gun_index].outputCurrent, &gunInfo.outputCurrent, sizeof(Presentoutputcurrent)); memcpy(&ShmCharger->gun_info[gun_index].gunPluginTimes, &gunInfo.gunPluginTimes, sizeof(Gun_Plugin_Times)); memcpy(&ShmCharger->gun_info[gun_index].temperature, &gunInfo.temperature, sizeof(Temperature)); memcpy(&ShmCharger->gun_info[gun_index].rtc, &gunInfo.rtc, sizeof(Rtc)); memcpy(&ShmCharger->gun_info[gun_index].acCcsInfo, &gunInfo.acCcsInfo, sizeof(Ac_Ccs_Info)); memcpy(&ShmCharger->gun_info[gun_index].primaryMcuState.socket_e, &gunInfo.primaryMcuState.socket_e, sizeof(Socket_E)); ShmCharger->gun_info[gun_index].primaryMcuState.cp_state = gunInfo.primaryMcuState.cp_state; ShmCharger->gun_info[gun_index].primaryMcuState.cp_voltage_negtive = gunInfo.primaryMcuState.cp_voltage_negtive; ShmCharger->gun_info[gun_index].primaryMcuState.cp_voltage_positive = gunInfo.primaryMcuState.cp_voltage_positive; ShmCharger->gun_info[gun_index].primaryMcuState.current_limit = gunInfo.primaryMcuState.current_limit; ShmCharger->gun_info[gun_index].primaryMcuState.locker_state = gunInfo.primaryMcuState.locker_state; ShmCharger->gun_info[gun_index].primaryMcuState.meter_state = gunInfo.primaryMcuState.meter_state; ShmCharger->gun_info[gun_index].primaryMcuState.pp_state = gunInfo.primaryMcuState.pp_state; ShmCharger->gun_info[gun_index].primaryMcuState.rating_current = gunInfo.primaryMcuState.rating_current; ShmCharger->gun_info[gun_index].primaryMcuState.relay_state = gunInfo.primaryMcuState.relay_state; ShmCharger->gun_info[gun_index].primaryMcuState.rotatory_switch = gunInfo.primaryMcuState.rotatory_switch; ShmCharger->gun_info[gun_index].primaryMcuState.shutter_state = gunInfo.primaryMcuState.shutter_state; ShmCharger->gun_info[gun_index].mcuFlag.isReadFwVerPass = gunInfo.mcuFlag.isReadFwVerPass; ShmCharger->gun_info[gun_index].mcuFlag.isReadMeterIcCorrectionStatus = gunInfo.mcuFlag.isReadMeterIcCorrectionStatus; ShmCharger->gun_info[gun_index].mcuFlag.isSetModelNamePass = gunInfo.mcuFlag.isSetModelNamePass; ShmCharger->gun_info[gun_index].mcuFlag.isSetSerialNumberPass = gunInfo.mcuFlag.isSetSerialNumberPass; ShmCharger->gun_info[gun_index].mcuFlag.isMcuUpgradeReq = gunInfo.mcuFlag.isMcuUpgradeReq; ShmCharger->gun_info[gun_index].ccsHandshakeState = gunInfo.ccsHandshakeState; ShmCharger->gun_info[gun_index].isUpgradeEnd = gunInfo.isUpgradeEnd; ShmCharger->gun_info[gun_index].isUpgradePASS = gunInfo.isUpgradePASS; ShmCharger->gun_info[gun_index].isGunPlugged = gunInfo.isGunPlugged; memcpy(&ShmCharger->gun_info[gun_index].ver, &gunInfo.ver, sizeof(Ver)); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState = gunInfo.primaryMcuState.cp_state; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotDuty = (gunInfo.primaryMcuState.current_limit>51?(unsigned char)((gunInfo.primaryMcuState.current_limit/2.5)+64):(unsigned char)(gunInfo.primaryMcuState.current_limit/0.6)); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotVoltage = gunInfo.primaryMcuState.cp_voltage_positive; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].RelayK1K2Status = gunInfo.primaryMcuState.relay_state; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingVoltage = (float)gunInfo.inputVoltage.L1N_L12; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingVoltageL2 = (float)gunInfo.inputVoltage.L2N_L23; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingVoltageL3 = (float)gunInfo.inputVoltage.L3N_L31; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrent = (float)gunInfo.outputCurrent.L1N_L12[0]; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrentL2 = (float)gunInfo.outputCurrent.L2N_L23[0]; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrentL3 = (float)gunInfo.outputCurrent.L3N_L31[0]; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ConnectorTemp = gunInfo.temperature.point[0]; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedVaGain = gunInfo.meterIcCorrectionStatus.bits.isCalibratedVaGain; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedVbGain = gunInfo.meterIcCorrectionStatus.bits.isCalibratedVbGain; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedVcGain = gunInfo.meterIcCorrectionStatus.bits.isCalibratedVcGain; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedVaOffset = gunInfo.meterIcCorrectionStatus.bits.isCalibratedVaOffset; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedVbOffset = gunInfo.meterIcCorrectionStatus.bits.isCalibratedVbOffset; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedVcOffset = gunInfo.meterIcCorrectionStatus.bits.isCalibratedVcOffset; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedCaGain = gunInfo.meterIcCorrectionStatus.bits.isCalibratedCaGain; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedCbGain = gunInfo.meterIcCorrectionStatus.bits.isCalibratedCbGain; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedCcGain = gunInfo.meterIcCorrectionStatus.bits.isCalibratedCcGain; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedCaOffset = gunInfo.meterIcCorrectionStatus.bits.isCalibratedCaOffset; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedCbOffset = gunInfo.meterIcCorrectionStatus.bits.isCalibratedCbOffset; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedCcOffset = gunInfo.meterIcCorrectionStatus.bits.isCalibratedCcOffset; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedPa = gunInfo.meterIcCorrectionStatus.bits.isCalibratedPa; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedPb = gunInfo.meterIcCorrectionStatus.bits.isCalibratedPb; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].meterIcCalInfo.isCalibratedPc = gunInfo.meterIcCorrectionStatus.bits.isCalibratedPc; result = PASS; break; } } return result; } /** * * @param socketFd * @return */ int conn_getGunIndex(int socketFd) { int result = -1; for(uint8_t idx=0;idxConnection_Info[idx].socketFd == socketFd) { result = ShmCabinet->Connection_Info[idx].gun_index; } } return result; } /** * * @param out */ void create_cmd_getChargingData(struct CABINET_Message *out) { memset(out->buffer, 0, ARRAY_SIZE(out->buffer)); out->size = 5; out->buffer[0] = 0x55; out->buffer[1] = 0x00; out->buffer[2] = 0x00; out->buffer[3] = CABINET_CMD_GET_CHARGING_DATA; out->buffer[out->size-1] = chksumCal(out); dM_Server(out->buffer, out->size, FALSE); } /** * * @param out */ void create_cmd_setConfigData(struct CABINET_Message *out, int socketFd) { memset(out->buffer, 0, ARRAY_SIZE(out->buffer)); out->size = (5 + sizeof(struct SysConfigData)); out->buffer[0] = 0x55; out->buffer[1] = (sizeof(struct SysConfigData) >> 8) & 0xff; out->buffer[2] = (sizeof(struct SysConfigData) >> 0) & 0xff; out->buffer[3] = CABINET_CMD_SET_CONFIG_DATA; for(uint8_t idx=0;idxConnection_Info[idx].socketFd == socketFd) { memcpy(&out->buffer[4], &ShmSysConfigAndInfo->SysConfig, sizeof(struct SysConfigData)); break; } } out->buffer[out->size-1] = chksumCal(out); dM_Server(out->buffer, out->size, FALSE); } /** * * @param out */ void create_cmd_setGunInfo(struct CABINET_Message *out, int socketFd) { memset(out->buffer, 0, ARRAY_SIZE(out->buffer)); out->size = (5 + sizeof(Gun_Info) + sizeof(Timeout_Spec)); out->buffer[0] = 0x55; out->buffer[1] = ((sizeof(Gun_Info) + sizeof(Timeout_Spec)) >> 8) & 0xff; out->buffer[2] = ((sizeof(Gun_Info) + sizeof(Timeout_Spec)) >> 0) & 0xff; out->buffer[3] = CABINET_CMD_SET_GUNINFO; for(uint8_t idx=0;idxConnection_Info[idx].socketFd == socketFd) { memcpy(&out->buffer[4], &ShmCharger->gun_info[ShmCabinet->Connection_Info[idx].gun_index], sizeof(Gun_Info)); memcpy(&out->buffer[4+sizeof(Gun_Info)], &ShmCharger->timeoutSpec, sizeof(Timeout_Spec)); break; } } out->buffer[out->size-1] = chksumCal(out); dM_Server(out->buffer, out->size, FALSE); } /** * * @return */ int tcpSocketServerStart(void) { int sockFd = 0; int clientSockFd = 0; int dupFd = 0; struct CABINET_Message input; struct CABINET_Message output; struct sockaddr_in serverInfo, clientInfo; socklen_t addrlen = sizeof(clientInfo); sockFd = socket(AF_INET , SOCK_STREAM , 0); if(sockFd == -1) { DEBUG_SERVER_ERROR("TCP cabinet socket create fail.\n"); sleep(5); return FAIL; } bzero(&serverInfo, sizeof(struct sockaddr_in)); serverInfo.sin_family = PF_INET; serverInfo.sin_addr.s_addr = htonl(INADDR_ANY); serverInfo.sin_port = htons(CABINET_LISTEN_PORT_TCP); if(bind(sockFd, (struct sockaddr *)&serverInfo, sizeof(serverInfo)) < 0) DEBUG_SERVER_ERROR("TCP cabinet server socket bind fail.\n"); if(listen(sockFd, CABINET_CONNECTION_LIMIT) < 0) DEBUG_SERVER_ERROR("TCP cabinet server socket listen fail.\n"); else DEBUG_SERVER_INFO("TCP cabinet server listen on port %d.\n", CABINET_LISTEN_PORT_TCP); // Main loop for(;;) { clientSockFd = accept(sockFd, (struct sockaddr*) &clientInfo, &addrlen); fcntl(clientSockFd, F_SETFD, FD_CLOEXEC); DEBUG_SERVER_INFO("Client connect in.\n"); DEBUG_SERVER_INFO("clientSockFd : %d\n", clientSockFd); if(clientSockFd > 0) { if(conn_getConectedQuantity() < CABINET_CONNECTION_LIMIT) { // Fork a child process to handle the new conn if(fork()==0) { uint8_t idxStep = 0; uint8_t socketEnable = YES; struct FLAG { uint8_t isConfigured:1; }flag; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = TIMEOUT_SOCKET_RX; setsockopt(clientSockFd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv)); // Assign socket handle as available handle in conn info pool dupFd = dup2(clientSockFd, conn_getDupFd()); conn_register(dupFd); while(socketEnable) { if((input.size = recv(dupFd, input.buffer, sizeof(input.buffer), 0)) > 0) { dM_Server(input.buffer, input.size, YES); if(isValidCheckSum(&input)) { conn_updateHeartBeatTime(dupFd); memset(output.buffer, 0x00, ARRAY_SIZE(output.buffer)); switch(input.buffer[3]) { case CABINET_CMD_GET_CHARGING_DATA: conn_updateGunInfo(dupFd, input.buffer[4], (Gun_Info*)&input.buffer[5]); //DEBUG_SERVER_INFO("Get charging data response.\n"); break; case CABINET_CMD_SET_CONFIG_DATA: if(input.buffer[4]) { flag.isConfigured = ON; } else DEBUG_SERVER_INFO("Get set configuration response: %d.\n", input.buffer[4]); break; case CABINET_CMD_SET_GUNINFO: if(input.buffer[4]) { } else DEBUG_SERVER_INFO("Get set gun info response: %d.\n", input.buffer[4]); break; default: DEBUG_SERVER_WARN("Receive unknown response.\n"); break; } } else { DEBUG_SERVER_WARN("Receive response check sum error.\n"); } } else if(input.size == 0) { DEBUG_SERVER_INFO("Client disSocketConnected.\n"); conn_reject(dupFd); socketEnable = NO; close(dupFd); close(clientSockFd); fflush(stdout); } else if(input.size == -1) { // Server slave handler switch(idxStep) { case 0: create_cmd_getChargingData(&output); send(clientSockFd, output.buffer, output.size, 0); idxStep++; break; default: if(!flag.isConfigured) { create_cmd_setConfigData(&output, dupFd); send(clientSockFd, output.buffer, output.size, 0); } else { create_cmd_setGunInfo(&output, dupFd); send(clientSockFd, output.buffer, output.size, 0); ShmCharger->gun_info[conn_getGunIndex(dupFd)].mcuResetRequest.isMcuResetRequest = OFF; } idxStep = 0; break; } } } conn_getConectedQuantity(); exit(0); } else { // if parent, close the socket and go back to listening new requests close(clientSockFd); } } else { DEBUG_SERVER_WARN("Connection is over limit.\n"); output.size = 5; output.buffer[0] = 0x55; output.buffer[1] = 0x00; output.buffer[2] = 0x00; output.buffer[3] = CABINET_CMD_CONNECTION_FULL; output.buffer[output.size-1] = chksumCal(&output); send(clientSockFd, output.buffer, output.size, 0); close(clientSockFd); } } sleep(1); } return FAIL; } /** * Cabinet socket client * @return */ int tcpSocketClientStart(void) { int sockfd; struct sockaddr_in info; struct hostent *ghbn; struct timeval tv; uint8_t socketEnable; uint8_t cntSocketErr; struct CABINET_Message input; struct CABINET_Message output; bzero(&info,sizeof(info)); ghbn = gethostbyname((char*)"192.168.201.201"); info.sin_family = PF_INET; info.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)ghbn->h_addr_list[0])); info.sin_port = htons(CABINET_LISTEN_PORT_TCP); ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer = OFF; DEBUG_CLIENT_INFO("Connect to %s:%d\n", inet_ntoa(*(struct in_addr *)ghbn->h_addr_list[0]), CABINET_LISTEN_PORT_TCP); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { DEBUG_CLIENT_ERROR("Fail to create a socket."); return 0; } if(connect(sockfd, (struct sockaddr *)&info,sizeof(info)) ==-1) { DEBUG_CLIENT_ERROR("Connection error.\n"); ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer = OFF; socketEnable = OFF; } else { DEBUG_CLIENT_INFO("Connect success.\n"); tv.tv_sec = 0; tv.tv_usec = TIMEOUT_SOCKET_RX; setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv); socketEnable = ON; cntSocketErr = 0; ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer = ON; } while(socketEnable) { memset(input.buffer, 0, ARRAY_SIZE(input.buffer)); if((input.size = recv(sockfd, input.buffer, ARRAY_SIZE(input.buffer), 0)) > 0) { dM_Client(input.buffer, input.size, YES); if(isValidCheckSum(&input)) { switch(input.buffer[3]) { case CABINET_CMD_GET_CHARGING_DATA: output.size = 6 + sizeof(Gun_Info); output.buffer[0] = 0x55; output.buffer[1] = ((sizeof(Gun_Info)+1) >> 8) & 0xff; output.buffer[2] = ((sizeof(Gun_Info)+1) >> 0) & 0xff; output.buffer[3] = input.buffer[3]; output.buffer[4] = 0; // TODO: gun_index assign memcpy(&output.buffer[5], &ShmDispenser->gun_info, sizeof(Gun_Info)); output.buffer[output.size-1] = chksumCal(&output); break; case CABINET_CMD_SET_CONFIG_DATA: output.size = 6; output.buffer[0] = 0x55; output.buffer[1] = 0x00; output.buffer[2] = 0x01; output.buffer[3] = input.buffer[3]; output.buffer[4] = 0x01; output.buffer[output.size-1] = chksumCal(&output); memcpy(&ShmDispenser->ConfigData, &input.buffer[4], sizeof(struct SysConfigData)); ShmDispenser->isCcsEnable = OFF; for(uint8_t idx=0;idx<3;idx++) { if(ShmDispenser->ConfigData.ModelName[7+idx] == '7') ShmDispenser->isCcsEnable = ON; } break; case CABINET_CMD_SET_GUNINFO: output.size = 6; output.buffer[0] = 0x55; output.buffer[1] = 0x00; output.buffer[2] = 0x01; output.buffer[3] = input.buffer[3]; output.buffer[4] = 0x01; output.buffer[output.size-1] = chksumCal(&output); Gun_Info rxGunInfo; memcpy(&rxGunInfo, &input.buffer[4], sizeof(Gun_Info)); /* * TODO: * 1. Variable set to share memory */ memcpy(&ShmDispenser->timeoutSpec, &input.buffer[4+sizeof(Gun_Info)], sizeof(Timeout_Spec)); memcpy(&ShmDispenser->gun_info.primaryMcuState.relayState, &rxGunInfo.primaryMcuState.relayState, sizeof(Relay)); ShmDispenser->gun_info.mcuResetRequest.isMcuResetRequest = rxGunInfo.mcuResetRequest.isMcuResetRequest; ShmDispenser->gun_info.primaryMcuLed.mode = rxGunInfo.primaryMcuLed.mode; ShmDispenser->gun_info.isOperactive = rxGunInfo.isOperactive; ShmDispenser->gun_info.legacyRequest.isLegacyRequest = rxGunInfo.legacyRequest.isLegacyRequest; ShmDispenser->gun_info.legacyRequest.isRelayOn = rxGunInfo.legacyRequest.isRelayOn; ShmDispenser->gun_info.targetCurrent = rxGunInfo.targetCurrent; ShmDispenser->gun_info.isResetSoftReq = rxGunInfo.isResetSoftReq; ShmDispenser->gun_info.isResetHardReq = rxGunInfo.isResetHardReq; ShmDispenser->gun_info.isUpgradeReq = rxGunInfo.isUpgradeReq; break; default: DEBUG_CLIENT_WARN("Receive unknown command.\n"); output.size = 5; output.buffer[0] = 0x55; output.buffer[1] = 0x00; output.buffer[2] = 0x00; output.buffer[3] = CABINET_CMD_UNKNOWN; output.buffer[output.size-1] = chksumCal(&output); break; } } else { DEBUG_CLIENT_WARN("Receive command check sum error.\n"); output.size = 5; output.buffer[0] = 0x55; output.buffer[1] = 0x00; output.buffer[2] = 0x00; output.buffer[3] = CABINET_CMD_CHKSUM_ERROR; output.buffer[output.size-1] = chksumCal(&output); } dM_Client(output.buffer, output.size, NO); send(sockfd, output.buffer, output.size, 0); } else if(input.size == 0) { DEBUG_CLIENT_INFO("DisSocketConnected.\n"); fflush(stdout); socketEnable = OFF; } else if(input.size == -1) { if(cntSocketErr > 5) { socketEnable = OFF; DEBUG_CLIENT_ERROR("Socket error occur.\n"); } else { cntSocketErr++; } } usleep(100000); } close(sockfd); return FAIL; } /** * Main process routine * @return */ int main(void) { // Initial share memory if(InitShareMemory() == FAIL) { DEBUG_SERVER_ERROR("InitShareMemory NG\n"); if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=ON; } sleep(5); return 0; } /* * TODO: * 1. Rotary switch define change with system specification */ for(uint8_t idx=0;idx<10;idx++) { if(ShmDispenser->gun_info.primaryMcuState.cp_state == CP_STATE_UNKNOWN) break; DEBUG_SERVER_INFO("Wait CP state query...%d\n", idx); sleep(5); }; if(ShmDispenser->gun_info.primaryMcuState.rotatory_switch == ROTARY_SWITCH_E_DISPENSER) { system("/sbin/ifconfig eth0:1 192.168.201.202 netmask 255.255.255.248 up &"); } else { system("/sbin/ifconfig eth0:1 192.168.201.201 netmask 255.255.255.248 up &"); } DEBUG_SERVER_INFO("Module_Cabinet initialized...\n"); if(ShmDispenser->gun_info.primaryMcuState.rotatory_switch != ROTARY_SWITCH_E_DISPENSER) { // TCP socket server start if(fork() == 0) { if(tcpSocketServerStart() == FAIL) { DEBUG_SERVER_ERROR("TCP socket server down.\n"); return 0; } } sleep(3); } for(;;) { // Slave logic tcpSocketClientStart(); usleep(100000); } return -1; }