17#ifndef TLM_SCC_TCP4TLM_MESSAGES_H_
18#define TLM_SCC_TCP4TLM_MESSAGES_H_
20#include "messages_generated.h"
30template <
typename Root>
class message_buffer {
32 message_buffer() =
default;
34 explicit message_buffer(std::vector<uint8_t> storage)
35 : storage_(std::move(storage))
40 const Root* root()
const {
return root_; }
41 const Root* operator->()
const {
return root_; }
42 explicit operator bool()
const {
return root_ !=
nullptr; }
44 const uint8_t* data()
const {
return storage_.empty() ? nullptr : storage_.data(); }
45 std::size_t size()
const {
return storage_.size(); }
47 static bool verify(
const uint8_t* data, std::size_t size) {
48 if(data ==
nullptr || size == 0) {
51 flatbuffers::Verifier verifier(data, size);
52 return verifier.VerifyBuffer<Root>(
nullptr);
56 void refresh_root() { root_ = verify(data(), size()) ? flatbuffers::GetRoot<Root>(data()) :
nullptr; }
58 std::vector<uint8_t> storage_;
64using response_status = ResponseStatus;
65using bus_access_type = BusAccessType;
67constexpr response_status ok = ResponseStatus_OK;
68constexpr response_status accepted = ResponseStatus_ACCEPTED;
69constexpr response_status delayed = ResponseStatus_DELAYED;
70constexpr response_status declined = ResponseStatus_DECLINED;
71constexpr response_status failure = ResponseStatus_FAILURE;
73constexpr bus_access_type normal_acc = BusAccessType_NORMAL_ACC;
74constexpr bus_access_type debug_acc = BusAccessType_DEBUG_ACC;
76inline const char* get_status_str(response_status status) {
return EnumNameResponseStatus(status); }
78inline uint32_t next_request_id() {
79 static std::atomic<uint32_t> id_counter{0};
83template <
typename Root>
inline message_buffer<Root> make_message(flatbuffers::FlatBufferBuilder& builder) {
84 auto detached = builder.Release();
85 return message_buffer<Root>(std::vector<uint8_t>(detached.data(), detached.data() + detached.size()));
88inline request_message make_request(RequestPayload payload_type, flatbuffers::Offset<void> payload,
89 flatbuffers::FlatBufferBuilder& builder) {
90 auto envelope = CreateRequestEnvelope(builder, payload_type, payload);
91 builder.Finish(envelope);
92 return make_message<RequestEnvelope>(builder);
95inline response_message make_response_message(ResponsePayload payload_type, flatbuffers::Offset<void> payload,
96 flatbuffers::FlatBufferBuilder& builder) {
97 auto envelope = CreateResponseEnvelope(builder, payload_type, payload);
98 builder.Finish(envelope);
99 return make_message<ResponseEnvelope>(builder);
102inline request_message make_notify_endpoint_msg(
const std::string& hostname, uint16_t port, uint32_t
id = next_request_id()) {
103 flatbuffers::FlatBufferBuilder builder;
104 auto payload = CreateNotifyEndpointMsgDirect(builder,
id, hostname.c_str(), port);
105 return make_request(RequestPayload_NotifyEndpointMsg, payload.Union(), builder);
108inline request_message make_notify_shutdown_msg(uint32_t
id = next_request_id()) {
109 flatbuffers::FlatBufferBuilder builder;
110 auto payload = CreateNotifyShutdownMsg(builder,
id);
111 return make_request(RequestPayload_NotifyShutdownMsg, payload.Union(), builder);
114inline request_message make_sync_msg(uint64_t time_stamp, uint32_t
id = next_request_id()) {
115 flatbuffers::FlatBufferBuilder builder;
116 auto payload = CreateSyncMsg(builder,
id, time_stamp);
117 return make_request(RequestPayload_SyncMsg, payload.Union(), builder);
120inline request_message make_bus_op_msg(uint64_t time_stamp, uint64_t time_offset, bus_access_type type, uint32_t index, uint64_t address,
121 uint32_t size,
bool no_response,
const std::vector<uint8_t>& data,
122 const std::vector<uint8_t>& byte_enable, uint32_t
id = next_request_id()) {
123 flatbuffers::FlatBufferBuilder builder;
124 auto payload = CreateBusOpMsgDirect(builder,
id, time_stamp, time_offset, type, index, address, size, no_response, &data, &byte_enable);
125 return make_request(RequestPayload_BusOpMsg, payload.Union(), builder);
128inline request_message make_sig_op_msg(uint64_t time_stamp, uint32_t index, uint8_t value, uint32_t
id = next_request_id()) {
129 flatbuffers::FlatBufferBuilder builder;
130 auto payload = CreateSigOpMsg(builder,
id, time_stamp, index, value);
131 return make_request(RequestPayload_SigOpMsg, payload.Union(), builder);
134inline request_message make_log_msg(
const std::string& msg, uint32_t
id = next_request_id()) {
135 flatbuffers::FlatBufferBuilder builder;
136 auto payload = CreateLogMsgDirect(builder,
id, msg.c_str());
137 return make_request(RequestPayload_LogMsg, payload.Union(), builder);
140inline uint32_t get_request_id(
const RequestEnvelope* req) {
144 switch(req->payload_type()) {
145 case RequestPayload_NotifyEndpointMsg:
146 return req->payload_as_NotifyEndpointMsg()->id();
147 case RequestPayload_NotifyShutdownMsg:
148 return req->payload_as_NotifyShutdownMsg()->id();
149 case RequestPayload_SyncMsg:
150 return req->payload_as_SyncMsg()->id();
151 case RequestPayload_BusOpMsg:
152 return req->payload_as_BusOpMsg()->id();
153 case RequestPayload_SigOpMsg:
154 return req->payload_as_SigOpMsg()->id();
155 case RequestPayload_LogMsg:
156 return req->payload_as_LogMsg()->id();
162inline response_status get_status(
const ResponseEnvelope* resp) {
163 if(resp ==
nullptr) {
166 switch(resp->payload_type()) {
167 case ResponsePayload_ResponseMsg:
168 return resp->payload_as_ResponseMsg()->status();
169 case ResponsePayload_BusDataMsg:
170 return resp->payload_as_BusDataMsg()->status();
176inline uint32_t get_req_id(
const ResponseEnvelope* resp) {
177 if(resp ==
nullptr) {
180 switch(resp->payload_type()) {
181 case ResponsePayload_ResponseMsg:
182 return resp->payload_as_ResponseMsg()->req_id();
183 case ResponsePayload_BusDataMsg:
184 return resp->payload_as_BusDataMsg()->req_id();
190inline bool belongs_to(
const ResponseEnvelope* resp,
const RequestEnvelope* req) {
return get_req_id(resp) == get_request_id(req); }
192inline response_message make_response(uint32_t req_id, response_status status = ok) {
193 flatbuffers::FlatBufferBuilder builder;
194 auto payload = CreateResponseMsg(builder, status, req_id);
195 return make_response_message(ResponsePayload_ResponseMsg, payload.Union(), builder);
198inline response_message make_response(
const RequestEnvelope* req, response_status status = ok) {
199 return make_response(get_request_id(req), status);
202inline response_message make_bus_data_msg(uint32_t req_id,
const std::vector<uint8_t>& data, response_status status = ok) {
203 flatbuffers::FlatBufferBuilder builder;
204 auto payload = CreateBusDataMsgDirect(builder, status, req_id, &data);
205 return make_response_message(ResponsePayload_BusDataMsg, payload.Union(), builder);
208inline response_message make_bus_data_msg(
const RequestEnvelope* req,
const std::vector<uint8_t>& data, response_status status = ok) {
209 return make_bus_data_msg(get_request_id(req), data, status);