Leosac  0.7.0
OpenSourceAccessControl
rplethprotocol.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014-2016 Leosac
3 
4  This file is part of Leosac.
5 
6  Leosac is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Affero General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Leosac is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Affero General Public License for more details.
15 
16  You should have received a copy of the GNU Affero General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
26 #include "rplethprotocol.hpp"
27 #include <tools/log.hpp>
28 #include <vector>
29 
30 using namespace Leosac::Module::Rpleth;
31 
33  bool from_server /* = false */)
34 {
36  if (from_server)
37  {
38  // this is used for unit testing
39  buffer.fastForward(1);
41  }
42  std::size_t toRead = buffer.toRead();
43 
44  packet.status = Success;
45  packet.isGood = false;
46  if (toRead < PacketMinSize)
47  return (packet);
48 
49  packet.dataLen = buffer[SizeByteIdx];
50  if (toRead < packet.dataLen + 4U)
51  return (packet);
52  if (packet.dataLen)
53  {
54  packet.data = std::vector<Byte>(packet.dataLen);
55  for (unsigned int i = 0; i < packet.dataLen; ++i)
56  packet.data[i] = buffer[SizeByteIdx + 1 + i];
57  }
58  packet.type = buffer[TypeByteIdx];
59  packet.command = buffer[CommandByteIdx];
60  packet.sum = buffer[SizeByteIdx + packet.dataLen + 1];
61  packet.isGood =
62  true; // The packet has enough information to be interpreted by the protocol
63  buffer.fastForward(4 + packet.dataLen); // Circular buffer was actually read but
64  // indexes were not updated
65  if (packet.type >= MaxType)
66  packet.status = BadType;
67  else if (packet.sum != packet.checksum())
68  packet.status = BadChecksum;
69  return (packet);
70 }
71 
72 std::size_t RplethProtocol::encodeCommand(const RplethPacket &packet, Byte *buffer,
73  std::size_t size)
74 {
75  if (size < packet.dataLen + 5U) // Buffer is too small
76  return (0);
78  {
79  buffer[0] = packet.status;
80  ++buffer;
81  }
82  buffer[TypeByteIdx] = packet.type;
83  buffer[CommandByteIdx] = packet.command;
84  buffer[SizeByteIdx] = packet.dataLen;
85  for (int i = 0; i < packet.dataLen; ++i)
86  buffer[SizeByteIdx + i + 1] = packet.data[i];
87  buffer[SizeByteIdx + packet.dataLen + 1] = packet.checksum();
88 
90  return (packet.dataLen + 4 + 1);
91  else
92  return (packet.dataLen + 4);
93 }
std::uint8_t Byte
Definition: bufferutils.hpp:31
static RplethPacket decodeCommand(CircularBuffer &buffer, bool from_server=false)
Decode a packet from a circular buffer object.
Rpleth protocol implementation.
static const std::size_t PacketMinSize
static const std::size_t TypeByteIdx
Namespace where implementation for Rpleth support takes place.
Implementation of a ring buffer.
static const std::size_t CommandByteIdx
static std::size_t encodeCommand(const RplethPacket &packet, Byte *buffer, std::size_t size)
static const std::size_t SizeByteIdx
void fastForward(std::size_t offset)