mirror of https://github.com/infosecn1nja/C3.git
531 lines
21 KiB
C++
531 lines
21 KiB
C++
#pragma once
|
|
|
|
#include "BaseQuery.h"
|
|
#include "Common/MWR/Crypto/Crypto.hpp"
|
|
#include "Common/MWR/C3/Internals/BackendCommons.h"
|
|
#include "RouteId.h"
|
|
|
|
namespace MWR::C3::Core
|
|
{
|
|
// Typedefs.
|
|
using ProtocolsUnderlyingType = std::uint8_t;
|
|
using PropagationUnderlyingType = std::uint8_t;
|
|
|
|
/// Protocol types.
|
|
enum class Protocols : ProtocolsUnderlyingType
|
|
{
|
|
N2N, ///< [NeighborToNeighbor][SENDERS AID.IID][N2N Procedure][FIELDS]...
|
|
S2G, ///< [SendToGate]|ENCRYPTED ANONYMOUSLY->|[SENDERS AID]|ENCRYPTED AUTHENTICATED->|[N2G Procedure][FIELDS]...
|
|
G2A, ///< [G2A]|SIGNED->|[RECEIVERS AID]|ENCRYPTED->|[G2N Procedure][FIELDS]...
|
|
G2R, ///< [G2R]|SIGNED->|[AID][G2N Procedure][FIELDS]...
|
|
//G2B, ///< [G2B]|SIGNED->|[AID][G2N Procedure][FIELDS]... NOT IMPLEMENTED.
|
|
};
|
|
|
|
/// Sub-protocols of S2X.
|
|
enum class Propagation : ProtocolsUnderlyingType
|
|
{
|
|
Agent, ///< [G2X]|SIGNED->|[G2A][RECEIVERS AID]|ENCRYPTED->|[G2N Procedure][FIELDS]...
|
|
Route, ///< [G2X]|SIGNED->|[G2R][AID][G2N Procedure][FIELDS]...
|
|
//Branch, ///< [G2X]|SIGNED->|[G2B][AID][G2N Procedure][FIELDS]... NOT IMPLEMENTED.
|
|
};
|
|
|
|
/// Retrieve packet number and move buffer to position after.
|
|
/// @param packetAtProcedureNumber reference to packet buffer.
|
|
static ProceduresUnderlyingType ReadProcedureNo(ByteView& packetAtProcedureNumber)
|
|
{
|
|
// Sanity check.
|
|
if (packetAtProcedureNumber.empty())
|
|
throw std::runtime_error{ OBF("Packet too short.") };
|
|
|
|
return packetAtProcedureNumber.Read<ProceduresUnderlyingType>();
|
|
}
|
|
|
|
/// Neighbor Relay -> Neighbor Relay Procedures.
|
|
namespace ProceduresN2N
|
|
{
|
|
/// Base for all N2N queries.
|
|
struct QueryN2N : BaseQuery
|
|
{
|
|
/// Public constructor.
|
|
/// @param sender device that received query.
|
|
/// @param neighborRouteId RouteId of query sender.
|
|
/// @param procedureNo number identifying procedure.
|
|
/// @param packetAfterProcedureNumber body of query.
|
|
QueryN2N(std::weak_ptr<DeviceBridge> sender, RouteId neighborRouteId, ProceduresUnderlyingType procedureNo, ByteView packetAfterProcedureNumber)
|
|
: BaseQuery{ sender }
|
|
, m_SendersRid{ neighborRouteId }
|
|
, m_QueryPacketBody{ packetAfterProcedureNumber }
|
|
{
|
|
|
|
}
|
|
|
|
/// Constructor creating empty query.
|
|
/// Should be filled then sent.
|
|
/// @param sendersRid RouteId of query sender.
|
|
/// @param responseType indicates if response is required.
|
|
QueryN2N(RouteId sendersRid, ResponseType responseType = ResponseType::None)
|
|
: BaseQuery{ responseType }
|
|
, m_SendersRid{ sendersRid }
|
|
{
|
|
}
|
|
|
|
/// Constructs the following header: [N2N|AID.IID|ProcedureNo|Query Field].
|
|
/// Use to send serialized data.
|
|
/// @return buffer containing whole packet.
|
|
ByteVector ComposeQueryPacket() const override
|
|
{
|
|
return CompileProtocolHeader().Concat(CompileQueryHeader()).Concat(m_QueryPacketBody);
|
|
}
|
|
|
|
/// Get decrypted query body.
|
|
ByteVector GetQueryPacket(Crypto::PublicKey const& authenticationKey, Crypto::PrivateKey const& decrpytionKey)
|
|
{
|
|
return Crypto::DecryptFromAnonymous(m_QueryPacketBody, authenticationKey, decrpytionKey);
|
|
}
|
|
|
|
/// Get Query Body.
|
|
ByteView GetQueryPacket()
|
|
{
|
|
return m_QueryPacketBody;
|
|
}
|
|
|
|
/// Get Sender RouteId.
|
|
RouteId const& GetSenderRouteId() const { return m_SendersRid; }
|
|
|
|
protected:
|
|
ByteVector m_QueryPacketBody; ///< Whole Query packet along with all the headers.
|
|
|
|
/// Constructs the following header: [N2N|AID.IID].
|
|
/// @return buffer containing composed header.
|
|
ByteVector CompileProtocolHeader() const override
|
|
{
|
|
return ByteVector{}.Write(static_cast<ProtocolsUnderlyingType>(Protocols::N2N), m_SendersRid.ToByteArray());
|
|
}
|
|
|
|
private:
|
|
RouteId m_SendersRid; ///< This Query sender's RouteId.
|
|
};
|
|
|
|
/// Helper to template creating Queries.
|
|
/// @tparam ProcedureNumber identifier for each query. Assure that only one type inherits from Query<> with unique identifier.
|
|
template<ProceduresUnderlyingType ProcedureNumber>
|
|
struct Query : QueryN2N
|
|
{
|
|
/// Get underlying number of procedure.
|
|
static constexpr ProceduresUnderlyingType GetProcedureNumberConstexpr() { return ProcedureNumber; }
|
|
|
|
/// Get underlying number of procedure.
|
|
ProceduresUnderlyingType GetProcedureNumber() const override { return GetProcedureNumberConstexpr(); }
|
|
|
|
/// Forwarded constructors.
|
|
using QueryN2N::QueryN2N;
|
|
};
|
|
|
|
/// Query type used to join network.
|
|
struct InitializeRouteQuery : Query<0>
|
|
{
|
|
/// Create new instance.
|
|
/// @param sendersRid RouteId created from relay AgentId, and grc DeviceId.
|
|
/// @param buildId id of relay build.
|
|
/// @param gatewayEncryptionKey key used to encrypt package. Only gateway will be able to decrypt package.
|
|
/// @param agentsPublicEncryptionKey gateway will use this key to send encrypted messages to relay.
|
|
/// @param grcHash hash identifying type of first interface.
|
|
/// @param timestamp time of generating message.
|
|
/// @param responseType inform if recipient if response is required.
|
|
static std::unique_ptr<InitializeRouteQuery> Create(RouteId sendersRid, BuildId buildId, Crypto::PublicKey gatewayEncryptionKey, Crypto::PublicKey agentsPublicEncryptionKey, HashT grcHash, int32_t timestamp, ResponseType responseType = ResponseType::None)
|
|
{
|
|
auto query = std::make_unique<InitializeRouteQuery>(sendersRid, responseType);
|
|
query->m_QueryPacketBody = Crypto::EncryptAnonymously(buildId.ToByteVector().Write(agentsPublicEncryptionKey.ToByteVector(), grcHash, timestamp, HostInfo().ToByteVector()), gatewayEncryptionKey);
|
|
return query;
|
|
}
|
|
|
|
private:
|
|
/// Inherit Constructors.
|
|
using Query::Query;
|
|
};
|
|
|
|
/// Start of negotiation process. New relay request unique connection.
|
|
struct ChannelIdExchangeStep1 : Query<2>
|
|
{
|
|
/// Create query.
|
|
/// @param sendersRid route id of sender.
|
|
/// @param generatedInputId input id of negotiated channel from new relay.
|
|
static std::unique_ptr<ChannelIdExchangeStep1> Create(RouteId sendersRid, ByteView generatedInputId)
|
|
{
|
|
auto query = std::make_unique<ChannelIdExchangeStep1>(sendersRid);
|
|
query->m_QueryPacketBody = ByteVector{}.Write(generatedInputId);
|
|
return query;
|
|
}
|
|
|
|
private:
|
|
/// Inherit Constructors.
|
|
using Query::Query;
|
|
};
|
|
|
|
/// Closure of negotiation process. Network relay accepts unique connection.
|
|
struct ChannelIdExchangeStep2 : Query<3>
|
|
{
|
|
/// Create query.
|
|
/// @param sendersRid route id of sender.
|
|
/// @param generatedInputId input id of negotiated channel from network relay side.
|
|
static std::unique_ptr<ChannelIdExchangeStep2> Create(RouteId sendersRid, ByteView generatedInputId)
|
|
{
|
|
auto query = std::make_unique<ChannelIdExchangeStep2>(sendersRid);
|
|
query->m_QueryPacketBody = ByteVector{}.Write(generatedInputId);
|
|
return query;
|
|
}
|
|
|
|
private:
|
|
/// Inherit Constructors.
|
|
using Query::Query;
|
|
};
|
|
|
|
/// Class representing support for C3 N2N Requests.
|
|
struct RequestHandler
|
|
{
|
|
/// Declaration of support for InitializeRouteQuery Request.
|
|
virtual void On(InitializeRouteQuery&&) = 0;
|
|
|
|
/// Declaration of support for ChannelIdExchangeStep1 Request.
|
|
virtual void On(ChannelIdExchangeStep1) = 0;
|
|
|
|
/// Declaration of support for ChannelIdExchangeStep2 Request.
|
|
virtual void On(ChannelIdExchangeStep2) = 0;
|
|
|
|
/// Function responsible interpreting request and calling right handle.
|
|
/// @param sender Device that reported request.
|
|
/// @param neighborRouteId Id of sender relay.
|
|
/// @param packetAtProcedureNumber request with embedded procedure number.
|
|
void ParseRequestAndHandleIt(std::weak_ptr<DeviceBridge> sender, RouteId neighborRouteId, ByteView packetAtProcedureNumber)
|
|
{
|
|
auto procedureNo = ReadProcedureNo(packetAtProcedureNumber);
|
|
HandleQuery(sender, neighborRouteId, procedureNo, packetAtProcedureNumber);
|
|
}
|
|
|
|
/// Function responsible interpreting request and calling right handle.
|
|
/// @param sender Device that reported request.
|
|
/// @param neighborRouteId Id of sender relay.
|
|
/// @param procedureNo number of procedure.
|
|
/// @param packetAfterProcedureNumber request in binary form.
|
|
void HandleQuery(std::weak_ptr<DeviceBridge> sender, RouteId neighborRouteId, ProceduresUnderlyingType procedureNo, ByteView packetAfterProcedureNumber)
|
|
{
|
|
switch (procedureNo)
|
|
{
|
|
case InitializeRouteQuery::GetProcedureNumberConstexpr():
|
|
return On(InitializeRouteQuery{ sender, neighborRouteId, procedureNo, packetAfterProcedureNumber });
|
|
case ChannelIdExchangeStep1::GetProcedureNumberConstexpr():
|
|
return On(ChannelIdExchangeStep1{ sender, neighborRouteId, procedureNo, packetAfterProcedureNumber });
|
|
case ChannelIdExchangeStep2::GetProcedureNumberConstexpr():
|
|
return On(ChannelIdExchangeStep2{ sender, neighborRouteId, procedureNo, packetAfterProcedureNumber });
|
|
}
|
|
|
|
throw std::invalid_argument{ OBF("Unknown N2N Query Procedure number: ") + std::to_string(procedureNo) + OBF(".") };
|
|
}
|
|
};
|
|
}
|
|
|
|
namespace ProceduresS2G
|
|
{
|
|
/// Base for all S2G queries.
|
|
struct QueryS2G : BaseQuery
|
|
{
|
|
/// Public constructor.
|
|
/// @param sender device that received query.
|
|
/// @param sendersRid RouteId of query sender.
|
|
/// @param timestamp reported time at relay.
|
|
/// @param packetAfterProcedureNumber body of query.
|
|
QueryS2G(std::weak_ptr<DeviceBridge> sender, RouteId sendersRid, int32_t timestamp, ByteView packetAfterProcedureNumber)
|
|
: BaseQuery{ sender }
|
|
, m_SendersRid{ sendersRid }
|
|
, m_Timestamp{timestamp}
|
|
, m_QueryPacketBody{ packetAfterProcedureNumber }
|
|
{
|
|
|
|
}
|
|
|
|
/// Public constructor.
|
|
/// @param sendersRid RouteId of query sender.
|
|
/// @param timestamp reported time at relay.
|
|
/// @param responseType is response required.
|
|
QueryS2G(RouteId sendersRid, int32_t timestamp, ResponseType responseType = ResponseType::None)
|
|
: BaseQuery{ responseType }
|
|
, m_SendersRid{ sendersRid }
|
|
, m_Timestamp{ timestamp }
|
|
{
|
|
}
|
|
|
|
|
|
/// Constructs the S2G header.
|
|
/// Use to send serialized data.
|
|
/// @return buffer containing whole packet.
|
|
ByteVector ComposeQueryPacket() const override
|
|
{
|
|
return CompileProtocolHeader().Concat(m_QueryPacketBody);
|
|
}
|
|
|
|
/// Get decrypted query body.
|
|
ByteVector GetQueryPacket(Crypto::PublicKey const& authenticationKey, Crypto::PrivateKey const& decrpytionKey)
|
|
{
|
|
return Crypto::DecryptFromAnonymous(m_QueryPacketBody, authenticationKey, decrpytionKey);
|
|
}
|
|
|
|
/// Get Query Body.
|
|
ByteVector GetQueryPacket()
|
|
{
|
|
return m_QueryPacketBody;
|
|
}
|
|
|
|
/// Get Sender RouteId.
|
|
RouteId const& GetSenderRouteId() const { return m_SendersRid; }
|
|
|
|
/// Get timestamp of request.
|
|
int32_t GetTimestamp() const { return m_Timestamp; }
|
|
|
|
protected:
|
|
ByteVector m_QueryPacketBody; ///< Whole Query packet along with all the headers.
|
|
|
|
/// Constructs the following header: [S2G].
|
|
/// @return buffer containing composed header.
|
|
ByteVector CompileProtocolHeader() const override
|
|
{
|
|
return ByteVector{}.Write(static_cast<ProtocolsUnderlyingType>(Protocols::S2G));
|
|
}
|
|
|
|
private:
|
|
RouteId m_SendersRid; ///< This Query sender's RouteId.
|
|
int32_t m_Timestamp; ///< Timestamp of request.
|
|
|
|
};
|
|
|
|
/// Helper to template creating Queries.
|
|
/// @tparam ProcedureNumber identifier for each query. Assure that only one type inherits from Query<> with unique identifier.
|
|
template<ProceduresUnderlyingType ProcedureNumber>
|
|
struct Query : QueryS2G
|
|
{
|
|
static constexpr ProceduresUnderlyingType GetProcedureNumberConstexpr() { return ProcedureNumber; }
|
|
ProceduresUnderlyingType GetProcedureNumber() const override { return GetProcedureNumberConstexpr(); }
|
|
|
|
/// Forwarded constructors.
|
|
using QueryS2G::QueryS2G;
|
|
};
|
|
|
|
|
|
/// Query used by relay in network, when new relay wants to join.
|
|
/// New Relay can only send N2N::InitializeRouteQuery to direct neigbor, but cannot communicate with wwhole network.
|
|
/// Network relay will send S2G::InitializeRouteQuery to gateway, announcing new relay.
|
|
struct InitializeRouteQuery : Query<0>
|
|
{
|
|
/// Create new instance.
|
|
/// @param rid of relay sending S2G
|
|
/// @param timestamp reported time at relay.
|
|
/// @param sendersRid rid of new relay, sender of N2
|
|
/// @param senderSideDid device id that connects new relay
|
|
/// @param encryptedBlob encrypted message for gateway from N2N packet.
|
|
/// @param gatewayPublicEncryptionKey key used to encrypt package. Only gateway will be able to decrypt package.
|
|
static std::unique_ptr<InitializeRouteQuery> Create(RouteId rid, int32_t timestamp, RouteId senderRid, DeviceId senderSideDid, ByteVector encryptedBlob, Crypto::PublicKey gatewayPublicEncryptionKey)
|
|
{
|
|
auto query = std::make_unique<InitializeRouteQuery>(rid, timestamp, ResponseType::None);
|
|
query->m_QueryPacketBody = Crypto::EncryptAnonymously(query->CompileQueryHeader().Concat(rid.ToByteVector()).Write(timestamp).Concat(senderRid.ToByteVector()).Concat(senderSideDid.ToByteVector()).Concat(encryptedBlob), gatewayPublicEncryptionKey);
|
|
return query;
|
|
}
|
|
|
|
/// Create new instance.
|
|
/// @param sender weak reference to device that reported request.
|
|
/// @param rid RouteID of Relay sending S2G.
|
|
/// @param timestamp reported time at relay.
|
|
/// @param encryptedBlob already encrypted packet body.
|
|
static std::unique_ptr<InitializeRouteQuery> Create(std::weak_ptr<DeviceBridge> sender, RouteId rid, int32_t timestamp, ByteView encryptedBlob)
|
|
{
|
|
auto query = std::make_unique<InitializeRouteQuery>(sender, rid, timestamp, encryptedBlob);
|
|
return query;
|
|
}
|
|
|
|
private:
|
|
/// Inherit Constructors.
|
|
using Query::Query;
|
|
};
|
|
|
|
/// Request to gateway announcing new device in network.
|
|
struct AddDeviceResponse : Query<1>
|
|
{
|
|
/// Create new instance.
|
|
/// @param rid of relay sending S2G
|
|
/// @param timestamp reported time at relay.
|
|
/// @param newDeviceId id of new device.
|
|
/// @param deviceTypeHash type of new device.
|
|
/// @param isChannel informs if device is channel or peripheral.
|
|
/// @param isNegotiationChannel if channel informs if new device can be used for negotiation.
|
|
/// @param gatewayPublicEncryptionKey key used to encrypt package. Only gateway will be able to decrypt package.
|
|
static std::unique_ptr<AddDeviceResponse> Create(RouteId rid, int32_t timestamp, DeviceId newDeviceId, HashT deviceTypeHash, bool isChannel, bool isNegotiationChannel, Crypto::PublicKey gatewayPublicEncryptionKey)
|
|
{
|
|
auto query = std::make_unique<AddDeviceResponse>(rid, timestamp, ResponseType::None);
|
|
std::uint8_t flags = static_cast<std::uint8_t>(isChannel) | (static_cast<std::uint8_t>(isNegotiationChannel) << 1);
|
|
query->m_QueryPacketBody = Crypto::EncryptAnonymously(query->CompileQueryHeader().Concat(rid.ToByteArray()).Write(timestamp).Concat(newDeviceId.ToByteVector()).Write(deviceTypeHash, flags), gatewayPublicEncryptionKey);
|
|
return query;
|
|
}
|
|
|
|
private:
|
|
/// Inherit Constructors.
|
|
using Query::Query;
|
|
};
|
|
|
|
/// Request to gateway when peripheral received new packet of data
|
|
struct DeliverToBinder : Query<2>
|
|
{
|
|
/// Create new instance.
|
|
/// @param rid of relay sending S2G
|
|
/// @param timestamp reported time at relay.
|
|
/// @param peripheralId id of peripheral sending packet.
|
|
/// @param connectorHash type of connector that should handle message.
|
|
/// @param blobFromPeripheral original message.
|
|
/// @param gatewayPublicEncryptionKey key used to encrypt package. Only gateway will be able to decrypt package.
|
|
static std::unique_ptr<DeliverToBinder> Create(RouteId rid, int32_t timestamp, DeviceId peripheralId, HashT connectorHash, ByteView blobFromPeripheral, Crypto::PublicKey gatewayPublicEncryptionKey)
|
|
{
|
|
auto query = std::make_unique<DeliverToBinder>(rid, timestamp, ResponseType::None);
|
|
query->m_QueryPacketBody = Crypto::EncryptAnonymously(query->CompileQueryHeader().Concat(rid.ToByteArray()).Write(timestamp).Concat(peripheralId.ToByteVector()).Write(connectorHash).Concat(blobFromPeripheral), gatewayPublicEncryptionKey);
|
|
return query;
|
|
}
|
|
|
|
/// Create new instance.
|
|
/// @param rid of relay sending S2G
|
|
/// @param timestamp reported time at relay.
|
|
/// @param encryptedBlob already encrypted packet body.
|
|
static std::unique_ptr<DeliverToBinder> Create(RouteId rid, int32_t timestamp, ByteView encryptedBlob)
|
|
{
|
|
auto query = std::make_unique<DeliverToBinder>(rid, timestamp, ResponseType::None);
|
|
query->m_QueryPacketBody = encryptedBlob;
|
|
return query;
|
|
}
|
|
|
|
private:
|
|
/// Inherit Constructors.
|
|
using Query::Query;
|
|
};
|
|
|
|
/// Request to gateway that new channel was negotiated.
|
|
struct NewNegotiatedChannelNotification : Query<3>
|
|
{
|
|
/// Create new instance.
|
|
/// @param rid of relay sending S2G
|
|
/// @param timestamp reported time at relay.
|
|
/// @param newDeviceId id of new device.
|
|
/// @param negotiatiorId id of channel that was used in negotiation process.
|
|
/// @param inId input id of new channel
|
|
/// @param outId output id of new channel
|
|
/// @param gatewayPublicEncryptionKey key used to encrypt package. Only gateway will be able to decrypt package.
|
|
static std::unique_ptr<NewNegotiatedChannelNotification> Create(RouteId rid, int32_t timestamp, DeviceId newDeviceId, DeviceId negotiatiorId, ByteView inId, ByteView outId, Crypto::PublicKey gatewayPublicEncryptionKey)
|
|
{
|
|
auto query = std::make_unique<NewNegotiatedChannelNotification>(rid, timestamp, ResponseType::None);
|
|
query->m_QueryPacketBody = Crypto::EncryptAnonymously
|
|
(
|
|
query->CompileQueryHeader()
|
|
.Concat(rid.ToByteArray())
|
|
.Write
|
|
(
|
|
timestamp
|
|
, newDeviceId.ToUnderlyingType()
|
|
, negotiatiorId.ToUnderlyingType()
|
|
, inId
|
|
, outId
|
|
)
|
|
, gatewayPublicEncryptionKey);
|
|
return query;
|
|
}
|
|
|
|
private:
|
|
/// Inherit Constructors.
|
|
using Query::Query;
|
|
};
|
|
|
|
/// Request carrying unspecified blob of data.
|
|
/// Use carefully, creating new request is recommended instead of using Notification.
|
|
struct Notification : Query<4>
|
|
{
|
|
/// Create new instance.
|
|
/// @param rid of relay sending S2G
|
|
/// @param timestamp reported time at relay.
|
|
/// @param blob unspecified data
|
|
/// @param gatewayPublicEncryptionKey key used to encrypt package. Only gateway will be able to decrypt package.
|
|
static std::unique_ptr<Notification> Create(RouteId rid, int32_t timestamp, MWR::ByteView blob, Crypto::PublicKey gatewayPublicEncryptionKey)
|
|
{
|
|
auto query = std::make_unique<Notification>(rid, timestamp, ResponseType::None);
|
|
query->m_QueryPacketBody = Crypto::EncryptAnonymously
|
|
(
|
|
query->CompileQueryHeader()
|
|
.Concat(rid.ToByteArray())
|
|
.Write
|
|
(
|
|
timestamp
|
|
, blob
|
|
)
|
|
, gatewayPublicEncryptionKey);
|
|
return query;
|
|
}
|
|
|
|
private:
|
|
/// Inherit Constructors.
|
|
using Query::Query;
|
|
};
|
|
|
|
/// Retrieve packet number and move buffer to position after.
|
|
/// @param packetAtProcedureNumber reference to packet buffer.
|
|
static ProceduresUnderlyingType ReadProcedureNo(ByteView& packetAtProcedureNumber)
|
|
{
|
|
// Sanity check.
|
|
if (packetAtProcedureNumber.empty())
|
|
throw std::runtime_error{ OBF("Packet too short.") };
|
|
|
|
return packetAtProcedureNumber.Read<ProceduresUnderlyingType>();;
|
|
}
|
|
|
|
/// Class representing support for C3 N2N Requests.
|
|
struct RequestHandler
|
|
{
|
|
/// Declaration of support for InitializeRouteQuery Request.
|
|
virtual void On(InitializeRouteQuery&&) = 0;
|
|
|
|
/// Default empty handler for AddDeviceResponse Request.
|
|
virtual void On(AddDeviceResponse) {};
|
|
|
|
/// Default empty handler for DeliverToBinder Request.
|
|
virtual void On(DeliverToBinder) {};
|
|
|
|
/// Default empty handler for NewNegotiatedChannelNotification Request.
|
|
virtual void On(NewNegotiatedChannelNotification) {};
|
|
|
|
/// Default empty handler for Notification Request.
|
|
virtual void On(Notification) {};
|
|
|
|
/// Function responsible interpreting request and calling right handle.
|
|
/// @param sender Device that reported request.
|
|
/// @param procedure type of procedure.
|
|
/// @param rid id of device that reported request.
|
|
/// @param timestamp reported time at relay.
|
|
/// @param encryptedData body of request.
|
|
void ParseRequestAndHandleIt(std::weak_ptr<DeviceBridge> sender, ProceduresUnderlyingType procedure, RouteId rid, int32_t timestamp, ByteView encryptedData)
|
|
{
|
|
switch (procedure)
|
|
{
|
|
case InitializeRouteQuery::GetProcedureNumberConstexpr():
|
|
On(InitializeRouteQuery{ sender, rid, timestamp, encryptedData });
|
|
break;
|
|
case AddDeviceResponse::GetProcedureNumberConstexpr():
|
|
On(AddDeviceResponse{ sender, rid, timestamp, encryptedData });
|
|
break;
|
|
case DeliverToBinder::GetProcedureNumberConstexpr():
|
|
On(DeliverToBinder{ sender, rid, timestamp, encryptedData });
|
|
break;
|
|
case NewNegotiatedChannelNotification::GetProcedureNumberConstexpr():
|
|
On(NewNegotiatedChannelNotification{ sender, rid, timestamp, encryptedData });
|
|
break;
|
|
case Notification::GetProcedureNumberConstexpr():
|
|
On(Notification{ sender, rid, timestamp, encryptedData });
|
|
break;
|
|
default:
|
|
throw std::runtime_error{ OBF("Failed to parse S2G packet. ") };
|
|
}
|
|
}
|
|
};
|
|
}
|
|
}
|