11#include "e3ap-1.0.0.pb.h"
22pb::ResponseCode to_pb_response_code(ResponseCode rc) {
23 return rc == ResponseCode::POSITIVE ? pb::RESPONSE_CODE_POSITIVE
24 : pb::RESPONSE_CODE_NEGATIVE;
28 return rc == pb::RESPONSE_CODE_NEGATIVE ? ResponseCode::NEGATIVE
29 : ResponseCode::POSITIVE;
32std::vector<uint8_t> to_bytes(
const std::string& s) {
33 return std::vector<uint8_t>(s.begin(), s.end());
38bool ProtobufE3Encoder::pdu_to_proto(
const Pdu& pdu, pb::E3Pdu& out)
const {
39 out.set_id(pdu.message_id);
40 out.set_timestamp(pdu.timestamp);
44 const auto* s = pdu.get_if<SetupRequest>();
46 auto* m = out.mutable_setup_request();
47 m->set_e3ap_protocol_version(s->e3ap_protocol_version);
48 m->set_dapp_name(s->dapp_name);
49 m->set_dapp_version(s->dapp_version);
50 m->set_vendor(s->vendor);
54 const auto* s = pdu.get_if<SetupResponse>();
56 auto* m = out.mutable_setup_response();
57 m->set_request_id(s->request_id);
58 m->set_response_code(to_pb_response_code(s->response_code));
59 if (s->e3ap_protocol_version) m->set_e3ap_protocol_version(*s->e3ap_protocol_version);
60 if (s->dapp_identifier) m->set_dapp_identifier(*s->dapp_identifier);
61 m->set_ran_identifier(s->ran_identifier);
62 for (
const auto& rf : s->ran_function_list) {
63 auto* pf = m->add_ran_function_list();
64 pf->set_ran_function_identifier(rf.ran_function_identifier);
65 for (
auto t : rf.telemetry_identifier_list) pf->add_telemetry_identifier_list(t);
66 for (
auto c : rf.control_identifier_list) pf->add_control_identifier_list(c);
67 pf->set_ran_function_data(rf.ran_function_data.data(), rf.ran_function_data.size());
72 const auto* s = pdu.get_if<SubscriptionRequest>();
74 auto* m = out.mutable_subscription_request();
75 m->set_dapp_identifier(s->dapp_identifier);
76 m->set_ran_function_identifier(s->ran_function_identifier);
77 for (
auto t : s->telemetry_identifier_list) m->add_telemetry_identifier_list(t);
78 for (
auto c : s->control_identifier_list) m->add_control_identifier_list(c);
79 if (s->subscription_time) m->set_subscription_time(*s->subscription_time);
80 if (s->periodicity) m->set_periodicity(*s->periodicity);
84 const auto* s = pdu.get_if<SubscriptionDelete>();
86 auto* m = out.mutable_subscription_delete();
87 m->set_dapp_identifier(s->dapp_identifier);
88 m->set_subscription_id(s->subscription_id);
92 const auto* s = pdu.get_if<SubscriptionResponse>();
94 auto* m = out.mutable_subscription_response();
95 m->set_request_id(s->request_id);
96 m->set_dapp_identifier(s->dapp_identifier);
97 m->set_response_code(to_pb_response_code(s->response_code));
98 if (s->subscription_id) m->set_subscription_id(*s->subscription_id);
102 const auto* s = pdu.get_if<IndicationMessage>();
103 if (!s)
return false;
104 auto* m = out.mutable_indication_message();
105 m->set_dapp_identifier(s->dapp_identifier);
106 m->set_ran_function_identifier(s->ran_function_identifier);
107 m->set_protocol_data(s->protocol_data.data(), s->protocol_data.size());
111 const auto* s = pdu.get_if<DAppControlAction>();
112 if (!s)
return false;
113 auto* m = out.mutable_dapp_control_action();
114 m->set_dapp_identifier(s->dapp_identifier);
115 m->set_ran_function_identifier(s->ran_function_identifier);
116 m->set_control_identifier(s->control_identifier);
117 m->set_sequence_id(s->sequence_id);
118 m->set_action_data(s->action_data.data(), s->action_data.size());
122 const auto* s = pdu.get_if<DAppReport>();
123 if (!s)
return false;
124 auto* m = out.mutable_dapp_report();
125 m->set_dapp_identifier(s->dapp_identifier);
126 m->set_ran_function_identifier(s->ran_function_identifier);
127 m->set_sequence_id(s->sequence_id);
128 m->set_report_data(s->report_data.data(), s->report_data.size());
132 const auto* s = pdu.get_if<XAppControlAction>();
133 if (!s)
return false;
134 auto* m = out.mutable_xapp_control_action();
135 m->set_dapp_identifier(s->dapp_identifier);
136 m->set_ran_function_identifier(s->ran_function_identifier);
137 m->set_sequence_id(s->sequence_id);
138 m->set_xapp_control_data(s->xapp_control_data.data(), s->xapp_control_data.size());
142 const auto* s = pdu.get_if<ReleaseMessage>();
143 if (!s)
return false;
144 auto* m = out.mutable_release_message();
145 m->set_dapp_identifier(s->dapp_identifier);
149 const auto* s = pdu.get_if<MessageAck>();
150 if (!s)
return false;
151 auto* m = out.mutable_message_ack();
152 m->set_request_id(s->request_id);
153 m->set_response_code(to_pb_response_code(s->response_code));
160Pdu ProtobufE3Encoder::proto_to_pdu(
const pb::E3Pdu& proto)
const {
163 pdu.timestamp = proto.timestamp();
165 switch (proto.msg_case()) {
166 case pb::E3Pdu::kSetupRequest: {
167 const auto& m = proto.setup_request();
169 s.e3ap_protocol_version = m.e3ap_protocol_version();
170 s.dapp_name = m.dapp_name();
171 s.dapp_version = m.dapp_version();
172 s.vendor = m.vendor();
174 pdu.choice = std::move(s);
177 case pb::E3Pdu::kSetupResponse: {
178 const auto& m = proto.setup_response();
180 s.request_id = m.request_id();
181 s.response_code = from_pb_response_code(m.response_code());
182 if (m.has_e3ap_protocol_version()) s.e3ap_protocol_version = m.e3ap_protocol_version();
183 if (m.has_dapp_identifier()) s.dapp_identifier = m.dapp_identifier();
184 s.ran_identifier = m.ran_identifier();
185 for (
int i = 0; i < m.ran_function_list_size(); ++i) {
186 const auto& pf = m.ran_function_list(i);
188 rf.ran_function_identifier = pf.ran_function_identifier();
189 for (
int j = 0; j < pf.telemetry_identifier_list_size(); ++j)
190 rf.telemetry_identifier_list.push_back(pf.telemetry_identifier_list(j));
191 for (
int j = 0; j < pf.control_identifier_list_size(); ++j)
192 rf.control_identifier_list.push_back(pf.control_identifier_list(j));
193 rf.ran_function_data = to_bytes(pf.ran_function_data());
194 s.ran_function_list.push_back(std::move(rf));
197 pdu.choice = std::move(s);
200 case pb::E3Pdu::kSubscriptionRequest: {
201 const auto& m = proto.subscription_request();
202 SubscriptionRequest s;
203 s.dapp_identifier = m.dapp_identifier();
204 s.ran_function_identifier = m.ran_function_identifier();
205 for (
int j = 0; j < m.telemetry_identifier_list_size(); ++j)
206 s.telemetry_identifier_list.push_back(m.telemetry_identifier_list(j));
207 for (
int j = 0; j < m.control_identifier_list_size(); ++j)
208 s.control_identifier_list.push_back(m.control_identifier_list(j));
209 if (m.has_subscription_time()) s.subscription_time = m.subscription_time();
210 if (m.has_periodicity()) s.periodicity = m.periodicity();
212 pdu.choice = std::move(s);
215 case pb::E3Pdu::kSubscriptionDelete: {
216 const auto& m = proto.subscription_delete();
217 SubscriptionDelete s;
218 s.dapp_identifier = m.dapp_identifier();
219 s.subscription_id = m.subscription_id();
221 pdu.choice = std::move(s);
224 case pb::E3Pdu::kSubscriptionResponse: {
225 const auto& m = proto.subscription_response();
226 SubscriptionResponse s;
227 s.request_id = m.request_id();
228 s.dapp_identifier = m.dapp_identifier();
229 s.response_code = from_pb_response_code(m.response_code());
230 if (m.has_subscription_id()) s.subscription_id = m.subscription_id();
232 pdu.choice = std::move(s);
235 case pb::E3Pdu::kIndicationMessage: {
236 const auto& m = proto.indication_message();
238 s.dapp_identifier = m.dapp_identifier();
239 s.ran_function_identifier = m.ran_function_identifier();
240 s.protocol_data = to_bytes(m.protocol_data());
242 pdu.choice = std::move(s);
245 case pb::E3Pdu::kDappControlAction: {
246 const auto& m = proto.dapp_control_action();
248 s.dapp_identifier = m.dapp_identifier();
249 s.ran_function_identifier = m.ran_function_identifier();
250 s.control_identifier = m.control_identifier();
251 s.sequence_id = m.sequence_id();
252 s.action_data = to_bytes(m.action_data());
254 pdu.choice = std::move(s);
257 case pb::E3Pdu::kDappReport: {
258 const auto& m = proto.dapp_report();
260 s.dapp_identifier = m.dapp_identifier();
261 s.ran_function_identifier = m.ran_function_identifier();
262 s.sequence_id = m.sequence_id();
263 s.report_data = to_bytes(m.report_data());
265 pdu.choice = std::move(s);
268 case pb::E3Pdu::kXappControlAction: {
269 const auto& m = proto.xapp_control_action();
271 s.dapp_identifier = m.dapp_identifier();
272 s.ran_function_identifier = m.ran_function_identifier();
273 s.sequence_id = m.sequence_id();
274 s.xapp_control_data = to_bytes(m.xapp_control_data());
276 pdu.choice = std::move(s);
279 case pb::E3Pdu::kReleaseMessage: {
280 const auto& m = proto.release_message();
282 s.dapp_identifier = m.dapp_identifier();
284 pdu.choice = std::move(s);
287 case pb::E3Pdu::kMessageAck: {
288 const auto& m = proto.message_ack();
290 s.request_id = m.request_id();
291 s.response_code = from_pb_response_code(m.response_code());
293 pdu.choice = std::move(s);
296 case pb::E3Pdu::MSG_NOT_SET:
304 if (!pdu_to_proto(pdu, proto)) {
305 return tl::unexpected(ErrorCode::ENCODE_FAILED);
307 std::string serialized;
308 if (!proto.SerializeToString(&serialized)) {
309 return tl::unexpected(ErrorCode::ENCODE_FAILED);
311 return EncodedMessage{std::vector<uint8_t>(serialized.begin(), serialized.end()),
320 if (data ==
nullptr && size != 0) {
321 return tl::unexpected(ErrorCode::DECODE_FAILED);
324 if (!proto.ParseFromArray(data,
static_cast<int>(size))) {
325 return tl::unexpected(ErrorCode::DECODE_FAILED);
327 if (proto.msg_case() == pb::E3Pdu::MSG_NOT_SET) {
328 return tl::unexpected(ErrorCode::DECODE_FAILED);
330 return proto_to_pdu(proto);
EncodeResult< Pdu > decode(const EncodedMessage &encoded) override
Decode bytes to a PDU.
EncodeResult< EncodedMessage > encode(const Pdu &pdu) override
Encode a PDU to bytes.
ResponseCode
E3AP response codes.
@ PROTOBUF
Protocol Buffers encoding.
tl::expected< T, ErrorCode > EncodeResult
Result type for encoding/decoding operations.
Protocol Buffers encoder for E3AP PDUs.
std::vector< uint8_t > buffer
Encoded data buffer.
Generic E3AP PDU structure.
uint32_t message_id
Unique message identifier.