diff --git a/src/iedModbus_mgr.sln b/src/iedModbus_mgr.sln index 1eb53ff..c580068 100644 --- a/src/iedModbus_mgr.sln +++ b/src/iedModbus_mgr.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.7.34018.315 +# Visual Studio 15 +VisualStudioVersion = 15.0.34112.143 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iedModbus_mgr", "iedModbus_mgr\iedModbus_mgr.vcxproj", "{01724C4F-628B-45B7-B0FF-B147D6D9D921}" EndProject @@ -13,8 +13,8 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {01724C4F-628B-45B7-B0FF-B147D6D9D921}.Debug|x64.ActiveCfg = Debug|x64 - {01724C4F-628B-45B7-B0FF-B147D6D9D921}.Debug|x64.Build.0 = Debug|x64 + {01724C4F-628B-45B7-B0FF-B147D6D9D921}.Debug|x64.ActiveCfg = Release|Win32 + {01724C4F-628B-45B7-B0FF-B147D6D9D921}.Debug|x64.Build.0 = Release|Win32 {01724C4F-628B-45B7-B0FF-B147D6D9D921}.Debug|x86.ActiveCfg = Debug|Win32 {01724C4F-628B-45B7-B0FF-B147D6D9D921}.Debug|x86.Build.0 = Debug|Win32 {01724C4F-628B-45B7-B0FF-B147D6D9D921}.Release|x64.ActiveCfg = Release|x64 diff --git a/src/iedModbus_mgr/iedModbus_mgr.cpp b/src/iedModbus_mgr/iedModbus_mgr.cpp index cb26b6e..5edca1d 100644 --- a/src/iedModbus_mgr/iedModbus_mgr.cpp +++ b/src/iedModbus_mgr/iedModbus_mgr.cpp @@ -29,7 +29,7 @@ int main(int argc, char** argv) xProcess_unique(); - std::cout << "RUN YSP MONITOR APP! V1.11-x86\n"; + std::cout << "RUN YSP MONITOR APP! V1.12-x86\n"; #if 1 //com_test 用来开发测试 发布时不起作用 if (argc > 1) { diff --git a/src/iedModbus_mgr/yspConfig.ini b/src/iedModbus_mgr/yspConfig.ini index 1699994..499dd13 100644 --- a/src/iedModbus_mgr/yspConfig.ini +++ b/src/iedModbus_mgr/yspConfig.ini @@ -1,5 +1,5 @@ [MODBUS] -SLAVE_IP_ADDR=192.168.50.154 +SLAVE_IP_ADDR=192.168.50.155 SLAVE_PORT=502 [ALERT] H2_THRESHOLD = 120 @@ -18,5 +18,5 @@ C2H4_alert=1 C2H6_alert=1 [MONITOR] -GAS_MONITOR_PERIOD = 1 +GAS_MONITOR_PERIOD = 33 diff --git a/src/iedModbus_mgr/ysp_modbus_slave.cpp b/src/iedModbus_mgr/ysp_modbus_slave.cpp index 74c2c5d..59ea2b4 100644 --- a/src/iedModbus_mgr/ysp_modbus_slave.cpp +++ b/src/iedModbus_mgr/ysp_modbus_slave.cpp @@ -2,6 +2,8 @@ #include "modbus_lib/modbus-tcp.h" #include "ysp_modbus_slave.h" #include "database/database.h" +# include +# include using namespace std; #define REG_ADDR (header_length+1) @@ -9,7 +11,7 @@ using namespace std; #define REG_VAL (header_length+3) #define IP_LOCAL_ADDR "192.168.1.21" -#define TCP_PORT 1502 +#define TCP_PORT 502 #define MODBUS_UART "COM3" //Ŀò uart modbus #define SERVER_ID 0x00000001 //Ĭϴӻַ #define SLAVE_REG_ADDR 0x008E //ӻmodbus ַļĴַ @@ -67,7 +69,7 @@ void xSet_slave_port(const char* tcp_port) DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { char* com = (char*)lp; CHAR rcv_buf[1024] = { 0 }; - int s = -1; + int s = -1,sockt=-1,extrasock=-1; int i = 0; int rc = 0; modbus_t* ctx = NULL; @@ -78,7 +80,11 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { uint16_t reg_addr, reg_val, reg_num; uint16_t tmp = 0; modbus_mapping_t* mb_mapping; - + fd_set fdset_ro, fdset_wr, fdset_ex; + struct timeval timeout; + struct sockaddr_in addr; + socklen_t addrlen; + //struct tcp_info info; /* һֻһmaster @@ -90,7 +96,7 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { //modbus_set_slave(ctx, SERVER_ID); } else if (use_backend == TCP_PI) { - ctx = modbus_new_tcp_pi(slave_ip_addr, "1502"); + ctx = modbus_new_tcp_pi(slave_ip_addr, "502"); } else { ctx = modbus_new_rtu(MODBUS_UART, 115200, 'N', 8, 1); @@ -109,156 +115,256 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { modbus_free(ctx); return -1; } - if (use_backend == TCP) { - std::cout << "modbus start listen\n" << std::endl; - s = modbus_tcp_listen(ctx, 1); - if (-1 == s) { - std::cout << "modbus tcp listen fial,check ip or port,exit thread\n" << std::endl; - return -1; - } - } - else if (use_backend == TCP_PI) { - s = modbus_tcp_pi_listen(ctx, 1); - } - else { -#if 0 - rc = modbus_connect(ctx); - if (rc == -1) { - fprintf(stderr, "Unable to connect %s\n", modbus_strerror(errno)); - modbus_free(ctx); - return -1; - } -#endif - } - - for (;;) { + for(;;){ if (use_backend == TCP) { - std::cout << std::endl << "modbus accept wait connect (hold)\n" << std::endl; - modbus_tcp_accept(ctx, &s); - std::cout << "modbus accept new connect\n" << std::endl; + if (s < 0) { + std::cout << "modbus start listen\n" << std::endl; + s = modbus_tcp_listen(ctx, 1); + if (-1 == s) { + std::cout << "modbus tcp listen fial,check ip or port,exit thread\n" << std::endl; + return -1; + } + } } else if (use_backend == TCP_PI) { - modbus_tcp_pi_accept(ctx, &s); - } - else { - rc = modbus_connect(ctx); - if (rc == -1) { - fprintf(stderr, "Unable to connect %s\n", modbus_strerror(errno)); - modbus_free(ctx); - return -1; + if (s < 0) { + s = modbus_tcp_pi_listen(ctx, 1); } } - std::cout << "modbus receive loop\n" << std::endl; - for (;;) {//ѭϢ - do { - rc = modbus_receive(ctx, query); - /* Filtered queries return 0 */ - } while (rc == 0);//ַ᷵0,CRC᷵-1errno=EMBBADCRC,᷵ؽյֽ - - /* The connection is not closed on errors which require on reply such as - bad CRC in RTU. */ - if (rc == -1 && errno != EMBBADCRC) { - /* Quit */ - std::cout << "error once connect over 1" << std::endl; - break; - } - if (rc == -1) - { - if (errno == EMBBADCRC) + + for (;;) { + if (use_backend == TCP) { + if (s < 0) + break; + FD_ZERO(&fdset_ro); + FD_ZERO(&fdset_wr); + FD_ZERO(&fdset_ex); + FD_SET(s, &fdset_ro); + FD_SET(s, &fdset_wr); + FD_SET(s, &fdset_ex); + memset((char*)&timeout, 0, sizeof(struct timeval)); + if (select(s + 1, &fdset_ro, &fdset_wr, &fdset_ex, &timeout) < 1) { - std::cout << "bad crc in query" << std::endl; + Sleep(1); continue; } - else + if (FD_ISSET(s, &fdset_ex)) { - std::cout << "parse modbus frame error: %s\n" << std::endl; - std::cout << "error once connect over 2" << std::endl; + //printf("رշ˿\n"); + closesocket(s); + s = -1; break; } + else if (FD_ISSET(s, &fdset_ro)) + { + std::cout << std::endl << "modbus accept wait connect (hold)\n" << std::endl; + sockt = modbus_tcp_accept(ctx, &s); + std::cout << "modbus accept new connect\n" << std::endl; + } + } + else if (use_backend == TCP_PI) { + modbus_tcp_pi_accept(ctx, &s); } - std::cout << "modbus new msg\n" << std::endl; - switch (query[header_length]) - { - case MODBUS_FC_READ_COILS://0x01 Read Coils in mb_mapping->tab_bitsIO״̬ - printf("unsurported function 2\n"); - //Ӧ,ݲӳ - modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_ILLEGAL_FUNCTION); - break; - case MODBUS_FC_READ_DISCRETE_INPUTS://0x02 Read Discrete Inputs in mb_mapping->tab_input_bitsIO״̬ - printf("unsurported function 2\n"); - //Ӧ,ݲӳ - modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_ILLEGAL_FUNCTION); - continue; - break; - case MODBUS_FC_READ_HOLDING_REGISTERS://0x03 Read Holding Registers in mb_mapping->tab_registers:REG - //Ĵ - std::cout << "modbus function 0x03\n" << std::endl; - if (MODBUS_GET_INT16_FROM_INT8(query, REG_ADDR) < (sizeof(ysp_modbus_regs_t) / 2 + sizeof(slave_add_t) / 2)) + std::cout << "modbus receive loop\n" << std::endl; + for (;;) {//ѭϢ +#if 1 + if (s < 0) + break; + FD_ZERO(&fdset_ro); + FD_ZERO(&fdset_wr); + FD_ZERO(&fdset_ex); + FD_SET(s, &fdset_ro); + FD_SET(s, &fdset_wr); + FD_SET(s, &fdset_ex); + memset((char*)&timeout, 0, sizeof(struct timeval)); + if (select(s + 1, &fdset_ro, &fdset_wr, &fdset_ex, &timeout) < 1) { - printf("reg vaild\n"); - //ȡʵʱ - if ((MODBUS_GET_INT16_FROM_INT8(query, REG_ADDR) + MODBUS_GET_INT16_FROM_INT8(query, REG_NUM)) > (sizeof(ysp_modbus_regs_t) / 2)+ (sizeof(slave_add_t) / 2)) - { - printf("reply to this special register address by an exception\n"); - //Ӧ - modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS); - continue; + //Sleep(1); + //continue; /* ʱcontinue*/ + }else if (FD_ISSET(s, &fdset_ex)) + { + //printf("رշ˿\n"); + closesocket(s); + s = -1; + break; + } + else if (FD_ISSET(s, &fdset_ro))// accept(*s, (struct sockaddr *) &addr, &addrlen); +#endif + { + //std::cout << std::endl << "second accept wait connect (hold)\n" << std::endl; + extrasock = accept(s, (struct sockaddr *) &addr, &addrlen); + //std::cout << "second accept new connect\n" << std::endl; + if (extrasock < 0) + ; + else { + if (sockt < 0) { + sockt = extrasock; + extrasock = -1; + } + else { + closesocket(extrasock); + extrasock = -1; + } } - printf("update data\n"); - // - if (fill_ysp_data(&ysp_modbus_data)) { - printf("get data from database fail, erase regs\n"); - //memset(&ysp_modbus_data, 0, sizeof(&ysp_modbus_data)); ظϴν + } + + if (NULL == ctx) + return 0; + if (0 > sockt) + break; + FD_ZERO(&fdset_ro); + FD_ZERO(&fdset_wr); + FD_ZERO(&fdset_ex); + FD_SET(sockt, &fdset_ro); + FD_SET(sockt, &fdset_wr); + FD_SET(sockt, &fdset_ex); + memset((char*)&timeout, 0, sizeof(struct timeval)); + if (select(sockt + 1, &fdset_ro, &fdset_wr, &fdset_ex, &timeout) < 1) + { + Sleep(1); + continue; + } + if (FD_ISSET(sockt, &fdset_ex)) + { + //printf("ر׽\n"); + closesocket(sockt); + sockt = -1; + break; + } + if (FD_ISSET(sockt, &fdset_ro)) // ɶ + { + do { + rc = modbus_receive(ctx, query); + /* Filtered queries return 0 */ + } while (rc == 0);//ַ᷵0,CRC᷵-1errno=EMBBADCRC,᷵ؽյֽ + + /* The connection is not closed on errors which require on reply such as + bad CRC in RTU. */ + if (rc == -1 && errno != EMBBADCRC) { + /* Quit */ + closesocket(sockt); + sockt = -1; + std::cout << "error once connect over 1" << std::endl; + break; } - printf("time h32:%d\n", ysp_modbus_data.time_H32); - printf("time l32:%d\n", ysp_modbus_data.time_L32); - ptr = (uint16_t*)&ysp_modbus_data; - for (i = 0; i < (sizeof(ysp_modbus_regs_t) / 2); i++) + if (rc == -1) { - mb_mapping->tab_registers[i] = ptr[i]; + if (errno == EMBBADCRC) + { + std::cout << "bad crc in query" << std::endl; + continue; + } + else + { + closesocket(sockt); + sockt = -1; + std::cout << "parse modbus frame error: %s\n" << std::endl; + std::cout << "error once connect over 2" << std::endl; + break; + } } - ptr1 = (uint16_t*)&salve_addr; - mb_mapping->tab_registers[i] = ptr1[1];//iԽСԽȴ - mb_mapping->tab_registers[i+1] = ptr1[0];//ptr1[0] ǵ͵ַ - //mb_mapping->tab_registers[i] =0x3344; - //mb_mapping->tab_registers[i+1] = 0x5566; } - break; - case MODBUS_FC_READ_INPUT_REGISTERS://0x04 Read Input Registers in mb_mapping->tab_input_registers:REG - //ڶȡֵȲλ޸ĵ,ݲӳ - break; - case MODBUS_FC_WRITE_SINGLE_COIL://0x05 Write Single Coil:slave_addr+cmd+reg_addr+[FF 00 or 00 00]+crc corresponding to mb_mapping->tab_bits - //д̵ - break; - case MODBUS_FC_WRITE_SINGLE_REGISTER://0x06 Write Single Register:slave_addr+cmd+reg_addr+reg_val+crc corresponding to mb_mapping->tab_registers - //дĴ,ݲӳ - printf("function code 0x06\n"); - reg_addr = MODBUS_GET_INT16_FROM_INT8(query, REG_ADDR); - reg_val = MODBUS_GET_INT16_FROM_INT8(query, REG_VAL); - printf( "reg_addr=%d reg_val=0x%04x\n", reg_addr, reg_val); - if (reg_addr == SLAVE_REG_ADDR) + else { - printf("modify slave address succ\n"); - salve_addr.slave_addr = reg_val; + //int len = sizeof(info); + //getsockopt(sockt, IPPROTO_TCP, TCP_INFO, &info, (socklen t *)&len);if (info.tcpi state == TCP CLOSE WAIT && info.tcpi state != TCP ESTABLISHED) + rc = recv(sockt, rcv_buf, 1,0); + if (rc <= 0) + { + if (errno == ETIMEDOUT) + { + closesocket(sockt); + sockt = -1; + printf("Client TCP may unexpectedly interrupt!\n"); + } + } + continue; } - break; - case MODBUS_FC_WRITE_MULTIPLE_COILS://0x0F Write Multiple Coils:slave_addr+cmd+reg_addr+coil_num+bit_arr+crc corresponding to mb_mapping->tab_bits - //д̵,ݲӳ - break; - case MODBUS_FC_WRITE_MULTIPLE_REGISTERS://0x10 Write Multiple Registers:slave_addr+cmd+reg_addr+reg_num+reg_val_arr+crc corresponding to mb_mapping->tab_registers - //дĴ - break; - default:// - break; - } - //Ӧ - rc = modbus_reply(ctx, query, rc, mb_mapping); - if (rc == -1) { - printf("reply modbus frame error:%s\n", modbus_strerror(errno)); - break; + std::cout << "modbus new msg\n" << std::endl; + switch (query[header_length]) + { + case MODBUS_FC_READ_COILS://0x01 Read Coils in mb_mapping->tab_bitsIO״̬ + printf("unsurported function 2\n"); + //Ӧ,ݲӳ + modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_ILLEGAL_FUNCTION); + break; + case MODBUS_FC_READ_DISCRETE_INPUTS://0x02 Read Discrete Inputs in mb_mapping->tab_input_bitsIO״̬ + printf("unsurported function 2\n"); + //Ӧ,ݲӳ + modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_ILLEGAL_FUNCTION); + continue; + break; + case MODBUS_FC_READ_HOLDING_REGISTERS://0x03 Read Holding Registers in mb_mapping->tab_registers:REG + //Ĵ + std::cout << "modbus function 0x03\n" << std::endl; + if (MODBUS_GET_INT16_FROM_INT8(query, REG_ADDR) < (sizeof(ysp_modbus_regs_t) / 2 + sizeof(slave_add_t) / 2)) + { + printf("reg vaild\n"); + //ȡʵʱ + if ((MODBUS_GET_INT16_FROM_INT8(query, REG_ADDR) + MODBUS_GET_INT16_FROM_INT8(query, REG_NUM)) > (sizeof(ysp_modbus_regs_t) / 2) + (sizeof(slave_add_t) / 2)) + { + printf("reply to this special register address by an exception\n"); + //Ӧ + modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS); + continue; + } + printf("update data\n"); + // + if (fill_ysp_data(&ysp_modbus_data)) { + printf("get data from database fail, erase regs\n"); + //memset(&ysp_modbus_data, 0, sizeof(&ysp_modbus_data)); ظϴν + } + printf("time h32:%d\n", ysp_modbus_data.time_H32); + printf("time l32:%d\n", ysp_modbus_data.time_L32); + ptr = (uint16_t*)&ysp_modbus_data; + for (i = 0; i < (sizeof(ysp_modbus_regs_t) / 2); i++) + { + mb_mapping->tab_registers[i] = ptr[i]; + } + ptr1 = (uint16_t*)&salve_addr; + mb_mapping->tab_registers[i] = ptr1[1];//iԽСԽȴ + mb_mapping->tab_registers[i + 1] = ptr1[0];//ptr1[0] ǵ͵ַ + //mb_mapping->tab_registers[i] =0x3344; + //mb_mapping->tab_registers[i+1] = 0x5566; + } + break; + case MODBUS_FC_READ_INPUT_REGISTERS://0x04 Read Input Registers in mb_mapping->tab_input_registers:REG + //ڶȡֵȲλ޸ĵ,ݲӳ + break; + case MODBUS_FC_WRITE_SINGLE_COIL://0x05 Write Single Coil:slave_addr+cmd+reg_addr+[FF 00 or 00 00]+crc corresponding to mb_mapping->tab_bits + //д̵ + break; + case MODBUS_FC_WRITE_SINGLE_REGISTER://0x06 Write Single Register:slave_addr+cmd+reg_addr+reg_val+crc corresponding to mb_mapping->tab_registers + //дĴ,ݲӳ + printf("function code 0x06\n"); + reg_addr = MODBUS_GET_INT16_FROM_INT8(query, REG_ADDR); + reg_val = MODBUS_GET_INT16_FROM_INT8(query, REG_VAL); + printf("reg_addr=%d reg_val=0x%04x\n", reg_addr, reg_val); + if (reg_addr == SLAVE_REG_ADDR) + { + printf("modify slave address succ\n"); + salve_addr.slave_addr = reg_val; + } + break; + case MODBUS_FC_WRITE_MULTIPLE_COILS://0x0F Write Multiple Coils:slave_addr+cmd+reg_addr+coil_num+bit_arr+crc corresponding to mb_mapping->tab_bits + //д̵,ݲӳ + break; + case MODBUS_FC_WRITE_MULTIPLE_REGISTERS://0x10 Write Multiple Registers:slave_addr+cmd+reg_addr+reg_num+reg_val_arr+crc corresponding to mb_mapping->tab_registers + //дĴ + break; + default:// + break; + } + + //Ӧ + rc = modbus_reply(ctx, query, rc, mb_mapping); + if (rc == -1) { + printf("reply modbus frame error:%s\n", modbus_strerror(errno)); + break; + } } - } + } }