Line data Source code
1 : #pragma once 2 : 3 : #include <SLIPStream/SLIPParser.hpp> 4 : #include <SLIPStream/SLIPSender.hpp> 5 : #include <Stream.h> 6 : 7 : /// @addtogroup SLIP 8 : /// @{ 9 : 10 : /** 11 : * @brief Class that implements SLIP, a simple packet framing protocol. 12 : * 13 : * [RFC 1055](https://tools.ietf.org/html/rfc1055) 14 : */ 15 : class SLIPStream { 16 : public: 17 : /// Functor that sends bytes over an Arduino Stream. 18 : struct StreamSender { 19 9 : StreamSender(Stream &stream) : stream(&stream) {} 20 3 : StreamSender(Stream *stream) : stream(stream) {} 21 57 : size_t operator()(uint8_t c) const { return stream->write(c); } 22 : Stream *stream; 23 : }; 24 : 25 : public: 26 4 : SLIPStream(Stream &stream, const SLIPParser &parser) 27 4 : : stream(&stream), parser(parser) {} 28 : SLIPStream(Stream &stream) : stream(&stream), parser(nullptr, 0) {} 29 : 30 : /** 31 : * @brief Sends a packet. 32 : * 33 : * @param data 34 : * A pointer to the start of the data. 35 : * @param len 36 : * The length of the data. 37 : * @return The number of bytes transmitted over the Stream. If no write 38 : * errors occur, this number will be larger than @p len, because 39 : * of the delimiters and stuffing bytes. 40 : */ 41 : size_t writePacket(const uint8_t *data, size_t len); 42 : 43 : /// @copydoc SLIPSender::beginPacket 44 : size_t beginPacket(); 45 : /// @copydoc SLIPSender::write 46 : size_t write(const uint8_t *data, size_t len); 47 : /// @copydoc SLIPSender::endPacket 48 : size_t endPacket(); 49 : 50 : /** 51 : * @brief Receives a packet into the read buffer. 52 : * 53 : * If more than len bytes are received, the packet will be truncated. 54 : * 55 : * @return The number of bytes stored in the buffer. 56 : */ 57 : size_t readPacket(); 58 : 59 : /// @copydoc SLIPParser::wasTruncated 60 4 : bool wasTruncated() const { return parser.wasTruncated(); } 61 : 62 : /// @copydoc SLIPParser::numTruncated 63 : size_t numTruncated() const { return parser.numTruncated(); } 64 : 65 : private: 66 : Stream *stream; 67 : SLIPParser parser; 68 : }; 69 : 70 : /// @} 71 : 72 : /// @addtogroup CRC 73 : /// @{ 74 : 75 : /** 76 : * @brief Class that implements SLIP, a simple packet framing protocol, and 77 : * that uses cyclic redundancy checks (CRCs) on transmitted and 78 : * received packets. 79 : * 80 : * @see [**RFC 1055**](https://tools.ietf.org/html/rfc1055) 81 : * @see [**Boost::CRC**](https://www.boost.org/doc/libs/1_72_0/doc/html/crc.html) 82 : */ 83 : template <class CRC> 84 : class SLIPStreamCRC { 85 : public: 86 : using StreamSender = SLIPStream::StreamSender; 87 : 88 9 : SLIPStreamCRC(Stream &stream, CRC &&senderCRC, const SLIPParser &parser, 89 : CRC &&parserCRC) 90 9 : : stream(&stream), sender(stream, std::forward<CRC>(senderCRC)), 91 9 : parser(parser, std::forward<CRC>(parserCRC)) {} 92 : 93 : /** 94 : * @brief Sends a packet. 95 : * 96 : * @param data 97 : * A pointer to the start of the data. 98 : * @param len 99 : * The length of the data. 100 : * @return The number of bytes transmitted over the Stream. If no write 101 : * errors occur, this number will be larger than @p len, because 102 : * of the delimiters, checksums and stuffing bytes. 103 : */ 104 : size_t writePacket(const uint8_t *data, size_t len); 105 : 106 : /// @copydoc SLIPSenderCRC::beginPacket 107 : size_t beginPacket(); 108 : /// @copydoc SLIPSenderCRC::write 109 : size_t write(const uint8_t *data, size_t len); 110 : /// @copydoc SLIPSenderCRC::endPacket 111 : size_t endPacket(); 112 : 113 : /// @copydoc SLIPStream::readPacket 114 : size_t readPacket(); 115 : 116 : /// @copydoc SLIPParserCRC::wasTruncated 117 10 : bool wasTruncated() const { return parser.wasTruncated(); } 118 : /// @copydoc SLIPParserCRC::numTruncated 119 5 : size_t numTruncated() const { return parser.numTruncated(); } 120 : 121 : /// @copydoc SLIPParserCRC::checksum_t 122 : using checksum_t = typename SLIPParserCRC<CRC>::checksum_t; 123 : 124 : /// @copydoc SLIPParserCRC::checksum 125 10 : checksum_t checksum() const { return parser.checksum(); } 126 : 127 : private: 128 : Stream *stream; 129 : SLIPSenderCRC<StreamSender, CRC> sender; 130 : SLIPParserCRC<CRC> parser; 131 : }; 132 : 133 : /// @} 134 : 135 : #include "SLIPStream.ipp"