|
|
|
@ -2,6 +2,8 @@
|
|
|
|
|
#include "modbus_lib/modbus-tcp.h"
|
|
|
|
|
#include "ysp_modbus_slave.h"
|
|
|
|
|
#include "database/database.h"
|
|
|
|
|
# include <winsock2.h>
|
|
|
|
|
# include <ws2tcpip.h>
|
|
|
|
|
|
|
|
|
|
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,7 +115,9 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
modbus_free(ctx);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
for(;;){
|
|
|
|
|
if (use_backend == TCP) {
|
|
|
|
|
if (s < 0) {
|
|
|
|
|
std::cout << "modbus start listen\n" << std::endl;
|
|
|
|
|
s = modbus_tcp_listen(ctx, 1);
|
|
|
|
|
if (-1 == s) {
|
|
|
|
@ -117,39 +125,114 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (use_backend == TCP_PI) {
|
|
|
|
|
if (s < 0) {
|
|
|
|
|
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 (;;) {
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
Sleep(1);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (FD_ISSET(s, &fdset_ex))
|
|
|
|
|
{
|
|
|
|
|
//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;
|
|
|
|
|
modbus_tcp_accept(ctx, &s);
|
|
|
|
|
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 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)
|
|
|
|
|
{
|
|
|
|
|
//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 {
|
|
|
|
|
rc = modbus_connect(ctx);
|
|
|
|
|
if (rc == -1) {
|
|
|
|
|
fprintf(stderr, "Unable to connect %s\n", modbus_strerror(errno));
|
|
|
|
|
modbus_free(ctx);
|
|
|
|
|
return -1;
|
|
|
|
|
if (sockt < 0) {
|
|
|
|
|
sockt = extrasock;
|
|
|
|
|
extrasock = -1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
closesocket(extrasock);
|
|
|
|
|
extrasock = -1;
|
|
|
|
|
}
|
|
|
|
|
std::cout << "modbus receive loop\n" << std::endl;
|
|
|
|
|
for (;;) {//Ñ»·½ÓÊÜÏûÏ¢
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 */
|
|
|
|
@ -159,6 +242,8 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
bad CRC in RTU. */
|
|
|
|
|
if (rc == -1 && errno != EMBBADCRC) {
|
|
|
|
|
/* Quit */
|
|
|
|
|
closesocket(sockt);
|
|
|
|
|
sockt = -1;
|
|
|
|
|
std::cout << "error once connect over 1" << std::endl;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -171,11 +256,31 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cout << "modbus new msg\n" << std::endl;
|
|
|
|
|
switch (query[header_length])
|
|
|
|
|
{
|
|
|
|
@ -259,6 +364,7 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|