LCOV - code coverage report
Current view: top level - src/SLIPStream - SLIPSender.hpp (source / functions) Hit Total Coverage
Test: a50220e856a3e6a640349bc2a11ab5c9f66053af Lines: 16 16 100.0 %
Date: 2020-02-08 16:55:39 Functions: 12 12 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <AH/STL/algorithm> // std::reverse
       4             : #include <AH/STL/utility>   // std::forward
       5             : #include <limits.h>         // CHAR_BIT
       6             : #include <stddef.h>         // size_t
       7             : #include <string.h>         // memcpy
       8             : 
       9             : #include <boost/integer.hpp> // boost::uint_t
      10             : 
      11             : #include <SLIPStream/SLIP.hpp>
      12             : 
      13             : /// @addtogroup SLIP
      14             : /// @{
      15             : 
      16             : /**
      17             :  * @brief   Class for sending SLIP packets.
      18             :  * 
      19             :  * @tparam  Sender 
      20             :  *          The functor that actually sends a byte over the transmission 
      21             :  *          channel. Takes a single byte as an argument and returns the number
      22             :  *          of bytes written (similar to `Serial.write(uint8_t)`):  
      23             :  *          `size_t sender(uint8_t byte)`
      24             :  */
      25             : template <class Sender>
      26             : class SLIPSender {
      27             :   public:
      28             :     /**
      29             :      * @brief   Default constructor.
      30             :      */
      31             :     SLIPSender() = default;
      32             :     /**
      33             :      * @brief   Constructor with sender initialization.
      34             :      * 
      35             :      * @param   sender 
      36             :      *          Initialization for the sender. Perfect forwarding is used.
      37             :      */
      38          13 :     SLIPSender(Sender &&sender) : sender(std::forward<Sender>(sender)) {}
      39             : 
      40             :     /**
      41             :      * @brief   Start a packet.
      42             :      * 
      43             :      * Sends a SLIP @ref SLIP_Constants::END "END" character to flush the buffer
      44             :      * of the receiver.
      45             :      * 
      46             :      * @return  The number of bytes sent by the Sender.
      47             :      */
      48           4 :     size_t beginPacket() { return sender(SLIP_Constants::END); }
      49             :     /**
      50             :      * @brief   Finish the packet.
      51             :      * 
      52             :      * Sends a SLIP @ref SLIP_Constants::END "END" character.
      53             :      * 
      54             :      * @return  The number of bytes sent by the Sender.
      55             :      */
      56           4 :     size_t endPacket() { return sender(SLIP_Constants::END); }
      57             : 
      58             :     /**
      59             :      * @brief   Write some data as the body of a packet.
      60             :      * 
      61             :      * The data is encoded by SLIP before sending, so arbitrary binary data can
      62             :      * be sent.
      63             :      * 
      64             :      * @param   data 
      65             :      *          A pointer to the data to send.
      66             :      * @param   len 
      67             :      *          The number of bytes to send.
      68             :      * @return  The number of bytes sent by the Sender.
      69             :      */
      70             :     size_t write(const uint8_t *data, size_t len);
      71             : 
      72             :   private:
      73             :     Sender sender;
      74             : };
      75             : 
      76             : /// @}
      77             : 
      78             : /// @addtogroup CRC
      79             : /// @{
      80             : 
      81             : /**
      82             :  * @brief   Class for sending SLIP packets with a CRC checksum to check the 
      83             :  *          integrity of the packets.
      84             :  * 
      85             :  * @tparam  Sender 
      86             :  *          The functor that actually sends a byte over the transmission 
      87             :  *          channel. Takes a single byte as an argument and returns the number
      88             :  *          of bytes written (similar to `Serial.write(uint8_t)`):  
      89             :  *          `size_t sender(uint8_t byte)`
      90             :  * @tparam  CRC 
      91             :  *          The CRC type to use.
      92             :  */
      93             : template <class Sender, class CRC>
      94             : class SLIPSenderCRC {
      95             :   public:
      96             :     /**
      97             :      * @brief   Default constructor.
      98             :      */
      99             :     SLIPSenderCRC() = default;
     100             :     /**
     101             :      * @brief   Constructor with sender initialization.
     102             :      * 
     103             :      * @param   sender 
     104             :      *          Initialization for the sender. Perfect forwarding is used.  
     105             :      *          The CRC is default-initialized.
     106             :      */
     107             :     SLIPSenderCRC(Sender &&sender) : sender(std::forward<Sender>(sender)) {}
     108             :     /**
     109             :      * @brief   Constructor with CRC initialization.
     110             :      * 
     111             :      * @param   crc 
     112             :      *          Initialization for the CRC. Perfect forwarding is used.  
     113             :      *          The sender is default-initialized.
     114             :      */
     115             :     SLIPSenderCRC(CRC &&crc) : crc(std::forward<CRC>(crc)) {}
     116             :     /**
     117             :      * @brief   Constructor with sender and CRC initialization.
     118             :      * 
     119             :      * @param   sender 
     120             :      *          Initialization for the sender. Perfect forwarding is used.  
     121             :      * @param   crc 
     122             :      *          Initialization for the CRC. Perfect forwarding is used.  
     123             :      */
     124          10 :     SLIPSenderCRC(Sender &&sender, CRC &&crc)
     125          10 :         : sender(std::forward<Sender>(sender)), crc(std::forward<CRC>(crc)) {}
     126             : 
     127             :     /// The integer type of the checksum.
     128             :     using checksum_t = typename boost::uint_t<CRC::bit_count>::least;
     129             : 
     130             :     /// @copydoc    SLIPSender::beginPacket()
     131           3 :     size_t beginPacket() {
     132           3 :         this->crc.reset();
     133           3 :         return sender.beginPacket();
     134             :     }
     135             : 
     136             :     /**
     137             :      * @brief   Finish the packet.
     138             :      * 
     139             :      * Encodes and sends the checksum of all data sent using the @ref write
     140             :      * function, followed by a SLIP @ref SLIP_Constants::END "END" character.
     141             :      * 
     142             :      * @return  The number of bytes sent by the Sender.
     143             :      */
     144           3 :     size_t endPacket() {
     145           3 :         constexpr size_t numChars = sizeof(checksum_t);
     146           3 :         uint8_t buffer[numChars];
     147           3 :         const checksum_t checksum = this->crc.checksum();
     148           3 :         memcpy(buffer, &checksum, numChars);
     149           3 :         std::reverse(std::begin(buffer), std::end(buffer));
     150           6 :         return sender.write(buffer, numChars) + sender.endPacket();
     151           3 :     }
     152             : 
     153             :     /// @copydoc    SLIPSender::write()
     154             :     size_t write(const uint8_t *data, size_t len);
     155             : 
     156             :   private:
     157             :     SLIPSender<Sender> sender;
     158             :     CRC crc;
     159             : };
     160             : 
     161             : /// @}
     162             : 
     163             : #include "SLIPSender.ipp"

Generated by: LCOV version 1.14-6-g40580cd