/*! \file pipacketextractor.h * \ingroup IO * \~\brief * \~english Packets extractor * \~russian Извлекатель пакетов */ /* 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" /// TODO: написать документацию, тут ничего не понятно // Pass data, recHeaderPtr, received_data, recHeaderSize. Return true if packet is correct nor return false. typedef int (*PacketExtractorHeaderFunc)(const uchar *, const uchar *, int); typedef bool (*PacketExtractorPayloadFunc)(const uchar *, int ); typedef bool (*PacketExtractorFooterFunc)(const uchar *, const uchar *, int); class PIP_EXPORT PIPacketExtractor: public PIIODevice { PIIODEVICE(PIPacketExtractor, "pckext"); friend class PIConnection; public: //! Extract algorithms 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() milliseconds */ }; //! Contructs extractor with child device "device_" and extract algorithm "mode" explicit PIPacketExtractor(PIIODevice * device_ = nullptr, SplitMode mode = None); virtual ~PIPacketExtractor() {stop();} //! Returns child %device PIIODevice * device() {return dev;} //! Set child %device to "device_" void setDevice(PIIODevice * device_); //! Returns buffer size int bufferSize() const {return buffer_size;} //! Set buffer size to "new_size" bytes, should be at least greater than whole packet size void setBufferSize(int new_size); void setHeaderCheckSlot(PacketExtractorHeaderFunc f) {func_header = f;} void setPayloadCheckSlot(PacketExtractorPayloadFunc f) {func_payload = f;} void setFooterCheckSlot(PacketExtractorFooterFunc f) {func_footer = f;} //! Set extract algorithm void setSplitMode(SplitMode mode) {setProperty("splitMode", int(mode));} //! Set payload size, used for PIPacketExtractor::Header and PIPacketExtractor::Footer algorithms void setPayloadSize(int size); //! Set header data, used for PIPacketExtractor::Header and PIPacketExtractor::HeaderAndFooter algorithms void setHeader(const PIByteArray & data); //! Set footer data, used for PIPacketExtractor::Footer and PIPacketExtractor::HeaderAndFooter algorithms void setFooter(const PIByteArray & data); //! Set packet size, used for PIPacketExtractor::Size algorithm void setPacketSize(int size) {setProperty("packetSize", size);} //! Set timeout in milliseconds, used for PIPacketExtractor::Timeout algorithm void setTimeout(double msecs) {setProperty("timeout", msecs);} //! Returns current extract algorithm SplitMode splitMode() const {return mode_;} //! Returns current payload size, used for PIPacketExtractor::Header and PIPacketExtractor::Footer algorithms int payloadSize() const {return dataSize;} //! Returns current header data, used for PIPacketExtractor::Header and PIPacketExtractor::HeaderAndFooter algorithms PIByteArray header() const {return src_header;} //! Returns current footer data, used for PIPacketExtractor::Footer and PIPacketExtractor::HeaderAndFooter algorithms PIByteArray footer() const {return src_footer;} //! Returns current packet size, used for PIPacketExtractor::Size algorithm int packetSize() const {return packetSize_;} //! Returns current timeout in milliseconds, used for PIPacketExtractor::Timeout algorithm double timeout() const {return time_;} //! Returns missed by validating functions bytes count ullong missedBytes() const {return missed;} //! Returns missed by validating functions packets count, = missedBytes() / packetSize ullong missedPackets() const {return missed_packets;} //! Returns pointer to \a missedBytes() count. Useful for output to PIConsole const ullong * missedBytes_ptr() const {return &missed;} //! Returns pointer to \a missedPackets() count. Useful for output to PIConsole const ullong * missedPackets_ptr() const {return &missed_packets;} //! Add data to extractor, raise \a packetReceived() if packet is ready void appendData(const uchar * d, int s) {threadedRead(d, s);} //! Add data to extractor, raise \a packetReceived() if packet is ready void appendData(const PIByteArray & data) {threadedRead(data.data(), data.size_s());} EVENT2(packetReceived, const uchar * , data, int, size); //! \events //! \{ //! \fn void packetReceived(const uchar * data, int size) //! \brief Raise on successfull \a packetValidate() function //! \} 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 *); virtual int readDevice(void * read_to, int max_size) override; virtual int writeDevice(const void * data, int max_size) override; virtual bool threadedRead(const uchar * readed, int size) override; virtual PIString constructFullPathDevice() const override; virtual bool openDevice() override; virtual bool closeDevice() override; virtual DeviceInfoFlags deviceInfoFlags() const override; PIIODevice * dev; PIByteArray buffer, tmpbuf, src_header, src_footer, trbuf; PacketExtractorHeaderFunc func_header; PacketExtractorPayloadFunc func_payload; PacketExtractorFooterFunc func_footer; SplitMode mode_; int buffer_size, dataSize, packetSize_hf, footerInd, packetSize_; double time_; bool header_found; ullong missed, missed_packets; }; #endif // PIPACKETEXTRACTOR_H