/* PIP - Platform Independent Primitives Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #include "piclientserver_client_base.h" #include "piethernet.h" #include "piliterals_time.h" PIClientServer::ClientBase::ClientBase() {} PIClientServer::ClientBase::~ClientBase() { close(); stopAndWait(); if (own_tcp) piDeleteSafety(tcp); piDeleteSafety(diag); } void PIClientServer::ClientBase::close() { if (!tcp) return; can_write = false; tcp->stop(); stream.clear(); } void PIClientServer::ClientBase::stopAndWait() { if (!tcp) return; tcp->stopAndWait(10_s); if (tcp->isThreadedRead()) tcp->terminateThreadedRead(); tcp->close(); stream.clear(); } int PIClientServer::ClientBase::write(const void * d, const size_t s) { if (!tcp) return -1; if (!can_write) return 0; PIMutexLocker guard(write_mutex); // piCout << "... send ..."; stream.send(PIByteArray(d, s)); // piCout << "... send ok"; return s; } void PIClientServer::ClientBase::enableDiagnostics() { if (diag) return; diag = new PIDiagnostics(); } PIDiagnostics::State PIClientServer::ClientBase::diagnostics() const { if (!diag) return {}; return diag->state(); } int PIClientServer::ClientBase::receivePacketProgress() const { return stream.receivePacketProgress(); } void PIClientServer::ClientBase::init() { if (!tcp) return; CONNECTL(&stream, sendRequest, [this](const PIByteArray & ba) { if (!can_write) return; tcp->send(ba); if (diag) diag->sended(ba.size_s()); // piMSleep(1); }); CONNECTL(&stream, packetReceiveEvent, [this](PIByteArray & ba) { readed(ba); }); CONNECTL(&stream, startPacketReceive, [this](int size) { receivePacketStart(size); }); CONNECTL(&stream, endPacketReceive, [this]() { receivePacketEnd(); }); CONNECTL(tcp, threadedReadEvent, [this](const uchar * readed, ssize_t size) { if (!can_write) return; stream.received(readed, size); if (diag) diag->received(size); }); CONNECTL(tcp, connected, [this]() { can_write = true; // piCout << "Connected"; connected(); }); CONNECTL(tcp, disconnected, [this](bool) { can_write = false; stream.clear(); // piCout << "Disconnected"; disconnected(); }); } void PIClientServer::ClientBase::destroy() { write_mutex.lock(); close(); piDeleteSafety(tcp); write_mutex.unlock(); // piCout << "Destroyed"; }