From 0e65151e9f20634343fa9415a159bacd2f9bed9e Mon Sep 17 00:00:00 2001 From: peri4 Date: Fri, 20 Aug 2021 10:55:47 +0300 Subject: [PATCH] PIEthernet error 232 PICloud many fixes PIBroadcast recursive fix --- libs/cloud/picloudclient.cpp | 79 +++++++++++++++++------------ libs/cloud/picloudserver.cpp | 16 +++--- libs/io_utils/pibroadcast.cpp | 1 + libs/main/cloud/picloudclient.h | 6 +-- libs/main/io_devices/piethernet.cpp | 12 ++++- 5 files changed, 69 insertions(+), 45 deletions(-) diff --git a/libs/cloud/picloudclient.cpp b/libs/cloud/picloudclient.cpp index d959a57d..76fbf436 100644 --- a/libs/cloud/picloudclient.cpp +++ b/libs/cloud/picloudclient.cpp @@ -24,16 +24,16 @@ PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), PICloudBase() { tcp.setRole(PICloud::TCP::Client); setName("cloud_client"); - is_connected = false; + is_connected = is_connecting = false; CONNECTL(ð, connected, [this](){opened_ = true; tcp.sendStart();}); CONNECTU(&streampacker, packetReceiveEvent, this, _readed); CONNECTL(ð, disconnected, [this](bool){ -// piCoutObj << "disconnected"; - opened_ = false; - is_connected = false; - cond_connect.notifyOne(); - cond_buff.notifyOne(); - piMSleep(100); + //piCoutObj << "eth.disconnected"; + bool ned = is_connected; + opened_ = is_connected = false; + notifyBuffer(); + if (ned) + disconnected(); }); } @@ -41,11 +41,10 @@ PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) PICloudClient::~PICloudClient() { eth.close(); if (is_connected) { - is_connected = false; disconnected(); - cond_buff.notifyOne(); - cond_connect.notifyOne(); + is_connected = false; } + notifyBuffer(); close(); stop(); } @@ -63,20 +62,26 @@ void PICloudClient::setKeepConnection(bool on) { bool PICloudClient::openDevice() { -// piCout << "PICloudClient open device" << path(); + if (isOpened()) return true; bool op = eth.connect(PIEthernet::Address::resolve(path()), false); if (op) { - mutex_buff.lock(); eth.startThreadedRead(); - bool conn_ok = cond_connect.waitFor(mutex_buff, (int)eth.readTimeout(), [this](){return isConnected();}); - piCoutObj << "conn_ok" << conn_ok; - mutex_buff.unlock(); + is_connecting = true; + PITimeMeasurer tm; + while (tm.elapsed_m() < (int)eth.readTimeout()) { + if (isConnected()) break; + if (!is_connecting) return false; + piMSleep(PIP_MIN_MSLEEP); + } + is_connecting = false; + bool conn_ok = isConnected(); + //piCoutObj << "conn_ok" << conn_ok; if (!conn_ok) { eth.stop(); eth.close(); - piMSleep(100); + //piMSleep(100); } - return isConnected(); + return conn_ok; } else { eth.close(); return false; @@ -85,38 +90,47 @@ bool PICloudClient::openDevice() { bool PICloudClient::closeDevice() { - PIThread::stop(false); - if (is_connected) { - is_connected = false; - disconnected(); - cond_buff.notifyOne(); - cond_connect.notifyOne(); - } eth.stop(); - if (eth.isOpened()) eth.close(); + PIThread::stop(false); + if (is_connected) + disconnected(); + is_connected = is_connecting = false; + notifyBuffer(); + waitForFinish(1000); + if (eth.isOpened()) + eth.close(); return true; } int PICloudClient::readDevice(void * read_to, int max_size) { -// piCoutObj << "readDevice"; + //piCoutObj << "readDevice"; if (!is_connected) return -1; mutex_buff.lock(); - cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty();}); + cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;}); int sz = piMini(max_size, buff.size()); - memcpy(read_to, buff.data(), sz); - buff.remove(0, sz); + if (sz > 0) { + memcpy(read_to, buff.data(), sz); + buff.remove(0, sz); + } mutex_buff.unlock(); return sz; } int PICloudClient::writeDevice(const void * data, int size) { -// piCoutObj << "writeDevice"; + //piCoutObj << "writeDevice"; return tcp.sendData(PIByteArray(data, size)); } +void PICloudClient::notifyBuffer() { + mutex_buff.lock(); + cond_buff.notifyOne(); + mutex_buff.unlock(); +} + + void PICloudClient::_readed(PIByteArray & ba) { mutex_buff.lock(); PIPair hdr = tcp.parseHeader(ba); @@ -126,14 +140,13 @@ void PICloudClient::_readed(PIByteArray & ba) { if (tcp.parseConnect(ba) == 1) { is_connected = true; connected(); - cond_connect.notifyOne(); } break; case PICloud::TCP::Disconnect: - is_connected = false; + //piCoutObj << "TCP::Disconnect ..."; static_cast(ð)->stop(); eth.close(); - disconnected(); + //piCoutObj << "TCP::Disconnect ok"; break; case PICloud::TCP::Data: if (is_connected) { diff --git a/libs/cloud/picloudserver.cpp b/libs/cloud/picloudserver.cpp index 0a07b67b..ab935bb5 100644 --- a/libs/cloud/picloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -28,7 +28,7 @@ PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) CONNECTU(&streampacker, packetReceiveEvent, this, _readed); CONNECTL(ð, connected, [this](){tcp.sendStart();}); CONNECTL(ð, disconnected, [this](bool){ - piCoutObj << "disconnected"; + //piCoutObj << "disconnected"; opened_ = false; piMSleep(100); }); @@ -57,7 +57,7 @@ PIVector PICloudServer::clients() const { bool PICloudServer::openDevice() { - piCout << "PICloudServer open device" << path(); + //piCout << "PICloudServer open device" << path(); bool op = eth.connect(PIEthernet::Address::resolve(path()), false); if (op) { eth.startThreadedRead(); @@ -143,10 +143,12 @@ bool PICloudServer::Client::closeDevice() { int PICloudServer::Client::readDevice(void * read_to, int max_size) { if (!is_connected) return -1; mutex_buff.lock(); - cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty();}); + cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;}); int sz = piMini(max_size, buff.size()); - memcpy(read_to, buff.data(), sz); - buff.remove(0, sz); + if (sz > 0) { + memcpy(read_to, buff.data(), sz); + buff.remove(0, sz); + } mutex_buff.unlock(); return sz; } @@ -179,7 +181,7 @@ void PICloudServer::_readed(PIByteArray & ba) { if (oc) { tcp.sendDisconnected(id); } else { - piCoutObj << "new Client" << id; + //piCoutObj << "new Client" << id; Client * c = new Client(this, id); CONNECTU(c, deleted, this, clientDeleted); clients_mutex.lock(); @@ -191,7 +193,7 @@ void PICloudServer::_readed(PIByteArray & ba) { } break; case PICloud::TCP::Disconnect: { uint id = tcp.parseDisconnect(ba); - piCoutObj << "remove Client" << id; + //piCoutObj << "remove Client" << id; clients_mutex.lock(); Client * oc = index_clients.value(id, nullptr); clients_mutex.unlock(); diff --git a/libs/io_utils/pibroadcast.cpp b/libs/io_utils/pibroadcast.cpp index 0a064ea5..a59b1314 100644 --- a/libs/io_utils/pibroadcast.cpp +++ b/libs/io_utils/pibroadcast.cpp @@ -221,6 +221,7 @@ void PIBroadcast::send(const PIByteArray & data) { void PIBroadcast::startRead() { if (!isRunning()) { + _started = false; reinit(); PIThread::start(3000); } diff --git a/libs/main/cloud/picloudclient.h b/libs/main/cloud/picloudclient.h index 1ea14883..c0b81779 100644 --- a/libs/main/cloud/picloudclient.h +++ b/libs/main/cloud/picloudclient.h @@ -50,14 +50,14 @@ protected: int writeDevice(const void * data, int size); DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Reliable;} + void notifyBuffer(); + private: EVENT_HANDLER1(void, _readed, PIByteArray &, data); PIByteArray buff; PIMutex mutex_buff; - PIMutex mutex_connect; PIConditionVariable cond_buff; - PIConditionVariable cond_connect; - std::atomic_bool is_connected; + std::atomic_bool is_connected, is_connecting; }; #endif // PICLOUDCLIENT_H diff --git a/libs/main/io_devices/piethernet.cpp b/libs/main/io_devices/piethernet.cpp index 7ef2428e..7e3f657d 100644 --- a/libs/main/io_devices/piethernet.cpp +++ b/libs/main/io_devices/piethernet.cpp @@ -1040,8 +1040,16 @@ PIEthernet::InterfaceList PIEthernet::interfaces() { } pAdapter = pAdapter->Next; } - } else - piCout << "[PIEthernet] GetAdaptersInfo failed with error:" << ret; + } else { + switch (ret) { + case ERROR_NO_DATA: break; + case ERROR_NOT_SUPPORTED: + piCout << "[PIEthernet] GetAdaptersInfo not supported"; + break; + default: + piCout << "[PIEthernet] GetAdaptersInfo failed with error:" << ret; + } + } if (pAdapterInfo) HeapFree(GetProcessHeap(), 0, (pAdapterInfo)); #else