Files
pip/libs/main/io_utils/pipacketextractor.h

258 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! \addtogroup IO
//! \{
//! \file pipacketextractor.h
//! \brief
//! \~english Packets extractor
//! \~russian Извлекатель пакетов
//! \details
//! \~english The PIPacketExtractor class provides packet recognition from data stream using various algorithms.
//! \~russian Класс PIPacketExtractor предоставляет распознавание пакетов из потока данных с использованием различных алгоритмов.
//! \~\}
/*
PIP - Platform Independent Primitives
Packets extractor
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 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 PIPACKETEXTRACTOR_H
#define PIPACKETEXTRACTOR_H
#include "piiodevice.h"
//! \~english Header validation function type
//! \~russian Тип функции проверки заголовка
typedef std::function<int(const uchar *, const uchar *, int)> PacketExtractorHeaderFunc;
//! \~english Payload validation function type
//! \~russian Тип функции проверки полезной нагрузки
typedef std::function<bool(const uchar *, int)> PacketExtractorPayloadFunc;
//! \~english Footer validation function type
//! \~russian Тип функции проверки окончания
typedef std::function<bool(const uchar *, const uchar *, int)> PacketExtractorFooterFunc;
//! \~english Packets extractor
//! \~russian Извлекатель пакетов
//! \details
//! \~english The PIPacketExtractor class provides packet recognition from data stream using various algorithms such as header detection,
//! footer detection, size-based extraction, and timeout-based extraction.
//! \~russian Класс PIPacketExtractor предоставляет распознавание пакетов из потока данных с использованием различных алгоритмов, таких как
//! обнаружение заголовка, обнаружение окончания, извлечение по размеру и извлечение по таймауту.
class PIP_EXPORT PIPacketExtractor: public PIIODevice {
PIIODEVICE(PIPacketExtractor, "pckext");
friend class PIConnection;
public:
//! \~english Extract algorithms
//! \~russian Алгоритмы извлечения
//! \details
//! \~english Defines the packet extraction algorithms supported by PIPacketExtractor
//! \~russian Определяет алгоритмы извлечения пакетов, поддерживаемые PIPacketExtractor
enum SplitMode {
None /** No data processing */,
Header /** Detect packets with \a header() and following \a payloadSize() */,
Footer /** Detect packets with \a footer() and leading \a payloadSize() */,
HeaderAndFooter /** Detect packets with \a header() and \a footer() without \a payloadSize() */,
Size /** Detect packets with \a packetSize() */,
Timeout /** Wait for first read, then read for \a timeout() */
};
//! \~english Constructs extractor with child device "device_" and extract algorithm "mode"
//! \~russian Создает экстрактор с дочерним устройством "device_" и алгоритмом извлечения "mode"
explicit PIPacketExtractor(PIIODevice * device_ = nullptr, SplitMode mode = None);
//! \~english Destructor
//! \~russian Деструктор
virtual ~PIPacketExtractor() { stop(); }
//! \~english Returns child %device
//! \~russian Возвращает дочернее устройство
PIIODevice * device() { return dev; }
//! \~english Set child %device to "device_"
//! \~russian Установить дочернее устройство в "device_"
void setDevice(PIIODevice * device_);
//! \~english Get bytes available
//! \~russian Получить доступные байты
//! \details
//! \~english Returns the number of bytes available for reading from the child device
//! \~russian Возвращает количество байт, доступных для чтения из дочернего устройства
ssize_t bytesAvailable() const override;
//! \~english Set header check function
//! \~russian Установить функцию проверки заголовка
//! \details
//! \~english Sets the callback function used to validate packet headers
//! \~russian Устанавливает функцию обратного вызова, используемую для проверки заголовков пакетов
void setHeaderCheckSlot(PacketExtractorHeaderFunc f) { func_header = f; }
//! \~english Set payload check function
//! \~russian Установить функцию проверки полезной нагрузки
//! \details
//! \~english Sets the callback function used to validate packet payload
//! \~russian Устанавливает функцию обратного вызова, используемую для проверки полезной нагрузки пакетов
void setPayloadCheckSlot(PacketExtractorPayloadFunc f) { func_payload = f; }
//! \~english Set footer check function
//! \~russian Установить функцию проверки окончания
//! \details
//! \~english Sets the callback function used to validate packet footers
//! \~russian Устанавливает функцию обратного вызова, используемую для проверки окончаний пакетов
void setFooterCheckSlot(PacketExtractorFooterFunc f) { func_footer = f; }
//! \~english Set extract algorithm
//! \~russian Установить алгоритм извлечения
//! \details
//! \~english Sets the packet extraction algorithm to be used
//! \~russian Устанавливает алгоритм извлечения пакетов, который будет использоваться
void setSplitMode(SplitMode mode) { setProperty("splitMode", int(mode)); }
//! \~english Set payload size, used for PIPacketExtractor::Header and PIPacketExtractor::Footer algorithms
//! \~russian Установить размер полезной нагрузки
//! \details
//! \~english Sets the expected payload size for Header and Footer extraction algorithms
//! \~russian Устанавливает ожидаемый размер полезной нагрузки для алгоритмов извлечения Header и Footer
void setPayloadSize(int size);
//! \~english Set header data, used for PIPacketExtractor::Header and PIPacketExtractor::HeaderAndFooter algorithms
//! \~russian Установить данные заголовка
//! \details
//! \~english Sets the header pattern used to identify packet start
//! \~russian Устанавливает шаблон заголовка, используемый для идентификации начала пакета
void setHeader(const PIByteArray & data);
//! \~english Set footer data, used for PIPacketExtractor::Footer and PIPacketExtractor::HeaderAndFooter algorithms
//! \~russian Установить данные окончания
//! \details
//! \~english Sets the footer pattern used to identify packet end
//! \~russian Устанавливает шаблон окончания, используемый для идентификации конца пакета
void setFooter(const PIByteArray & data);
//! \~english Set timeout, used for PIPacketExtractor::Timeout algorithm
//! \~russian Установить таймаут
//! \details Sets the timeout duration for the Timeout extraction algorithm
//! \~russian Устанавливает длительность таймаута для алгоритма извлечения Timeout
void setTimeout(PISystemTime tm) { setProperty("timeout", tm); }
//! \~english Returns current extract algorithm
//! \~russian Возвращает текущий алгоритм извлечения
//! \details
//! \~english Returns the currently configured packet extraction algorithm
//! \~russian Возвращает текущий настроенный алгоритм извлечения пакетов
SplitMode splitMode() const { return mode_; }
//! \~english Returns current payload size
//! \~russian Возвращает текущий размер полезной нагрузки
//! \details
//! \~english Returns the expected payload size used by Header and Footer algorithms
//! \~russian Возвращает ожидаемый размер полезной нагрузки, используемый алгоритмами Header и Footer
int payloadSize() const { return dataSize; }
//! \~english Returns current header data
//! \~russian Возвращает текущие данные заголовка
//! \details
//! \~english Returns the configured header pattern
//! \~russian Возвращает настроенный шаблон заголовка
PIByteArray header() const { return src_header; }
//! \~english Returns current footer data
//! \~russian Возвращает текущие данные окончания
//! \details
//! \~english Returns the configured footer pattern
//! \~russian Возвращает настроенный шаблон окончания
PIByteArray footer() const { return src_footer; }
//! \~english Returns current timeout in milliseconds
//! \~russian Возвращает текущий таймаут в миллисекундах
//! \details
//! \~english Returns the configured timeout duration
//! \~russian Возвращает настроенную длительность таймаута
PISystemTime timeout() const { return time_; }
//! \~english Returns missed by validating functions bytes count
//! \~russian Возвращает количество байт, пропущенных функциями проверки
//! \details
//! \~english Returns the number of bytes that were skipped during validation failures
//! \~russian Возвращает количество байт, которые были пропущены при неудачных проверках
ullong missedBytes() const { return missed; }
//! \~english Add data to extractor, raise \a packetReceived() if packet is ready
//! \~russian Добавить данные в экстрактор, вызвать \a packetReceived() если пакет готов
void appendData(const uchar * d, int s) { threadedRead(d, s); }
//! \~english Add data to extractor, raise \a packetReceived() if packet is ready
//! \~russian Добавить данные в экстрактор, вызвать \a packetReceived() если пакет готов
void appendData(const PIByteArray & data) { threadedRead(data.data(), data.size_s()); }
//! \events
//! \{
//! \fn void packetReceived(const uchar * data, int size)
//! \brief Raise on successfull \a packetValidate() function
EVENT2(packetReceived, const uchar *, data, int, size);
//! \}
protected:
/** \brief Function to validate header
* \param src Your header content
* \param rec Received header
* \param size Header size
* \details Default implementation returns by-byte "src" with "rec" compare result */
virtual int validateHeader(const uchar * src, const uchar * rec, int size);
/** \brief Function to validate footer
* \param src Your footer content
* \param rec Received footer
* \param size Footer size
* \details Default implementation returns by-byte "src" with "rec" compare result */
virtual bool validateFooter(const uchar * src, const uchar * rec, int size);
/** \brief Function to validate payload
* \param rec Received payload
* \param size payload size
* \details Default implementation returns \b true */
virtual bool validatePayload(const uchar * rec, int size);
private:
void construct();
void propertyChanged(const char *) override;
ssize_t readDevice(void * read_to, ssize_t max_size) override;
ssize_t writeDevice(const void * data, ssize_t max_size) override;
bool threadedRead(const uchar * readed, ssize_t size) override;
PIString constructFullPathDevice() const override;
bool openDevice() override;
bool closeDevice() override;
DeviceInfoFlags deviceInfoFlags() const override;
PIIODevice * dev;
PIByteArray src_header, src_footer, tmpbuf;
PacketExtractorHeaderFunc func_header;
PacketExtractorPayloadFunc func_payload;
PacketExtractorFooterFunc func_footer;
SplitMode mode_;
int dataSize, packetSize_pending, footerInd;
PISystemTime time_;
bool header_found;
ullong missed;
};
#endif // PIPACKETEXTRACTOR_H