diff --git a/nwthread.cc b/nwthread.cc index 635cf86..ac25229 100644 --- a/nwthread.cc +++ b/nwthread.cc @@ -118,31 +118,97 @@ void NetworkThread::ClientSendStatustext(char *txt) { } +#define BUFFER_SIZE 0x10000 void NetworkThread::Thread() { + int i; + long int len; + TCP tcp; + char buffer[BUFFER_SIZE]; + printf ("%s:%d NetworkThread::Thread Started\n", __FILE__, __LINE__); - TCP tcp; ClientSendStatustext((char*)"connecting"); + Lock(); + req_fc = 0; + UnLock(); + // + // connect to ip address + // SetState (NWT_connect); - if (tcp.Connect(host, port) != 1) { + i = tcp.Connect(host, port); + if (i < 0) { + // + // error on connect, stop thread. ClientSendStatustext(strerror(errno)); + + SetState(NWT_nothing); + ClientSendStatustext(NULL); + printf ("%s:%d NetworkThread::Thread Finished on connect\n", __FILE__, __LINE__); + + return; } - else { + if (i == 1) ClientSendStatustext((char*)"connected"); + // FIXME: else: still connecting need some timeout and checks. + + SetState(NWT_running); + // + // connection established + // go into the main loop + while (GetState() == NWT_running) { // - // destination host and port should be set already - SetState(NWT_running); - while (GetState() == NWT_running) { - ClientSendStatustext((char*)"connected"); - usleep (1000); + // check for new data + i = tcp.IsData(1000); + if (i < 0) { + SetState(NWT_error); + break; } - if(GetState() == NWT_close) { - ClientSendStatustext((char*)""); + else if (i == 0) continue; + + // + // we got some data + printf ("read data\n"); + len = tcp.Read(buffer, BUFFER_SIZE); + Lock(); + if (len < 0) state = NWT_close; + else { + // + // we could get some data, if busy reset connection + if (req_fc == 0) { + // got data without request? - Protokol error + errno = EPROTO; + state = NWT_error; + break; + } + + // + // return data + + } + UnLock(); } + + // + // main loop stopped, clean up + i = GetState(); + switch (i) { + case NWT_error: + ClientSendStatustext(strerror(errno)); + tcp.Close(); + break; + case NWT_close: + ClientSendStatustext((char*)"Connection Closed"); + tcp.Close(); + break; + default: + ClientSendStatustext((char*)"Unknown Error"); + tcp.Close(); + break; + } + SetState(NWT_nothing); - ClientSendStatustext(NULL); printf ("%s:%d NetworkThread::Thread Finished\n", __FILE__, __LINE__); }; diff --git a/nwthread.h b/nwthread.h index 681b34e..8df548f 100644 --- a/nwthread.h +++ b/nwthread.h @@ -11,11 +11,13 @@ #include #include #include +#include enum { NWT_nothing, NWT_connect, NWT_running, + NWT_error, NWT_close }; @@ -25,6 +27,13 @@ private: GMutex mutex; GThread *thread; int state; + + int req_fc; // 0 .. is no request + int req_offset; + int req_size; + int req_timeout; // timeout[ms] + struct timeval req_time; + std::string host, port; void SetState(int s); @@ -41,6 +50,7 @@ public: int Disconnect(); int GetState(); + int SendRequest(); void Thread(); }; diff --git a/tcp.cc b/tcp.cc index 8689944..4b4d72e 100644 --- a/tcp.cc +++ b/tcp.cc @@ -218,6 +218,9 @@ int TCP::Connect(string hostport, int defaultport) { }; +// +// try to connect. +// return: -1 on error, 0 on in progress, 1 on connected int TCP::Connect() { int err, s; struct addrinfo hints, *res, *rp; @@ -232,7 +235,7 @@ int TCP::Connect() { err = getaddrinfo(remote_host.c_str(), remote_port.c_str(), &hints, &res); if (err != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err)); - return 0; + return -1; } // @@ -249,8 +252,16 @@ int TCP::Connect() { if (s == -1) continue; if (connect(s, rp->ai_addr, rp->ai_addrlen) != -1) { sock = s; + err = 1; // set return value break; } + + if (errno == EINPROGRESS) { + // socket set up, but in NONBLOCKED mode + sock = s; + err = 0; // set return value + break; + } close(s); } @@ -259,12 +270,12 @@ int TCP::Connect() { // // connect not successfull // - if (rp == NULL) return 0; - writecnt = 0; readcnt = 0; - return 1; + if (rp == NULL) return -1; + + return err; }; @@ -290,7 +301,9 @@ long int TCP::Read(char *buffer, long int len) { len_ = -2; } else if (len_ == 0) len_ = -1; - if (len_ < 0) Close(); + if (len_ < 0) { + Close(); + } readcnt += len_; @@ -375,6 +388,11 @@ int TCP::IsConnected() { }; +/* + * is there any data or changed on the socket? + * Parmeter: timeout[ms] + * Result: -1 on error, 0 no data, 1 new data + */ int TCP::IsData(int timeout) { fd_set sockset; struct timeval tval; diff --git a/testmodbus-client.ui b/testmodbus-client.ui index 5582bbf..54a4ec2 100644 --- a/testmodbus-client.ui +++ b/testmodbus-client.ui @@ -14,6 +14,7 @@ 4 4 vertical + 4 True @@ -116,7 +117,9 @@ True False - Refresh [ms]: + Refresh [ms]: +(< 100 = On Demand) + right False @@ -309,10 +312,287 @@ - + + True + False + 4 + 4 + 0 + + + True + False + 12 + + + True + False + vertical + + + True + False + 8 + + + Update / Read + True + True + False + True + + + False + True + 0 + + + + + FC4 + True + True + False + True + True + + + False + True + end + 1 + + + + + FC3 + True + True + False + True + True + + + False + True + end + 2 + + + + + FC2 + True + True + False + True + True + + + False + True + end + 3 + + + + + FC1 + True + True + False + True + True + + + False + True + end + 4 + + + + + False + True + 4 + 0 + + + + + + True + False + start + start + 16 + 4 + 4 + + + True + False + Register / Flag: + + + 0 + 0 + + + + + True + False + Numbers: + + + 0 + 1 + + + + + True + True + 5 + 5 + + + 1 + 0 + + + + + True + True + 5 + 5 + + + 1 + 1 + + + + + Dont Use FC15/16 +(will only request one value) + True + True + False + True + + + 3 + 0 + + + + + + + + + + + + + + False + False + 4 + 1 + + + + + + + + + True + False + Request + + + + + + + + + False + True + 1 + - + + True + False + 4 + 4 + 0 + + + True + False + 12 + + + True + False + vertical + + + + + + + + + + + + True + True + in + + + True + True + + + + + True + True + 3 + + + + + + + + + True + False + Result + + + + + + + + + True + True + 2 +