572 lines
34 KiB
C++
572 lines
34 KiB
C++
//! \addtogroup IO-Utils
|
||
//! \{
|
||
//! \file piconnection.h
|
||
//! \brief
|
||
//! \~english Complex I/O point
|
||
//! \~russian Составное устройство ввода/вывода
|
||
//! \details
|
||
//! \~english This class provides a complex I/O point that can manage multiple devices, filters, channels, and senders.
|
||
//! \~russian Этот класс предоставляет составное устройство ввода/вывода, которое может управлять множеством устройств, фильтров, каналов и отправителей.
|
||
//! \~\}
|
||
/*
|
||
PIP - Platform Independent Primitives
|
||
Complex I/O point
|
||
Ivan Pelipenko peri4ko@yandex.ru
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef PICONNECTION_H
|
||
#define PICONNECTION_H
|
||
|
||
#include "pidiagnostics.h"
|
||
#include "pipacketextractor.h"
|
||
|
||
class PIConfig;
|
||
|
||
//! \~english Complex I/O point
|
||
//! \~russian Составное устройство ввода/вывода
|
||
//! \details This class provides a complex I/O point that can manage multiple devices, filters, channels, and senders.
|
||
//! \~russian Этот класс предоставляет составное устройство ввода/вывода, которое может управлять множеством устройств, фильтров, каналов и отправителей.
|
||
class PIP_EXPORT PIConnection: public PIObject {
|
||
PIOBJECT_SUBCLASS(PIConnection, PIObject);
|
||
|
||
public:
|
||
//! \~english Constructs connection with name "name", or with default name = "connection"
|
||
//! \~russian Создает подключение с именем "name" или с именем по умолчанию "connection"
|
||
PIConnection(const PIString & name = PIStringAscii("connection"));
|
||
|
||
//! \~english Constructs connection and configure it from config file "config" from section "name"
|
||
//! \~russian Создает подключение и настраивает его из файла конфигурации "config" из секции "name"
|
||
PIConnection(const PIString & config, const PIString & name);
|
||
|
||
//! \~english Constructs connection and configure it from config content "string" from section "name"
|
||
//! \~russian Создает подключение и настраивает его из содержимого конфигурации "string" из секции "name"
|
||
PIConnection(PIString * string, const PIString & name);
|
||
|
||
//! \~english Destructor
|
||
//! \~russian Деструктор
|
||
~PIConnection();
|
||
|
||
//! \~english Configure connection from config file "config" from section "name". Returns if configuration was successful
|
||
//! \~russian Настраивает подключение из файла конфигурации "config" из секции "name". Возвращает успешность настройки
|
||
//! \details \b Warning: all devices, filters and channels removed before configure!
|
||
//! \~russian \b Внимание: все устройства, фильтры и каналы удаляются перед настройкой!
|
||
bool configureFromConfig(const PIString & config, const PIString & name = PIStringAscii("connection"));
|
||
|
||
//! \~english Configure connection from config content "string" from section "name". Returns if configuration was successful
|
||
//! \~russian Настраивает подключение из содержимого конфигурации "string" из секции "name". Возвращает успешность настройки
|
||
//! \details \b Warning: all devices, filters and channels removed before configure!
|
||
//! \~russian \b Внимание: все устройства, фильтры и каналы удаляются перед настройкой!
|
||
bool configureFromString(PIString * string, const PIString & name = PIStringAscii("connection"));
|
||
|
||
//! \~english Returns config file section of current connection configuration
|
||
//! \~russian Возвращает секцию файла конфигурации текущей конфигурации подключения
|
||
PIString makeConfig() const;
|
||
|
||
|
||
//! \~english Add device with full path "full_path", open mode "mode" to Device pool and connection
|
||
//! \~russian Добавляет устройство с полным путем "full_path", режимом открытия "mode" в пул устройств и подключение
|
||
//! \details Returns pointer to device or null if device can not be created. If "start" is true,
|
||
//! \~english read thread is started immediately. Else, you can start read thread with functions \a startThreadedRead()
|
||
//! \~russian поток чтения запускается немедленно. В противном случае можно запустить поток чтения с помощью функций \a startThreadedRead()
|
||
//! \~english or \a startAllThreadedReads(). By default, read thread doesn`t start
|
||
//! \~russian или \a startAllThreadedReads(). По умолчанию поток чтения не запускается
|
||
PIIODevice * addDevice(const PIString & full_path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite, bool start = false);
|
||
|
||
//! \~english Sets the name for device "dev"
|
||
//! \~russian Устанавливает имя для устройства "dev"
|
||
void setDeviceName(PIIODevice * dev, const PIString & name);
|
||
|
||
//! \~english Returns list of device names
|
||
//! \~russian Возвращает список имен устройств
|
||
PIStringList deviceNames(const PIIODevice * dev) const;
|
||
|
||
//! \~english Remove device with full path "full_path" from connection
|
||
//! \~russian Удаляет устройство с полным путем "full_path" из подключения
|
||
//! \details Returns if device was removed. If there is no connection bounded to this device,
|
||
//! \~english it will be removed from Device pool
|
||
//! \~russian оно будет удалено из пула устройств
|
||
bool removeDevice(const PIString & full_path);
|
||
|
||
//! \~english Remove all device from connection
|
||
//! \~russian Удаляет все устройства из подключения
|
||
//! \details If there is no connection bounded to there devices, they removed from Device pool
|
||
//! \~russian Если к устройствам не привязано подключение, они удаляются из пула устройств
|
||
void removeAllDevices();
|
||
|
||
//! \~english Returns device with full path "full_path" or null if there is no such device
|
||
//! \~russian Возвращает устройство с полным путем "full_path" или null, если такого устройства нет
|
||
PIIODevice * deviceByFullPath(const PIString & full_path) const;
|
||
|
||
//! \~english Returns device with name "name" or null if there is no such device
|
||
//! \~russian Возвращает устройство с именем "name" или null, если такого устройства нет
|
||
PIIODevice * deviceByName(const PIString & name) const;
|
||
|
||
//! \~english Returns all devices bounded to this connection
|
||
//! \~russian Возвращает все устройства, привязанные к этому подключению
|
||
PIVector<PIIODevice *> boundedDevices() const;
|
||
|
||
//! \~english Add filter with name "name" to device with full path "full_path_name" or filter "full_path_name"
|
||
//! \~russian Добавляет фильтр с именем "name" к устройству с полным путем "full_path_name" или фильтру "full_path_name"
|
||
//! \details If there is no filter with name "name", connection create new with split mode "mode" and bound
|
||
//! \~english to it device "full_path_name" or filter "full_path_name". If filter with name "name" already exists,
|
||
//! \~english device "full_path_name" or filter "full_path_name" add to this filter.
|
||
//! \~russian к нему устройство "full_path_name" или фильтр "full_path_name". Если фильтр с именем "name" уже существует,
|
||
//! \~english This function returns PIPacketExtractor * assosiated with this filter
|
||
//! \~russian устройство "full_path_name" или фильтр "full_path_name" добавляется к этому фильтру.
|
||
//! \~english This function returns PIPacketExtractor * assosiated with this filter
|
||
//! \~russian Эта функция возвращает PIPacketExtractor *, связанный с этим фильтром
|
||
//! \~\sa PIPacketExtractor
|
||
//! \details \b Attention! "mode" is altual olny if new filter was created!
|
||
//! \~russian \b Внимание! "mode" актуален только если был создан новый фильтр!
|
||
PIPacketExtractor *
|
||
addFilter(const PIString & name, const PIString & full_path_name, PIPacketExtractor::SplitMode mode = PIPacketExtractor::None);
|
||
|
||
//! \~english Add filter with name "name" to device "dev"
|
||
//! \~russian Добавляет фильтр с именем "name" к устройству "dev"
|
||
PIPacketExtractor *
|
||
addFilter(const PIString & name, const PIIODevice * dev, PIPacketExtractor::SplitMode mode = PIPacketExtractor::None) {
|
||
return addFilter(name, devFPath(dev), mode);
|
||
}
|
||
|
||
//! \~english Add filter with "filter" to device "dev"
|
||
//! \~russian Добавляет фильтр "filter" к устройству "dev"
|
||
PIPacketExtractor * addFilter(PIPacketExtractor * filter, const PIString & full_path_name);
|
||
|
||
//! \~english Add filter with "filter" to device "dev"
|
||
//! \~russian Добавляет фильтр "filter" к устройству "dev"
|
||
PIPacketExtractor * addFilter(PIPacketExtractor * filter, const PIIODevice * dev) { return addFilter(filter, devFPath(dev)); }
|
||
|
||
//! \~english Remove from filter with name "name" device with full path "full_path_name" or filter "full_path_name"
|
||
//! \~russian Удаляет из фильтра с именем "name" устройство с полным путем "full_path_name" или фильтр "full_path_name"
|
||
//! \details If there is no devices bounded to this filter, it will be removed. Returns if device was removed
|
||
//! \~russian Если к этому фильтру не привязано устройств, он будет удален. Возвращает успешность удаления устройства
|
||
bool removeFilter(const PIString & name, const PIString & full_path_name);
|
||
|
||
//! \~english Remove from filter with name "name" device or filter "dev"
|
||
//! \~russian Удаляет из фильтра с именем "name" устройство или фильтр "dev"
|
||
bool removeFilter(const PIString & name, const PIIODevice * dev);
|
||
|
||
//! \~english Remove filter with name "name". Returns if filter was removed
|
||
//! \~russian Удаляет фильтр с именем "name". Возвращает успешность удаления фильтра
|
||
bool removeFilter(const PIString & name);
|
||
|
||
//! \~english Remove all filters from connection
|
||
//! \~russian Удаляет все фильтры из подключения
|
||
void removeAllFilters();
|
||
|
||
//! \~english Returns all filters of connection
|
||
//! \~russian Возвращает все фильтры подключения
|
||
PIVector<PIPacketExtractor *> filters() const;
|
||
|
||
//! \~english Returns all filter names of connection
|
||
//! \~russian Возвращает все имена фильтров подключения
|
||
PIStringList filterNames() const;
|
||
|
||
//! \~english Returns PIPacketExtractor * assosiated with filter "name" or null if there is no such filter
|
||
//! \~russian Возвращает PIPacketExtractor *, связанный с фильтром "name" или null, если такого фильтра нет
|
||
PIPacketExtractor * filter(const PIString & name) const;
|
||
|
||
//! \~english Returns all devices bounded to filter "name"
|
||
//! \~russian Возвращает все устройства, привязанные к фильтру "name"
|
||
PIVector<PIIODevice *> filterBoundedDevices(const PIString & name) const;
|
||
|
||
//! \~english Add to connection channel from "name_from" to "name_to"
|
||
//! \~russian Добавляет в подключение канал от "name_from" к "name_to"
|
||
//! \details "name_from" and "name_to" can be full pathes of devices or device names or filter names.
|
||
//! \~english Returns \b false if there if no such device or filter, else create channel and returns \b true
|
||
//! \~russian Возвращает \b false, если такого устройства или фильтра нет, иначе создает канал и возвращает \b true
|
||
bool addChannel(const PIString & name_from, const PIString & name_to);
|
||
|
||
//! \~english Add to connection channel from "name_from" to "dev_to"
|
||
//! \~russian Добавляет в подключение канал от "name_from" к "dev_to"
|
||
bool addChannel(const PIString & name_from, const PIIODevice * dev_to) { return addChannel(name_from, devFPath(dev_to)); }
|
||
|
||
//! \~english Add to connection channel from "dev_from" to "name_to"
|
||
//! \~russian Добавляет в подключение канал от "dev_from" к "name_to"
|
||
bool addChannel(const PIIODevice * dev_from, const PIString & name_to) { return addChannel(devFPath(dev_from), name_to); }
|
||
|
||
//! \~english Add to connection channel from "dev_from" to "dev_to"
|
||
//! \~russian Добавляет в подключение канал от "dev_from" к "dev_to"
|
||
bool addChannel(const PIIODevice * dev_from, const PIIODevice * dev_to) { return addChannel(devFPath(dev_from), devFPath(dev_to)); }
|
||
|
||
//! \~english Remove from connection channel from "name_from" to "name_to"
|
||
//! \~russian Удаляет из подключения канал от "name_from" к "name_to"
|
||
//! \details "name_from" and "name_to" can be full pathes of devices or filter names.
|
||
//! \~english Returns \b false if there if no such device or filter, else remove channel and returns \b true
|
||
//! \~russian Возвращает \b false, если такого устройства или фильтра нет, иначе удаляет канал и возвращает \b true
|
||
bool removeChannel(const PIString & name_from, const PIString & name_to);
|
||
|
||
//! \~english Remove from connection channel from "name_from" to "dev_to"
|
||
//! \~russian Удаляет из подключения канал от "name_from" к "dev_to"
|
||
bool removeChannel(const PIString & name_from, const PIIODevice * dev_to) { return removeChannel(name_from, devFPath(dev_to)); }
|
||
|
||
//! \~english Remove from connection channel from "dev_from" to "name_to"
|
||
//! \~russian Удаляет из подключения канал от "dev_from" к "name_to"
|
||
bool removeChannel(const PIIODevice * dev_from, const PIString & name_to) { return removeChannel(devFPath(dev_from), name_to); }
|
||
|
||
//! \~english Remove from connection channel from "dev_from" to "dev_to"
|
||
//! \~russian Удаляет из подключения канал от "dev_from" к "dev_to"
|
||
bool removeChannel(const PIIODevice * dev_from, const PIIODevice * dev_to) {
|
||
return removeChannel(devFPath(dev_from), devFPath(dev_to));
|
||
}
|
||
|
||
//! \~english Remove from connection all channels from "name_from"
|
||
//! \~russian Удаляет из подключения все каналы от "name_from"
|
||
//! \details "name_from" can be full path of device or filter name.
|
||
//! \~english Returns \b false if there if no such device or filter, else remove channels and returns \b true
|
||
//! \~russian Возвращает \b false, если такого устройства или фильтра нет, иначе удаляет каналы и возвращает \b true
|
||
bool removeChannel(const PIString & name_from);
|
||
|
||
//! \~english Remove from connection all channels from "dev_from"
|
||
//! \~russian Удаляет из подключения все каналы от "dev_from"
|
||
bool removeChannel(const PIIODevice * dev_from) { return removeChannel(devFPath(dev_from)); }
|
||
|
||
//! \~english Remove from connection all channels
|
||
//! \~russian Удаляет из подключения все каналы
|
||
void removeAllChannels();
|
||
|
||
//! \~english Returns all channels of this connection as full pathes or filter names pair array (from, to)
|
||
//! \~russian Возвращает все каналы этого подключения в виде массива пар полных путей или имен фильтров (от, до)
|
||
PIVector<PIPair<PIString, PIString>> channels() const;
|
||
|
||
//! \~english Add to connection sender with name "name" device with full path "full_path"
|
||
//! \~russian Добавляет в подключение отправителя с именем "name" устройство с полным путем "full_path"
|
||
//! \details If there is no sender with name "name", connection create new, bound
|
||
//! \~english to it device "full_path_name" and start sender timer with frequency "frequency".
|
||
//! \~russian к нему устройство "full_path_name" и запускает таймер отправителя с частотой "frequency".
|
||
//! \~english If sender with name "name" already exists, device "full_path_name" add to this sender
|
||
//! \~russian Если отправитель с именем "name" уже существует, устройство "full_path_name" добавляется к этому отправителю
|
||
//! \~english If "start" is true, sender is started immediately. Else, you can start sender with
|
||
//! \~russian Если "start" равно true, отправитель запускается немедленно. В противном случае можно запустить отправителя с помощью
|
||
//! \~english functions \a startSender()
|
||
//! \~russian функций \a startSender()
|
||
//! \~\sa startSender()
|
||
//! \details \b Attention! "frequency" is actual olny if new sender was created!
|
||
//! \~russian \b Внимание! "frequency" актуален только если был создан новый отправитель!
|
||
void addSender(const PIString & name, const PIString & full_path_name, float frequency, bool start = false);
|
||
|
||
//! \~english Add to connection sender with name "name" device "dev"
|
||
//! \~russian Добавляет в подключение отправителя с именем "name" устройство "dev"
|
||
void addSender(const PIString & name, const PIIODevice * dev, float frequency, bool start = false) {
|
||
addSender(name, devFPath(dev), frequency, start);
|
||
}
|
||
|
||
//! \~english Remove from sender with name "name" device with full path "full_path_name"
|
||
//! \~russian Удаляет из отправителя с именем "name" устройство с полным путем "full_path_name"
|
||
//! \details If there is no devices bounded to this sender, it will be removed. Returns if sender was removed
|
||
//! \~russian Если к этому отправителю не привязано устройств, он будет удален. Возвращает успешность удаления отправителя
|
||
bool removeSender(const PIString & name, const PIString & full_path_name);
|
||
|
||
//! \~english Remove from sender with name "name" device "dev"
|
||
//! \~russian Удаляет из отправителя с именем "name" устройство "dev"
|
||
bool removeSender(const PIString & name, const PIIODevice * dev) { return removeSender(name, devFPath(dev)); }
|
||
|
||
//! \~english Remove sender with name "name", returns if sender was removed
|
||
//! \~russian Удаляет отправителя с именем "name", возвращает успешность удаления отправителя
|
||
bool removeSender(const PIString & name);
|
||
|
||
//! \~english Set sender "name" fixed send data "data", returns if sender exists
|
||
//! \~russian Устанавливает фиксированные данные отправки для отправителя "name", возвращает существование отправителя
|
||
bool setSenderFixedData(const PIString & name, const PIByteArray & data);
|
||
|
||
//! \~english Remove sender "name" fixed send data, returns if sender exists
|
||
//! \~russian Удаляет фиксированные данные отправки для отправителя "name", возвращает существование отправителя
|
||
bool clearSenderFixedData(const PIString & name);
|
||
|
||
//! \~english Returns sender "name" fixed send data
|
||
//! \~russian Возвращает фиксированные данные отправки для отправителя "name"
|
||
PIByteArray senderFixedData(const PIString & name) const;
|
||
|
||
//! \~english Returns sender "name" timer frequency, -1 if there is no such sender, or 0 if sender is not started yet
|
||
//! \~russian Возвращает частоту таймера отправителя "name", -1 если такого отправителя нет, или 0 если отправитель еще не запущен
|
||
float senderFrequency(const PIString & name) const;
|
||
|
||
//! \~english Remove from connection all senders
|
||
//! \~russian Удаляет из подключения всех отправителей
|
||
void removeAllSenders();
|
||
|
||
//! \~english Start read thread of device with full path "full_path"
|
||
//! \~russian Запускает поток чтения устройства с полным путем "full_path"
|
||
void startThreadedRead(const PIString & full_path_name);
|
||
|
||
//! \~english Start read thread of device "dev"
|
||
//! \~russian Запускает поток чтения устройства "dev"
|
||
void startThreadedRead(const PIIODevice * dev) { startThreadedRead(devFPath(dev)); }
|
||
|
||
//! \~english Start read threads of all Device pool device
|
||
//! \~russian Запускает потоки чтения всех устройств пула устройств
|
||
void startAllThreadedReads();
|
||
|
||
//! \~english Start sender "name" timer
|
||
//! \~russian Запускает таймер отправителя "name"
|
||
void startSender(const PIString & name);
|
||
|
||
//! \~english Start all senders timers
|
||
//! \~russian Запускает все таймеры отправителей
|
||
void startAllSenders();
|
||
|
||
//! \~english Start all read threads and senders
|
||
//! \~russian Запускает все потоки чтения и отправителей
|
||
void start() {
|
||
startAllThreadedReads();
|
||
startAllSenders();
|
||
}
|
||
|
||
//! \~english Stop read thread of device with full path "full_path"
|
||
//! \~russian Останавливает поток чтения устройства с полным путем "full_path"
|
||
void stopThreadedRead(const PIString & full_path_name);
|
||
|
||
//! \~english Stop read thread of device "dev"
|
||
//! \~russian Останавливает поток чтения устройства "dev"
|
||
void stopThreadedRead(const PIIODevice * dev) { stopThreadedRead(devFPath(dev)); }
|
||
|
||
//! \~english Stop read threads of all Device pool device
|
||
//! \~russian Останавливает потоки чтения всех устройств пула устройств
|
||
void stopAllThreadedReads();
|
||
|
||
//! \~english Stop sender "name" timer
|
||
//! \~russian Останавливает таймер отправителя "name"
|
||
void stopSender(const PIString & name);
|
||
|
||
//! \~english Stop all senders timers
|
||
//! \~russian Останавливает все таймеры отправителей
|
||
void stopAllSenders();
|
||
|
||
//! \~english Stop all read threads and senders
|
||
//! \~russian Останавливает все потоки чтения и отправителей
|
||
void stop() {
|
||
stopAllThreadedReads();
|
||
stopAllSenders();
|
||
}
|
||
|
||
//! \~english Stop connection and remove all devices
|
||
//! \~russian Останавливает подключение и удаляет все устройства
|
||
void destroy() {
|
||
stop();
|
||
removeAllDevices();
|
||
}
|
||
|
||
//! \~english Returns if there are no devices in this connection
|
||
//! \~russian Возвращает, если в этом подключении нет устройств
|
||
bool isEmpty() const { return device_modes.isEmpty(); }
|
||
|
||
|
||
//! \~english Returns PIDiagnostics * assosiated with device with full path "full_path_name", name "full_path_name" or filter "full_path_name"
|
||
//! \~russian Возвращает PIDiagnostics *, связанный с устройством с полным путем "full_path_name", именем "full_path_name" или фильтром "full_path_name"
|
||
PIDiagnostics * diagnostic(const PIString & full_path_name) const;
|
||
|
||
//! \~english Returns PIDiagnostics * assosiated with device or filter "dev"
|
||
//! \~russian Возвращает PIDiagnostics *, связанный с устройством или фильтром "dev"
|
||
PIDiagnostics * diagnostic(const PIIODevice * dev) const { return diags_.value(const_cast<PIIODevice *>(dev), 0); }
|
||
|
||
//! \~english Write data "data" to device with full path "full_path" and returns result of \a write() function of device
|
||
//! \~russian Записывает данные "data" в устройство с полным путем "full_path" и возвращает результат функции \a write() устройства
|
||
int writeByFullPath(const PIString & full_path, const PIByteArray & data);
|
||
|
||
//! \~english Write data "data" to device with name "name" and returns result of \a write() function of device
|
||
//! \~russian Записывает данные "data" в устройство с именем "name" и возвращает результат функции \a write() устройства
|
||
int writeByName(const PIString & name, const PIByteArray & data);
|
||
|
||
//! \~english Write data "data" to device "dev" and returns result of \a write() function of device
|
||
//! \~russian Записывает данные "data" в устройство "dev" и возвращает результат функции \a write() устройства
|
||
int write(PIIODevice * dev, const PIByteArray & data);
|
||
|
||
//! \~english Returns all connections in application
|
||
//! \~russian Возвращает все подключения в приложении
|
||
static PIVector<PIConnection *> allConnections();
|
||
|
||
//! \~english Returns all devices in Device pool
|
||
//! \~russian Возвращает все устройства в пуле устройств
|
||
static PIVector<PIIODevice *> allDevices();
|
||
|
||
//! \~english Set Device pool fake mode to \"yes\" and returns previous mode
|
||
//! \~russian Устанавливает фальшивый режим пула устройств в \"yes\" и возвращает предыдущий режим
|
||
static bool setFakeMode(bool yes);
|
||
|
||
//! \~english Returns if Device pool works in fake mode
|
||
//! \~russian Возвращает, работает ли пул устройств в фальшивом режиме
|
||
static bool isFakeMode();
|
||
|
||
//! \~english Device pool class
|
||
//! \~russian Класс пула устройств
|
||
class PIP_EXPORT DevicePool: public PIThread {
|
||
PIOBJECT_SUBCLASS(DevicePool, PIThread);
|
||
friend void __DevicePool_threadReadDP(void * ddp);
|
||
friend class PIConnection;
|
||
|
||
protected:
|
||
struct DeviceData;
|
||
|
||
public:
|
||
DevicePool();
|
||
~DevicePool();
|
||
|
||
void init();
|
||
PIIODevice *
|
||
addDevice(PIConnection * parent, const PIString & fp, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite, bool start = true);
|
||
bool removeDevice(PIConnection * parent, const PIString & fp);
|
||
void unboundConnection(PIConnection * parent);
|
||
PIIODevice * device(const PIString & fp) const;
|
||
DeviceData * deviceData(PIIODevice * d) const;
|
||
//! \~english Returns list of bounded connections
|
||
//! \~russian Возвращает список привязанных подключений
|
||
PIVector<PIConnection *> boundedConnections() const;
|
||
//! \~english Returns list of bounded devices
|
||
//! \~russian Возвращает список привязанных устройств
|
||
PIVector<PIIODevice *> boundedDevices() const;
|
||
//! \~english Returns list of bounded devices for specific parent connection
|
||
//! \~russian Возвращает список привязанных устройств для конкретного родительского подключения
|
||
PIVector<PIIODevice *> boundedDevices(const PIConnection * parent) const;
|
||
|
||
protected:
|
||
//! \~english Device data structure
|
||
//! \~russian Структура данных устройства
|
||
struct PIP_EXPORT DeviceData {
|
||
//! \~english Constructor
|
||
//! \~russian Конструктор
|
||
DeviceData(): dev(0), rthread(0), started(false) {}
|
||
//! \~english Destructor
|
||
//! \~russian Деструктор
|
||
~DeviceData();
|
||
//! \~english Device pointer
|
||
//! \~russian Указатель на устройство
|
||
PIIODevice * dev;
|
||
//! \~english Read thread pointer
|
||
//! \~russian Указатель на поток чтения
|
||
PIThread * rthread;
|
||
//! \~english Started flag
|
||
//! \~russian Флаг запуска
|
||
bool started;
|
||
//! \~english List of listeners
|
||
//! \~russian Список слушателей
|
||
PIVector<PIConnection *> listeners;
|
||
};
|
||
|
||
//! \~english Thread execution function
|
||
//! \~russian Функция выполнения потока
|
||
void run() override;
|
||
|
||
//! \~english Called when device is read
|
||
//! \~russian Вызывается при чтении устройства
|
||
void deviceReaded(DeviceData * dd, const PIByteArray & data);
|
||
|
||
//! \~english Map of devices
|
||
//! \~russian Карта устройств
|
||
PIMap<PIString, DeviceData *> devices;
|
||
//! \~english Fake mode flag
|
||
//! \~russian Флаг фальшивого режима
|
||
bool fake;
|
||
};
|
||
|
||
//! \~english Data received event
|
||
//! \~russian Событие получения данных
|
||
EVENT2(dataReceivedEvent, const PIString &, from, const PIByteArray &, data);
|
||
//! \~english Packet received event
|
||
//! \~russian Событие получения пакета
|
||
EVENT2(packetReceivedEvent, const PIString &, from, const PIByteArray &, data);
|
||
//! \~english Quality changed event
|
||
//! \~russian Событие изменения качества
|
||
EVENT3(qualityChanged, const PIIODevice *, dev, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality);
|
||
|
||
//! \~english Events
|
||
//! \~russian События
|
||
//! \{
|
||
|
||
//! \fn void dataReceivedEvent(const PIString & from, const PIByteArray & data)
|
||
//! \~english Raise on data received from device with full path "from"
|
||
//! \~russian Возникает при получении данных от устройства с полным путем "from"
|
||
|
||
//! \fn void packetReceivedEvent(const PIString & from, const PIByteArray & data)
|
||
//! \~english Raise on packet received from filter with name "from"
|
||
//! \~russian Возникает при получении пакета от фильтра с именем "from"
|
||
|
||
//! \fn void qualityChanged(const PIIODevice * device, PIDiagnostics::Quality new_quality, PIDiagnostics::Quality old_quality)
|
||
//! \~english Raise on diagnostic quality of device "device" changed from "old_quality" to "new_quality"
|
||
//! \~russian Возникает при изменении диагностического качества устройства "device" с "old_quality" на "new_quality"
|
||
|
||
//! \}
|
||
|
||
protected:
|
||
//! \~english Executes on data received from device with full path "from"
|
||
//! \~russian Выполняется при получении данных от устройства с полным путем "from"
|
||
virtual void dataReceived(const PIString & from, const PIByteArray & data) {}
|
||
|
||
//! \~english Executes on packet received from filter with name "from"
|
||
//! \~russian Выполняется при получении пакета от фильтра с именем "from"
|
||
virtual void packetReceived(const PIString & from, const PIByteArray & data) {}
|
||
|
||
//! \~english You should returns data for sender "sender_name"
|
||
//! \~russian Вы должны возвращать данные для отправителя "sender_name"
|
||
virtual PIByteArray senderData(const PIString & sender_name);
|
||
|
||
private:
|
||
bool configure(PIConfig & conf, const PIString & name_);
|
||
void rawReceived(PIIODevice * dev, const PIString & from, const PIByteArray & data);
|
||
void unboundExtractor(PIPacketExtractor * pe);
|
||
EVENT_HANDLER2(void, packetExtractorReceived, const uchar *, data, int, size);
|
||
EVENT_HANDLER2(void, diagQualityChanged, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality);
|
||
|
||
PIString devPath(const PIIODevice * d) const;
|
||
PIString devFPath(const PIIODevice * d) const;
|
||
PIIODevice * devByString(const PIString & s) const;
|
||
|
||
struct PIP_EXPORT Extractor {
|
||
Extractor(): extractor(0) {}
|
||
~Extractor();
|
||
PIPacketExtractor * extractor;
|
||
PIVector<PIIODevice *> devices;
|
||
};
|
||
|
||
class PIP_EXPORT Sender: public PITimer {
|
||
PIOBJECT_SUBCLASS(Sender, PIObject);
|
||
|
||
public:
|
||
Sender(PIConnection * parent_ = 0);
|
||
~Sender() { stopAndWait(); }
|
||
PIConnection * parent;
|
||
PIVector<PIIODevice *> devices;
|
||
PIByteArray sdata;
|
||
PISystemTime int_;
|
||
void tick(int) override;
|
||
};
|
||
|
||
PIMap<PIString, Extractor *> extractors;
|
||
PIMap<PIString, Sender *> senders;
|
||
PIMap<PIString, PIIODevice *> device_names;
|
||
PIMap<PIIODevice *, PIIODevice::DeviceMode> device_modes;
|
||
PIMap<PIIODevice *, PIVector<PIPacketExtractor *>> bounded_extractors;
|
||
PIMap<PIIODevice *, PIVector<PIIODevice *>> channels_;
|
||
PIMap<PIIODevice *, PIDiagnostics *> diags_;
|
||
|
||
static PIVector<PIConnection *> _connections;
|
||
};
|
||
|
||
void __DevicePool_threadReadDP(void * ddp);
|
||
|
||
|
||
extern PIP_EXPORT PIConnection::DevicePool * __device_pool__;
|
||
|
||
class PIP_EXPORT __DevicePoolContainer__ {
|
||
public:
|
||
__DevicePoolContainer__();
|
||
static bool inited_;
|
||
};
|
||
|
||
static __DevicePoolContainer__ __device_pool_container__;
|
||
|
||
|
||
#endif // PICONNECTION_H
|