feat(tcp): TCPStreamer DataSources, in-process TCPStreamService, stream multiplexing and TCPStreamJoin
Add TCPStreamer/TCPStreamerClient (TCP transport behind the UDPSServerI/UDPSClientI seam), an optional single in-process TCPStreamService serving many streams over worker threads, multiplexed SUBSCRIBE (comma list, stream index in fragmentIdx), and TCPStreamJoin, which merges several streams into one sample-and-hold stream paced by a master. StreamHub takes a comma list of streams over one connection. Includes GTests, E2E scenarios s58-s73 and docs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
5562877c99
commit
50d85363a3
79 files changed
+12348
-138
No files matched your search
@@ -51,6 +51,8 @@ UDPSourceSession::UDPSourceSession()
|
||||
ringTemporal_(1000000u),
|
||||
ringScalar_(100000u),
|
||||
initialised_(false),
|
||||
client_(static_cast<MARTe::UDPSClientI *>(0)),
|
||||
external_(false),
|
||||
numSignals_(0u),
|
||||
publishMode_(0u),
|
||||
configured_(false),
|
||||
@@ -112,7 +114,10 @@ bool UDPSourceSession::Initialise(const char *id, const char *label,
|
||||
const char *addr, uint16 port,
|
||||
uint32 maxPts,
|
||||
const char *mcGroup,
|
||||
uint16 dataPort) {
|
||||
uint16 dataPort,
|
||||
const char *transport,
|
||||
const char *streamName,
|
||||
MARTe::UDPSClientI *external) {
|
||||
(void) Stop();
|
||||
|
||||
id_ = id;
|
||||
@@ -121,25 +126,42 @@ bool UDPSourceSession::Initialise(const char *id, const char *label,
|
||||
port_ = port;
|
||||
mcGroup_ = (mcGroup != static_cast<const char *>(0)) ? mcGroup : "";
|
||||
dataPort_ = dataPort;
|
||||
transport_ = ((transport != static_cast<const char *>(0)) && (strcmp(transport, "tcp") == 0)) ? "tcp" : "udp";
|
||||
streamName_ = (streamName != static_cast<const char *>(0)) ? streamName : "";
|
||||
maxPoints_ = (maxPts > 0u) ? maxPts : 20000u;
|
||||
|
||||
/* Build ConfigurationDatabase for UDPSClient */
|
||||
ConfigurationDatabase cfg;
|
||||
(void) cfg.Write("ServerAddr", addr);
|
||||
(void) cfg.Write("Port", static_cast<uint32>(port));
|
||||
if ((mcGroup != static_cast<const char *>(0)) && (strlen(mcGroup) > 0u)) {
|
||||
const bool useTcp = (transport_ == "tcp");
|
||||
if (useTcp) {
|
||||
if (streamName_.Size() > 0u) {
|
||||
(void) cfg.Write("StreamName", streamName_.Buffer());
|
||||
}
|
||||
} else if ((mcGroup != static_cast<const char *>(0)) && (strlen(mcGroup) > 0u)) {
|
||||
(void) cfg.Write("MulticastGroup", mcGroup);
|
||||
if (dataPort > 0u) {
|
||||
(void) cfg.Write("DataPort", static_cast<uint32>(dataPort));
|
||||
}
|
||||
}
|
||||
|
||||
if (!client_.Initialise(cfg)) {
|
||||
external_ = (external != static_cast<MARTe::UDPSClientI *>(0));
|
||||
if (external_) {
|
||||
client_ = external; /* already configured by its owner */
|
||||
}
|
||||
else {
|
||||
client_ = useTcp ? static_cast<MARTe::UDPSClientI *>(&tcpClient_)
|
||||
: static_cast<MARTe::UDPSClientI *>(&udpClient_);
|
||||
}
|
||||
if (!external_ && !client_->Initialise(cfg)) {
|
||||
REPORT_ERROR_STATIC(MARTe::ErrorManagement::FatalError,
|
||||
"UDPSourceSession[%s]: Failed to initialise UDPSClient.", id);
|
||||
"UDPSourceSession[%s]: Failed to initialise %s client.",
|
||||
id, useTcp ? "TCPSClient" : "UDPSClient");
|
||||
client_ = static_cast<MARTe::UDPSClientI *>(0);
|
||||
return false;
|
||||
}
|
||||
client_.SetListener(this);
|
||||
client_->SetListener(this);
|
||||
|
||||
(void) metaMutex_.FastLock();
|
||||
numSignals_ = 0u;
|
||||
@@ -165,12 +187,22 @@ bool UDPSourceSession::Start() {
|
||||
statByteCount_ = 0u;
|
||||
stateStr_ = "connecting";
|
||||
statsMutex_.FastUnLock();
|
||||
return client_.Start();
|
||||
return client_->Start();
|
||||
}
|
||||
|
||||
void UDPSourceSession::DetachClient() {
|
||||
if (!external_) { return; }
|
||||
(void) Stop();
|
||||
if (client_ != static_cast<MARTe::UDPSClientI *>(0)) {
|
||||
client_->SetListener(static_cast<MARTe::UDPSClientListener *>(0));
|
||||
}
|
||||
client_ = static_cast<MARTe::UDPSClientI *>(0);
|
||||
external_ = false;
|
||||
}
|
||||
|
||||
bool UDPSourceSession::Stop() {
|
||||
if (!initialised_) { return true; }
|
||||
return client_.Stop();
|
||||
if (!initialised_ || (client_ == static_cast<MARTe::UDPSClientI *>(0))) { return true; }
|
||||
return client_->Stop();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@@ -200,7 +232,7 @@ void UDPSourceSession::OnUDPSConfig(const uint8 *payload, uint32 payloadSize) {
|
||||
|
||||
void UDPSourceSession::OnUDPSData(const uint8 *payload, uint32 payloadSize) {
|
||||
/* Valid only for the duration of this callback. */
|
||||
ParseDataPayload(payload, payloadSize, client_.GetLastDataGap());
|
||||
ParseDataPayload(payload, payloadSize, client_->GetLastDataGap());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@@ -947,6 +979,10 @@ StreamString UDPSourceSession::GetMulticastGroup() const { return mcGroup_; }
|
||||
|
||||
uint16 UDPSourceSession::GetDataPort() const { return dataPort_; }
|
||||
|
||||
StreamString UDPSourceSession::GetTransport() const { return transport_; }
|
||||
|
||||
StreamString UDPSourceSession::GetStreamName() const { return streamName_; }
|
||||
|
||||
bool UDPSourceSession::IsConfigured() const {
|
||||
(void) metaMutex_.FastLock();
|
||||
bool c = configured_;
|
||||
|
||||
Reference in new issue
Block a user