Implemented client datasource
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "HistoryWriter.h"
|
||||
#include "AdvancedErrorManagement.h"
|
||||
#include "UDPSProtocol.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -129,8 +130,8 @@ void HistoryWriter::OnSourceConfigured(uint32 sessionIdx, const char *sourceId,
|
||||
MARTe::UDPSSignalDescriptor desc;
|
||||
if (!sess.GetSignalDescriptor(s, desc)) { continue; }
|
||||
|
||||
/* Skip time-only signals (type uint64, typically TimeArray) */
|
||||
if (desc.typeCode == 13u) { continue; } /* uint64 = 13 in UDPS */
|
||||
/* Skip time-reference signals (uint64 type, typically TimeArray) */
|
||||
if (desc.typeCode == MARTe::UDPS_TYPECODE_UINT64) { continue; }
|
||||
|
||||
float64 estRate = static_cast<float64>(desc.samplingRate);
|
||||
if (estRate <= 0.0) { estRate = 1000.0; } /* fallback */
|
||||
@@ -490,8 +491,9 @@ void HistoryWriter::AppendInfoJSON(char *&buf, uint32 &off, uint32 &cap) const {
|
||||
for (uint32 s = 0u; s < kHistMaxSignals; s++) {
|
||||
if (!fileActive_[i][s]) { continue; }
|
||||
const SignalFile &sf = files_[i][s];
|
||||
if (sf.count == 0u) { continue; }
|
||||
|
||||
/* Report even when count==0 — the file exists but hasn't received
|
||||
* data yet (or was just created). Clients need the entry to enable
|
||||
* history UI; t0/t1 == 0 signals "still priming". */
|
||||
HistJsonAppendf(buf, off, cap,
|
||||
"%s\"%s:%s\":{\"t0\":%.17g,\"t1\":%.17g,\"count\":%u,\"capacity\":%u}",
|
||||
(first ? "" : ","),
|
||||
|
||||
@@ -42,6 +42,12 @@ public:
|
||||
*/
|
||||
void Write(float64 t, float64 v);
|
||||
|
||||
/**
|
||||
* @brief Write @p n (t, v) pairs in a single lock acquisition.
|
||||
* Much faster than calling Write() n times for large batches.
|
||||
*/
|
||||
void WriteBatch(const float64 *t, const float64 *v, uint32 n);
|
||||
|
||||
/**
|
||||
* @brief Copy the last (oldest-to-newest) min(n, count) points into tOut/vOut.
|
||||
* @return Number of points actually written.
|
||||
@@ -144,6 +150,22 @@ inline void SignalRingBuffer::Write(float64 t, float64 v) {
|
||||
mutex.FastUnLock();
|
||||
}
|
||||
|
||||
inline void SignalRingBuffer::WriteBatch(const float64 *t, const float64 *v,
|
||||
uint32 n) {
|
||||
if (n == 0u) { return; }
|
||||
(void) mutex.FastLock();
|
||||
if (capacity > 0u) {
|
||||
for (uint32 i = 0u; i < n; i++) {
|
||||
tBuf[head] = t[i];
|
||||
vBuf[head] = v[i];
|
||||
head = (head + 1u) % capacity;
|
||||
if (count < capacity) { count++; }
|
||||
}
|
||||
totalWritten += static_cast<MARTe::uint64>(n);
|
||||
}
|
||||
mutex.FastUnLock();
|
||||
}
|
||||
|
||||
inline uint32 SignalRingBuffer::Read(float64 *tOut, float64 *vOut, uint32 n) const {
|
||||
if ((capacity == 0u) || (count == 0u)) { return 0u; }
|
||||
(void) mutex.FastLock();
|
||||
|
||||
@@ -255,13 +255,27 @@ bool StreamHub::Run() {
|
||||
PushStats();
|
||||
}
|
||||
|
||||
/* History: flush headers periodically */
|
||||
/* History: flush headers at the configured interval, then re-broadcast
|
||||
* historyInfo so new clients (or clients that saw empty signal lists
|
||||
* before the first data was written) pick up the current state. */
|
||||
if (history_.IsEnabled()) {
|
||||
uint32 histFlushDiv = history_.Decimation() > 0u
|
||||
? pushRateHz_ * 5u : pushRateHz_ * 5u; /* every 5s */
|
||||
if (histFlushDiv == 0u) { histFlushDiv = 1u; }
|
||||
if ((tickCount_ % histFlushDiv) == 0u) {
|
||||
uint32 flushIntervalTicks = pushRateHz_ * 5u; /* default 5 s */
|
||||
if (pushRateHz_ > 0u) {
|
||||
flushIntervalTicks = pushRateHz_ * 5u;
|
||||
}
|
||||
if (flushIntervalTicks == 0u) { flushIntervalTicks = 1u; }
|
||||
if ((tickCount_ % flushIntervalTicks) == 0u) {
|
||||
history_.FlushHeaders();
|
||||
/* Re-broadcast so clients see updated signal counts and
|
||||
* time ranges after the first batch of data is written. */
|
||||
uint32 cap2 = 8192u;
|
||||
char *hbuf = new char[cap2];
|
||||
uint32 hoff = 0u;
|
||||
JsonAppendf(hbuf, hoff, cap2, "{\"type\":\"historyInfo\",");
|
||||
history_.AppendInfoJSON(hbuf, hoff, cap2);
|
||||
JsonAppendf(hbuf, hoff, cap2, "}");
|
||||
wsServer_.BroadcastText(hbuf, hoff);
|
||||
delete[] hbuf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,6 +662,14 @@ void StreamHub::OnWSClientConnected() {
|
||||
wsServer_.BroadcastText(hbuf, hoff);
|
||||
delete[] hbuf;
|
||||
}
|
||||
|
||||
/* Inform the new client about the current MaxPoints setting. */
|
||||
{
|
||||
char mp[64];
|
||||
int n = snprintf(mp, sizeof(mp),
|
||||
"{\"type\":\"maxPointsUpdated\",\"maxPoints\":%u}", maxPoints_);
|
||||
if (n > 0) { wsServer_.BroadcastText(mp, static_cast<uint32>(n)); }
|
||||
}
|
||||
}
|
||||
|
||||
void StreamHub::OnWSClientDisconnected() {
|
||||
|
||||
@@ -63,7 +63,10 @@ UDPSourceSession::UDPSourceSession()
|
||||
statLastRxTicks_(0u),
|
||||
statFragCount_(0u),
|
||||
statByteCount_(0u),
|
||||
hrtFreq_(static_cast<float64>(MARTe::HighResolutionTimer::Frequency())),
|
||||
timeScratch_(static_cast<float64 *>(0)),
|
||||
valScratch_(static_cast<float64 *>(0)),
|
||||
tsBatchScratch_(static_cast<float64 *>(0)),
|
||||
timeScratchLen_(0u),
|
||||
trigEngine_(static_cast<TriggerEngine *>(0)),
|
||||
trigEpochSeen_(0xFFFFFFFFu),
|
||||
@@ -76,6 +79,8 @@ UDPSourceSession::UDPSourceSession()
|
||||
UDPSourceSession::~UDPSourceSession() {
|
||||
(void) Stop();
|
||||
delete[] timeScratch_;
|
||||
delete[] valScratch_;
|
||||
delete[] tsBatchScratch_;
|
||||
}
|
||||
|
||||
void UDPSourceSession::ResetCalibration() {
|
||||
@@ -84,6 +89,7 @@ void UDPSourceSession::ResetCalibration() {
|
||||
timeSigCalib_[i] = 0.0;
|
||||
lastPktWallValid_[i] = false;
|
||||
lastPktWallS_[i] = 0.0;
|
||||
accScalarPrevN_[i] = 0u;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +233,11 @@ void UDPSourceSession::ParseConfigPayload(const uint8 *payload, uint32 size) {
|
||||
}
|
||||
if (maxElems > timeScratchLen_) {
|
||||
delete[] timeScratch_;
|
||||
delete[] valScratch_;
|
||||
delete[] tsBatchScratch_;
|
||||
timeScratch_ = new float64[maxElems];
|
||||
valScratch_ = new float64[maxElems];
|
||||
tsBatchScratch_ = new float64[maxElems];
|
||||
timeScratchLen_ = maxElems;
|
||||
}
|
||||
|
||||
@@ -369,17 +379,19 @@ void UDPSourceSession::ParseDataPayload(const uint8 *payload, uint32 size) {
|
||||
} else {
|
||||
anchorIsFirstSample = false;
|
||||
}
|
||||
/* Batch decode: compute all timestamps and values, then batch write. */
|
||||
const float64 dt = (desc.samplingRate > 0.0) ? (1.0 / desc.samplingRate) : 0.0;
|
||||
DecodeElems(payload, sigOff[s], desc, nElems, valScratch_);
|
||||
for (uint32 e = 0u; e < nElems; e++) {
|
||||
const float64 val = DecodeOneElem(payload, sigOff[s], desc, e);
|
||||
const float64 t = anchorIsFirstSample
|
||||
tsBatchScratch_[e] = anchorIsFirstSample
|
||||
? (anchor + static_cast<float64>(e) * dt)
|
||||
: (anchor - static_cast<float64>(nElems - 1u - e) * dt);
|
||||
WriteSample(s, e, t, val);
|
||||
}
|
||||
WriteSampleBatch(s, tsBatchScratch_, valScratch_, nElems);
|
||||
}
|
||||
else if (isFullArray) {
|
||||
/* Per-element timestamps from the referenced time-signal array. */
|
||||
/* Per-element timestamps from the referenced time-signal array.
|
||||
* Batch decode + batch write (single ring lock per signal). */
|
||||
if (hasTimeSig && (sigElems[tIdx] >= nElems) &&
|
||||
(nElems <= timeScratchLen_)) {
|
||||
DecodeElems(payload, sigOff[tIdx], descs[tIdx], nElems, timeScratch_);
|
||||
@@ -390,15 +402,18 @@ void UDPSourceSession::ParseDataPayload(const uint8 *payload, uint32 size) {
|
||||
timeSigCalibValid_[tIdx] = true;
|
||||
}
|
||||
const float64 calib = timeSigCalib_[tIdx];
|
||||
DecodeElems(payload, sigOff[s], desc, nElems, valScratch_);
|
||||
for (uint32 e = 0u; e < nElems; e++) {
|
||||
const float64 val = DecodeOneElem(payload, sigOff[s], desc, e);
|
||||
WriteSample(s, e, calib + timeScratch_[e] * timerToSec, val);
|
||||
tsBatchScratch_[e] = calib + timeScratch_[e] * timerToSec;
|
||||
}
|
||||
WriteSampleBatch(s, tsBatchScratch_, valScratch_, nElems);
|
||||
} else {
|
||||
/* No time signal: all samples get arrival wall time. */
|
||||
DecodeElems(payload, sigOff[s], desc, nElems, valScratch_);
|
||||
for (uint32 e = 0u; e < nElems; e++) {
|
||||
const float64 val = DecodeOneElem(payload, sigOff[s], desc, e);
|
||||
WriteSample(s, e, wallNowS, val);
|
||||
tsBatchScratch_[e] = wallNowS;
|
||||
}
|
||||
WriteSampleBatch(s, tsBatchScratch_, valScratch_, nElems);
|
||||
}
|
||||
}
|
||||
else if (numElements == 1u) {
|
||||
@@ -407,22 +422,55 @@ void UDPSourceSession::ParseDataPayload(const uint8 *payload, uint32 size) {
|
||||
const float64 val = DecodeOneElem(payload, sigOff[s], desc, 0u);
|
||||
WriteSample(s, 0u, wallNowS, val);
|
||||
}
|
||||
else if (lastPktWallValid_[s] && (wallNowS > lastPktWallS_[s])) {
|
||||
/* Accumulated scalar: the packet carries one sample per RT
|
||||
* cycle — spread them across the inter-packet wall-clock gap
|
||||
* (same scheme as packed arrays) instead of stamping them all
|
||||
* with the arrival time, which renders as a stair plot. */
|
||||
const float64 dt = (wallNowS - lastPktWallS_[s]) /
|
||||
static_cast<float64>(nElems);
|
||||
const float64 base = lastPktWallS_[s];
|
||||
for (uint32 e = 0u; e < nElems; e++) {
|
||||
const float64 val = DecodeOneElem(payload, sigOff[s], desc, e);
|
||||
WriteSample(s, 0u, base + static_cast<float64>(e + 1u) * dt, val);
|
||||
else {
|
||||
/* Accumulated scalar: reconstruct per-sample timestamps from
|
||||
* the packet's embedded sender HRT (the acquisition time of the
|
||||
* oldest sample), NOT the packet arrival time. The kernel
|
||||
* frequently delivers several queued datagrams in one burst, so
|
||||
* two packets can be processed microseconds apart even though
|
||||
* each represents ~10 ms of signal; arrival-time interpolation
|
||||
* then crams a packet's samples into that tiny gap, rendering
|
||||
* the trace as a sawtooth ("chainsaw"). The sender HRT is
|
||||
* immune to this because it is sampled at acquisition.
|
||||
*
|
||||
* hrtTimestamp is the HRT counter of sample 0; hrtFreq_ (the
|
||||
* local HRT frequency, identical to the sender on the same
|
||||
* host) converts it to seconds, then a one-time calibration
|
||||
* maps the sender clock onto wall-clock. */
|
||||
const float64 hrt0Sec = static_cast<float64>(hrtTimestamp) /
|
||||
hrtFreq_;
|
||||
if ((!timeSigCalibValid_[s]) ||
|
||||
(Fabs((timeSigCalib_[s] + hrt0Sec) - wallNowS) >
|
||||
kRecalibThresholdS)) {
|
||||
timeSigCalib_[s] = wallNowS - hrt0Sec;
|
||||
timeSigCalibValid_[s] = true;
|
||||
}
|
||||
}
|
||||
if (nElems > 1u) {
|
||||
lastPktWallS_[s] = wallNowS;
|
||||
|
||||
/* Per-sample dt: samplingRate if present, else derive it from
|
||||
* the sender-HRT gap to the previous packet divided by that
|
||||
* packet's sample count (the flushes carry contiguous RT
|
||||
* cycles, so this is exactly one cycle period). */
|
||||
float64 dt;
|
||||
if (desc.samplingRate > 0.0) {
|
||||
dt = 1.0 / desc.samplingRate;
|
||||
} else if (lastPktWallValid_[s] && (accScalarPrevN_[s] > 0u) &&
|
||||
(hrt0Sec > lastPktWallS_[s])) {
|
||||
dt = (hrt0Sec - lastPktWallS_[s]) /
|
||||
static_cast<float64>(accScalarPrevN_[s]);
|
||||
} else {
|
||||
dt = 1.0e-3; /* 1 kHz default until the gap is known */
|
||||
}
|
||||
|
||||
const float64 base = timeSigCalib_[s] + hrt0Sec;
|
||||
DecodeElems(payload, sigOff[s], desc, nElems, valScratch_);
|
||||
for (uint32 e = 0u; e < nElems; e++) {
|
||||
tsBatchScratch_[e] = base + static_cast<float64>(e) * dt;
|
||||
}
|
||||
WriteSampleBatch(s, tsBatchScratch_, valScratch_, nElems);
|
||||
|
||||
lastPktWallS_[s] = hrt0Sec; /* sender seconds for next dt */
|
||||
lastPktWallValid_[s] = true;
|
||||
accScalarPrevN_[s] = nElems;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -435,14 +483,23 @@ void UDPSourceSession::ParseDataPayload(const uint8 *payload, uint32 size) {
|
||||
* and overlaps the next packet under jitter), elements span
|
||||
* (lastPktWall, wallNow]: the samples were acquired before the
|
||||
* packet arrived, and this keeps ring time strictly monotonic. */
|
||||
if (lastPktWallValid_[s] && (wallNowS > lastPktWallS_[s])) {
|
||||
const float64 dt = (wallNowS - lastPktWallS_[s]) /
|
||||
static_cast<float64>(nElems);
|
||||
const float64 base = lastPktWallS_[s];
|
||||
for (uint32 e = 0u; e < nElems; e++) {
|
||||
const float64 val = DecodeOneElem(payload, sigOff[s], desc, e);
|
||||
WriteSample(s, e, base + static_cast<float64>(e + 1u) * dt, val);
|
||||
if (lastPktWallValid_[s] && (wallNowS >= lastPktWallS_[s])) {
|
||||
float64 dt;
|
||||
float64 base;
|
||||
if (wallNowS > lastPktWallS_[s]) {
|
||||
dt = (wallNowS - lastPktWallS_[s]) /
|
||||
static_cast<float64>(nElems);
|
||||
base = lastPktWallS_[s];
|
||||
} else {
|
||||
dt = (desc.samplingRate > 0.0)
|
||||
? (1.0 / desc.samplingRate) : 1.0e-6;
|
||||
base = lastPktWallS_[s] - static_cast<float64>(nElems) * dt;
|
||||
}
|
||||
DecodeElems(payload, sigOff[s], desc, nElems, valScratch_);
|
||||
for (uint32 e = 0u; e < nElems; e++) {
|
||||
tsBatchScratch_[e] = base + static_cast<float64>(e + 1u) * dt;
|
||||
}
|
||||
WriteSampleBatch(s, tsBatchScratch_, valScratch_, nElems);
|
||||
}
|
||||
lastPktWallS_[s] = wallNowS;
|
||||
lastPktWallValid_[s] = true;
|
||||
|
||||
@@ -187,6 +187,22 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Batch ring write for signal @p s, with optional trigger check.
|
||||
* Uses WriteBatch internally (single lock acquisition for all samples). */
|
||||
inline void WriteSampleBatch(uint32 s, const float64 *t, const float64 *v,
|
||||
uint32 n) {
|
||||
rings_[s].WriteBatch(t, v, n);
|
||||
/* Trigger check must still run per-sample for the watched signal. */
|
||||
if ((trigSigIdx_ >= 0) && (static_cast<uint32>(trigSigIdx_) == s) &&
|
||||
(trigEngine_ != static_cast<TriggerEngine *>(0))) {
|
||||
for (uint32 e = 0u; e < n; e++) {
|
||||
if ((trigElemIdx_ < 0) || (static_cast<uint32>(trigElemIdx_) == e)) {
|
||||
trigEngine_->CheckSample(t[e], v[e]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decode @p nElems consecutive elements of signal @p desc starting
|
||||
* at payload offset @p off into @p out (dequantised physical values).
|
||||
@@ -253,12 +269,23 @@ private:
|
||||
bool timeSigCalibValid_[UDPSS_MAX_SIGNALS];
|
||||
|
||||
/* Last packet arrival wall time per signal — used to interpolate per-element
|
||||
* timestamps for packed TIMEMODE_PACKET arrays (Go hub lastPktNs). */
|
||||
* timestamps for packed TIMEMODE_PACKET arrays (Go hub lastPktNs).
|
||||
* For accumulated scalars this instead holds the previous packet's
|
||||
* sender-clock seconds (HRT-derived), used to derive the per-sample dt. */
|
||||
float64 lastPktWallS_[UDPSS_MAX_SIGNALS];
|
||||
bool lastPktWallValid_[UDPSS_MAX_SIGNALS];
|
||||
|
||||
/* Scratch for decoding referenced time-signal arrays (receive thread only). */
|
||||
float64 *timeScratch_;
|
||||
/* Accumulated-scalar timing: HRT counter frequency (local == sender on the
|
||||
* same host) and the previous packet's sample count, used to reconstruct
|
||||
* per-sample timestamps from the embedded sender HRT instead of the (UDP
|
||||
* burst-sensitive) packet arrival time. */
|
||||
float64 hrtFreq_;
|
||||
uint32 accScalarPrevN_[UDPSS_MAX_SIGNALS];
|
||||
|
||||
/* Scratch buffers for decoding arrays (receive thread only). */
|
||||
float64 *timeScratch_; ///< Time values scratch
|
||||
float64 *valScratch_; ///< Data values scratch
|
||||
float64 *tsBatchScratch_; ///< Timestamps scratch for batch write
|
||||
uint32 timeScratchLen_;
|
||||
|
||||
/* Trigger hookup (resolution cache is receive-thread only). */
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#############################################################
|
||||
#
|
||||
# Copyright 2015 F4E | European Joint Undertaking for ITER
|
||||
# and the Development of Fusion Energy ('Fusion for Energy')
|
||||
#
|
||||
# Licensed under the EUPL, Version 1.1 or - as soon they
|
||||
# will be approved by the European Commission - subsequent
|
||||
# versions of the EUPL (the "Licence");
|
||||
# You may not use this work except in compliance with the
|
||||
# Licence.
|
||||
# You may obtain a copy of the Licence at:
|
||||
#
|
||||
# http://ec.europa.eu/idabc/eupl
|
||||
#
|
||||
# Unless required by applicable law or agreed to in
|
||||
# writing, software distributed under the Licence is
|
||||
# distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
# express or implied.
|
||||
# See the Licence for the specific language governing
|
||||
# permissions and limitations under the Licence.
|
||||
#
|
||||
#############################################################
|
||||
|
||||
include Makefile.inc
|
||||
@@ -0,0 +1,25 @@
|
||||
#############################################################
|
||||
#
|
||||
# Copyright 2015 F4E | European Joint Undertaking for ITER
|
||||
# and the Development of Fusion Energy ('Fusion for Energy')
|
||||
#
|
||||
# Licensed under the EUPL, Version 1.1 or - as soon they
|
||||
# will be approved by the European Commission - subsequent
|
||||
# versions of the EUPL (the "Licence");
|
||||
# You may not use this work except in compliance with the
|
||||
# Licence.
|
||||
# You may obtain a copy of the Licence at:
|
||||
#
|
||||
# http://ec.europa.eu/idabc/eupl
|
||||
#
|
||||
# Unless required by applicable law or agreed to in
|
||||
# writing, software distributed under the Licence is
|
||||
# distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
# express or implied.
|
||||
# See the Licence for the specific language governing
|
||||
# permissions and limitations under the Licence.
|
||||
#
|
||||
#############################################################
|
||||
|
||||
include Makefile.inc
|
||||
@@ -0,0 +1,60 @@
|
||||
#############################################################
|
||||
#
|
||||
# Copyright 2015 F4E | European Joint Undertaking for ITER
|
||||
# and the Development of Fusion Energy ('Fusion for Energy')
|
||||
#
|
||||
# Licensed under the EUPL, Version 1.1 or - as soon they
|
||||
# will be approved by the European Commission - subsequent
|
||||
# versions of the EUPL (the "Licence");
|
||||
# You may not use this work except in compliance with the
|
||||
# Licence.
|
||||
# You may obtain a copy of the Licence at:
|
||||
#
|
||||
# http://ec.europa.eu/idabc/eupl
|
||||
#
|
||||
# Unless required by applicable law or agreed to in
|
||||
# writing, software distributed under the Licence is
|
||||
# distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
# express or implied.
|
||||
# See the Licence for the specific language governing
|
||||
# permissions and limitations under the Licence.
|
||||
#
|
||||
#############################################################
|
||||
|
||||
OBJSX = UDPStreamerClient.x
|
||||
|
||||
PACKAGE=Components/DataSources
|
||||
ROOT_DIR=../../../../
|
||||
MAKEDEFAULTDIR=$(MARTe2_DIR)/MakeDefaults
|
||||
|
||||
include $(MAKEDEFAULTDIR)/MakeStdLibDefs.$(TARGET)
|
||||
|
||||
INCLUDES += -I.
|
||||
INCLUDES += -I$(ROOT_DIR)/Common/UDP
|
||||
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/UDPStream
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L0Types
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L1Portability
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L2Objects
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L3Streams
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Messages
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Configuration
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L5GAMs
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L1Portability
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L3Services
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4Messages
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L5GAMs
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
|
||||
|
||||
LIBRARIES += -L$(MARTe2_DIR)/Build/$(TARGET)/Core -lMARTe2
|
||||
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/UDPStream -lUDPStream
|
||||
|
||||
all: $(OBJS) \
|
||||
$(BUILD_DIR)/UDPStreamerClient$(LIBEXT) \
|
||||
$(BUILD_DIR)/UDPStreamerClient$(DLLEXT)
|
||||
echo $(OBJS)
|
||||
|
||||
include depends.$(TARGET)
|
||||
|
||||
include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET)
|
||||
@@ -0,0 +1,564 @@
|
||||
/**
|
||||
* @file UDPStreamerClient.cpp
|
||||
* @brief Source file for class UDPStreamerClient
|
||||
* @date 24/06/2026
|
||||
* @author Martino Ferrari
|
||||
*
|
||||
* @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
|
||||
* the Development of Fusion Energy ('Fusion for Energy').
|
||||
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved
|
||||
* by the European Commission - subsequent versions of the EUPL (the "Licence")
|
||||
* You may not use this work except in compliance with the Licence.
|
||||
* You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
|
||||
*
|
||||
* @warning Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the Licence is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the Licence permissions and limitations under the Licence.
|
||||
*
|
||||
* @details This source file contains the definition of all the methods for
|
||||
* the class UDPStreamerClient (public, protected, and private).
|
||||
*/
|
||||
|
||||
#define DLL_API
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Standard header includes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include <string.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Project header includes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "AdvancedErrorManagement.h"
|
||||
#include "ConfigurationDatabase.h"
|
||||
#include "GlobalObjectsDatabase.h"
|
||||
#include "MemoryOperationsHelper.h"
|
||||
#include "UDPSProtocol.h"
|
||||
#include "UDPStreamerClient.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Static definitions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
/** Default server address when none is specified. */
|
||||
static const char8 *const UDPS_CLIENT_DEFAULT_ADDR = "127.0.0.1";
|
||||
|
||||
/** Default port used when none is specified. */
|
||||
static const uint16 UDPS_CLIENT_DEFAULT_PORT = 44500u;
|
||||
|
||||
/** Default data-port offset: dataPort = port + this when DataPort is absent. */
|
||||
static const uint16 UDPS_CLIENT_DEFAULT_DP_OFFSET = 1u;
|
||||
|
||||
/** Default max payload per UDP datagram (bytes). */
|
||||
static const uint32 UDPS_CLIENT_DEFAULT_MAX_PAYLOAD = 1400u;
|
||||
|
||||
/** Bytes prepended to each DATA payload for the HRT packet timestamp. */
|
||||
static const uint32 UDPS_CLIENT_TIMESTAMP_BYTES = 8u;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Decode helpers */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Reads one quantised wire element (1 or 2 bytes) as a float64,
|
||||
* mirroring UDPSourceSession::DecodeRawValue for the quantised type codes.
|
||||
*/
|
||||
static float64 DecodeQuantRaw(const uint8 *ptr, uint8 quantType) {
|
||||
float64 raw = 0.0;
|
||||
switch (quantType) {
|
||||
case UDPS_QUANT_UINT8: {
|
||||
uint8 v = 0u; (void) memcpy(&v, ptr, 1u); raw = static_cast<float64>(v);
|
||||
break;
|
||||
}
|
||||
case UDPS_QUANT_INT8: {
|
||||
int8 v = 0; (void) memcpy(&v, ptr, 1u); raw = static_cast<float64>(v);
|
||||
break;
|
||||
}
|
||||
case UDPS_QUANT_UINT16: {
|
||||
uint16 v = 0u; (void) memcpy(&v, ptr, 2u); raw = static_cast<float64>(v);
|
||||
break;
|
||||
}
|
||||
case UDPS_QUANT_INT16: {
|
||||
int16 v = 0; (void) memcpy(&v, ptr, 2u); raw = static_cast<float64>(v);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dequantises a raw value, mirroring UDPSourceSession::DequantizeValue.
|
||||
*/
|
||||
static float64 DequantValue(float64 raw, uint8 quantType,
|
||||
float64 rangeMin, float64 rangeMax) {
|
||||
const float64 range = rangeMax - rangeMin;
|
||||
float64 val;
|
||||
switch (quantType) {
|
||||
case UDPS_QUANT_UINT8:
|
||||
val = rangeMin + (raw / 255.0) * range;
|
||||
break;
|
||||
case UDPS_QUANT_INT8:
|
||||
val = rangeMin + ((raw + 127.0) / 254.0) * range;
|
||||
break;
|
||||
case UDPS_QUANT_UINT16:
|
||||
val = rangeMin + (raw / 65535.0) * range;
|
||||
break;
|
||||
case UDPS_QUANT_INT16:
|
||||
val = rangeMin + ((raw + 32767.0) / 65534.0) * range;
|
||||
break;
|
||||
default:
|
||||
val = raw;
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Method definitions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
UDPStreamerClient::UDPStreamerClient() :
|
||||
MemoryDataSourceI(),
|
||||
UDPSClientListener(),
|
||||
client() {
|
||||
serverAddress = UDPS_CLIENT_DEFAULT_ADDR;
|
||||
port = UDPS_CLIENT_DEFAULT_PORT;
|
||||
maxPayloadSize = UDPS_CLIENT_DEFAULT_MAX_PAYLOAD;
|
||||
cpuMask = 0xFFFFFFFFu;
|
||||
stackSize = THREADS_DEFAULT_STACKSIZE;
|
||||
dataPort = UDPS_CLIENT_DEFAULT_PORT + UDPS_CLIENT_DEFAULT_DP_OFFSET;
|
||||
useMulticast = false;
|
||||
numSigs = 0u;
|
||||
signalInfos = NULL_PTR(UDPStreamerClientSignal *);
|
||||
totalSrcBytes = 0u;
|
||||
configValidated = false;
|
||||
publishMode = UDPS_PUBLISH_STRICT;
|
||||
receiverUp = false;
|
||||
readyBuffer = NULL_PTR(uint8 *);
|
||||
scratchBuffer = NULL_PTR(uint8 *);
|
||||
newDataReady = false;
|
||||
|
||||
if (!dataSem.Create()) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "Could not create EventSem.");
|
||||
}
|
||||
bufMutex.Create(false);
|
||||
}
|
||||
|
||||
UDPStreamerClient::~UDPStreamerClient() {
|
||||
(void) dataSem.Post();
|
||||
|
||||
if (receiverUp) {
|
||||
(void) client.Stop();
|
||||
receiverUp = false;
|
||||
}
|
||||
|
||||
HeapI *heap = GlobalObjectsDatabase::Instance()->GetStandardHeap();
|
||||
if (signalInfos != NULL_PTR(UDPStreamerClientSignal *)) {
|
||||
delete[] signalInfos;
|
||||
signalInfos = NULL_PTR(UDPStreamerClientSignal *);
|
||||
}
|
||||
if (readyBuffer != NULL_PTR(uint8 *)) {
|
||||
heap->Free(reinterpret_cast<void *&>(readyBuffer));
|
||||
}
|
||||
if (scratchBuffer != NULL_PTR(uint8 *)) {
|
||||
heap->Free(reinterpret_cast<void *&>(scratchBuffer));
|
||||
}
|
||||
|
||||
(void) dataSem.Close();
|
||||
}
|
||||
|
||||
bool UDPStreamerClient::Initialise(StructuredDataI &data) {
|
||||
bool ok = MemoryDataSourceI::Initialise(data);
|
||||
|
||||
if (ok) {
|
||||
StreamString addr = "";
|
||||
if (!data.Read("ServerAddress", addr) || (addr.Size() == 0u)) {
|
||||
addr = UDPS_CLIENT_DEFAULT_ADDR;
|
||||
REPORT_ERROR(ErrorManagement::Information,
|
||||
"ServerAddress not specified; using default %s.",
|
||||
UDPS_CLIENT_DEFAULT_ADDR);
|
||||
}
|
||||
serverAddress = addr;
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (!data.Read("Port", port)) {
|
||||
port = UDPS_CLIENT_DEFAULT_PORT;
|
||||
REPORT_ERROR(ErrorManagement::Information,
|
||||
"Port not specified; using default %u.",
|
||||
static_cast<uint32>(port));
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (!data.Read("MaxPayloadSize", maxPayloadSize)) {
|
||||
maxPayloadSize = UDPS_CLIENT_DEFAULT_MAX_PAYLOAD;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (!data.Read("CPUMask", cpuMask)) {
|
||||
cpuMask = 0xFFFFFFFFu;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (!data.Read("StackSize", stackSize)) {
|
||||
stackSize = THREADS_DEFAULT_STACKSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
StreamString mcastStr = "";
|
||||
(void) data.Read("MulticastGroup", mcastStr);
|
||||
if (mcastStr.Size() > 0u) {
|
||||
multicastGroup = mcastStr;
|
||||
useMulticast = true;
|
||||
uint16 dp = 0u;
|
||||
if (!data.Read("DataPort", dp)) {
|
||||
dp = port + UDPS_CLIENT_DEFAULT_DP_OFFSET;
|
||||
}
|
||||
dataPort = dp;
|
||||
REPORT_ERROR(ErrorManagement::Information,
|
||||
"Multicast mode: group=%s, server=%s, controlPort=%u, dataPort=%u.",
|
||||
multicastGroup.Buffer(), serverAddress.Buffer(),
|
||||
static_cast<uint32>(port), static_cast<uint32>(dataPort));
|
||||
}
|
||||
else {
|
||||
useMulticast = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Forward the transport parameters to the shared UDPSClient receiver,
|
||||
* translating the DataSource parameter names to the UDPSClient keys. */
|
||||
if (ok) {
|
||||
ConfigurationDatabase cdb;
|
||||
ok = cdb.Write("ServerAddr", serverAddress);
|
||||
if (ok) { ok = cdb.Write("Port", static_cast<uint32>(port)); }
|
||||
if (ok && useMulticast) {
|
||||
ok = cdb.Write("MulticastGroup", multicastGroup);
|
||||
if (ok) { ok = cdb.Write("DataPort", static_cast<uint32>(dataPort)); }
|
||||
}
|
||||
if (ok) { ok = cdb.Write("MaxPayloadSize", maxPayloadSize); }
|
||||
if (ok) { ok = cdb.Write("CPUMask", cpuMask); }
|
||||
if (ok) { ok = cdb.Write("StackSize", stackSize); }
|
||||
if (ok) { ok = cdb.MoveToRoot(); }
|
||||
if (ok) { ok = client.Initialise(cdb); }
|
||||
if (!ok) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"Could not configure the UDPSClient receiver.");
|
||||
}
|
||||
client.SetListener(this);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool UDPStreamerClient::SetConfiguredDatabase(StructuredDataI &data) {
|
||||
bool ok = MemoryDataSourceI::SetConfiguredDatabase(data);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
numSigs = GetNumberOfSignals();
|
||||
if (numSigs == 0u) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"At least one signal must be defined.");
|
||||
return false;
|
||||
}
|
||||
|
||||
signalInfos = new UDPStreamerClientSignal[numSigs];
|
||||
|
||||
totalSrcBytes = 0u;
|
||||
for (uint32 i = 0u; (i < numSigs) && ok; i++) {
|
||||
StreamString sigName;
|
||||
ok = GetSignalName(i, sigName);
|
||||
if (!ok) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError,
|
||||
"Could not get name for signal %u.", i);
|
||||
break;
|
||||
}
|
||||
|
||||
uint32 nelems = 1u;
|
||||
(void) GetSignalNumberOfElements(i, nelems);
|
||||
if (nelems == 0u) { nelems = 1u; }
|
||||
|
||||
uint32 bsz = 0u;
|
||||
(void) GetSignalByteSize(i, bsz);
|
||||
|
||||
signalInfos[i].name = sigName;
|
||||
signalInfos[i].type = GetSignalType(i);
|
||||
signalInfos[i].quantType = UDPS_QUANT_NONE;
|
||||
signalInfos[i].numElements = nelems;
|
||||
signalInfos[i].rangeMin = 0.0;
|
||||
signalInfos[i].rangeMax = 1.0;
|
||||
signalInfos[i].srcByteSize = bsz;
|
||||
signalInfos[i].wireElemBytes = (nelems > 0u) ? (bsz / nelems) : bsz;
|
||||
signalInfos[i].bufferOffset = totalSrcBytes;
|
||||
totalSrcBytes += bsz;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool UDPStreamerClient::AllocateMemory() {
|
||||
bool ok = MemoryDataSourceI::AllocateMemory();
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (totalSrcBytes == 0u) {
|
||||
totalSrcBytes = stateMemorySize;
|
||||
}
|
||||
|
||||
HeapI *heap = GlobalObjectsDatabase::Instance()->GetStandardHeap();
|
||||
|
||||
readyBuffer = reinterpret_cast<uint8 *>(heap->Malloc(totalSrcBytes));
|
||||
if (readyBuffer == NULL_PTR(uint8 *)) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "Could not allocate readyBuffer.");
|
||||
return false;
|
||||
}
|
||||
(void) MemoryOperationsHelper::Set(readyBuffer, 0, totalSrcBytes);
|
||||
|
||||
scratchBuffer = reinterpret_cast<uint8 *>(heap->Malloc(totalSrcBytes));
|
||||
if (scratchBuffer == NULL_PTR(uint8 *)) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "Could not allocate scratchBuffer.");
|
||||
return false;
|
||||
}
|
||||
(void) MemoryOperationsHelper::Set(scratchBuffer, 0, totalSrcBytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char8 *UDPStreamerClient::GetBrokerName(StructuredDataI &data,
|
||||
const SignalDirection direction) {
|
||||
const char8 *brokerName = "";
|
||||
if (direction == InputSignals) {
|
||||
brokerName = "MemoryMapSynchronisedInputBroker";
|
||||
}
|
||||
return brokerName;
|
||||
}
|
||||
|
||||
bool UDPStreamerClient::PrepareNextState(const char8 *const currentStateName,
|
||||
const char8 *const nextStateName) {
|
||||
bool ok = true;
|
||||
if (!receiverUp) {
|
||||
ok = client.Start();
|
||||
if (ok) {
|
||||
receiverUp = true;
|
||||
}
|
||||
else {
|
||||
REPORT_ERROR(ErrorManagement::FatalError,
|
||||
"Could not start the UDPSClient receiver.");
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool UDPStreamerClient::Synchronise() {
|
||||
ErrorManagement::ErrorType waitErr = dataSem.ResetWait(TimeoutType(10u));
|
||||
if (waitErr == ErrorManagement::NoError) {
|
||||
bufMutex.FastLock(TTInfiniteWait);
|
||||
(void) MemoryOperationsHelper::Copy(memory, readyBuffer, totalSrcBytes);
|
||||
newDataReady = false;
|
||||
bufMutex.FastUnLock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* UDPSClientListener callbacks */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void UDPStreamerClient::OnUDPSConfig(const uint8 *payload, uint32 payloadSize) {
|
||||
if (payloadSize < 4u) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"CONFIG payload too small (%u bytes).", payloadSize);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 serverNumSigs = 0u;
|
||||
(void) memcpy(&serverNumSigs, payload, 4u);
|
||||
|
||||
if (serverNumSigs != numSigs) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"CONFIG signal count mismatch: server=%u, client=%u.",
|
||||
serverNumSigs, numSigs);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32 needed = 4u + (numSigs * UDPS_SIGNAL_DESC_SIZE);
|
||||
if (payloadSize < needed) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"CONFIG payload truncated (%u < %u bytes).", payloadSize, needed);
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
for (uint32 i = 0u; (i < numSigs) && ok; i++) {
|
||||
UDPSSignalDescriptor desc;
|
||||
(void) memcpy(&desc, payload + 4u + (i * UDPS_SIGNAL_DESC_SIZE),
|
||||
UDPS_SIGNAL_DESC_SIZE);
|
||||
|
||||
char8 nameBuf[UDPS_MAX_SIGNAL_NAME + 1u];
|
||||
(void) memcpy(nameBuf, desc.name, UDPS_MAX_SIGNAL_NAME);
|
||||
nameBuf[UDPS_MAX_SIGNAL_NAME] = '\0';
|
||||
StreamString serverName = nameBuf;
|
||||
|
||||
if (signalInfos[i].name != serverName) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"CONFIG signal %u name mismatch: server=%s, client=%s.",
|
||||
i, serverName.Buffer(), signalInfos[i].name.Buffer());
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32 serverElems = desc.numRows * desc.numCols;
|
||||
if (serverElems == 0u) { serverElems = 1u; }
|
||||
if (serverElems != signalInfos[i].numElements) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"CONFIG signal %u element count mismatch: server=%u, client=%u.",
|
||||
i, serverElems, signalInfos[i].numElements);
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
signalInfos[i].quantType = desc.quantType;
|
||||
signalInfos[i].rangeMin = desc.rangeMin;
|
||||
signalInfos[i].rangeMax = desc.rangeMax;
|
||||
if (desc.quantType != UDPS_QUANT_NONE) {
|
||||
uint32 q = 0u;
|
||||
if ((desc.quantType == UDPS_QUANT_UINT8) ||
|
||||
(desc.quantType == UDPS_QUANT_INT8)) {
|
||||
q = 1u;
|
||||
}
|
||||
else if ((desc.quantType == UDPS_QUANT_UINT16) ||
|
||||
(desc.quantType == UDPS_QUANT_INT16)) {
|
||||
q = 2u;
|
||||
}
|
||||
signalInfos[i].wireElemBytes = q;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
const uint32 pmOffset = needed;
|
||||
publishMode = (payloadSize > pmOffset) ? payload[pmOffset] : UDPS_PUBLISH_STRICT;
|
||||
|
||||
bufMutex.FastLock(TTInfiniteWait);
|
||||
configValidated = true;
|
||||
bufMutex.FastUnLock();
|
||||
|
||||
REPORT_ERROR(ErrorManagement::Information,
|
||||
"CONFIG validated: %u signals, publishMode=%u, totalSrcBytes=%u.",
|
||||
numSigs, static_cast<uint32>(publishMode), totalSrcBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void UDPStreamerClient::OnUDPSData(const uint8 *payload, uint32 payloadSize) {
|
||||
if (!configValidated) {
|
||||
return;
|
||||
}
|
||||
if (payloadSize < UDPS_CLIENT_TIMESTAMP_BYTES) {
|
||||
return;
|
||||
}
|
||||
|
||||
(void) MemoryOperationsHelper::Set(scratchBuffer, 0, totalSrcBytes);
|
||||
DecodeSnapshot(payload, payloadSize, scratchBuffer);
|
||||
|
||||
bufMutex.FastLock(TTInfiniteWait);
|
||||
(void) MemoryOperationsHelper::Copy(readyBuffer, scratchBuffer, totalSrcBytes);
|
||||
newDataReady = true;
|
||||
bufMutex.FastUnLock();
|
||||
|
||||
(void) dataSem.Post();
|
||||
}
|
||||
|
||||
void UDPStreamerClient::OnUDPSConnected() {
|
||||
REPORT_ERROR(ErrorManagement::Information,
|
||||
"UDPStreamerClient connected to %s:%u.",
|
||||
serverAddress.Buffer(), static_cast<uint32>(port));
|
||||
}
|
||||
|
||||
void UDPStreamerClient::OnUDPSDisconnected() {
|
||||
bufMutex.FastLock(TTInfiniteWait);
|
||||
configValidated = false;
|
||||
bufMutex.FastUnLock();
|
||||
REPORT_ERROR(ErrorManagement::Information, "UDPStreamerClient disconnected.");
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Decode logic */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void UDPStreamerClient::DecodeSnapshot(const uint8 *payload, uint32 size,
|
||||
uint8 *dst) {
|
||||
uint32 offset = UDPS_CLIENT_TIMESTAMP_BYTES;
|
||||
uint32 numSamples = 1u;
|
||||
|
||||
if (publishMode == UDPS_PUBLISH_ACCUMULATE) {
|
||||
if ((offset + 4u) > size) { return; }
|
||||
(void) memcpy(&numSamples, payload + offset, 4u);
|
||||
offset += 4u;
|
||||
if (numSamples == 0u) { numSamples = 1u; }
|
||||
}
|
||||
|
||||
uint32 off = offset;
|
||||
for (uint32 s = 0u; s < numSigs; s++) {
|
||||
const UDPStreamerClientSignal &info = signalInfos[s];
|
||||
const uint32 wireElemBytes = info.wireElemBytes;
|
||||
if (wireElemBytes == 0u) { return; }
|
||||
|
||||
const uint32 ne = info.numElements;
|
||||
const bool accScalar = (publishMode == UDPS_PUBLISH_ACCUMULATE) && (ne == 1u);
|
||||
const uint32 elemsToRead = accScalar ? numSamples : ne;
|
||||
|
||||
if ((off + (elemsToRead * wireElemBytes)) > size) { return; }
|
||||
|
||||
uint8 *d = dst + info.bufferOffset;
|
||||
|
||||
if (info.quantType == UDPS_QUANT_NONE) {
|
||||
if (accScalar) {
|
||||
/* Publish the most recent accumulated sample. */
|
||||
const uint8 *srcLast = payload + off +
|
||||
((numSamples - 1u) * wireElemBytes);
|
||||
(void) memcpy(d, srcLast, wireElemBytes);
|
||||
}
|
||||
else {
|
||||
(void) memcpy(d, payload + off, ne * wireElemBytes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const bool isF32 = (info.type == Float32Bit);
|
||||
const uint32 startElem = accScalar ? (numSamples - 1u) : 0u;
|
||||
const uint32 count = accScalar ? 1u : ne;
|
||||
for (uint32 e = 0u; e < count; e++) {
|
||||
const uint8 *ptr = payload + off +
|
||||
((startElem + e) * wireElemBytes);
|
||||
const float64 raw = DecodeQuantRaw(ptr, info.quantType);
|
||||
const float64 val = DequantValue(raw, info.quantType,
|
||||
info.rangeMin, info.rangeMax);
|
||||
if (isF32) {
|
||||
float32 f32 = static_cast<float32>(val);
|
||||
(void) memcpy(d, &f32, 4u);
|
||||
d += 4u;
|
||||
}
|
||||
else {
|
||||
float64 f64 = val;
|
||||
(void) memcpy(d, &f64, 8u);
|
||||
d += 8u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
off += elemsToRead * wireElemBytes;
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_REGISTER(UDPStreamerClient, "1.0")
|
||||
|
||||
} /* namespace MARTe */
|
||||
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* @file UDPStreamerClient.h
|
||||
* @brief Header file for class UDPStreamerClient
|
||||
* @date 24/06/2026
|
||||
* @author Martino Ferrari
|
||||
*
|
||||
* @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
|
||||
* the Development of Fusion Energy ('Fusion for Energy').
|
||||
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved
|
||||
* by the European Commission - subsequent versions of the EUPL (the "Licence")
|
||||
* You may not use this work except in compliance with the Licence.
|
||||
* You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
|
||||
*
|
||||
* @warning Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the Licence is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the Licence permissions and limitations under the Licence.
|
||||
*
|
||||
* @details This header file contains the declaration of the class UDPStreamerClient
|
||||
* with all of its public, protected and private members.
|
||||
*
|
||||
* The UDPStreamerClient is an input DataSource that receives signal data from
|
||||
* a UDPStreamer server over the network. It reuses the StreamHub hub's network
|
||||
* code base: transport, fragment reassembly, multicast and auto-reconnect are
|
||||
* delegated to the shared UDPSClient receiver, and this class only implements
|
||||
* the UDPSClientListener callbacks to validate the CONFIG and decode DATA into
|
||||
* the real-time signal memory.
|
||||
*/
|
||||
|
||||
#ifndef UDPSTREAMERCLIENT_H_
|
||||
#define UDPSTREAMERCLIENT_H_
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Standard header includes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Project header includes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "EventSem.h"
|
||||
#include "FastPollingMutexSem.h"
|
||||
#include "MemoryDataSourceI.h"
|
||||
#include "StreamString.h"
|
||||
#include "TypeDescriptor.h"
|
||||
#include "UDPSClient.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Class declaration */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
/**
|
||||
* @brief Per-signal decode metadata resolved from the server CONFIG packet.
|
||||
*/
|
||||
struct UDPStreamerClientSignal {
|
||||
StreamString name; /**< Signal name (must match server). */
|
||||
TypeDescriptor type; /**< MARTe2 destination type. */
|
||||
uint8 quantType; /**< UDPS_QUANT_* code from CONFIG. */
|
||||
uint32 numElements; /**< Element count (scalar = 1). */
|
||||
float64 rangeMin; /**< Dequantisation lower bound. */
|
||||
float64 rangeMax; /**< Dequantisation upper bound. */
|
||||
uint32 srcByteSize; /**< Destination byte size for the signal. */
|
||||
uint32 wireElemBytes; /**< Bytes per element on the wire. */
|
||||
uint32 bufferOffset; /**< Offset of this signal in the flat buffer. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A DataSource that receives signal data from a UDPStreamer server.
|
||||
*
|
||||
* @details This input DataSource owns a shared ::MARTe::UDPSClient (the same
|
||||
* receiver used by the StreamHub hub) which runs a background thread, connects
|
||||
* to the server, reassembles fragmented updates and auto-reconnects on silence.
|
||||
* The CONFIG and DATA payloads are delivered through the UDPSClientListener
|
||||
* callbacks; DATA is decoded into a double-buffered staging area which the
|
||||
* real-time thread copies into signal memory during Synchronise().
|
||||
*
|
||||
* Two operating modes are selected by the presence or absence of MulticastGroup.
|
||||
*
|
||||
* @par Top-level configuration parameters
|
||||
* | Parameter | Type | Default | Description |
|
||||
* |-----------------|---------|--------------|-------------|
|
||||
* | ServerAddress | string | "127.0.0.1" | UDPStreamer server IP address. |
|
||||
* | Port | uint16 | 44500 | Server port (CONNECT/UDP unicast, TCP control multicast). |
|
||||
* | MulticastGroup | string | *(absent)* | Enables multicast mode. IPv4 multicast address. |
|
||||
* | DataPort | uint16 | Port+1 | UDP port for DATA datagrams in multicast mode. |
|
||||
* | MaxPayloadSize | uint32 | 1400 | Maximum payload bytes per datagram (excluding header). |
|
||||
* | CPUMask | uint32 | 0xFFFFFFFF | CPU affinity bitmask for the background thread. |
|
||||
* | StackSize | uint32 | 65536 | Stack size in bytes for the background thread. |
|
||||
*
|
||||
* The client's signal configuration must match the server's: signal count,
|
||||
* names and element counts are validated against the received CONFIG.
|
||||
*/
|
||||
class UDPStreamerClient : public MemoryDataSourceI,
|
||||
public UDPSClientListener {
|
||||
public:
|
||||
CLASS_REGISTER_DECLARATION()
|
||||
|
||||
/**
|
||||
* @brief Constructor. Initialises all members to safe defaults.
|
||||
*/
|
||||
UDPStreamerClient();
|
||||
|
||||
/**
|
||||
* @brief Destructor. Stops the background receiver and frees memory.
|
||||
*/
|
||||
virtual ~UDPStreamerClient();
|
||||
|
||||
/**
|
||||
* @brief Parses top-level configuration and configures the UDPSClient.
|
||||
*/
|
||||
virtual bool Initialise(StructuredDataI &data);
|
||||
|
||||
/**
|
||||
* @brief Validates signal types and builds the per-signal metadata array.
|
||||
*/
|
||||
virtual bool SetConfiguredDatabase(StructuredDataI &data);
|
||||
|
||||
/**
|
||||
* @brief Allocates signal memory plus readyBuffer and scratchBuffer.
|
||||
*/
|
||||
virtual bool AllocateMemory();
|
||||
|
||||
/**
|
||||
* @brief Returns "MemoryMapSynchronisedInputBroker" for InputSignals.
|
||||
*/
|
||||
virtual const char8 *GetBrokerName(StructuredDataI &data,
|
||||
const SignalDirection direction);
|
||||
|
||||
/**
|
||||
* @brief Copies the latest received data into signal memory.
|
||||
*/
|
||||
virtual bool Synchronise();
|
||||
|
||||
/**
|
||||
* @brief Starts the background receiver on the first state transition.
|
||||
*/
|
||||
virtual bool PrepareNextState(const char8 *const currentStateName,
|
||||
const char8 *const nextStateName);
|
||||
|
||||
/* ---- UDPSClientListener callbacks (invoked from the receiver thread) ---- */
|
||||
|
||||
/**
|
||||
* @brief Validates a reassembled CONFIG payload against the local signals.
|
||||
*/
|
||||
virtual void OnUDPSConfig(const uint8 *payload, uint32 payloadSize);
|
||||
|
||||
/**
|
||||
* @brief Decodes a reassembled DATA payload into the staging buffer.
|
||||
*/
|
||||
virtual void OnUDPSData(const uint8 *payload, uint32 payloadSize);
|
||||
|
||||
/**
|
||||
* @brief Logs that the server connection is established.
|
||||
*/
|
||||
virtual void OnUDPSConnected();
|
||||
|
||||
/**
|
||||
* @brief Invalidates the CONFIG so stale data is not published.
|
||||
*/
|
||||
virtual void OnUDPSDisconnected();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Decodes a single snapshot from a DATA payload into @p dst.
|
||||
* @details Mirrors the StreamHub hub layout (UDPSourceSession): an 8-byte
|
||||
* HRT timestamp, an optional 4-byte sample count (Accumulate mode), then
|
||||
* per-signal data in CONFIG order. For accumulated scalars the most recent
|
||||
* sample is published.
|
||||
*/
|
||||
void DecodeSnapshot(const uint8 *payload, uint32 size, uint8 *dst);
|
||||
|
||||
/* Configuration parameters */
|
||||
StreamString serverAddress; /**< Server IP address. */
|
||||
uint16 port; /**< Server port. */
|
||||
uint32 maxPayloadSize; /**< Max payload bytes per datagram. */
|
||||
uint32 cpuMask; /**< Background thread CPU affinity. */
|
||||
uint32 stackSize; /**< Background thread stack size. */
|
||||
StreamString multicastGroup; /**< Multicast group IP; empty = unicast. */
|
||||
uint16 dataPort; /**< UDP port for DATA datagrams (multicast). */
|
||||
bool useMulticast; /**< True when MulticastGroup is set. */
|
||||
|
||||
/* Signal metadata */
|
||||
uint32 numSigs; /**< Number of signals. */
|
||||
UDPStreamerClientSignal *signalInfos; /**< Per-signal metadata (heap). */
|
||||
uint32 totalSrcBytes; /**< Total destination signal bytes. */
|
||||
bool configValidated; /**< True after a valid CONFIG. */
|
||||
uint8 publishMode; /**< UDPS_PUBLISH_* from CONFIG. */
|
||||
|
||||
/* Shared receiver (same code base as the StreamHub hub) */
|
||||
UDPSClient client; /**< Transport, reassembly and reconnect. */
|
||||
bool receiverUp; /**< True once the receiver thread is started. */
|
||||
|
||||
/* Double-buffering for RT safety */
|
||||
uint8 *readyBuffer; /**< Protected copy of decoded signal data. */
|
||||
uint8 *scratchBuffer; /**< Receiver-thread-private decode buffer. */
|
||||
FastPollingMutexSem bufMutex; /**< Protects readyBuffer. */
|
||||
EventSem dataSem; /**< Wakes the RT thread on new data. */
|
||||
bool newDataReady; /**< Set when readyBuffer has fresh data. */
|
||||
};
|
||||
|
||||
} /* namespace MARTe */
|
||||
|
||||
#endif /* UDPSTREAMERCLIENT_H_ */
|
||||
@@ -0,0 +1,140 @@
|
||||
../../../..//Build/x86-linux/Components/DataSources/UDPStreamerClient/UDPStreamerClient.o: \
|
||||
UDPStreamerClient.cpp \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/AdvancedErrorManagement.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Architecture/x86_gcc/CompilerTypes.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorInformation.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/HighResolutionTimerA.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimerCalibrator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamMemoryReference.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/BufferedStreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryDatabase.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectsDatabase.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/StandardHeap.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HeapI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../ErrorManagement.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../Generic/StandardHeap_Generic.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FastPollingMutexSem.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Atomic.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/AtomicA.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItem.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CString.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Introspection.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/IntrospectionEntry.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TypeDescriptor.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BasicType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolderT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/IteratorT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Iterator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SortFilter.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SearchFilter.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/LoadableLibrary.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticList.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticListHolder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Matrix.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/MemoryOperationsHelper.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FormatDescriptor.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/ConfigurationDatabase.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/AnyObject.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItemT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilderT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/ConfigurationDatabaseNode.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Fnv1aHashFunction.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/HashFunction.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Reference.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainerFilter.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainerNode.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/UnorderedMap.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainerFilterObjectName.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/TypeConversion.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
||||
../../../..//Common/UDP/UDPSProtocol.h UDPStreamerClient.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/EventSem.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryDataSourceI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/DataSourceI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/StatefulI.h \
|
||||
../../../..//Source/Components/Interfaces/UDPStream/UDPSClient.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicTCPSocket.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicSocket.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/InternetHost.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/InternetHostCore.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/InternetMulticastCore.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HandleI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/SocketCore.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicUDPSocket.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/Threads.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ThreadsB.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/ExceptionHandler.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ProcessorType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitSet.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/InternetHost.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/SingleThreadService.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThread.h
|
||||
@@ -0,0 +1,143 @@
|
||||
UDPStreamerClient.o: UDPStreamerClient.cpp \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/AdvancedErrorManagement.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Architecture/x86_gcc/CompilerTypes.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorInformation.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/HighResolutionTimerA.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimerCalibrator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamMemoryReference.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/BufferedStreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryDatabase.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectsDatabase.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/StandardHeap.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HeapI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../ErrorManagement.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../Generic/StandardHeap_Generic.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FastPollingMutexSem.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Atomic.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/AtomicA.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItem.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CString.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Introspection.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/IntrospectionEntry.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TypeDescriptor.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BasicType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolderT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/IteratorT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Iterator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SortFilter.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SearchFilter.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/LoadableLibrary.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticList.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticListHolder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Matrix.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/MemoryOperationsHelper.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FormatDescriptor.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/Threads.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ThreadsB.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/ExceptionHandler.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ProcessorType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitSet.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItemT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilderT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryMapSynchronisedInputBroker.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryMapInputBroker.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryMapBroker.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/BrokerI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/DataSourceI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/ConfigurationDatabase.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/AnyObject.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/ConfigurationDatabaseNode.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Fnv1aHashFunction.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/HashFunction.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Reference.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainerFilter.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainerNode.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/UnorderedMap.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainerFilterObjectName.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/TypeConversion.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/StatefulI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/ExecutableI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||
UDPStreamerClient.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicTCPSocket.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicSocket.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/InternetHost.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/InternetHostCore.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/InternetMulticastCore.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HandleI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/SocketCore.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicUDPSocket.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/EventSem.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryDataSourceI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/SingleThreadService.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThread.h \
|
||||
../UDPStreamer/UDPStreamer.h
|
||||
Reference in New Issue
Block a user