libe3 0.2.5
C++ library for E3AP RAN vendor integration
Loading...
Searching...
No Matches
posix_connector.hpp
Go to the documentation of this file.
1/**
2 * @file posix_connector.hpp
3 * @brief POSIX socket-based E3 Connector
4 *
5 * SPDX-FileCopyrightText: Copyright (c) 2026 Northeastern University
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9#ifndef LIBE3_POSIX_CONNECTOR_HPP
10#define LIBE3_POSIX_CONNECTOR_HPP
11
13#include <atomic>
14#include <cstddef>
15#include <vector>
16
17namespace libe3 {
18
19/**
20 * @brief POSIX socket-based E3 connector
21 *
22 * Provides transport using POSIX sockets. Supports TCP, SCTP, and IPC transports.
23 * Ported from the original C implementation's posix_* functions.
24 *
25 * RAN role serves multiple dApp peers: both data listeners keep accepting
26 * for the connector's lifetime, receive() polls every accepted subscriber
27 * socket, and send() broadcasts each framed message to every accepted
28 * indication socket (mirroring the ZMQ PUB/SUB semantics, where the RAN
29 * broadcasts and each dApp filters by its own dApp identifier). Peer
30 * sockets are only touched by their owning I/O thread: inbound sockets by
31 * the inbound loop, outbound sockets by the outbound loop.
32 */
34public:
37 const std::string& setup_endpoint,
38 const std::string& inbound_endpoint,
39 const std::string& outbound_endpoint,
40 uint16_t setup_port,
41 uint16_t inbound_port,
42 uint16_t outbound_port
43 );
44
45 ~PosixE3Connector() override;
46
48 int recv_setup_request(std::vector<uint8_t>& buffer) override;
49 ErrorCode send_response(const std::vector<uint8_t>& data) override;
51 int receive(std::vector<uint8_t>& buffer) override;
53 ErrorCode send(const std::vector<uint8_t>& data) override;
54
55 // Client-side (dApp role) operations.
57 ErrorCode send_setup_request_client(const std::vector<uint8_t>& data) override;
58 int recv_setup_response_client(std::vector<uint8_t>& buffer) override;
61
62 void dispose() override;
63 void shutdown() override;
64
65 E3LinkLayer link_layer() const noexcept override {
66 return E3LinkLayer::POSIX;
67 }
68
69 E3TransportLayer transport_layer() const noexcept override {
70 return transport_layer_;
71 }
72
73 bool is_connected() const noexcept override {
74 return connected_;
75 }
76
77private:
78 E3TransportLayer transport_layer_;
79
80 int setup_socket_{-1};
81 int setup_connection_socket_{-1};
82 int inbound_socket_{-1};
83 int inbound_connection_socket_{-1};
84 int outbound_socket_{-1};
85 int outbound_connection_socket_{-1};
86
87 // RAN-role peer sockets (multi-peer). During normal operation each vector
88 // is touched only by its owning I/O thread: inbound_peer_sockets_ by the
89 // inbound (receive) loop, outbound_peer_sockets_ by the outbound (send)
90 // loop. dispose() and the destructor also iterate and clear both vectors
91 // from the caller's thread; that is race-free ONLY because
92 // E3Interface::stop() joins the inbound and outbound threads before calling
93 // dispose(). A caller that disposes without joining those threads first
94 // would race on these vectors.
95 std::vector<int> inbound_peer_sockets_;
96 std::vector<int> outbound_peer_sockets_;
97
98 // Rotating start index for the inbound peer scan in receive(), so no single
99 // peer with continuously-queued data can starve the others. Owned by the
100 // inbound thread; taken modulo the current peer count on each use.
101 size_t inbound_rr_{0};
102
103 uint16_t setup_port_;
104 uint16_t inbound_port_;
105 uint16_t outbound_port_;
106
107 bool connected_{false};
108 std::atomic<bool> shutdown_requested_{false};
109
110 static constexpr int CHUNK_SIZE = 8192;
111 static constexpr int UNUSED_SOCKET = -2;
112
113 int send_in_chunks(int sockfd, const uint8_t* buffer, size_t buffer_size);
114 int recv_with_size(int sockfd, std::vector<uint8_t>& buffer);
115};
116
117} // namespace libe3
118
119#endif // LIBE3_POSIX_CONNECTOR_HPP
const std::string & inbound_endpoint() const noexcept
Get inbound endpoint.
const std::string & setup_endpoint() const noexcept
Get setup endpoint.
const std::string & outbound_endpoint() const noexcept
Get outbound endpoint.
E3Connector(const E3Connector &)=delete
E3LinkLayer link_layer() const noexcept override
Get the link layer type.
ErrorCode send_setup_request_client(const std::vector< uint8_t > &data) override
Send a SetupRequest on the setup channel (dApp role).
int recv_setup_request(std::vector< uint8_t > &buffer) override
Receive a setup request.
void dispose() override
Clean up and release all resources.
int receive(std::vector< uint8_t > &buffer) override
Receive data from the inbound channel.
ErrorCode send(const std::vector< uint8_t > &data) override
Send data on the outbound channel.
ErrorCode setup_initial_connection_client() override
Connect the setup channel (dApp role: REQ connect).
E3TransportLayer transport_layer() const noexcept override
Get the transport layer type.
int recv_setup_response_client(std::vector< uint8_t > &buffer) override
Receive a SetupResponse on the setup channel (dApp role).
PosixE3Connector(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)
ErrorCode send_response(const std::vector< uint8_t > &data) override
Send a setup response.
void shutdown() override
Interrupt blocking operations for shutdown.
ErrorCode setup_outbound_connection_client() override
Connect the outbound channel (dApp role: PUB connect to the RAN's subscriber endpoint).
ErrorCode setup_inbound_connection_client() override
Connect the inbound channel (dApp role: SUB connect to the RAN's publisher endpoint).
ErrorCode setup_initial_connection() override
Set up the initial connection (setup channel).
ErrorCode setup_inbound_connection() override
Set up the inbound connection (SUB channel).
ErrorCode setup_outbound_connection() override
Set up the outbound connection (PUB channel).
bool is_connected() const noexcept override
Check if connector is connected.
Abstract E3 Connector interface for transport layer.
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
E3LinkLayer
Link layer types (matches Python E3LinkLayer).
Definition types.hpp:60
@ POSIX
POSIX socket-based transport.
Definition types.hpp:62