libe3 0.2.5
C++ library for E3AP RAN vendor integration
Loading...
Searching...
No Matches
e3_connector.hpp
Go to the documentation of this file.
1/**
2 * @file e3_connector.hpp
3 * @brief Abstract E3 Connector interface for transport layer
4 *
5 * Defines the abstract interface that all transport connectors must implement.
6 * Ported from the original C implementation's E3Connector structure.
7 *
8 * SPDX-FileCopyrightText: Copyright (c) 2026 Northeastern University
9 * SPDX-License-Identifier: Apache-2.0
10 */
11
12#ifndef LIBE3_E3_CONNECTOR_HPP
13#define LIBE3_E3_CONNECTOR_HPP
14
15#include "types.hpp"
16#include <memory>
17#include <string>
18#include <functional>
19
20namespace libe3 {
21
22/**
23 * @brief Abstract base class for E3AP transport connectors
24 *
25 * This class defines the transport-agnostic interface that all connectors
26 * must implement. The design mirrors the original C implementation's
27 * function pointer approach, but uses virtual methods for type safety.
28 *
29 * Derived classes:
30 * - PosixE3Connector: POSIX socket-based transport (TCP, SCTP, IPC)
31 * - ZmqE3Connector: ZeroMQ-based transport
32 */
34public:
35 virtual ~E3Connector() = default;
36
37 // Non-copyable, movable
38 E3Connector(const E3Connector&) = delete;
42
43 /**
44 * @brief Set up the initial connection (setup channel)
45 *
46 * This establishes the REQ/REP channel used for E3 Setup procedures.
47 * @return ErrorCode::SUCCESS on success, error code otherwise
48 */
50
51 /**
52 * @brief Receive a setup request
53 *
54 * Blocks until a setup request is received on the setup channel.
55 * @param buffer Buffer to store received data
56 * @return Number of bytes received, or negative error code
57 */
58 virtual int recv_setup_request(std::vector<uint8_t>& buffer) = 0;
59
60 /**
61 * @brief Send a setup response
62 * @param data Response data to send
63 * @return ErrorCode::SUCCESS on success, error code otherwise
64 */
65 virtual ErrorCode send_response(const std::vector<uint8_t>& data) = 0;
66
67 /**
68 * @brief Set up the inbound connection (SUB channel)
69 *
70 * This establishes the channel for receiving control actions from dApps.
71 * @return ErrorCode::SUCCESS on success, error code otherwise
72 */
74
75 /**
76 * @brief Receive data from the inbound channel
77 * @param buffer Buffer to store received data
78 * @return Number of bytes received, or negative error code
79 */
80 virtual int receive(std::vector<uint8_t>& buffer) = 0;
81
82 /**
83 * @brief Set up the outbound connection (PUB channel)
84 *
85 * This establishes the channel for sending indications to dApps.
86 * @return ErrorCode::SUCCESS on success, error code otherwise
87 */
89
90 /**
91 * @brief Send data on the outbound channel
92 * @param data Data to send
93 * @return ErrorCode::SUCCESS on success, error code otherwise
94 */
95 virtual ErrorCode send(const std::vector<uint8_t>& data) = 0;
96
97 // =========================================================================
98 // Client-side (dApp role) operations
99 //
100 // Mirrors of the server-side methods above but with bind/listen replaced
101 // by connect. Default implementations return INVALID_PARAM so connectors
102 // that have not been taught the dApp role surface a clear error instead
103 // of silently misbehaving. ZmqE3Connector and PosixE3Connector override
104 // these.
105 // =========================================================================
106
107 /**
108 * @brief Connect the setup channel (dApp role: REQ connect).
109 */
111 return ErrorCode::INVALID_PARAM;
112 }
113
114 /**
115 * @brief Send a SetupRequest on the setup channel (dApp role).
116 */
117 virtual ErrorCode send_setup_request_client(const std::vector<uint8_t>& /*data*/) {
118 return ErrorCode::INVALID_PARAM;
119 }
120
121 /**
122 * @brief Receive a SetupResponse on the setup channel (dApp role).
123 */
124 virtual int recv_setup_response_client(std::vector<uint8_t>& /*buffer*/) {
125 return static_cast<int>(ErrorCode::INVALID_PARAM);
126 }
127
128 /**
129 * @brief Connect the inbound channel (dApp role: SUB connect to the
130 * RAN's publisher endpoint).
131 */
133 return ErrorCode::INVALID_PARAM;
134 }
135
136 /**
137 * @brief Connect the outbound channel (dApp role: PUB connect to the
138 * RAN's subscriber endpoint).
139 */
141 return ErrorCode::INVALID_PARAM;
142 }
143
144 /**
145 * @brief Clean up and release all resources
146 */
147 virtual void dispose() = 0;
148
149 /**
150 * @brief Interrupt blocking operations for shutdown
151 *
152 * Called before joining threads to unblock any blocking socket operations.
153 * Default implementation does nothing (for connectors that use timeouts).
154 */
155 virtual void shutdown() {}
156
157 /**
158 * @brief Get the link layer type
159 */
160 virtual E3LinkLayer link_layer() const noexcept = 0;
161
162 /**
163 * @brief Get the transport layer type
164 */
165 virtual E3TransportLayer transport_layer() const noexcept = 0;
166
167 /**
168 * @brief Check if connector is connected
169 */
170 virtual bool is_connected() const noexcept = 0;
171
172 /**
173 * @brief Set role (RAN or DAPP). Affects bind vs connect direction and
174 * cleanup behaviour. Must be set before any setup_* call. Default RAN.
175 */
176 void set_role(E3Role role) noexcept { role_ = role; }
177
178 /**
179 * @brief Get current role.
180 */
181 E3Role role() const noexcept { return role_; }
182
183 /**
184 * @brief Get setup endpoint
185 */
186 const std::string& setup_endpoint() const noexcept { return setup_endpoint_; }
187
188 /**
189 * @brief Get inbound endpoint
190 */
191 const std::string& inbound_endpoint() const noexcept { return inbound_endpoint_; }
192
193 /**
194 * @brief Get outbound endpoint
195 */
196 const std::string& outbound_endpoint() const noexcept { return outbound_endpoint_; }
197
198protected:
199 E3Connector() = default;
200
201 std::string setup_endpoint_;
202 std::string inbound_endpoint_;
205};
206
207/**
208 * @brief Factory function to create appropriate connector
209 *
210 * Creates a connector instance based on the link and transport layers specified.
211 *
212 * @param link_layer Link layer to use (ZMQ or POSIX)
213 * @param transport_layer Transport layer to use (SCTP, TCP, or IPC)
214 * @param setup_endpoint Endpoint for setup channel
215 * @param inbound_endpoint Endpoint for inbound channel
216 * @param outbound_endpoint Endpoint for outbound channel
217 * @param io_threads Number of I/O threads (for ZMQ)
218 * @return Unique pointer to created connector, nullptr on failure
219 */
220std::unique_ptr<E3Connector> create_connector(
221 E3LinkLayer link_layer,
222 E3TransportLayer transport_layer,
223 const std::string& setup_endpoint,
224 const std::string& inbound_endpoint,
225 const std::string& outbound_endpoint,
226 uint16_t setup_port,
227 uint16_t inbound_port,
228 uint16_t outbound_port,
229 size_t io_threads = 2,
230 E3Role role = E3Role::RAN
231);
232
233} // namespace libe3
234
235#endif // LIBE3_E3_CONNECTOR_HPP
virtual ErrorCode setup_inbound_connection()=0
Set up the inbound connection (SUB channel).
virtual ~E3Connector()=default
virtual int recv_setup_request(std::vector< uint8_t > &buffer)=0
Receive a setup request.
E3Connector()=default
void set_role(E3Role role) noexcept
Set role (RAN or DAPP). Affects bind vs connect direction and cleanup behaviour. Must be set before a...
std::string inbound_endpoint_
std::string outbound_endpoint_
virtual bool is_connected() const noexcept=0
Check if connector is connected.
std::string setup_endpoint_
const std::string & inbound_endpoint() const noexcept
Get inbound endpoint.
E3Connector & operator=(E3Connector &&)=default
virtual ErrorCode setup_outbound_connection()=0
Set up the outbound connection (PUB channel).
const std::string & setup_endpoint() const noexcept
Get setup endpoint.
virtual void shutdown()
Interrupt blocking operations for shutdown.
virtual void dispose()=0
Clean up and release all resources.
virtual E3LinkLayer link_layer() const noexcept=0
Get the link layer type.
virtual ErrorCode send_response(const std::vector< uint8_t > &data)=0
Send a setup response.
virtual int receive(std::vector< uint8_t > &buffer)=0
Receive data from the inbound channel.
virtual E3TransportLayer transport_layer() const noexcept=0
Get the transport layer type.
const std::string & outbound_endpoint() const noexcept
Get outbound endpoint.
E3Connector(E3Connector &&)=default
virtual ErrorCode setup_initial_connection_client()
Connect the setup channel (dApp role: REQ connect).
E3Connector & operator=(const E3Connector &)=delete
virtual int recv_setup_response_client(std::vector< uint8_t > &)
Receive a SetupResponse on the setup channel (dApp role).
E3Connector(const E3Connector &)=delete
virtual ErrorCode send(const std::vector< uint8_t > &data)=0
Send data on the outbound channel.
virtual ErrorCode setup_initial_connection()=0
Set up the initial connection (setup channel).
virtual ErrorCode setup_outbound_connection_client()
Connect the outbound channel (dApp role: PUB connect to the RAN's subscriber endpoint).
E3Role role() const noexcept
Get current role.
virtual ErrorCode setup_inbound_connection_client()
Connect the inbound channel (dApp role: SUB connect to the RAN's publisher endpoint).
virtual ErrorCode send_setup_request_client(const std::vector< uint8_t > &)
Send a SetupRequest on the setup channel (dApp role).
ErrorCode
Error codes returned by libe3 operations Use shared error-code list (see libe3/error_codes....
Definition types.hpp:141
E3TransportLayer
Transport layer types (matches Python E3TransportLayer).
Definition types.hpp:83
E3Role
Role this E3 endpoint plays in the protocol.
Definition types.hpp:75
@ RAN
RAN function (binds sockets; today's only behaviour).
Definition types.hpp:76
E3LinkLayer
Link layer types (matches Python E3LinkLayer).
Definition types.hpp:60
std::unique_ptr< E3Connector > create_connector(E3LinkLayer link_layer, E3TransportLayer transport_layer, const std::string &setup_endpoint, const std::string &inbound_endpoint, const std::string &outbound_endpoint, uint16_t setup_port, uint16_t inbound_port, uint16_t outbound_port, size_t io_threads=2, E3Role role=E3Role::RAN)
Factory function to create appropriate connector.
E3AP Protocol Types - Vendor-neutral type definitions.