Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
160
libs/tracking/protocol.cpp
Normal file
160
libs/tracking/protocol.cpp
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
#include "tracking/protocol.hpp"
|
||||
|
||||
#include "coding/endianness.hpp"
|
||||
#include "coding/reader.hpp"
|
||||
#include "coding/writer.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/logging.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename Container>
|
||||
vector<uint8_t> CreateDataPacketImpl(Container const & points, tracking::Protocol::PacketType const type)
|
||||
{
|
||||
vector<uint8_t> buffer;
|
||||
MemWriter<decltype(buffer)> writer(buffer);
|
||||
|
||||
uint32_t version = tracking::Protocol::Encoder::kLatestVersion;
|
||||
switch (type)
|
||||
{
|
||||
case tracking::Protocol::PacketType::DataV0: version = 0; break;
|
||||
case tracking::Protocol::PacketType::DataV1: version = 1; break;
|
||||
case tracking::Protocol::PacketType::Error:
|
||||
case tracking::Protocol::PacketType::AuthV0:
|
||||
LOG(LERROR, ("Can't create a non-DATA packet as a DATA packet. PacketType =", type));
|
||||
return {};
|
||||
}
|
||||
|
||||
tracking::Protocol::Encoder::SerializeDataPoints(version, writer, points);
|
||||
|
||||
auto packet = tracking::Protocol::CreateHeader(type, static_cast<uint32_t>(buffer.size()));
|
||||
packet.insert(packet.end(), begin(buffer), end(buffer));
|
||||
|
||||
return packet;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace tracking
|
||||
{
|
||||
uint8_t const Protocol::kOk[4] = {'O', 'K', '\n', '\n'};
|
||||
uint8_t const Protocol::kFail[4] = {'F', 'A', 'I', 'L'};
|
||||
|
||||
static_assert(sizeof(Protocol::kFail) >= sizeof(Protocol::kOk), "");
|
||||
|
||||
// static
|
||||
vector<uint8_t> Protocol::CreateHeader(PacketType type, uint32_t payloadSize)
|
||||
{
|
||||
vector<uint8_t> header;
|
||||
InitHeader(header, type, payloadSize);
|
||||
return header;
|
||||
}
|
||||
|
||||
// static
|
||||
vector<uint8_t> Protocol::CreateAuthPacket(string const & clientId)
|
||||
{
|
||||
vector<uint8_t> packet;
|
||||
|
||||
InitHeader(packet, PacketType::CurrentAuth, static_cast<uint32_t>(clientId.size()));
|
||||
packet.insert(packet.end(), begin(clientId), end(clientId));
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
// static
|
||||
vector<uint8_t> Protocol::CreateDataPacket(DataElementsCirc const & points, PacketType type)
|
||||
{
|
||||
return CreateDataPacketImpl(points, type);
|
||||
}
|
||||
|
||||
// static
|
||||
vector<uint8_t> Protocol::CreateDataPacket(DataElementsVec const & points, PacketType type)
|
||||
{
|
||||
return CreateDataPacketImpl(points, type);
|
||||
}
|
||||
|
||||
// static
|
||||
pair<Protocol::PacketType, size_t> Protocol::DecodeHeader(vector<uint8_t> const & data)
|
||||
{
|
||||
if (data.size() < sizeof(uint32_t /* header */))
|
||||
{
|
||||
LOG(LWARNING, ("Header size is too small", data.size(), sizeof(uint32_t /* header */)));
|
||||
return make_pair(PacketType::Error, data.size());
|
||||
}
|
||||
|
||||
uint32_t size = (*reinterpret_cast<uint32_t const *>(data.data())) & 0xFFFFFF00;
|
||||
if (!IsBigEndianMacroBased())
|
||||
size = ReverseByteOrder(size);
|
||||
return make_pair(PacketType(static_cast<uint8_t>(data[0])), size);
|
||||
}
|
||||
|
||||
// static
|
||||
string Protocol::DecodeAuthPacket(Protocol::PacketType type, vector<uint8_t> const & data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Protocol::PacketType::AuthV0: return string(begin(data), end(data));
|
||||
case Protocol::PacketType::Error:
|
||||
case Protocol::PacketType::DataV0:
|
||||
case Protocol::PacketType::DataV1: LOG(LERROR, ("Error decoding AUTH packet. PacketType =", type)); break;
|
||||
}
|
||||
return string();
|
||||
}
|
||||
|
||||
// static
|
||||
Protocol::DataElementsVec Protocol::DecodeDataPacket(PacketType type, vector<uint8_t> const & data)
|
||||
{
|
||||
DataElementsVec points;
|
||||
MemReaderWithExceptions memReader(data.data(), data.size());
|
||||
ReaderSource<MemReaderWithExceptions> src(memReader);
|
||||
try
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Protocol::PacketType::DataV0: Encoder::DeserializeDataPoints(0 /* version */, src, points); break;
|
||||
case Protocol::PacketType::DataV1: Encoder::DeserializeDataPoints(1 /* version */, src, points); break;
|
||||
case Protocol::PacketType::Error:
|
||||
case Protocol::PacketType::AuthV0: LOG(LERROR, ("Error decoding DATA packet. PacketType =", type)); return {};
|
||||
}
|
||||
return points;
|
||||
}
|
||||
catch (Reader::SizeException const & ex)
|
||||
{
|
||||
LOG(LWARNING, ("Wrong packet. SizeException. Msg:", ex.Msg(), ". What:", ex.what()));
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void Protocol::InitHeader(vector<uint8_t> & packet, PacketType type, uint32_t payloadSize)
|
||||
{
|
||||
packet.resize(sizeof(uint32_t));
|
||||
uint32_t & size = *reinterpret_cast<uint32_t *>(packet.data());
|
||||
size = payloadSize;
|
||||
|
||||
ASSERT_LESS(size, 0x00FFFFFF, ());
|
||||
|
||||
if (!IsBigEndianMacroBased())
|
||||
size = ReverseByteOrder(size);
|
||||
|
||||
packet[0] = static_cast<uint8_t>(type);
|
||||
}
|
||||
|
||||
string DebugPrint(Protocol::PacketType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Protocol::PacketType::Error: return "Error";
|
||||
case Protocol::PacketType::AuthV0: return "AuthV0";
|
||||
case Protocol::PacketType::DataV0: return "DataV0";
|
||||
case Protocol::PacketType::DataV1: return "DataV1";
|
||||
}
|
||||
stringstream ss;
|
||||
ss << "Unknown(" << static_cast<uint32_t>(type) << ")";
|
||||
return ss.str();
|
||||
}
|
||||
} // namespace tracking
|
||||
Loading…
Add table
Add a link
Reference in a new issue