diff --git a/CMakeLists.txt b/CMakeLists.txt index 74115564..d7f0f166 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ set(PIP_SRC_COMPRESS "src_compress") set(PIP_SRC_USB "src_usb") set(PIP_SRC_FFTW "src_fftw") set(PIP_SRC_OPENCL "src_opencl") +set(PIP_SRC_IO_UTILS "src_io_utils") set(PIP_LIBS_TARGETS pip) set(LIBS_MAIN) set(LIBS_STATUS) @@ -120,6 +121,9 @@ gather_src("${PIP_SRC_FFTW}" CPP_LIB_FFTW HDRS PHDRS) # OpenCL lib gather_src("${PIP_SRC_OPENCL}" CPP_LIB_OPENCL HDRS PHDRS) +# IO Utils lib +gather_src("${PIP_SRC_IO_UTILS}" CPP_LIB_IO_UTILS HDRS PHDRS) + # Check Bessel functions set(CMAKE_REQUIRED_INCLUDES math.h) @@ -400,6 +404,19 @@ else() endif() +# Check if PIP IO Utils library supports crypt +set(IO_UTILS_LIBS pip) +add_library(pip_io_utils SHARED ${CPP_LIB_IO_UTILS}) +if(sodium_FOUND) + message(STATUS "Building IO Utils library with crypt support") + list(APPEND IO_UTILS_LIBS pip_crypt) +else() + message(STATUS "Building IO Utils library without crypt support, attention!") +endif() +target_link_libraries(pip_io_utils ${IO_UTILS_LIBS}) +list(APPEND PIP_LIBS_TARGETS pip_io_utils) + + # Test program add_executable(pip_test "main.cpp") diff --git a/FindPIP.cmake b/FindPIP.cmake index 44cc2074..e6d835ac 100644 --- a/FindPIP.cmake +++ b/FindPIP.cmake @@ -7,6 +7,7 @@ find_library(PIP_USB_LIBRARY pip_usb HINTS ${PIP_DIR}/lib ${MINGW_LIB} /usr/lib find_library(PIP_CRYPT_LIBRARY pip_crypt HINTS ${PIP_DIR}/lib ${MINGW_LIB} /usr/lib /usr/local/lib) find_library(PIP_FFTW_LIBRARY pip_fftw HINTS ${PIP_DIR}/lib ${MINGW_LIB} /usr/lib /usr/local/lib) find_library(PIP_COMPRESS_LIBRARY pip_compress HINTS ${PIP_DIR}/lib ${MINGW_LIB} /usr/lib /usr/local/lib) +find_library(PIP_IO_UTILS_LIBRARY pip_io_utils HINTS ${PIP_DIR}/lib ${MINGW_LIB} /usr/lib /usr/local/lib) find_file(PIP_H_INCLUDE "pip.h" HINTS ${PIP_DIR}/include/pip ${MINGW_INCLUDE}/pip /usr/include/pip /usr/local/include/pip) if (DEFINED ANDROID_PLATFORM) set(PIP_INCLUDES ${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include/pip) diff --git a/src_main/io_utils/piethutilbase.cpp b/src_io_utils/piethutilbase.cpp similarity index 79% rename from src_main/io_utils/piethutilbase.cpp rename to src_io_utils/piethutilbase.cpp index 91adaa10..761e9897 100644 --- a/src_main/io_utils/piethutilbase.cpp +++ b/src_io_utils/piethutilbase.cpp @@ -18,7 +18,9 @@ */ #include "piethutilbase.h" -#include "picrypt.h" +#ifdef PIP_CRYPT +# include "picrypt.h" +#endif PIEthUtilBase::PIEthUtilBase() { @@ -31,22 +33,35 @@ PIEthUtilBase::~PIEthUtilBase() { void PIEthUtilBase::createCryptKey(const PIString & k) { +#ifdef PIP_CRYPT _key = PICrypt::hash("sodium_bug"); _key = PICrypt::hash(k); +#else + piCout << "[PIEthUtilBase] PICrypt wasn`t built!"; +#endif _crypt = true; } PIByteArray PIEthUtilBase::cryptData(const PIByteArray & data) { if (!_crypt) return data; - return PICrypt::crypt(data, _key); + return +#ifdef PIP_CRYPT + PICrypt::crypt(data, _key); +#else + PIByteArray(); +#endif } PIByteArray PIEthUtilBase::decryptData(const PIByteArray & data) { if (!_crypt) return data; +#ifdef PIP_CRYPT bool ok = false; PIByteArray ret = PICrypt::decrypt(data, _key, &ok); if (!ok) return PIByteArray(); return ret; +#else + return PIByteArray(); +#endif } diff --git a/src_main/io_utils/pimulticast.cpp b/src_io_utils/pimulticast.cpp similarity index 92% rename from src_main/io_utils/pimulticast.cpp rename to src_io_utils/pimulticast.cpp index 1ab7a1e8..6edc8e93 100644 --- a/src_main/io_utils/pimulticast.cpp +++ b/src_io_utils/pimulticast.cpp @@ -109,7 +109,7 @@ void PIMulticast::initAll(PIVector al) { } eth_lo = new PIEthernet(); eth_lo->setDebug(false); - ce->setName("PIMulticast_loopback"); + eth_lo->setName("PIMulticast_loopback"); if (!_send_only) { eth_lo->setParameter(PIEthernet::ReuseAddress, false); CONNECTU(eth_lo, threadedReadEvent, this, mcastRead); @@ -127,6 +127,7 @@ void PIMulticast::initAll(PIVector al) { void PIMulticast::send(const PIByteArray & data) { PIByteArray cd = cryptData(data); if (cd.isEmpty()) return; + PIMutexLocker ml(mcast_mutex); piForeach (PIEthernet * e, eth_mcast) e->send(cd); if (eth_lo) { @@ -139,6 +140,7 @@ void PIMulticast::send(const PIByteArray & data) { void PIMulticast::startRead() { if (_send_only) return; + PIMutexLocker ml(mcast_mutex); piForeach (PIEthernet * e, eth_mcast) e->startThreadedRead(); if (eth_lo) @@ -148,6 +150,7 @@ void PIMulticast::startRead() { void PIMulticast::stopRead() { + PIMutexLocker ml(mcast_mutex); piForeach (PIEthernet * e, eth_mcast) e->stopThreadedRead(); if (eth_lo) @@ -157,7 +160,9 @@ void PIMulticast::stopRead() { void PIMulticast::reinit() { - + initAll(PIEthernet::allAddresses()); + if (_started) + startRead(); } @@ -172,7 +177,5 @@ void PIMulticast::mcastRead(uchar * data, int size) { void PIMulticast::run() { PIVector al = PIEthernet::allAddresses(); if (al == prev_al) return; - initAll(al); - if (_started) - startRead(); + reinit(); } diff --git a/src_main/io_utils/pistreampacker.cpp b/src_io_utils/pistreampacker.cpp similarity index 100% rename from src_main/io_utils/pistreampacker.cpp rename to src_io_utils/pistreampacker.cpp diff --git a/src_main/console/piconsole.cpp b/src_main/console/piconsole.cpp index db258b96..2a2e9c60 100644 --- a/src_main/console/piconsole.cpp +++ b/src_main/console/piconsole.cpp @@ -19,7 +19,6 @@ #include "piconsole.h" #include "piincludes_p.h" #include "pipeer.h" -#include "piprotocol.h" #include "pidiagnostics.h" #include "pisystemmonitor.h" #ifndef WINDOWS @@ -806,39 +805,6 @@ void PIConsole::addVariable(const PIString & name, const ullong * ptr, int col, ADD_VAR_BODY tv.type = 13; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} void PIConsole::addVariable(const PIString & name, const PISystemTime * ptr, int col, FormatFlags format) { ADD_VAR_BODY tv.type = 20; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -/** \brief Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - * \details This function add to column "column" next lines: - * * "protocol " - * * "Rec - receiverDeviceName": \a PIProtocol::receiverDeviceState - * * "Send - senderDeviceName": \a PIProtocol::senderDeviceState - * * "Received count": \a PIProtocol::receiveCount - * * "Invalid count": \a PIProtocol::wrongCount - * * "Missed count": \a PIProtocol::missedCount - * * "Sended count": \a PIProtocol::sendCount - * * "Immediate Frequency, Hz": \a PIProtocol::immediateFrequency - * * "Integral Frequency, Hz": \a PIProtocol::integralFrequency - * * "Receive speed": \a PIProtocol::receiveSpeed - * * "Send speed": \a PIProtocol::sendSpeed - * * "Receiver history size": \a PIProtocol::receiverHistorySize - * * "Sender history size": \a PIProtocol::senderHistorySize - * * "Disconnect Timeout, s": \a PIProtocol::disconnectTimeout - * * "Quality": \a PIProtocol::quality - * */ -void PIConsole::addVariable(const PIString & name, const PIProtocol * ptr, int col, FormatFlags format) { - addString("protocol " + name, col, format | PIConsole::Bold); - addVariable("Rec - " + ptr->receiverDeviceName(), ptr->receiverDeviceState_ptr(), col, format); - addVariable("Send - " + ptr->senderDeviceName(), ptr->senderDeviceState_ptr(), col, format); - addVariable("Received count", ptr->receiveCount_ptr(), col, format); - addVariable("Invalid count", ptr->wrongCount_ptr(), col, format); - addVariable("Missed count", ptr->missedCount_ptr(), col, format); - addVariable("Sended count", ptr->sendCount_ptr(), col, format); - addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), col, format); - addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), col, format); - addVariable("Receive speed", ptr->receiveSpeed_ptr(), col, format); - addVariable("Send speed", ptr->sendSpeed_ptr(), col, format); - addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), col, format); - addVariable("Quality", ptr->quality_ptr(), col, format); -} /** \brief Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" * \details This function add to column "column" next lines: * * " diagnostics" diff --git a/src_main/console/piconsole.h b/src_main/console/piconsole.h index cf085a9c..b5ed4a2d 100644 --- a/src_main/console/piconsole.h +++ b/src_main/console/piconsole.h @@ -133,7 +133,6 @@ public: //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" void addVariable(const PIString & name, const PISystemTime * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - void addVariable(const PIString & name, const PIProtocol * ptr, int column = 1, FormatFlags format = PIConsole::Normal); void addVariable(const PIString & name, const PIDiagnostics * ptr, int column = 1, FormatFlags format = PIConsole::Normal); void addVariable(const PIString & name, const PISystemMonitor * ptr, int column = 1, FormatFlags format = PIConsole::Normal); diff --git a/src_main/io_devices/pimultiprotocol.cpp b/src_main/io_devices/pimultiprotocol.cpp deleted file mode 100755 index adbd0386..00000000 --- a/src_main/io_devices/pimultiprotocol.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - PIP - Platform Independent Primitives - Multiprotocol - Copyright (C) 2018 Ivan Pelipenko peri4ko@yandex.ru - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "pimultiprotocol.h" - /// DEPRECATED diff --git a/src_main/io_devices/pimultiprotocol.h b/src_main/io_devices/pimultiprotocol.h deleted file mode 100755 index bf292f6a..00000000 --- a/src_main/io_devices/pimultiprotocol.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - PIP - Platform Independent Primitives - Multiprotocol - Copyright (C) 2018 Ivan Pelipenko peri4ko@yandex.ru - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef PIMULTIPROTOCOL_H -#define PIMULTIPROTOCOL_H - -#include "piprotocol.h" - -class PIMultiProtocol: public PIMultiProtocolBase /// DEPRECATED -{ -public: - PIMultiProtocol() {;} /// DEPRECATED - virtual ~PIMultiProtocol() {clear();} - - void addProtocol(PIProtocol & prot) {prots.push_back(&prot); prot.setMultiProtocolOwner(this); prot.new_mp_prot = false;} - void addProtocol(PIProtocol * prot) {prots.push_back(prot); prot->setMultiProtocolOwner(this); prot->new_mp_prot = false;} - void addProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0, - void * recDataPtr = 0, int recDataSize = 0, void * sendDataPtr = 0, int sendDataSize = 0) {; - prots.push_back(new PIProtocol(config, name, recHeaderPtr, recHeaderSize, recDataPtr, recDataSize, sendDataPtr, sendDataSize)); - prots.back()->setMultiProtocolOwner(this); - prots.back()->new_mp_prot = true; - } - PIProtocol * protocol(const PIString & name) {piForeach (PIProtocol * i, prots) if (i->name() == name) return i; return 0;} - PIProtocol * protocol(const int index) {return prots[index];} - PIProtocol * operator [](const int index) {return prots[index];} - - void startSend() {piForeach (PIProtocol * i, prots) i->startSend();} - void startReceive() {piForeach (PIProtocol * i, prots) i->startReceive();} - void start() {piForeach (PIProtocol * i, prots) i->start();} - - void stopSend() {piForeach (PIProtocol * i, prots) i->stopSend();} - void stopReceive() {piForeach (PIProtocol * i, prots) i->stopReceive();} - void stop() {piForeach (PIProtocol * i, prots) i->stop();} - - PIProtocol::Quality worseQuality() const {PIProtocol::Quality cq = PIProtocol::Good; piForeachC (PIProtocol * i, prots) if (cq > i->quality()) cq = i->quality(); return cq;} - PIProtocol::Quality bestQuality() const {PIProtocol::Quality cq = PIProtocol::Unknown; piForeachC (PIProtocol * i, prots) if (cq < i->quality()) cq = i->quality(); return cq;} - - int count() const {return prots.size_s();} - void clear() {stop(); piForeach (PIProtocol * i, prots) if (i->new_mp_prot) delete i; prots.clear();} - -private: - PIVector prots; - -}; - -class PIRepeater: public PIMultiProtocol { /// DEPRECATED -public: - PIRepeater(const PIString & config, const PIString & name_) { /// DEPRECATED - PIConfig conf(config, PIIODevice::ReadOnly); - if (!conf.isOpened()) { - piCoutObj << "[PIRepeater \"" << name_ << "\"] Can`t open \"" << config << "\"!"; - return; - } - PIConfig::Entry & b(conf.getValue(name_)); - if (b.childCount() != 2) { - piCoutObj << "[PIRepeater \"" << name_ << "\"] \"" << config << "\" should consist 2 nodes!"; - return; - } - addProtocol(config, b.child(0)->fullName()); - addProtocol(config, b.child(1)->fullName()); - start(); - } - - PIString firstChannelName() {if (count() == 2) return protocol(0)->receiverDeviceName() + " -> " + protocol(1)->senderDeviceName(); return "Config error";} - PIString secondChannelName() {if (count() == 2) return protocol(1)->receiverDeviceName() + " -> " + protocol(0)->senderDeviceName(); return "Config error";} - - ullong receiveCount() {if (count() == 2) return protocol(0)->receiveCount(); return 0;} - const ullong * receiveCount_ptr() {if (count() == 2) return protocol(0)->receiveCount_ptr(); return 0;} - ullong sendCount() {if (count() == 2) return protocol(0)->sendCount(); return 0;} - const ullong * sendCount_ptr() {if (count() == 2) return protocol(0)->sendCount_ptr(); return 0;} - -private: - void received(PIProtocol * prot, bool , uchar * data, int size) {if (prot == protocol(0)) protocol(1)->send(data, size); else protocol(0)->send(data, size);} - -}; - -#endif // PIMULTIPROTOCOL_H diff --git a/src_main/io_devices/piprotocol.cpp b/src_main/io_devices/piprotocol.cpp deleted file mode 100755 index 8d0b09b3..00000000 --- a/src_main/io_devices/piprotocol.cpp +++ /dev/null @@ -1,718 +0,0 @@ -/* - PIP - Platform Independent Primitives - Protocol, input/output channel (COM, UDP) - Copyright (C) 2018 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "piprotocol.h" - -/** \class PIProtocol - * \brief - * \details - * \section PIProtocol_sec0 Synopsis - * - * - * - * */ - - /// DEPRECATED -PIProtocol::PIProtocol(const PIString & config, const PIString & name_, void * recHeaderPtr, int recHeaderSize, void * recDataPtr, int recDataSize, void * sendDataPtr_, int sendDataSize_): PIObject() { - init(); - protName = name_; - PIObject::setName(name_); - PIConfig conf(config, PIIODevice::ReadOnly); - if (!conf.isOpened()) { - piCoutObj << "Can`t open \"" << config << "\"!"; - devReceiverState = devSenderState = "Config error"; - return; - } - PIConfig::Entry & b(conf.getValue(name_)), - & rb(b.getValue("receiver")), - & sb(b.getValue("sender")); - - init_receiver(b, rb, config); - init_sender(b, sb, config); - - headerPtr = (uchar * )recHeaderPtr; - headerSize = recHeaderSize; - dataPtr = (uchar * )recDataPtr; - dataSize = recDataSize; - sendDataPtr = (uchar * )sendDataPtr_; - sendDataSize = sendDataSize_; - packet_ext->setHeader(PIByteArray(recHeaderPtr, recHeaderSize)); - packet_ext->setPayloadSize(recDataSize); - packet_ext->setPacketSize(recDataSize); - packet_ext->setSplitMode(PIPacketExtractor::Header); - bool null_h = (recHeaderPtr == 0 || recHeaderSize == 0), null_d = (recDataPtr == 0 || recDataSize == 0); - if (null_h && null_d) packet_ext->setSplitMode(PIPacketExtractor::None); - else { - if (null_h) packet_ext->setSplitMode(PIPacketExtractor::Size); - } -} - - -PIProtocol::~PIProtocol() { - delete diagTimer; - delete sendTimer; - delete secTimer; - delete packet_ext; - if (eth != 0) delete eth; - if (ser != 0) delete ser; -} - - -void PIProtocol::init() { - packet_ext = new PIPacketExtractor(0, PIPacketExtractor::None); - packet_ext->setThreadedReadData(this); - packet_ext->setThreadedReadSlot(receiveEvent); - packet_ext->setHeaderCheckSlot(headerValidateEvent); - packet_ext->setName("__S__PIProtocol::packet_ext"); - work = new_mp_prot = false; - eth = 0; - ser = 0; - ret_func = 0; - mp_owner = 0; - net_diag = PIProtocol::Unknown; - cur_pckt = 0; - packets[0] = packets[1] = pckt_cnt = pckt_cnt_max = 0; - diagTimer = 0; - timeout_ = 3.f; - sendTimer = new PITimer(sendEvent, this); - diagTimer = new PITimer(diagEvent, this); - secTimer = new PITimer(secEvent, this); - sendTimer->setName("__S__PIProtocol::sendTimer"); - diagTimer->setName("__S__PIProtocol::diagTimer"); - secTimer->setName("__S__PIProtocol::secTimer"); - wrong_count = receive_count = send_count = missed_count = 0; - packets_in_sec = packets_out_sec = bytes_in_sec = bytes_out_sec = 0; - immediate_freq = integral_freq = ifreq = 0.f; - headerPtr = dataPtr = sendDataPtr = 0; - headerSize = dataSize = sendDataSize = 0; - type_rec = type_send = PIProtocol::None; - devSenderState = devReceiverState = "Unknown"; - devSenderName = devReceiverName = "no device"; - secTimer->start(1000.); - /*addEvent("receiver started"); - addEvent("receiver stopped"); - addEvent("sender started"); - addEvent("sender stopped"); - addEvent("received"); - addEvent("quality changed"); - addEventHandler(HANDLER(PIProtocol, startReceive)); - addEventHandler(HANDLER(PIProtocol, startSend)); - addEventHandler(HANDLER(PIProtocol, start)); - addEventHandler(HANDLER(PIProtocol, stopReceive)); - addEventHandler(HANDLER(PIProtocol, stopSend)); - addEventHandler(HANDLER(PIProtocol, stop));*/ -} - - -void PIProtocol::init_sender(PIConfig::Entry & b, PIConfig::Entry & sb, const PIString & config) { - int ps, gps; - bool ok, gok, flag, gflag, has_dev = false; - float freq, gfreq; - PIFlags pp(0); - PIString dev, gdev; - - if (sb.isEntryExists("ip") && sb.isEntryExists("device")) { - piCoutObj << "Ambiguous sender type in \"" << config << "\"!"; - devSenderState = "Config error"; - return; - } - dev = sb.getValue("ip", "", &ok); - gdev = b.getValue("ip", "", &gok); - has_dev = false; - if (ok || gok) { - if (gok && !ok) dev = gdev; - if (gok && ok && (dev != gdev)) { - piCoutObj << "Ambiguous sender type in \"" << config << "\"!"; - devSenderState = "Config error"; - return; - } - ps = sb.getValue("port", 0, &ok); - gps = b.getValue("port", 0, &gok); - if (ok || gok) { - if (gok && !ok) ps = gps; - if (gok && ok && (ps != gps)) { - piCoutObj << "Ambiguous send port in \"" << config << "\"!"; - devSenderState = "Config error"; - return; - } - type_send = PIProtocol::Ethernet; - if (eth == 0) eth = new PIEthernet(); - eth->setName("__S__PIProtocol::eth"); - setSenderAddress(dev, ps); - //setReceiverAddress(dev, ps); - has_dev = true; - flag = sb.getValue("reconnectEnabled", true, &ok); - gflag = b.getValue("reconnectEnabled", true, &gok); - if (ok || gok) { - if (gok && !ok) flag = gflag; - if (gok && ok && (flag != gflag)) { - piCoutObj << "Ambiguous \"reconnectEnabled\" flag in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - eth->setReopenEnabled(flag); - } - freq = sb.getValue("reconnectTimeout", 1., &ok); - gfreq = b.getValue("reconnectTimeout", 1., &gok); - if (ok || gok) { - if (gok && !ok) freq = gfreq; - if (gok && ok && (freq != gfreq)) { - piCoutObj << "Ambiguous \"reconnectTimeout\" value in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - eth->setReopenTimeout(freq * 1000); - } - /*if (sendDataPtr_ == 0) - piCoutObj << "Warning: null send data pointer!"; - if (sendDataSize_ == 0) - piCoutObj << "Warning: null send data size!";*/ - } else { - piCoutObj << "Can`t find \"" << name() << ".sender.port\" or \"" << name() << ".port\" in \"" << config << "\"!"; - devSenderState = "Config error"; - return; - } - } - dev = sb.getValue("device", "", &ok); - gdev = b.getValue("device", "", &gok); - if (ok || gok) { - if (gok && !ok) dev = gdev; - if (gok && ok && (dev != gdev)) { - piCoutObj << "Ambiguous sender type in \"" << config << "\"!"; - devSenderState = "Config error"; - return; - } - ps = sb.getValue("speed", 0, &ok); - gps = b.getValue("speed", 0, &gok); - if (ok || gok) { - if (gok && !ok) ps = gps; - if (gok && ok && (ps != gps)) { - piCoutObj << "Ambiguous send \"speed\" in \"" << config << "\"!"; - devSenderState = "Config error"; - return; - } - flag = sb.getValue("parity", false, &ok); - gflag = b.getValue("parity", false, &gok); - if (ok || gok) { - if (gok && !ok) flag = gflag; - if (gok && ok && (flag != gflag)) { - piCoutObj << "Ambiguous send \"parity\" in \"" << config << "\"!"; - devSenderState = "Config error"; - return; - } - pp.setFlag(PISerial::ParityControl, flag); - } - flag = sb.getValue("twoStopBits", false, &ok); - gflag = b.getValue("twoStopBits", false, &gok); - if (ok || gok) { - if (gok && !ok) flag = gflag; - if (gok && ok && (flag != gflag)) { - piCoutObj << "Ambiguous send \"twoStopBits\" parity in \"" << config << "\"!"; - devSenderState = "Config error"; - return; - } - pp.setFlag(PISerial::TwoStopBits, flag); - } - } else { - piCoutObj << "Can`t find \"" << name() << ".sender.speed\" or \"" << name() << ".speed\" in \"" << config << "\"!"; - devSenderState = "Config error"; - return; - } - type_send = PIProtocol::Serial; - if (ser == 0) ser = new PISerial(dev); - ser->setName("__S__PIProtocol::ser"); - setSenderDevice(dev, (PISerial::Speed)ps); - ser->setOutSpeed((PISerial::Speed)ps); - ser->setParameters(pp); - has_dev = true; - /*if (sendDataPtr_ == 0) - piCoutObj << "Warning: null send data pointer!"; - if (sendDataSize_ == 0) - piCoutObj << "Warning: null send data size!";*/ - } - freq = sb.getValue("frequency", -1.f, &ok); - gfreq = b.getValue("frequency", -1.f, &gok); - if (gok && !ok) freq = gfreq; - if (gok && ok && (freq != gfreq)) { - piCoutObj << "Ambiguous sender frequency in \"" << config << "\"!"; - devSenderState = "Config error"; - return; - } - if (freq > 0.f && !has_dev) - piCoutObj << "Warning: no sender device and not null send frequency!"; - setSenderFrequency(freq); -} - - -void PIProtocol::init_receiver(PIConfig::Entry & b, PIConfig::Entry & rb, const PIString & config) { - int ps, gps; - bool ok, gok, flag, gflag, has_dev = false; - float freq, gfreq; - PIFlags pp(0); - PIString dev, gdev; - - if (rb.isEntryExists("ip") && rb.isEntryExists("device")) { - piCoutObj << "Ambiguous receiver type in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - dev = rb.getValue("ip", "", &ok); - gdev = b.getValue("ip", "", &gok); - if (ok || gok) { - if (gok && !ok) dev = gdev; - if (gok && ok && (dev != gdev)) { - piCoutObj << "Ambiguous receiver type in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - ps = rb.getValue("port", 0, &ok); - gps = b.getValue("port", 0, &gok); - if (ok || gok) { - if (gok && !ok) ps = gps; - if (gok && ok && (ps != gps)) { - piCoutObj << "Ambiguous receive port in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - type_rec = PIProtocol::Ethernet; - eth = new PIEthernet(); - eth->setName("__S__PIProtocol::eth"); - packet_ext->setDevice(eth); - //setSenderAddress(dev, ps); - setReceiverAddress(dev, ps); - has_dev = true; - flag = rb.getValue("reconnectEnabled", true, &ok); - gflag = b.getValue("reconnectEnabled", true, &gok); - if (ok || gok) { - if (gok && !ok) flag = gflag; - if (gok && ok && (flag != gflag)) { - piCoutObj << "Ambiguous \"reconnectEnabled\" flag in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - eth->setReopenEnabled(flag); - } - freq = rb.getValue("reconnectTimeout", 1., &ok); - gfreq = b.getValue("reconnectTimeout", 1., &gok); - if (ok || gok) { - if (gok && !ok) freq = gfreq; - if (gok && ok && (freq != gfreq)) { - piCoutObj << "Ambiguous \"reconnectTimeout\" value in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - eth->setReopenTimeout(freq * 1000); - } - /*if (recDataPtr == 0) - piCoutObj << "Warning: null receive data pointer!"; - if (recDataSize == 0) - piCoutObj << "Warning: null receive data size!";*/ - } else { - piCoutObj << "Can`t find \"" << name() << ".receiver.port\" or \"" << name() << ".port\" in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - } - dev = rb.getValue("device", "", &ok); - gdev = b.getValue("device", "", &gok); - if (ok || gok) { - if (gok && !ok) dev = gdev; - if (gok && ok && (dev != gdev)) { - piCoutObj << "Ambiguous receiver type in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - ps = rb.getValue("speed", 0, &ok); - gps = b.getValue("speed", 0, &gok); - if (ok || gok) { - if (gok && !ok) ps = gps; - if (gok && ok && (ps != gps)) { - piCoutObj << "Ambiguous receive \"speed\" in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - flag = rb.getValue("parity", false, &ok); - gflag = b.getValue("parity", false, &gok); - if (ok || gok) { - if (gok && !ok) flag = gflag; - if (gok && ok && (flag != gflag)) { - piCoutObj << "Ambiguous receive \"parity\" in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - pp.setFlag(PISerial::ParityControl, flag); - } - flag = rb.getValue("twoStopBits", false, &ok); - gflag = b.getValue("twoStopBits", false, &gok); - if (ok || gok) { - if (gok && !ok) flag = gflag; - if (gok && ok && (flag != gflag)) { - piCoutObj << "Ambiguous receive \"twoStopBits\" parity in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - pp.setFlag(PISerial::TwoStopBits, flag); - } - type_rec = PIProtocol::Serial; - type_send = PIProtocol::Serial; - ser = new PISerial(dev); - ser->setName("__S__PIProtocol::ser"); - packet_ext->setDevice(ser); - //setSenderDevice(dev, (PISerial::Speed)ps); - setReceiverDevice(dev, (PISerial::Speed)ps); - ser->setInSpeed((PISerial::Speed)ps); - ser->setParameters(pp); - ps = rb.getValue("vtime", 1, &ok); - gps = b.getValue("vtime", 1, &gok); - if (ok || gok) { - if (gok && !ok) ps = gps; - if (gok && ok && (ps != gps)) { - piCoutObj << "Ambiguous receive \"vtime\" in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - ser->setVTime(ps); - } - has_dev = true; - /*if (recDataPtr == 0) - piCoutObj << "Warning: null receive data pointer!"; - if (recDataSize == 0) - piCoutObj << "Warning: null receive data size!";*/ - } else { - piCoutObj << "Can`t find \"" << name() << ".receiver.speed\" or \"" << name() << ".speed\" in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - } - freq = rb.getValue("frequency", -1.f, &ok); - gfreq = b.getValue("frequency", -1.f, &gok); - if (gok && !ok) freq = gfreq; - if (gok && ok && (freq != gfreq)) { - piCoutObj << "Ambiguous expected frequency in \"" << config << "\"!"; - devReceiverState = "Config error"; - return; - } - if (freq > 0.f && !has_dev) - piCoutObj << "Warning: no receiver device and not null expected frequency!"; - float tm = b.getValue("disconnectTimeout", 3.f); - if (tm <= 0.f) - piCoutObj << "Warning: diconnect timeout <= 0 s!"; - timeout_ = (tm < 0.f) ? 0.f : tm; - setExpectedFrequency(freq); -} - - -void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force) { - if (force) { - type_send = type_rec = PIProtocol::Serial; - if (ser == 0) { - ser = new PISerial(); - ser->setName("__S__PIProtocol::ser"); - packet_ext->setDevice(ser); - } - } - if (type_rec == PIProtocol::Serial && ser != 0) { - ser->setDevice(device); - ser->setSpeed(speed); - devReceiverName = device; - devSenderName = device; - } -} - - -void PIProtocol::setReceiverAddress(const PIString & ip, int port, bool force) { - if (force) { - type_rec = PIProtocol::Ethernet; - if (eth == 0) { - eth = new PIEthernet(); - eth->setName("__S__PIProtocol::eth"); - packet_ext->setDevice(eth); - } - } - if (type_rec == PIProtocol::Ethernet && eth != 0) { - eth->setReadAddress(ip, port); - if (ip.trimmed().isEmpty()) devReceiverName = "no ip"; - else devReceiverName = ip + ":" + PIString::fromNumber(port); - } -} - - -void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed, bool force) { - if (force) { - type_send = type_rec = PIProtocol::Serial; - if (ser == 0) ser = new PISerial(); - ser->setName("__S__PIProtocol::ser"); - } - if (type_send == PIProtocol::Serial && ser != 0) { - ser->setDevice(device); - ser->setSpeed(speed); - ser->open(); - devSenderName = device; - } -} - - -void PIProtocol::setSenderAddress(const PIString & ip, int port, bool force) { - if (force) { - type_send = PIProtocol::Ethernet; - if (eth == 0) eth = new PIEthernet(); - eth->setName("__S__PIProtocol::eth"); - } - if (type_send == PIProtocol::Ethernet && eth != 0) { - eth->setSendAddress(ip, port); - if (ip.isEmpty()) devSenderName = "no ip"; - else devSenderName = ip + ":" + PIString::fromNumber(port); - } -} - - -void PIProtocol::setSenderIP(const PIString & ip, bool force) { - if (force) { - type_send = PIProtocol::Ethernet; - if (eth == 0) eth = new PIEthernet(); - } - if (type_send == PIProtocol::Ethernet && eth != 0) { - eth->setSendIP(ip); - if (ip.isEmpty()) devSenderName = "no ip"; - else devSenderName = ip + ":" + PIString::fromNumber(eth->sendPort()); - } -} - - -void PIProtocol::setSenderPort(int port, bool force) { - if (force) { - type_send = PIProtocol::Ethernet; - if (eth == 0) eth = new PIEthernet(); - eth->setName("__S__PIProtocol::eth"); - } - if (type_send == PIProtocol::Ethernet && eth != 0) { - eth->setSendPort(port); - if (eth->sendIP().isEmpty()) devSenderName = "no ip"; - else devSenderName = eth->sendIP() + ":" + PIString::fromNumber(port); - } -} - - -void PIProtocol::setExpectedFrequency(float frequency) { - exp_freq = frequency; - changeDisconnectTimeout(); -} - - -void PIProtocol::changeDisconnectTimeout() { - pckt_cnt_max = int(piRound(timeout_ * exp_freq)); - if (pckt_cnt_max < 3) pckt_cnt_max = 3; - last_packets.resize(pckt_cnt_max); -} - - -void PIProtocol::startReceive(float exp_frequency) { - if (exp_frequency > 0.f) exp_freq = exp_frequency; - //if (type_rec == PIProtocol::Serial) ser->start(); - //if (type_rec == PIProtocol::Ethernet) eth->start(); - packet_ext->startThreadedRead(); - msleep(1); - check_state(); - if (exp_freq <= 0.f) return; - setExpectedFrequency(exp_freq); - diagTimer->start(1000. / exp_freq); - diag_tm.reset(); - receiverStarted(); -} - - -void PIProtocol::startSend(float frequency) { - //cout << "** start send " << send_freq << ", " << frequency << endl; - if (frequency > 0.f) send_freq = frequency; - msleep(1); - check_state(); - if (send_freq <= 0.f) return; - sendTimer->start(1000. / send_freq); - diag_tm.reset(); - senderStarted(); -} - - -void PIProtocol::stopReceive() { - //if (type_rec == PIProtocol::Serial) ser->stop(); - //if (type_rec == PIProtocol::Ethernet) eth->stop(); - packet_ext->stop(); - diagTimer->stop(); - receiverStopped(); -} - - -bool PIProtocol::receiveEvent(void * t, uchar * data, int size) { - PIProtocol * p = (PIProtocol * )t; - if (!p->receive(data, size)) return false; - p->work = true; - //p->lock(); - if (p->validate()) { - p->received(true); - //p->unlock(); - p->ifreq = p->diag_tm.elapsed_m(); - if (p->ifreq > 0.) p->ifreq = 1000. / p->ifreq; - p->diag_tm.reset(); - p->receive_count++; - p->packets_in_sec++; - p->bytes_in_sec += size; - p->cur_pckt = 1; - if (p->ret_func != 0) p->ret_func(p); - if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, true, data, size); - return true; - } - p->received(false); - //p->unlock(); - p->wrong_count++; - if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, false, data, size); - return false; -} - - -void PIProtocol::diagEvent(void * t, int) { - PIProtocol * p = (PIProtocol * )t; - p->calc_freq(); - p->calc_diag(); - p->check_state(); - if (p->ser != 0) p->missed_count = p->packet_ext->missedPackets(); -} - - -void PIProtocol::secEvent(void * t, int ) { - PIProtocol * p = (PIProtocol * )t; - p->speedIn = PIString::readableSize(p->bytes_in_sec) + "/s"; - p->speedOut = PIString::readableSize(p->bytes_out_sec) + "/s"; - p->bytes_in_sec = p->bytes_out_sec = p->packets_in_sec = p->packets_out_sec = 0; - if (p->ser != 0) p->missed_count = p->packet_ext->missedPackets(); -} - - -void PIProtocol::calc_diag() { - PIProtocol::Quality diag; - if (!work) { - diag = PIProtocol::Unknown; - return; - } - if (pckt_cnt < pckt_cnt_max) { - last_packets[pckt_cnt] = cur_pckt; - pckt_cnt++; - } else { - packets[(int)last_packets.back()]--; - if (!last_packets.isEmpty()) last_packets.pop_back(); - last_packets.push_front(cur_pckt); - } - packets[(int)cur_pckt]++; - cur_pckt = 0; - float good_percents; - good_percents = (float)packets[1] / pckt_cnt * 100.f; - if (good_percents == 0.f) diag = PIProtocol::Failure; - else if (good_percents <= 20.f) diag = PIProtocol::Bad; - else if (good_percents > 20.f && good_percents <= 80.f) diag = PIProtocol::Average; - else diag = PIProtocol::Good; - if (diag != net_diag) { - qualityChanged(diag, net_diag); - net_diag = diag; - } -} - - -void PIProtocol::calc_freq() { - float tf;// = float(1000.f / diagTimer->elapsed_m()); - tf = immediate_freq = ifreq; - ifreq = 0.f; - if (last_freq.size_s() >= pckt_cnt_max && last_freq.size_s() > 0) last_freq.pop_front(); - last_freq.push_back(tf); - tf = last_freq[0]; - for (uint i = 1; i < last_freq.size(); ++i) - tf += last_freq[i]; - integral_freq = tf / last_freq.size(); -} - - -void PIProtocol::check_state() { - if (type_rec == PIProtocol::Serial) { - if (ser != 0) { - if (ser->isOpened()) devReceiverState = "Opened"; - else devReceiverState = "Not opened"; - } - else devReceiverState = "Not exists"; - } - if (type_rec == PIProtocol::Ethernet) { - if (eth != 0) { - if (eth->isOpened()) devReceiverState = "Opened"; - else devReceiverState = "Not opened"; - } - else devReceiverState = "Not exists"; - } - if (type_send == PIProtocol::Serial) { - if (ser != 0) { - if (ser->isOpened()) devSenderState = "Opened"; - else devSenderState = "Not opened"; - } - else devSenderState = "Not exists"; - } - if (type_send == PIProtocol::Ethernet) { - if (eth != 0) { - if (eth->isOpened()) devSenderState = "Opened"; - else devSenderState = "Not opened"; - } - else devSenderState = "Not exists"; - } -} - - -void PIProtocol::send(const void * data, int size, bool direct) { - if (!direct) { - if (data == 0 || size == 0) return; - if (!aboutSend()) return; - } - if (type_send == PIProtocol::Serial) - if (ser->send(data, size)) { - send_count++; - packets_out_sec++; - bytes_out_sec += size; - } - if (type_send == PIProtocol::Ethernet) - if (eth->send(data, size)) { - send_count++; - packets_out_sec++; - bytes_out_sec += size; - } -} - - -void PIProtocol::send() { - //lock(); - //memcpy(packet, sendDataPtr, sendDataSize); - //unlock(); - if (!aboutSend()) return; - if (sendDataPtr == 0 || sendDataSize == 0) return; - if (type_send == PIProtocol::Serial) - if (ser->send(sendDataPtr, sendDataSize)) { - send_count++; - packets_out_sec++; - bytes_out_sec += sendDataSize; - } - if (type_send == PIProtocol::Ethernet) - if (eth->send(sendDataPtr, sendDataSize)) { - send_count++; - packets_out_sec++; - bytes_out_sec += sendDataSize; - } -} diff --git a/src_main/io_devices/piprotocol.h b/src_main/io_devices/piprotocol.h deleted file mode 100755 index e5ebca82..00000000 --- a/src_main/io_devices/piprotocol.h +++ /dev/null @@ -1,238 +0,0 @@ -/*! \file piprotocol.h - * \brief Highly configurable from file I/O channel -*/ -/* - PIP - Platform Independent Primitives - Protocol, input/output channel (COM, UDP) - Copyright (C) 2018 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef PIPROTOCOL_H -#define PIPROTOCOL_H - -#include "piserial.h" -#include "piethernet.h" -#include "pipacketextractor.h" -#include "pitimer.h" -#include "piconfig.h" -#include "pifile.h" - -class PIProtocol; /// DEPRECATED - -class PIP_EXPORT PIMultiProtocolBase: protected PIObject /// DEPRECATED -{ - PIOBJECT_SUBCLASS(PIMultiProtocolBase, PIObject) - friend class PIProtocol; -public: - PIMultiProtocolBase() {;} /// DEPRECATED - virtual ~PIMultiProtocolBase() {;} - -protected: - virtual void received(PIProtocol * prot, bool corrected, uchar * data, int size) {;} - -private: - static void receiveEvent(PIMultiProtocolBase * p, PIProtocol * prot, bool corrected, uchar * data, int size) {p->mutex_receive.lock(); p->received(prot, corrected, data, size); p->mutex_receive.unlock();} - - PIMutex mutex_receive; - -}; - -typedef void (*ReceiveFunc)(void * ); - -/// events: -/// void receiverStarted() -/// void receiverStopped() -/// void senderStarted() -/// void senderStopped() -/// void received(bool validate_is_ok) -/// void qualityChanged(PIProtocol::Quality old_quality, PIProtocol::Quality new_quality) -/// -/// handlers: -/// void startReceive(float exp_frequency = -1.f) -/// void stopReceive() -/// void startSend(float frequency = -1.f) -/// void stopSend() -/// void start() -/// void stop() -/// void send() -/// void send(const void * data, int size, bool direct = false) -class PIP_EXPORT PIProtocol: public PIObject /// DEPRECATED -{ - PIOBJECT_SUBCLASS(PIProtocol, PIObject) - friend class PIMultiProtocolBase; - friend class PIMultiProtocol; - enum Type {None, Serial, Ethernet}; -public: - - //! Contructs an empty unconfigured protocol - PIProtocol(): PIObject() {init();} /// DEPRECATED - - //! Contructs protocol configured from file "config", config file section "name" - PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0, - void * recDataPtr = 0, int recDataSize = 0, void * sendDataPtr = 0, int sendDataSize = 0); // from config - - virtual ~PIProtocol(); - - //! Connection quality - enum Quality { - Unknown /** Unknown, no one packet received yet */ = 1, - Failure /** No connection, no one correct packet received for last period */ = 2, - Bad /** Bad connection, correct packets received <= 20% */ = 3, - Average /** Average connection, correct packets received > 20% and <= 80% */ = 4, - Good /** Good connection, correct packets received > 80% */ = 5 - }; - - EVENT_HANDLER0(void, startReceive) {startReceive(-1.f);} - EVENT_HANDLER1(void, startReceive, float, exp_frequency); // if "frequency = -1" used last passed value - EVENT_HANDLER0(void, stopReceive); - void setExpectedFrequency(float frequency); // for connection quality diagnostic - void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial - void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; packet_ext->setHeader(PIByteArray(headerPtr, headerSize)); packet_ext->setPayloadSize(dataSize); packet_ext->setPacketSize(dataSize);} - void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; packet_ext->setHeader(PIByteArray(headerPtr, headerSize)); packet_ext->setPayloadSize(dataSize); packet_ext->setPacketSize(dataSize);} - void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet - void setReceiverParameters(PIFlags parameters) {if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial - void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;} - float expectedFrequency() const {return exp_freq;} - - EVENT_HANDLER0(void, startSend) {startSend(-1.f);} // if "frequency = -1" used last passed value - EVENT_HANDLER1(void, startSend, float, frequency); // if "frequency = -1" used last passed value - EVENT_HANDLER0(void, stopSend) {sendTimer->stop(); senderStopped();} - void setSenderFrequency(float frequency) {send_freq = frequency;} - void setSenderDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial - void setSenderData(void * dataPtr, int dataSize) {sendDataPtr = (uchar * )dataPtr; sendDataSize = dataSize;} - void setSenderAddress(const PIString & ip, int port, bool force = false); // for Ethernet - void setSenderIP(const PIString & ip, bool force = false); // for Ethernet - void setSenderPort(int port, bool force = false); // for Ethernet - void setSenderParameters(PIFlags parameters) {if (type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial - float senderFrequency() const {return send_freq;} - - EVENT_HANDLER0(void, start) {startReceive(); startSend();} - EVENT_HANDLER0(void, stop) {stopReceive(); stopSend();} - EVENT_HANDLER0(void, send); - EVENT_HANDLER2(void, send, const void *, data, int, size) {send(data, size, false);} - EVENT_HANDLER3(void, send, const void *, data, int, size, bool, direct); - - void setName(const PIString & name) {protName = name; PIObject::setName(name);} - PIString name() const {return protName;} - void setDisconnectTimeout(float timeout) {timeout_ = timeout; changeDisconnectTimeout();} - float disconnectTimeout() const {return timeout_;} - const float * disconnectTimeout_ptr() const {return &timeout_;} - float immediateFrequency() const {return immediate_freq;} - float integralFrequency() const {return integral_freq;} - const float * immediateFrequency_ptr() const {return &immediate_freq;} - const float * integralFrequency_ptr() const {return &integral_freq;} - ullong receiveCountPerSec() const {return packets_in_sec;} - const ullong * receiveCountPerSec_ptr() const {return &packets_in_sec;} - ullong sendCountPerSec() const {return packets_out_sec;} - const ullong * sendCountPerSec_ptr() const {return &packets_out_sec;} - ullong receiveBytesPerSec() const {return bytes_in_sec;} - const ullong * receiveBytesPerSec_ptr() const {return &bytes_in_sec;} - ullong sendBytesPerSec() const {return bytes_out_sec;} - const ullong * sendBytesPerSec_ptr() const {return &bytes_out_sec;} - ullong receiveCount() const {return receive_count;} - const ullong * receiveCount_ptr() const {return &receive_count;} - ullong wrongCount() const {return wrong_count;} - const ullong * wrongCount_ptr() const {return &wrong_count;} - ullong sendCount() const {return send_count;} - const ullong * sendCount_ptr() const {return &send_count;} - ullong missedCount() const {return missed_count;} - const ullong * missedCount_ptr() const {return &missed_count;} - PIProtocol::Quality quality() const {return net_diag;} // receive quality - const int * quality_ptr() const {return (int * )&net_diag;} // receive quality pointer - PIString receiverDeviceName() const {return devReceiverName;} - PIString senderDeviceName() const {return devSenderName;} - PIString receiverDeviceState() const {return devReceiverState;} - const PIString * receiverDeviceState_ptr() const {return &devReceiverState;} - PIString senderDeviceState() const {return devSenderState;} - const PIString * senderDeviceState_ptr() const {return &devSenderState;} - PIString receiveSpeed() const {return speedIn;} - const PIString * receiveSpeed_ptr() const {return &speedIn;} - PIString sendSpeed() const {return speedOut;} - const PIString * sendSpeed_ptr() const {return &speedOut;} - - void * receiveData() {return dataPtr;} - void * sendData() {return sendDataPtr;} - - PIPacketExtractor * packetExtractor() {return packet_ext;} -// PIByteArray lastHeader() {return packet_ext->lastHeader();} - - EVENT0(receiverStarted) - EVENT0(receiverStopped) - EVENT0(senderStarted) - EVENT0(senderStopped) - EVENT1(received, bool, validate_is_ok) - EVENT2(qualityChanged, PIProtocol::Quality, new_quality, PIProtocol::Quality, old_quality) - -protected: - virtual bool receive(uchar * data, int size) {if (dataPtr != 0) memcpy(dataPtr, data, size); return true;} // executed when raw data received, break if 'false' return - virtual bool validate() {return true;} // function for validate algorithm and save data from dataPtr to external struct - virtual bool headerValidate(uchar * src, uchar * rec, int size) {for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;} // function for validate header (COM-port and headerSize > 0) - virtual uint checksum_i(void * data, int size) { // function for checksum (uint) - uint c = 0; - for (int i = 0; i < size; ++i) - c += ((uchar*)data)[i]; - return ~(c + 1); - } - virtual uchar checksum_c(void * data, int size) { // function for checksum (uchar) - uchar c = 0; - for (int i = 0; i < size; ++i) - c += ((uchar*)data)[i]; - return ~(c + 1); - } - virtual bool aboutSend() {return true;} // executed before send data, if return 'false' then data is not sending - - void init(); - void init_sender(PIConfig::Entry & b, PIConfig::Entry & sb, const PIString & config); - void init_receiver(PIConfig::Entry & b, PIConfig::Entry & rb, const PIString & config); - void check_state(); - void calc_freq(); - void calc_diag(); - - PISerial * ser; - PIEthernet * eth; - uint dataSize, headerSize, sendDataSize; - uchar * dataPtr, * headerPtr, * sendDataPtr; - -private: - static void sendEvent(void * e, int) {((PIProtocol * )e)->send();} - static bool receiveEvent(void * t, uchar * data, int size); - static bool headerValidateEvent(void * t, uchar * src, uchar * rec, int size) {return ((PIProtocol * )t)->headerValidate(src, rec, size);} - static void diagEvent(void * t, int); - static void secEvent(void * t, int); - - void setMultiProtocolOwner(PIMultiProtocolBase * mp) {mp_owner = mp;} - PIMultiProtocolBase * multiProtocolOwner() const {return mp_owner;} - void changeDisconnectTimeout(); - - ReceiveFunc ret_func; - PIPacketExtractor * packet_ext; - PITimer * diagTimer, * sendTimer, * secTimer; - PITimeMeasurer diag_tm; - PIMultiProtocolBase * mp_owner; - PIProtocol::Type type_send, type_rec; - PIProtocol::Quality net_diag; - PIDeque last_freq; - PIDeque last_packets; - PIString protName, devReceiverName, devReceiverState, devSenderName, devSenderState, speedIn, speedOut; - bool work, new_mp_prot; - float exp_freq, send_freq, ifreq, immediate_freq, integral_freq, timeout_; - int packets[2], pckt_cnt, pckt_cnt_max; - char cur_pckt; - ullong wrong_count, receive_count, send_count, missed_count, packets_in_sec, packets_out_sec, bytes_in_sec, bytes_out_sec; - -}; - -#endif // PIPROTOCOL_H