//! \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 . */ #ifndef PIPACKETEXTRACTOR_H #define PIPACKETEXTRACTOR_H #include "piiodevice.h" //! \~english Header validation function type //! \~russian Тип функции проверки заголовка typedef std::function PacketExtractorHeaderFunc; //! \~english Payload validation function type //! \~russian Тип функции проверки полезной нагрузки typedef std::function PacketExtractorPayloadFunc; //! \~english Footer validation function type //! \~russian Тип функции проверки окончания typedef std::function 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