git-svn-id: svn://db.shs.com.ru/pip@634 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
@@ -36,6 +36,7 @@ set(PIP_SRC_COMPRESS "src_compress")
|
|||||||
set(PIP_SRC_USB "src_usb")
|
set(PIP_SRC_USB "src_usb")
|
||||||
set(PIP_SRC_FFTW "src_fftw")
|
set(PIP_SRC_FFTW "src_fftw")
|
||||||
set(PIP_SRC_OPENCL "src_opencl")
|
set(PIP_SRC_OPENCL "src_opencl")
|
||||||
|
set(PIP_SRC_IO_UTILS "src_io_utils")
|
||||||
set(PIP_LIBS_TARGETS pip)
|
set(PIP_LIBS_TARGETS pip)
|
||||||
set(LIBS_MAIN)
|
set(LIBS_MAIN)
|
||||||
set(LIBS_STATUS)
|
set(LIBS_STATUS)
|
||||||
@@ -120,6 +121,9 @@ gather_src("${PIP_SRC_FFTW}" CPP_LIB_FFTW HDRS PHDRS)
|
|||||||
# OpenCL lib
|
# OpenCL lib
|
||||||
gather_src("${PIP_SRC_OPENCL}" CPP_LIB_OPENCL HDRS PHDRS)
|
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
|
# Check Bessel functions
|
||||||
set(CMAKE_REQUIRED_INCLUDES math.h)
|
set(CMAKE_REQUIRED_INCLUDES math.h)
|
||||||
@@ -400,6 +404,19 @@ else()
|
|||||||
endif()
|
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
|
# Test program
|
||||||
add_executable(pip_test "main.cpp")
|
add_executable(pip_test "main.cpp")
|
||||||
|
|||||||
@@ -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_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_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_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)
|
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)
|
if (DEFINED ANDROID_PLATFORM)
|
||||||
set(PIP_INCLUDES ${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include/pip)
|
set(PIP_INCLUDES ${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include/pip)
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "piethutilbase.h"
|
#include "piethutilbase.h"
|
||||||
#include "picrypt.h"
|
#ifdef PIP_CRYPT
|
||||||
|
# include "picrypt.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
PIEthUtilBase::PIEthUtilBase() {
|
PIEthUtilBase::PIEthUtilBase() {
|
||||||
@@ -31,22 +33,35 @@ PIEthUtilBase::~PIEthUtilBase() {
|
|||||||
|
|
||||||
|
|
||||||
void PIEthUtilBase::createCryptKey(const PIString & k) {
|
void PIEthUtilBase::createCryptKey(const PIString & k) {
|
||||||
|
#ifdef PIP_CRYPT
|
||||||
_key = PICrypt::hash("sodium_bug");
|
_key = PICrypt::hash("sodium_bug");
|
||||||
_key = PICrypt::hash(k);
|
_key = PICrypt::hash(k);
|
||||||
|
#else
|
||||||
|
piCout << "[PIEthUtilBase] PICrypt wasn`t built!";
|
||||||
|
#endif
|
||||||
_crypt = true;
|
_crypt = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIByteArray PIEthUtilBase::cryptData(const PIByteArray & data) {
|
PIByteArray PIEthUtilBase::cryptData(const PIByteArray & data) {
|
||||||
if (!_crypt) return 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) {
|
PIByteArray PIEthUtilBase::decryptData(const PIByteArray & data) {
|
||||||
if (!_crypt) return data;
|
if (!_crypt) return data;
|
||||||
|
#ifdef PIP_CRYPT
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
PIByteArray ret = PICrypt::decrypt(data, _key, &ok);
|
PIByteArray ret = PICrypt::decrypt(data, _key, &ok);
|
||||||
if (!ok) return PIByteArray();
|
if (!ok) return PIByteArray();
|
||||||
return ret;
|
return ret;
|
||||||
|
#else
|
||||||
|
return PIByteArray();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ void PIMulticast::initAll(PIVector<PIEthernet::Address> al) {
|
|||||||
}
|
}
|
||||||
eth_lo = new PIEthernet();
|
eth_lo = new PIEthernet();
|
||||||
eth_lo->setDebug(false);
|
eth_lo->setDebug(false);
|
||||||
ce->setName("PIMulticast_loopback");
|
eth_lo->setName("PIMulticast_loopback");
|
||||||
if (!_send_only) {
|
if (!_send_only) {
|
||||||
eth_lo->setParameter(PIEthernet::ReuseAddress, false);
|
eth_lo->setParameter(PIEthernet::ReuseAddress, false);
|
||||||
CONNECTU(eth_lo, threadedReadEvent, this, mcastRead);
|
CONNECTU(eth_lo, threadedReadEvent, this, mcastRead);
|
||||||
@@ -127,6 +127,7 @@ void PIMulticast::initAll(PIVector<PIEthernet::Address> al) {
|
|||||||
void PIMulticast::send(const PIByteArray & data) {
|
void PIMulticast::send(const PIByteArray & data) {
|
||||||
PIByteArray cd = cryptData(data);
|
PIByteArray cd = cryptData(data);
|
||||||
if (cd.isEmpty()) return;
|
if (cd.isEmpty()) return;
|
||||||
|
PIMutexLocker ml(mcast_mutex);
|
||||||
piForeach (PIEthernet * e, eth_mcast)
|
piForeach (PIEthernet * e, eth_mcast)
|
||||||
e->send(cd);
|
e->send(cd);
|
||||||
if (eth_lo) {
|
if (eth_lo) {
|
||||||
@@ -139,6 +140,7 @@ void PIMulticast::send(const PIByteArray & data) {
|
|||||||
|
|
||||||
void PIMulticast::startRead() {
|
void PIMulticast::startRead() {
|
||||||
if (_send_only) return;
|
if (_send_only) return;
|
||||||
|
PIMutexLocker ml(mcast_mutex);
|
||||||
piForeach (PIEthernet * e, eth_mcast)
|
piForeach (PIEthernet * e, eth_mcast)
|
||||||
e->startThreadedRead();
|
e->startThreadedRead();
|
||||||
if (eth_lo)
|
if (eth_lo)
|
||||||
@@ -148,6 +150,7 @@ void PIMulticast::startRead() {
|
|||||||
|
|
||||||
|
|
||||||
void PIMulticast::stopRead() {
|
void PIMulticast::stopRead() {
|
||||||
|
PIMutexLocker ml(mcast_mutex);
|
||||||
piForeach (PIEthernet * e, eth_mcast)
|
piForeach (PIEthernet * e, eth_mcast)
|
||||||
e->stopThreadedRead();
|
e->stopThreadedRead();
|
||||||
if (eth_lo)
|
if (eth_lo)
|
||||||
@@ -157,7 +160,9 @@ void PIMulticast::stopRead() {
|
|||||||
|
|
||||||
|
|
||||||
void PIMulticast::reinit() {
|
void PIMulticast::reinit() {
|
||||||
|
initAll(PIEthernet::allAddresses());
|
||||||
|
if (_started)
|
||||||
|
startRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -172,7 +177,5 @@ void PIMulticast::mcastRead(uchar * data, int size) {
|
|||||||
void PIMulticast::run() {
|
void PIMulticast::run() {
|
||||||
PIVector<PIEthernet::Address> al = PIEthernet::allAddresses();
|
PIVector<PIEthernet::Address> al = PIEthernet::allAddresses();
|
||||||
if (al == prev_al) return;
|
if (al == prev_al) return;
|
||||||
initAll(al);
|
reinit();
|
||||||
if (_started)
|
|
||||||
startRead();
|
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
#include "piconsole.h"
|
#include "piconsole.h"
|
||||||
#include "piincludes_p.h"
|
#include "piincludes_p.h"
|
||||||
#include "pipeer.h"
|
#include "pipeer.h"
|
||||||
#include "piprotocol.h"
|
|
||||||
#include "pidiagnostics.h"
|
#include "pidiagnostics.h"
|
||||||
#include "pisystemmonitor.h"
|
#include "pisystemmonitor.h"
|
||||||
#ifndef WINDOWS
|
#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);}
|
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) {
|
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);}
|
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 <name>"
|
|
||||||
* * "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"
|
/** \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:
|
* \details This function add to column "column" next lines:
|
||||||
* * "<name> diagnostics"
|
* * "<name> diagnostics"
|
||||||
|
|||||||
@@ -133,7 +133,6 @@ public:
|
|||||||
//! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
|
//! 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 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 PIDiagnostics * ptr, int column = 1, FormatFlags format = PIConsole::Normal);
|
||||||
void addVariable(const PIString & name, const PISystemMonitor * ptr, int column = 1, FormatFlags format = PIConsole::Normal);
|
void addVariable(const PIString & name, const PISystemMonitor * ptr, int column = 1, FormatFlags format = PIConsole::Normal);
|
||||||
|
|
||||||
|
|||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pimultiprotocol.h"
|
|
||||||
/// DEPRECATED
|
|
||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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<PIProtocol * > 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
|
|
||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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<bool>("received");
|
|
||||||
addEvent<PIProtocol::Quality>("quality changed");
|
|
||||||
addEventHandler<float>(HANDLER(PIProtocol, startReceive));
|
|
||||||
addEventHandler<float>(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<PISerial::Parameters> 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<PISerial::Parameters> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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<PISerial::Parameters> 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<PISerial::Parameters> 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<float> last_freq;
|
|
||||||
PIDeque<char> 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
|
|
||||||
Reference in New Issue
Block a user