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
@@ -0,0 +1 @@
|
||||
include Makefile.inc
|
||||
@@ -0,0 +1,33 @@
|
||||
#############################################################
|
||||
# MARTe2 Integrated Components — TCPStreamService
|
||||
#############################################################
|
||||
OBJSX=TCPSFrameQueue.x TCPSServiceStream.x TCPSWorker.x TCPStreamService.x TCPStreamJoin.x
|
||||
|
||||
PACKAGE=Components/Interfaces
|
||||
|
||||
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/Scheduler/L1Portability
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L3Services
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
|
||||
|
||||
all: $(OBJS) $(SUBPROJ) \
|
||||
$(BUILD_DIR)/TCPStreamService$(LIBEXT) \
|
||||
$(BUILD_DIR)/TCPStreamService$(DLLEXT)
|
||||
echo $(OBJS)
|
||||
|
||||
include depends.$(TARGET)
|
||||
|
||||
include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET)
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef TCPS_CONN_H_
|
||||
#define TCPS_CONN_H_
|
||||
|
||||
/**
|
||||
* @file TCPSConn.h
|
||||
* @brief One accepted connection of a TCPStreamService (internal).
|
||||
*
|
||||
* Ownership: created by the acceptor thread, then owned and deleted by exactly
|
||||
* one TCPSWorker. `streams` and `closeRequested` are the only fields touched
|
||||
* from other threads; `stream` is guarded by the service topology lock, the
|
||||
* queue by `qMutex`.
|
||||
*/
|
||||
|
||||
#include "CompilerTypes.h"
|
||||
#include "FastPollingMutexSem.h"
|
||||
#include "TCPSFrameQueue.h"
|
||||
#include "TCPStreamService.h"
|
||||
#include "UDPSProtocol.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
class TCPSWorker;
|
||||
class TCPSServiceStream;
|
||||
|
||||
struct TCPSConn {
|
||||
TCPSConn(int socketFd, TCPSWorker *owner, uint32 queueDepth, uint64 handshakeDeadline)
|
||||
: fd(socketFd), worker(owner), subscribed(false), hsHave(0u),
|
||||
hsWant(UDPS_HEADER_SIZE), hsHeaderOk(false), hsDeadline(handshakeDeadline),
|
||||
numStreams(0u), closeRequested(false) {
|
||||
for (uint32 i = 0u; i < TCPS_MAX_CONN_STREAMS; i++) {
|
||||
streams[i] = NULL_PTR(TCPSServiceStream *);
|
||||
}
|
||||
q.Init(queueDepth);
|
||||
}
|
||||
~TCPSConn() {
|
||||
if (fd >= 0) {
|
||||
(void)close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
int fd;
|
||||
TCPSWorker *worker;
|
||||
|
||||
/* Worker-thread only. */
|
||||
bool subscribed;
|
||||
uint8 hs[UDPS_HEADER_SIZE + TCPS_MAX_SUBSCRIBE_PAYLOAD + 1u];
|
||||
uint32 hsHave;
|
||||
uint32 hsWant;
|
||||
bool hsHeaderOk;
|
||||
uint64 hsDeadline;
|
||||
|
||||
/* Service topology lock. */
|
||||
TCPSServiceStream *streams[TCPS_MAX_CONN_STREAMS]; ///< index = stream index on the wire
|
||||
uint32 numStreams;
|
||||
volatile bool closeRequested;
|
||||
|
||||
/* qMutex. */
|
||||
FastPollingMutexSem qMutex;
|
||||
TCPSFrameQueue q;
|
||||
|
||||
private:
|
||||
TCPSConn(const TCPSConn &);
|
||||
TCPSConn &operator=(const TCPSConn &);
|
||||
};
|
||||
|
||||
} // namespace MARTe
|
||||
|
||||
#endif // TCPS_CONN_H_
|
||||
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* @file TCPSFrameQueue.cpp
|
||||
* @brief Implementation of TCPSFrameQueue.
|
||||
*/
|
||||
|
||||
#include "TCPSFrameQueue.h"
|
||||
|
||||
#include "HighResolutionTimer.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
struct TCPSFrameQueue::Slot {
|
||||
Slot() : buf(NULL_PTR(uint8 *)), cap(0u), len(0u), isConfig(false), stream(0u) {}
|
||||
~Slot() {
|
||||
if (buf != NULL_PTR(uint8 *)) {
|
||||
delete[] buf;
|
||||
}
|
||||
}
|
||||
uint8 *buf;
|
||||
uint32 cap;
|
||||
uint32 len;
|
||||
bool isConfig;
|
||||
uint16 stream;
|
||||
};
|
||||
|
||||
/** magic(4) + type(1) + counter(4): offset of the header's fragmentIdx field. */
|
||||
static const uint32 TCPS_FRAGIDX_OFFSET = 9u;
|
||||
|
||||
TCPSFrameQueue::TCPSFrameQueue()
|
||||
: slots(NULL_PTR(Slot **)), cap(0u), depth(0u), count(0u), sent(0u), lastProgress(0u) {
|
||||
}
|
||||
|
||||
TCPSFrameQueue::~TCPSFrameQueue() {
|
||||
if (slots != NULL_PTR(Slot **)) {
|
||||
for (uint32 i = 0u; i < cap; i++) {
|
||||
delete slots[i];
|
||||
}
|
||||
delete[] slots;
|
||||
}
|
||||
}
|
||||
|
||||
void TCPSFrameQueue::Init(uint32 d) {
|
||||
depth = d;
|
||||
cap = d + 2u;
|
||||
slots = new Slot *[cap];
|
||||
for (uint32 i = 0u; i < cap; i++) {
|
||||
slots[i] = new Slot();
|
||||
}
|
||||
count = 0u;
|
||||
sent = 0u;
|
||||
lastProgress = HighResolutionTimer::Counter();
|
||||
}
|
||||
|
||||
void TCPSFrameQueue::Reserve(uint32 numStreams) {
|
||||
const uint32 want = numStreams * (depth + 2u);
|
||||
if (want > cap) {
|
||||
Slot **grown = new Slot *[want];
|
||||
for (uint32 i = 0u; i < cap; i++) {
|
||||
grown[i] = slots[i];
|
||||
}
|
||||
for (uint32 i = cap; i < want; i++) {
|
||||
grown[i] = new Slot();
|
||||
}
|
||||
delete[] slots;
|
||||
slots = grown;
|
||||
cap = want;
|
||||
}
|
||||
}
|
||||
|
||||
/** Remove slot @p i, keeping order; the slot object is recycled at the end. */
|
||||
void TCPSFrameQueue::RemoveAt(uint32 i) {
|
||||
Slot *v = slots[i];
|
||||
for (uint32 j = i + 1u; j < count; j++) {
|
||||
slots[j - 1u] = slots[j];
|
||||
}
|
||||
slots[count - 1u] = v;
|
||||
count--;
|
||||
}
|
||||
|
||||
bool TCPSFrameQueue::Push(uint16 streamIdx, bool isConfig, const uint8 *frame,
|
||||
uint32 frameBytes, uint32 &dropped) {
|
||||
const uint32 firstFree = (sent > 0u) ? 1u : 0u; // slots below this are on the wire
|
||||
|
||||
if (isConfig) {
|
||||
uint32 i = firstFree;
|
||||
while (i < count) {
|
||||
if (slots[i]->stream == streamIdx) {
|
||||
if (!slots[i]->isConfig) {
|
||||
dropped++;
|
||||
}
|
||||
RemoveAt(i);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32 dataCount = 0u;
|
||||
for (uint32 i = 0u; i < count; i++) {
|
||||
if ((slots[i]->stream == streamIdx) && !slots[i]->isConfig) {
|
||||
dataCount++;
|
||||
}
|
||||
}
|
||||
if (dataCount >= depth) {
|
||||
uint32 victim = count;
|
||||
for (uint32 i = firstFree; (i < count) && (victim == count); i++) {
|
||||
if ((slots[i]->stream == streamIdx) && !slots[i]->isConfig) {
|
||||
victim = i;
|
||||
}
|
||||
}
|
||||
dropped++;
|
||||
if (victim == count) {
|
||||
return false; // only the frame on the wire is queued
|
||||
}
|
||||
RemoveAt(victim);
|
||||
}
|
||||
}
|
||||
|
||||
if (count >= cap) {
|
||||
dropped++;
|
||||
return false;
|
||||
}
|
||||
|
||||
Slot &s = *slots[count];
|
||||
if (s.cap < frameBytes) {
|
||||
if (s.buf != NULL_PTR(uint8 *)) {
|
||||
delete[] s.buf;
|
||||
}
|
||||
s.buf = new uint8[frameBytes];
|
||||
s.cap = frameBytes;
|
||||
}
|
||||
memcpy(s.buf, frame, frameBytes);
|
||||
if (frameBytes >= (TCPS_FRAGIDX_OFFSET + 2u)) {
|
||||
memcpy(&s.buf[TCPS_FRAGIDX_OFFSET], &streamIdx, 2u);
|
||||
}
|
||||
s.len = frameBytes;
|
||||
s.isConfig = isConfig;
|
||||
s.stream = streamIdx;
|
||||
if (count == 0u) {
|
||||
sent = 0u;
|
||||
lastProgress = HighResolutionTimer::Counter();
|
||||
}
|
||||
count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Account for @p bytes written from the head of the queue. */
|
||||
void TCPSFrameQueue::Consume(uint32 bytes) {
|
||||
while ((bytes > 0u) && (count > 0u)) {
|
||||
const uint32 left = slots[0]->len - sent;
|
||||
if (bytes >= left) {
|
||||
bytes -= left;
|
||||
RemoveAt(0u);
|
||||
sent = 0u;
|
||||
} else {
|
||||
sent += bytes;
|
||||
bytes = 0u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TCPSFrameQueue::Flush(int fd) {
|
||||
bool alive = true;
|
||||
while (alive && (count > 0u)) {
|
||||
struct iovec iov[TCPS_MAX_BATCH];
|
||||
uint32 n = (count < TCPS_MAX_BATCH) ? count : TCPS_MAX_BATCH;
|
||||
for (uint32 i = 0u; i < n; i++) {
|
||||
const uint32 off = (i == 0u) ? sent : 0u;
|
||||
iov[i].iov_base = &slots[i]->buf[off];
|
||||
iov[i].iov_len = slots[i]->len - off;
|
||||
}
|
||||
struct msghdr msg;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.msg_iov = iov;
|
||||
msg.msg_iovlen = n;
|
||||
ssize_t w = sendmsg(fd, &msg, MSG_NOSIGNAL | MSG_DONTWAIT);
|
||||
if (w > 0) {
|
||||
lastProgress = HighResolutionTimer::Counter();
|
||||
Consume(static_cast<uint32>(w));
|
||||
} else if ((w < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
|
||||
break;
|
||||
} else if ((w < 0) && (errno == EINTR)) {
|
||||
continue;
|
||||
} else {
|
||||
alive = false;
|
||||
}
|
||||
}
|
||||
return alive;
|
||||
}
|
||||
|
||||
bool TCPSFrameQueue::Empty() const {
|
||||
return count == 0u;
|
||||
}
|
||||
|
||||
uint64 TCPSFrameQueue::LastProgress() const {
|
||||
return lastProgress;
|
||||
}
|
||||
|
||||
} // namespace MARTe
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef TCPS_FRAME_QUEUE_H_
|
||||
#define TCPS_FRAME_QUEUE_H_
|
||||
|
||||
/**
|
||||
* @file TCPSFrameQueue.h
|
||||
* @brief Bounded per-connection output queue of UDPS frames (header + payload).
|
||||
*
|
||||
* Same semantics as the per-client queue inside TCPSServer: at most `depth`
|
||||
* DATA frames wait; when full the oldest DATA frame that is not already
|
||||
* (partially) on the wire is discarded and counted. A CONFIG is never dropped
|
||||
* and, when queued, discards the DATA frames behind the one on the wire (they
|
||||
* were encoded for the previous layout).
|
||||
*
|
||||
* Not thread-safe: the owner serialises Push() / Flush().
|
||||
*/
|
||||
|
||||
#include "CompilerTypes.h"
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
class TCPSFrameQueue {
|
||||
public:
|
||||
TCPSFrameQueue();
|
||||
~TCPSFrameQueue();
|
||||
|
||||
/** Allocate `depth` DATA slots plus two CONFIG slots (room for one stream). */
|
||||
void Init(uint32 depth);
|
||||
|
||||
/**
|
||||
* Make room for @p numStreams multiplexed streams: each gets its own `depth`
|
||||
* DATA frames plus two CONFIG slots. Grow-only; call while the queue is idle
|
||||
* (before the connection is attached to any stream).
|
||||
*/
|
||||
void Reserve(uint32 numStreams);
|
||||
|
||||
/**
|
||||
* Append a complete frame (copied). The frame is stamped with @p streamIdx in
|
||||
* its header's fragmentIdx field. Accounting is per stream: a full stream
|
||||
* evicts its own oldest DATA, and a CONFIG only discards the queued frames
|
||||
* of its own stream.
|
||||
* @param[in,out] dropped incremented by the number of DATA frames discarded.
|
||||
* @return false if the frame itself was refused (queue full of in-flight data).
|
||||
*/
|
||||
bool Push(uint16 streamIdx, bool isConfig, const uint8 *frame, uint32 frameBytes,
|
||||
uint32 &dropped);
|
||||
|
||||
/**
|
||||
* Write as much as the socket accepts without blocking, batching up to
|
||||
* TCPS_MAX_BATCH frames per system call.
|
||||
* @return false if the connection is broken.
|
||||
*/
|
||||
bool Flush(int fd);
|
||||
|
||||
/** Most frames sent by one sendmsg(). */
|
||||
static const uint32 TCPS_MAX_BATCH = 16u;
|
||||
|
||||
bool Empty() const;
|
||||
/** HRT ticks of the last byte written (or of the queue becoming non-empty). */
|
||||
uint64 LastProgress() const;
|
||||
|
||||
private:
|
||||
struct Slot;
|
||||
TCPSFrameQueue(const TCPSFrameQueue &);
|
||||
TCPSFrameQueue &operator=(const TCPSFrameQueue &);
|
||||
|
||||
void RemoveAt(uint32 i);
|
||||
void Consume(uint32 bytes);
|
||||
|
||||
Slot **slots;
|
||||
uint32 cap;
|
||||
uint32 depth;
|
||||
uint32 count;
|
||||
uint32 sent;
|
||||
uint64 lastProgress;
|
||||
};
|
||||
|
||||
} // namespace MARTe
|
||||
|
||||
#endif // TCPS_FRAME_QUEUE_H_
|
||||
@@ -0,0 +1,329 @@
|
||||
/**
|
||||
* @file TCPSServiceStream.cpp
|
||||
* @brief Implementation of TCPSServiceStream.
|
||||
*/
|
||||
|
||||
#define DLL_API
|
||||
|
||||
#include "TCPSServiceStream.h"
|
||||
|
||||
#include "AdvancedErrorManagement.h"
|
||||
#include "ObjectRegistryDatabase.h"
|
||||
#include "TCPSConn.h"
|
||||
#include "TCPSWorker.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
const uint32 TCPSServiceStream::TCPSS_DEFAULT_MAX_PAYLOAD;
|
||||
|
||||
static const uint32 TCPSS_MAX_FRAME_PAYLOAD = 1048576u;
|
||||
|
||||
TCPSServiceStream::TCPSServiceStream(const char8 *serviceObjectName, const char8 *name)
|
||||
: serviceName(serviceObjectName), streamName(name), registered(false),
|
||||
maxPayloadSize(TCPSS_DEFAULT_MAX_PAYLOAD), subs(NULL_PTR(TCPSConn **)), subIdx(NULL_PTR(uint16 *)),
|
||||
capSubs(0u), numSubs(0u), cachedConfigFrame(NULL_PTR(uint8 *)),
|
||||
cachedConfigBytes(0u), cachedConfigCap(0u), configCounter(0u), drops(0u),
|
||||
numTaps(0u), dataFrame(NULL_PTR(uint8 *)), dataFrameCap(0u) {
|
||||
for (uint32 i = 0u; i < TCPSS_MAX_TAPS; i++) {
|
||||
taps[i] = NULL_PTR(TCPSStreamTapI *);
|
||||
}
|
||||
}
|
||||
|
||||
TCPSServiceStream::~TCPSServiceStream() {
|
||||
(void)Stop();
|
||||
if (cachedConfigFrame != NULL_PTR(uint8 *)) {
|
||||
delete[] cachedConfigFrame;
|
||||
}
|
||||
if (dataFrame != NULL_PTR(uint8 *)) {
|
||||
delete[] dataFrame;
|
||||
}
|
||||
if (subs != NULL_PTR(TCPSConn **)) {
|
||||
delete[] subs;
|
||||
}
|
||||
if (subIdx != NULL_PTR(uint16 *)) {
|
||||
delete[] subIdx;
|
||||
}
|
||||
}
|
||||
|
||||
bool TCPSServiceStream::Initialise(StructuredDataI &data) {
|
||||
bool ok = true;
|
||||
maxPayloadSize = TCPSS_DEFAULT_MAX_PAYLOAD;
|
||||
(void)data.Read("MaxPayloadSize", maxPayloadSize);
|
||||
if ((maxPayloadSize == 0u) || (maxPayloadSize > TCPSS_MAX_FRAME_PAYLOAD)) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::ParametersError,
|
||||
"TCPSServiceStream: MaxPayloadSize %u must be in 1..%u.",
|
||||
maxPayloadSize, TCPSS_MAX_FRAME_PAYLOAD);
|
||||
ok = false;
|
||||
}
|
||||
if ((streamName.Size() > 0u) && (strchr(streamName.Buffer(), ',') != NULL_PTR(char8 *))) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::ParametersError,
|
||||
"TCPSServiceStream: StreamName '%s' may not contain a comma.",
|
||||
streamName.Buffer());
|
||||
ok = false;
|
||||
}
|
||||
if ((streamName.Size() == 0u) || (streamName.Size() > TCPS_MAX_STREAM_NAME)) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::ParametersError,
|
||||
"TCPSServiceStream: StreamName must be 1..%u characters.",
|
||||
TCPS_MAX_STREAM_NAME);
|
||||
ok = false;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TCPSServiceStream::Start() {
|
||||
if (registered) {
|
||||
return true;
|
||||
}
|
||||
if (!service.IsValid()) {
|
||||
ReferenceT<TCPStreamService> found =
|
||||
ObjectRegistryDatabase::Instance()->Find(serviceName.Buffer());
|
||||
if (!found.IsValid()) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::InitialisationError,
|
||||
"TCPSServiceStream: no TCPStreamService named '%s'.",
|
||||
serviceName.Buffer());
|
||||
return false;
|
||||
}
|
||||
service = found;
|
||||
}
|
||||
mutex.FastLock();
|
||||
if (subs == NULL_PTR(TCPSConn **)) {
|
||||
capSubs = service->MaxClients();
|
||||
subs = new TCPSConn *[capSubs];
|
||||
subIdx = new uint16[capSubs];
|
||||
}
|
||||
numSubs = 0u;
|
||||
mutex.FastUnLock();
|
||||
registered = service->RegisterStream(this);
|
||||
return registered;
|
||||
}
|
||||
|
||||
bool TCPSServiceStream::Stop() {
|
||||
if (registered) {
|
||||
service->UnregisterStream(this); // drops every subscriber
|
||||
registered = false;
|
||||
}
|
||||
mutex.FastLock();
|
||||
if (cachedConfigFrame != NULL_PTR(uint8 *)) {
|
||||
cachedConfigBytes = 0u;
|
||||
}
|
||||
mutex.FastUnLock();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TCPSServiceStream::ServiceClients() {
|
||||
}
|
||||
|
||||
bool TCPSServiceStream::BuildFrame(uint8 *&buf, uint32 &cap, uint8 type, uint32 counter,
|
||||
const uint8 *payload, uint32 payloadSize,
|
||||
uint32 &frameBytes) {
|
||||
bool ok = (payloadSize <= TCPSS_MAX_FRAME_PAYLOAD);
|
||||
if (ok) {
|
||||
const uint32 need = UDPS_HEADER_SIZE + payloadSize;
|
||||
if (cap < need) {
|
||||
if (buf != NULL_PTR(uint8 *)) {
|
||||
delete[] buf;
|
||||
}
|
||||
buf = new uint8[need];
|
||||
cap = need;
|
||||
}
|
||||
UDPSBuildHeader(buf, type, counter, 0u, 1u, payloadSize);
|
||||
if (payloadSize > 0u) {
|
||||
memcpy(&buf[UDPS_HEADER_SIZE], payload, payloadSize);
|
||||
}
|
||||
frameBytes = need;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/** Caller holds `mutex`. */
|
||||
void TCPSServiceStream::Distribute(bool isConfig, const uint8 *frame, uint32 frameBytes) {
|
||||
for (uint32 i = 0u; i < numSubs; i++) {
|
||||
TCPSConn *c = subs[i];
|
||||
uint32 dropped = 0u;
|
||||
c->qMutex.FastLock();
|
||||
const bool wasEmpty = c->q.Empty();
|
||||
(void)c->q.Push(subIdx[i], isConfig, frame, frameBytes, dropped);
|
||||
c->qMutex.FastUnLock();
|
||||
drops += dropped;
|
||||
if (wasEmpty) {
|
||||
c->worker->Wake();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TCPSServiceStream::SendConfig(const uint8 *payload, uint32 payloadSize) {
|
||||
if (!registered) {
|
||||
return false;
|
||||
}
|
||||
if (payloadSize > TCPSS_MAX_FRAME_PAYLOAD) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::ParametersError,
|
||||
"TCPSServiceStream: CONFIG of %u bytes exceeds the frame limit.",
|
||||
payloadSize);
|
||||
return false;
|
||||
}
|
||||
mutex.FastLock();
|
||||
configCounter++;
|
||||
bool ok = BuildFrame(cachedConfigFrame, cachedConfigCap, UDPS_TYPE_CONFIG, configCounter,
|
||||
payload, payloadSize, cachedConfigBytes);
|
||||
if (ok) {
|
||||
Distribute(true, cachedConfigFrame, cachedConfigBytes);
|
||||
}
|
||||
mutex.FastUnLock();
|
||||
if (ok && (numTaps > 0u)) {
|
||||
tapMutex.FastLock();
|
||||
for (uint32 i = 0u; i < numTaps; i++) {
|
||||
taps[i]->OnTapConfig(this, payload, payloadSize);
|
||||
}
|
||||
tapMutex.FastUnLock();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TCPSServiceStream::SendData(uint32 counter, const uint8 *payload, uint32 payloadSize) {
|
||||
if (!registered) {
|
||||
return false;
|
||||
}
|
||||
if (numTaps > 0u) {
|
||||
tapMutex.FastLock();
|
||||
for (uint32 i = 0u; i < numTaps; i++) {
|
||||
taps[i]->OnTapData(this, counter, payload, payloadSize);
|
||||
}
|
||||
tapMutex.FastUnLock();
|
||||
}
|
||||
if (numSubs == 0u) {
|
||||
return true;
|
||||
}
|
||||
uint32 frameBytes = 0u;
|
||||
if (!BuildFrame(dataFrame, dataFrameCap, UDPS_TYPE_DATA, counter, payload, payloadSize,
|
||||
frameBytes)) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::ParametersError,
|
||||
"TCPSServiceStream: DATA of %u bytes exceeds the frame limit.",
|
||||
payloadSize);
|
||||
return false;
|
||||
}
|
||||
mutex.FastLock();
|
||||
Distribute(false, dataFrame, frameBytes);
|
||||
mutex.FastUnLock();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TCPSServiceStream::AddTap(TCPSStreamTapI *tap) {
|
||||
bool ok = false;
|
||||
uint8 *cfg = NULL_PTR(uint8 *);
|
||||
uint32 cfgBytes = 0u;
|
||||
mutex.FastLock();
|
||||
if (cachedConfigBytes > UDPS_HEADER_SIZE) {
|
||||
cfgBytes = cachedConfigBytes - UDPS_HEADER_SIZE;
|
||||
cfg = new uint8[cfgBytes];
|
||||
memcpy(cfg, &cachedConfigFrame[UDPS_HEADER_SIZE], cfgBytes);
|
||||
}
|
||||
mutex.FastUnLock();
|
||||
tapMutex.FastLock();
|
||||
if (numTaps < TCPSS_MAX_TAPS) {
|
||||
taps[numTaps] = tap;
|
||||
numTaps = numTaps + 1u;
|
||||
ok = true;
|
||||
if (cfg != NULL_PTR(uint8 *)) {
|
||||
tap->OnTapConfig(this, cfg, cfgBytes);
|
||||
}
|
||||
}
|
||||
tapMutex.FastUnLock();
|
||||
if (cfg != NULL_PTR(uint8 *)) {
|
||||
delete[] cfg;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void TCPSServiceStream::RemoveTap(TCPSStreamTapI *tap) {
|
||||
tapMutex.FastLock();
|
||||
for (uint32 i = 0u; i < numTaps; i++) {
|
||||
if (taps[i] == tap) {
|
||||
taps[i] = taps[numTaps - 1u];
|
||||
numTaps = numTaps - 1u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tapMutex.FastUnLock();
|
||||
}
|
||||
|
||||
bool TCPSServiceStream::HasClients() const {
|
||||
/* A tap (TCPStreamJoin) consumes frames like a subscriber: the producer must keep publishing. */
|
||||
return (numSubs > 0u) || (numTaps > 0u);
|
||||
}
|
||||
|
||||
bool TCPSServiceStream::IsMulticast() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16 TCPSServiceStream::GetPort() const {
|
||||
return service.IsValid() ? service->GetBoundPort() : static_cast<uint16>(0u);
|
||||
}
|
||||
|
||||
const char8 *TCPSServiceStream::GetStreamName() const {
|
||||
return streamName.Buffer();
|
||||
}
|
||||
|
||||
uint32 TCPSServiceStream::GetClientCount() const {
|
||||
return numSubs;
|
||||
}
|
||||
|
||||
uint64 TCPSServiceStream::GetClientDrops() const {
|
||||
return drops;
|
||||
}
|
||||
|
||||
uint32 TCPSServiceStream::GetMaxPayloadSize() const {
|
||||
return maxPayloadSize;
|
||||
}
|
||||
|
||||
bool TCPSServiceStream::AttachConn(TCPSConn *c, uint16 streamIdx) {
|
||||
bool ok = false;
|
||||
mutex.FastLock();
|
||||
if (numSubs < capSubs) {
|
||||
// The CONFIG goes in first so the client always decodes DATA against it.
|
||||
if (cachedConfigBytes > 0u) {
|
||||
uint32 dropped = 0u;
|
||||
c->qMutex.FastLock();
|
||||
(void)c->q.Push(streamIdx, true, cachedConfigFrame, cachedConfigBytes, dropped);
|
||||
c->qMutex.FastUnLock();
|
||||
}
|
||||
subs[numSubs] = c;
|
||||
subIdx[numSubs] = streamIdx;
|
||||
numSubs = numSubs + 1u;
|
||||
ok = true;
|
||||
}
|
||||
mutex.FastUnLock();
|
||||
return ok;
|
||||
}
|
||||
|
||||
void TCPSServiceStream::DetachConn(TCPSConn *c) {
|
||||
mutex.FastLock();
|
||||
for (uint32 i = 0u; i < numSubs; i++) {
|
||||
if (subs[i] == c) {
|
||||
subs[i] = subs[numSubs - 1u];
|
||||
subIdx[i] = subIdx[numSubs - 1u];
|
||||
numSubs = numSubs - 1u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex.FastUnLock();
|
||||
}
|
||||
|
||||
void TCPSServiceStream::DropAllConns() {
|
||||
mutex.FastLock();
|
||||
for (uint32 i = 0u; i < numSubs; i++) {
|
||||
TCPSConn *c = subs[i];
|
||||
for (uint32 k = 0u; k < c->numStreams; k++) {
|
||||
if (c->streams[k] == this) {
|
||||
c->streams[k] = NULL_PTR(TCPSServiceStream *);
|
||||
}
|
||||
}
|
||||
subs[i]->closeRequested = true;
|
||||
subs[i]->worker->Wake();
|
||||
}
|
||||
numSubs = 0u;
|
||||
mutex.FastUnLock();
|
||||
}
|
||||
|
||||
} // namespace MARTe
|
||||
@@ -0,0 +1,110 @@
|
||||
#ifndef TCPS_SERVICE_STREAM_H_
|
||||
#define TCPS_SERVICE_STREAM_H_
|
||||
|
||||
/**
|
||||
* @file TCPSServiceStream.h
|
||||
* @brief UDPSServerI handle that publishes one named stream through a
|
||||
* TCPStreamService instead of through a private listening socket.
|
||||
*
|
||||
* It is what a TCPStreamer uses when its `Service` key is set. All socket work
|
||||
* (accept, handshake, flush, eviction) is done by the service's threads; the
|
||||
* producer thread only builds the frame and copies it into the bounded queue of
|
||||
* every subscribed connection (SendData never blocks on a socket).
|
||||
*/
|
||||
|
||||
#include "FastPollingMutexSem.h"
|
||||
#include "ReferenceT.h"
|
||||
#include "StreamString.h"
|
||||
#include "MutexSem.h"
|
||||
#include "TCPSStreamTapI.h"
|
||||
#include "TCPStreamService.h"
|
||||
#include "UDPSProtocol.h"
|
||||
#include "UDPSTransportI.h"
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
struct TCPSConn;
|
||||
|
||||
class TCPSServiceStream : public UDPSServerI {
|
||||
public:
|
||||
/** Default maximum payload bytes per frame (matches TCPSServer). */
|
||||
static const uint32 TCPSS_DEFAULT_MAX_PAYLOAD = 60000u;
|
||||
|
||||
TCPSServiceStream(const char8 *serviceObjectName, const char8 *streamName);
|
||||
virtual ~TCPSServiceStream();
|
||||
|
||||
/** Keys: MaxPayloadSize (uint32, 1..1 MiB, default 60000). */
|
||||
virtual bool Initialise(StructuredDataI &data);
|
||||
/** Resolve the service by name and register the stream (fails on a duplicate name). */
|
||||
virtual bool Start();
|
||||
/** Unregister and drop every subscriber (idempotent). */
|
||||
virtual bool Stop();
|
||||
/** No-op: the service threads do the housekeeping. */
|
||||
virtual void ServiceClients();
|
||||
virtual bool SendConfig(const uint8 *payload, uint32 payloadSize);
|
||||
virtual bool SendData(uint32 counter, const uint8 *payload, uint32 payloadSize);
|
||||
virtual bool HasClients() const;
|
||||
virtual bool IsMulticast() const;
|
||||
/** @return the service's bound port (0 while the service is unresolved). */
|
||||
virtual uint16 GetPort() const;
|
||||
|
||||
const char8 *GetStreamName() const;
|
||||
uint32 GetClientCount() const;
|
||||
/** @return DATA frames discarded for slow subscribers (all time). */
|
||||
uint64 GetClientDrops() const;
|
||||
uint32 GetMaxPayloadSize() const;
|
||||
|
||||
/** Most taps one stream can carry. */
|
||||
static const uint32 TCPSS_MAX_TAPS = 4u;
|
||||
/**
|
||||
* Observe every CONFIG / DATA this stream publishes. The cached CONFIG (if any) is
|
||||
* replayed to the new tap before AddTap returns. Taps run on the producer thread.
|
||||
* @return false if the tap table is full.
|
||||
*/
|
||||
bool AddTap(TCPSStreamTapI *tap);
|
||||
/** Remove a tap; once it returns no callback is running or will start. */
|
||||
void RemoveTap(TCPSStreamTapI *tap);
|
||||
|
||||
/* ---- called by TCPStreamService with its topology lock held ---- */
|
||||
/** Add a connection and prime it with the cached CONFIG. @return false if full. */
|
||||
bool AttachConn(TCPSConn *c, uint16 streamIdx);
|
||||
void DetachConn(TCPSConn *c);
|
||||
/** Ask every subscriber to close and forget them. */
|
||||
void DropAllConns();
|
||||
|
||||
private:
|
||||
bool BuildFrame(uint8 *&buf, uint32 &cap, uint8 type, uint32 counter,
|
||||
const uint8 *payload, uint32 payloadSize, uint32 &frameBytes);
|
||||
void Distribute(bool isConfig, const uint8 *frame, uint32 frameBytes);
|
||||
|
||||
StreamString serviceName;
|
||||
mutable StreamString streamName;
|
||||
ReferenceT<TCPStreamService> service;
|
||||
bool registered;
|
||||
uint32 maxPayloadSize;
|
||||
|
||||
FastPollingMutexSem mutex; ///< guards subs, numSubs, cachedConfig*, drops
|
||||
TCPSConn **subs;
|
||||
uint16 *subIdx; ///< stream index each subscriber knows this stream by
|
||||
uint32 capSubs;
|
||||
volatile uint32 numSubs;
|
||||
uint8 *cachedConfigFrame;
|
||||
uint32 cachedConfigBytes;
|
||||
uint32 cachedConfigCap;
|
||||
uint32 configCounter;
|
||||
uint64 drops;
|
||||
|
||||
FastPollingMutexSem tapMutex; ///< held while a tap callback runs
|
||||
TCPSStreamTapI *taps[TCPSS_MAX_TAPS];
|
||||
volatile uint32 numTaps;
|
||||
|
||||
uint8 *dataFrame; ///< producer-thread scratch
|
||||
uint32 dataFrameCap;
|
||||
|
||||
TCPSServiceStream(const TCPSServiceStream &);
|
||||
TCPSServiceStream &operator=(const TCPSServiceStream &);
|
||||
};
|
||||
|
||||
} // namespace MARTe
|
||||
|
||||
#endif // TCPS_SERVICE_STREAM_H_
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef TCPS_STREAM_TAP_I_H_
|
||||
#define TCPS_STREAM_TAP_I_H_
|
||||
|
||||
/**
|
||||
* @file TCPSStreamTapI.h
|
||||
* @brief Hooks used by TCPStreamJoin to follow the streams of a TCPStreamService.
|
||||
*
|
||||
* TCPSStreamTapI observes the CONFIG / DATA payloads a stream publishes (on the
|
||||
* producer's thread, after the frame went to the subscribers). TCPSStreamObserverI
|
||||
* observes streams registering with / leaving a service.
|
||||
*/
|
||||
|
||||
#include "CompilerTypes.h"
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
class TCPSServiceStream;
|
||||
|
||||
class TCPSStreamTapI {
|
||||
public:
|
||||
virtual ~TCPSStreamTapI() {}
|
||||
/** A CONFIG payload was published (or the cached one is replayed on AddTap). */
|
||||
virtual void OnTapConfig(TCPSServiceStream *source, const uint8 *payload, uint32 payloadSize) = 0;
|
||||
/** A DATA payload was published. */
|
||||
virtual void OnTapData(TCPSServiceStream *source, uint32 counter, const uint8 *payload,
|
||||
uint32 payloadSize) = 0;
|
||||
};
|
||||
|
||||
class TCPSStreamObserverI {
|
||||
public:
|
||||
virtual ~TCPSStreamObserverI() {}
|
||||
/** @p stream just registered. May call back into the service. */
|
||||
virtual void OnStreamRegistered(TCPSServiceStream *stream) = 0;
|
||||
/** @p stream is leaving (it is still valid during the call). */
|
||||
virtual void OnStreamUnregistered(TCPSServiceStream *stream) = 0;
|
||||
};
|
||||
|
||||
} // namespace MARTe
|
||||
|
||||
#endif // TCPS_STREAM_TAP_I_H_
|
||||
@@ -0,0 +1,266 @@
|
||||
/**
|
||||
* @file TCPSWorker.cpp
|
||||
* @brief Implementation of TCPSWorker.
|
||||
*/
|
||||
|
||||
#define DLL_API
|
||||
|
||||
#include "TCPSWorker.h"
|
||||
|
||||
#include "AdvancedErrorManagement.h"
|
||||
#include "Atomic.h"
|
||||
#include "HighResolutionTimer.h"
|
||||
#include "TCPSConn.h"
|
||||
#include "TCPStreamService.h"
|
||||
#include "UDPSProtocol.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
/** Longest wait in poll(): bounds Stop() latency and the stall / handshake checks. */
|
||||
static const int TCPS_WORKER_SLICE_MS = 50;
|
||||
|
||||
TCPSWorker::TCPSWorker(TCPStreamService &owner, uint32 maxConnections)
|
||||
: service(owner), maxConns(maxConnections), thread(*this),
|
||||
incoming(new TCPSConn *[maxConnections]), numIncoming(0u),
|
||||
conns(new TCPSConn *[maxConnections]), numConns(0u),
|
||||
pfds(new struct pollfd[maxConnections + 1u]), load(0) {
|
||||
wakeFd[0] = -1;
|
||||
wakeFd[1] = -1;
|
||||
if (pipe(wakeFd) == 0) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int flags = fcntl(wakeFd[i], F_GETFL, 0);
|
||||
if (flags >= 0) {
|
||||
(void)fcntl(wakeFd[i], F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TCPSWorker::~TCPSWorker() {
|
||||
Stop();
|
||||
CloseAll();
|
||||
for (uint32 i = 0u; i < numIncoming; i++) {
|
||||
delete incoming[i];
|
||||
service.ConnClosed();
|
||||
}
|
||||
delete[] incoming;
|
||||
delete[] conns;
|
||||
delete[] pfds;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (wakeFd[i] >= 0) {
|
||||
(void)close(wakeFd[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TCPSWorker::Start(uint32 cpuMask, uint32 stackSize) {
|
||||
if (wakeFd[0] < 0) {
|
||||
return false;
|
||||
}
|
||||
thread.SetCPUMask(cpuMask);
|
||||
thread.SetStackSize(stackSize);
|
||||
return thread.Start() == ErrorManagement::NoError;
|
||||
}
|
||||
|
||||
void TCPSWorker::Stop() {
|
||||
(void)thread.Stop();
|
||||
}
|
||||
|
||||
bool TCPSWorker::AddIncoming(TCPSConn *c) {
|
||||
bool ok = false;
|
||||
incomingMutex.FastLock();
|
||||
if (numIncoming < maxConns) {
|
||||
incoming[numIncoming] = c;
|
||||
numIncoming++;
|
||||
ok = true;
|
||||
}
|
||||
incomingMutex.FastUnLock();
|
||||
if (ok) {
|
||||
Atomic::Increment(&load);
|
||||
Wake();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void TCPSWorker::Wake() {
|
||||
if (wakeFd[1] >= 0) {
|
||||
const uint8 b = 1u;
|
||||
// EAGAIN means the pipe is already full of wake-ups: nothing to add.
|
||||
ssize_t r = write(wakeFd[1], &b, 1u);
|
||||
(void)r;
|
||||
}
|
||||
}
|
||||
|
||||
int32 TCPSWorker::Load() const {
|
||||
return load;
|
||||
}
|
||||
|
||||
void TCPSWorker::AdoptIncoming() {
|
||||
incomingMutex.FastLock();
|
||||
for (uint32 i = 0u; i < numIncoming; i++) {
|
||||
conns[numConns] = incoming[i];
|
||||
numConns++;
|
||||
}
|
||||
numIncoming = 0u;
|
||||
incomingMutex.FastUnLock();
|
||||
}
|
||||
|
||||
void TCPSWorker::CloseConn(TCPSConn *c) {
|
||||
service.Detach(c);
|
||||
delete c; // closes the socket
|
||||
service.ConnClosed();
|
||||
Atomic::Decrement(&load);
|
||||
}
|
||||
|
||||
void TCPSWorker::CloseAll() {
|
||||
for (uint32 i = 0u; i < numConns; i++) {
|
||||
CloseConn(conns[i]);
|
||||
}
|
||||
numConns = 0u;
|
||||
}
|
||||
|
||||
bool TCPSWorker::Drain(TCPSConn &c) {
|
||||
uint8 scratch[64];
|
||||
bool alive = true;
|
||||
for (;;) {
|
||||
ssize_t n = recv(c.fd, scratch, sizeof(scratch), MSG_DONTWAIT);
|
||||
if (n > 0) {
|
||||
continue; // clients have nothing more to say after SUBSCRIBE
|
||||
}
|
||||
if (n == 0) {
|
||||
alive = false;
|
||||
} else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
||||
alive = true;
|
||||
} else if (errno == EINTR) {
|
||||
continue;
|
||||
} else {
|
||||
alive = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return alive;
|
||||
}
|
||||
|
||||
bool TCPSWorker::HandshakeStep(TCPSConn &c) {
|
||||
ssize_t n = recv(c.fd, &c.hs[c.hsHave], c.hsWant - c.hsHave, MSG_DONTWAIT);
|
||||
if (n == 0) {
|
||||
return false;
|
||||
}
|
||||
if (n < 0) {
|
||||
return (errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR);
|
||||
}
|
||||
c.hsHave += static_cast<uint32>(n);
|
||||
|
||||
if (!c.hsHeaderOk && (c.hsHave >= UDPS_HEADER_SIZE)) {
|
||||
UDPSPacketHeader h;
|
||||
memcpy(&h, c.hs, UDPS_HEADER_SIZE);
|
||||
if ((h.magic != UDPS_MAGIC) || (h.type != UDPS_TYPE_SUBSCRIBE) ||
|
||||
(h.payloadBytes == 0u) || (h.payloadBytes > TCPS_MAX_SUBSCRIBE_PAYLOAD)) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::Warning,
|
||||
"TCPStreamService: connection did not open with a valid SUBSCRIBE; closing.");
|
||||
service.NoteRejected();
|
||||
return false;
|
||||
}
|
||||
c.hsHeaderOk = true;
|
||||
c.hsWant = UDPS_HEADER_SIZE + h.payloadBytes;
|
||||
}
|
||||
if (c.hsHeaderOk && (c.hsHave == c.hsWant)) {
|
||||
c.hs[c.hsWant] = 0u;
|
||||
char8 *names = reinterpret_cast<char8 *>(&c.hs[UDPS_HEADER_SIZE]);
|
||||
if (!service.Attach(&c, names)) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::Warning,
|
||||
"TCPStreamService: cannot attach to '%s'; closing.", names);
|
||||
service.NoteRejected();
|
||||
return false;
|
||||
}
|
||||
c.subscribed = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ErrorManagement::ErrorType TCPSWorker::Execute(ExecutionInfo &info) {
|
||||
if (info.GetStage() == ExecutionInfo::TerminationStage) {
|
||||
return ErrorManagement::NoError;
|
||||
}
|
||||
if (info.GetStage() != ExecutionInfo::MainStage) {
|
||||
return ErrorManagement::NoError;
|
||||
}
|
||||
|
||||
AdoptIncoming();
|
||||
|
||||
pfds[0].fd = wakeFd[0];
|
||||
pfds[0].events = POLLIN;
|
||||
pfds[0].revents = 0;
|
||||
for (uint32 i = 0u; i < numConns; i++) {
|
||||
TCPSConn *c = conns[i];
|
||||
short ev = POLLIN;
|
||||
if (c->subscribed) {
|
||||
c->qMutex.FastLock();
|
||||
if (!c->q.Empty()) {
|
||||
ev = static_cast<short>(ev | POLLOUT);
|
||||
}
|
||||
c->qMutex.FastUnLock();
|
||||
}
|
||||
pfds[i + 1u].fd = c->fd;
|
||||
pfds[i + 1u].events = ev;
|
||||
pfds[i + 1u].revents = 0;
|
||||
}
|
||||
|
||||
int pr = poll(pfds, static_cast<nfds_t>(numConns + 1u), TCPS_WORKER_SLICE_MS);
|
||||
if (pr < 0) {
|
||||
return ErrorManagement::NoError; // EINTR
|
||||
}
|
||||
if ((pfds[0].revents & POLLIN) != 0) {
|
||||
uint8 sink[64];
|
||||
while (read(wakeFd[0], sink, sizeof(sink)) > 0) {
|
||||
}
|
||||
}
|
||||
|
||||
const uint64 now = HighResolutionTimer::Counter();
|
||||
const uint64 stallTicks = service.StallTicks();
|
||||
uint32 kept = 0u;
|
||||
for (uint32 i = 0u; i < numConns; i++) {
|
||||
TCPSConn *c = conns[i];
|
||||
const short re = pfds[i + 1u].revents;
|
||||
bool keep = !c->closeRequested && ((re & (POLLERR | POLLNVAL)) == 0);
|
||||
|
||||
if (keep && ((re & (POLLIN | POLLHUP)) != 0)) {
|
||||
keep = c->subscribed ? Drain(*c) : HandshakeStep(*c);
|
||||
}
|
||||
if (keep && c->subscribed) {
|
||||
c->qMutex.FastLock();
|
||||
keep = c->q.Flush(c->fd);
|
||||
if (keep && !c->q.Empty() && (stallTicks > 0u) &&
|
||||
(now > c->q.LastProgress()) && ((now - c->q.LastProgress()) > stallTicks)) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::Warning,
|
||||
"TCPStreamService: client stalled; disconnecting.");
|
||||
service.NoteEviction();
|
||||
keep = false;
|
||||
}
|
||||
c->qMutex.FastUnLock();
|
||||
}
|
||||
if (keep && !c->subscribed && (now > c->hsDeadline)) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::Warning,
|
||||
"TCPStreamService: SUBSCRIBE timeout; closing.");
|
||||
service.NoteRejected();
|
||||
keep = false;
|
||||
}
|
||||
|
||||
if (keep) {
|
||||
conns[kept] = c;
|
||||
kept++;
|
||||
} else {
|
||||
CloseConn(c);
|
||||
}
|
||||
}
|
||||
numConns = kept;
|
||||
return ErrorManagement::NoError;
|
||||
}
|
||||
|
||||
} // namespace MARTe
|
||||
@@ -0,0 +1,68 @@
|
||||
#ifndef TCPS_WORKER_H_
|
||||
#define TCPS_WORKER_H_
|
||||
|
||||
/**
|
||||
* @file TCPSWorker.h
|
||||
* @brief One I/O thread of a TCPStreamService (internal).
|
||||
*
|
||||
* Owns a set of connections, polls them (plus a self-pipe used by producers to
|
||||
* announce new frames), performs the SUBSCRIBE handshake, flushes the bounded
|
||||
* queues and evicts stalled / dead peers.
|
||||
*/
|
||||
|
||||
#include "EmbeddedServiceMethodBinderI.h"
|
||||
#include "ExecutionInfo.h"
|
||||
#include "FastPollingMutexSem.h"
|
||||
#include "SingleThreadService.h"
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
class TCPStreamService;
|
||||
struct TCPSConn;
|
||||
|
||||
class TCPSWorker : public EmbeddedServiceMethodBinderI {
|
||||
public:
|
||||
TCPSWorker(TCPStreamService &owner, uint32 maxConns);
|
||||
virtual ~TCPSWorker();
|
||||
|
||||
bool Start(uint32 cpuMask, uint32 stackSize);
|
||||
void Stop();
|
||||
|
||||
/** Hand a freshly accepted connection to this worker (acceptor thread). */
|
||||
bool AddIncoming(TCPSConn *c);
|
||||
/** Interrupt the poll so queued data is flushed now (any thread, cheap). */
|
||||
void Wake();
|
||||
/** @return connections currently assigned (approximate). */
|
||||
int32 Load() const;
|
||||
|
||||
virtual ErrorManagement::ErrorType Execute(ExecutionInfo &info);
|
||||
|
||||
private:
|
||||
void AdoptIncoming();
|
||||
bool HandshakeStep(TCPSConn &c);
|
||||
bool Drain(TCPSConn &c);
|
||||
void CloseConn(TCPSConn *c);
|
||||
void CloseAll();
|
||||
|
||||
TCPStreamService &service;
|
||||
uint32 maxConns;
|
||||
|
||||
SingleThreadService thread;
|
||||
int wakeFd[2];
|
||||
|
||||
FastPollingMutexSem incomingMutex;
|
||||
TCPSConn **incoming;
|
||||
uint32 numIncoming;
|
||||
|
||||
TCPSConn **conns;
|
||||
uint32 numConns;
|
||||
struct pollfd *pfds;
|
||||
|
||||
volatile int32 load;
|
||||
};
|
||||
|
||||
} // namespace MARTe
|
||||
|
||||
#endif // TCPS_WORKER_H_
|
||||
@@ -0,0 +1,494 @@
|
||||
/**
|
||||
* @file TCPStreamJoin.cpp
|
||||
* @brief Source file for class TCPStreamJoin
|
||||
* @date 06/11/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.
|
||||
*/
|
||||
|
||||
#define DLL_API
|
||||
|
||||
#include "TCPStreamJoin.h"
|
||||
|
||||
#include "AdvancedErrorManagement.h"
|
||||
#include "ConfigurationDatabase.h"
|
||||
#include "ObjectRegistryDatabase.h"
|
||||
#include "UDPSProtocol.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
const uint32 TCPStreamJoin::TCPSJ_MAX_SOURCES;
|
||||
|
||||
TCPStreamJoin::Source::Source()
|
||||
: stream(NULL_PTR(TCPSServiceStream *)), configOk(false), cfg(NULL_PTR(uint8 *)),
|
||||
cfgBytes(0u), numSigs(0u), hrt(0u), body(NULL_PTR(uint8 *)), bodyCap(0u),
|
||||
bodySize(0u), haveBody(false) {
|
||||
}
|
||||
|
||||
TCPStreamJoin::Source::~Source() {
|
||||
if (cfg != NULL_PTR(uint8 *)) {
|
||||
delete[] cfg;
|
||||
}
|
||||
if (body != NULL_PTR(uint8 *)) {
|
||||
delete[] body;
|
||||
}
|
||||
}
|
||||
|
||||
TCPStreamJoin::TCPStreamJoin()
|
||||
: Object(), TCPSStreamTapI(), TCPSStreamObserverI(), out(NULL_PTR(TCPSServiceStream *)),
|
||||
observing(false), src(NULL_PTR(Source *)), numSrc(0u), master(0u), maxPayload(60000u),
|
||||
active(false), configPublished(false), sizeLogged(false), outCounter(0u), emitted(0u),
|
||||
scratch(NULL_PTR(uint8 *)), scratchCap(0u) {
|
||||
}
|
||||
|
||||
TCPStreamJoin::~TCPStreamJoin() {
|
||||
if (observing) {
|
||||
service->RemoveObserver(this);
|
||||
observing = false;
|
||||
}
|
||||
for (uint32 i = 0u; i < numSrc; i++) {
|
||||
mtx.FastLock();
|
||||
TCPSServiceStream *s = src[i].stream;
|
||||
src[i].stream = NULL_PTR(TCPSServiceStream *);
|
||||
mtx.FastUnLock();
|
||||
if (s != NULL_PTR(TCPSServiceStream *)) {
|
||||
s->RemoveTap(this);
|
||||
}
|
||||
}
|
||||
if (out != NULL_PTR(TCPSServiceStream *)) {
|
||||
delete out; // unregisters the merged stream
|
||||
out = NULL_PTR(TCPSServiceStream *);
|
||||
}
|
||||
if (src != NULL_PTR(Source *)) {
|
||||
delete[] src;
|
||||
}
|
||||
if (scratch != NULL_PTR(uint8 *)) {
|
||||
delete[] scratch;
|
||||
}
|
||||
}
|
||||
|
||||
bool TCPStreamJoin::Initialise(StructuredDataI &data) {
|
||||
bool ok = Object::Initialise(data);
|
||||
|
||||
StreamString serviceName;
|
||||
if (ok && (!data.Read("Service", serviceName) || (serviceName.Size() == 0u))) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError, "Parameter 'Service' is required.");
|
||||
ok = false;
|
||||
}
|
||||
if (ok && (!data.Read("StreamName", outName) || (outName.Size() == 0u))) {
|
||||
outName = GetName();
|
||||
}
|
||||
StreamString sources;
|
||||
if (ok && (!data.Read("Sources", sources) || (sources.Size() == 0u))) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError, "Parameter 'Sources' is required.");
|
||||
ok = false;
|
||||
}
|
||||
StreamString masterName;
|
||||
if (ok && !data.Read("Master", masterName)) {
|
||||
masterName = "";
|
||||
}
|
||||
maxPayload = 60000u;
|
||||
(void)data.Read("MaxPayloadSize", maxPayload);
|
||||
|
||||
if (ok) {
|
||||
// Split "a, b ,c" into trimmed names.
|
||||
src = new Source[TCPSJ_MAX_SOURCES];
|
||||
const char8 *p = sources.Buffer();
|
||||
while (ok && (p != NULL_PTR(const char8 *))) {
|
||||
const char8 *comma = strchr(p, ',');
|
||||
const char8 *end = (comma != NULL_PTR(const char8 *)) ? comma : (p + strlen(p));
|
||||
while ((p < end) && (*p == ' ')) {
|
||||
p++;
|
||||
}
|
||||
const char8 *e = end;
|
||||
while ((e > p) && (e[-1] == ' ')) {
|
||||
e--;
|
||||
}
|
||||
const uint32 len = static_cast<uint32>(e - p);
|
||||
if ((len == 0u) || (len > TCPS_MAX_STREAM_NAME) || (numSrc >= TCPSJ_MAX_SOURCES)) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"Sources must list 1..%u names of 1..%u characters.",
|
||||
TCPSJ_MAX_SOURCES, TCPS_MAX_STREAM_NAME);
|
||||
ok = false;
|
||||
}
|
||||
if (ok) {
|
||||
StreamString name;
|
||||
uint32 wlen = len;
|
||||
(void)name.Write(p, wlen);
|
||||
for (uint32 i = 0u; i < numSrc; i++) {
|
||||
if (src[i].name == name) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"Source '%s' is listed twice.", name.Buffer());
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (name == outName) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"The merged stream '%s' cannot be one of its own sources.",
|
||||
name.Buffer());
|
||||
ok = false;
|
||||
}
|
||||
src[numSrc].name = name;
|
||||
numSrc++;
|
||||
}
|
||||
p = (comma != NULL_PTR(const char8 *)) ? (comma + 1) : NULL_PTR(const char8 *);
|
||||
}
|
||||
}
|
||||
if (ok && (masterName.Size() > 0u)) {
|
||||
const int32 m = FindByName(masterName.Buffer());
|
||||
if (m < 0) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"Master '%s' is not one of the Sources.", masterName.Buffer());
|
||||
ok = false;
|
||||
}
|
||||
else {
|
||||
master = static_cast<uint32>(m);
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
service = ObjectRegistryDatabase::Instance()->Find(serviceName.Buffer());
|
||||
if (!service.IsValid()) {
|
||||
REPORT_ERROR(ErrorManagement::InitialisationError,
|
||||
"No TCPStreamService named '%s' (declare it before the join).",
|
||||
serviceName.Buffer());
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
out = new TCPSServiceStream(serviceName.Buffer(), outName.Buffer());
|
||||
ConfigurationDatabase scdb;
|
||||
ok = scdb.Write("MaxPayloadSize", maxPayload) && scdb.MoveToRoot() && out->Initialise(scdb);
|
||||
}
|
||||
if (ok) {
|
||||
// Last: the replay of already registered streams may complete the join right here.
|
||||
observing = service->AddObserver(this);
|
||||
if (!observing) {
|
||||
REPORT_ERROR(ErrorManagement::InitialisationError,
|
||||
"The service cannot take another observer.");
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
int32 TCPStreamJoin::FindByName(const char8 *name) const {
|
||||
int32 r = -1;
|
||||
for (uint32 i = 0u; (i < numSrc) && (r < 0); i++) {
|
||||
if (strcmp(src[i].name.Buffer(), name) == 0) {
|
||||
r = static_cast<int32>(i);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int32 TCPStreamJoin::FindByStream(const TCPSServiceStream *s) const {
|
||||
int32 r = -1;
|
||||
for (uint32 i = 0u; (i < numSrc) && (r < 0); i++) {
|
||||
if (src[i].stream == s) {
|
||||
r = static_cast<int32>(i);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
bool TCPStreamJoin::AllRegistered() const {
|
||||
bool all = true;
|
||||
for (uint32 i = 0u; i < numSrc; i++) {
|
||||
all = all && (src[i].stream != NULL_PTR(TCPSServiceStream *));
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
bool TCPStreamJoin::IsActive() const {
|
||||
return active;
|
||||
}
|
||||
|
||||
bool TCPStreamJoin::HasConfig() const {
|
||||
return configPublished;
|
||||
}
|
||||
|
||||
uint64 TCPStreamJoin::GetFramesEmitted() const {
|
||||
return emitted;
|
||||
}
|
||||
|
||||
uint32 TCPStreamJoin::GetNumSources() const {
|
||||
return numSrc;
|
||||
}
|
||||
|
||||
void TCPStreamJoin::OnStreamRegistered(TCPSServiceStream *stream) {
|
||||
bool mine = false;
|
||||
int32 idx = -1;
|
||||
mtx.FastLock();
|
||||
idx = FindByName(stream->GetStreamName());
|
||||
if ((idx >= 0) && (src[idx].stream == NULL_PTR(TCPSServiceStream *))) {
|
||||
src[idx].stream = stream;
|
||||
mine = true;
|
||||
}
|
||||
mtx.FastUnLock();
|
||||
if (!mine) {
|
||||
return;
|
||||
}
|
||||
// Replays the cached CONFIG into OnTapConfig; the join mutex must not be held.
|
||||
if (!stream->AddTap(this)) {
|
||||
REPORT_ERROR(ErrorManagement::InitialisationError,
|
||||
"Stream '%s' cannot take another tap.", stream->GetStreamName());
|
||||
mtx.FastLock();
|
||||
src[idx].stream = NULL_PTR(TCPSServiceStream *);
|
||||
mtx.FastUnLock();
|
||||
return;
|
||||
}
|
||||
Evaluate();
|
||||
}
|
||||
|
||||
void TCPStreamJoin::Evaluate() {
|
||||
mtx.FastLock();
|
||||
const bool start = !active && AllRegistered();
|
||||
mtx.FastUnLock();
|
||||
if (start) {
|
||||
// Registering may call back into observers (including this one): no lock held.
|
||||
const bool ok = out->Start();
|
||||
mtx.FastLock();
|
||||
if (ok) {
|
||||
active = true;
|
||||
outCounter = 0u;
|
||||
PublishConfigLocked();
|
||||
}
|
||||
mtx.FastUnLock();
|
||||
}
|
||||
}
|
||||
|
||||
void TCPStreamJoin::OnStreamUnregistered(TCPSServiceStream *stream) {
|
||||
mtx.FastLock();
|
||||
const int32 idx = FindByStream(stream);
|
||||
bool wasActive = false;
|
||||
if (idx >= 0) {
|
||||
Source &s = src[idx];
|
||||
s.stream = NULL_PTR(TCPSServiceStream *);
|
||||
s.configOk = false;
|
||||
s.haveBody = false;
|
||||
s.bodySize = 0u;
|
||||
wasActive = active;
|
||||
active = false;
|
||||
configPublished = false;
|
||||
}
|
||||
mtx.FastUnLock();
|
||||
if (idx < 0) {
|
||||
return;
|
||||
}
|
||||
stream->RemoveTap(this);
|
||||
if (wasActive) {
|
||||
(void)out->Stop(); // subscribers of the merged stream are dropped
|
||||
}
|
||||
}
|
||||
|
||||
bool TCPStreamJoin::ParseConfig(Source &s, const uint8 *payload, uint32 n) {
|
||||
bool ok = (n >= 5u);
|
||||
uint32 numSigs = 0u;
|
||||
if (ok) {
|
||||
memcpy(&numSigs, payload, 4u);
|
||||
const uint64 need = 4u + static_cast<uint64>(numSigs) * UDPS_SIGNAL_DESC_SIZE + 1u;
|
||||
ok = (numSigs > 0u) && (need <= n);
|
||||
}
|
||||
if (ok) {
|
||||
const uint32 off = 4u + numSigs * UDPS_SIGNAL_DESC_SIZE;
|
||||
if (payload[off] == UDPS_PUBLISH_ACCUMULATE) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"Source '%s' uses Accumulate publishing, which cannot be merged.",
|
||||
s.name.Buffer());
|
||||
ok = false;
|
||||
}
|
||||
else {
|
||||
s.numSigs = numSigs;
|
||||
s.hrt = 0u;
|
||||
if (n >= (off + 1u + 8u)) {
|
||||
memcpy(&s.hrt, &payload[off + 1u], 8u);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"Source '%s' sent a malformed CONFIG.", s.name.Buffer());
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void TCPStreamJoin::OnTapConfig(TCPSServiceStream *source, const uint8 *payload, uint32 payloadSize) {
|
||||
mtx.FastLock();
|
||||
const int32 idx = FindByStream(source);
|
||||
if (idx >= 0) {
|
||||
Source &s = src[idx];
|
||||
s.haveBody = false;
|
||||
s.bodySize = 0u;
|
||||
configPublished = false;
|
||||
sizeLogged = false;
|
||||
s.configOk = ParseConfig(s, payload, payloadSize);
|
||||
if (s.configOk) {
|
||||
if (s.cfgBytes < payloadSize) {
|
||||
if (s.cfg != NULL_PTR(uint8 *)) {
|
||||
delete[] s.cfg;
|
||||
}
|
||||
s.cfg = new uint8[payloadSize];
|
||||
}
|
||||
memcpy(s.cfg, payload, payloadSize);
|
||||
s.cfgBytes = payloadSize;
|
||||
}
|
||||
PublishConfigLocked();
|
||||
}
|
||||
mtx.FastUnLock();
|
||||
}
|
||||
|
||||
/** Caller holds `mtx`. */
|
||||
void TCPStreamJoin::PublishConfigLocked() {
|
||||
configPublished = false;
|
||||
bool ok = active;
|
||||
uint64 totalSigs = 0u;
|
||||
uint64 hrt = UDPS_HRT_FREQUENCY_UNKNOWN;
|
||||
for (uint32 i = 0u; ok && (i < numSrc); i++) {
|
||||
ok = src[i].configOk;
|
||||
totalSigs += src[i].numSigs;
|
||||
if (ok && (src[i].hrt != UDPS_HRT_FREQUENCY_UNKNOWN)) {
|
||||
if ((hrt != UDPS_HRT_FREQUENCY_UNKNOWN) && (hrt != src[i].hrt)) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"Join '%s': sources have different HRT frequencies, cannot merge.",
|
||||
outName.Buffer());
|
||||
ok = false;
|
||||
}
|
||||
hrt = src[i].hrt;
|
||||
}
|
||||
}
|
||||
const uint64 cfgSize = 4u + totalSigs * UDPS_SIGNAL_DESC_SIZE + 1u + 8u;
|
||||
if (ok && (cfgSize > maxPayload)) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"Join '%s': merged CONFIG of %u bytes exceeds MaxPayloadSize.",
|
||||
outName.Buffer(), static_cast<uint32>(cfgSize));
|
||||
ok = false;
|
||||
}
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
uint8 *buf = new uint8[static_cast<uint32>(cfgSize)];
|
||||
const uint32 nSigs = static_cast<uint32>(totalSigs);
|
||||
memcpy(buf, &nSigs, 4u);
|
||||
uint32 pos = 4u;
|
||||
uint32 base = 0u;
|
||||
for (uint32 i = 0u; ok && (i < numSrc); i++) {
|
||||
const char8 *prefix = src[i].name.Buffer();
|
||||
for (uint32 k = 0u; ok && (k < src[i].numSigs); k++) {
|
||||
UDPSSignalDescriptor d;
|
||||
memcpy(&d, &src[i].cfg[4u + k * UDPS_SIGNAL_DESC_SIZE], UDPS_SIGNAL_DESC_SIZE);
|
||||
d.name[UDPS_MAX_SIGNAL_NAME - 1u] = '\0';
|
||||
const uint32 len = static_cast<uint32>(strlen(prefix) + 1u + strlen(d.name));
|
||||
if (len >= UDPS_MAX_SIGNAL_NAME) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"Join '%s': signal name '%s_%s' is longer than %u characters.",
|
||||
outName.Buffer(), prefix, d.name, UDPS_MAX_SIGNAL_NAME - 1u);
|
||||
ok = false;
|
||||
}
|
||||
else {
|
||||
char8 merged[UDPS_MAX_SIGNAL_NAME];
|
||||
(void)snprintf(merged, sizeof(merged), "%s_%s", prefix, d.name);
|
||||
memset(d.name, 0, sizeof(d.name));
|
||||
memcpy(d.name, merged, strlen(merged));
|
||||
if (d.timeSignalIdx != UDPS_NO_TIME_SIGNAL) {
|
||||
d.timeSignalIdx += base;
|
||||
}
|
||||
memcpy(&buf[pos], &d, UDPS_SIGNAL_DESC_SIZE);
|
||||
pos += UDPS_SIGNAL_DESC_SIZE;
|
||||
}
|
||||
}
|
||||
base += src[i].numSigs;
|
||||
}
|
||||
if (ok) {
|
||||
buf[pos] = UDPS_PUBLISH_STRICT;
|
||||
pos += 1u;
|
||||
memcpy(&buf[pos], &hrt, 8u);
|
||||
pos += 8u;
|
||||
ok = out->SendConfig(buf, pos);
|
||||
}
|
||||
configPublished = ok;
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
void TCPStreamJoin::OnTapData(TCPSServiceStream *source, uint32 counter, const uint8 *payload,
|
||||
uint32 payloadSize) {
|
||||
(void)counter;
|
||||
mtx.FastLock();
|
||||
const int32 idx = FindByStream(source);
|
||||
if ((idx >= 0) && src[idx].configOk && (payloadSize >= 8u)) {
|
||||
Source &s = src[idx];
|
||||
const uint32 bl = payloadSize - 8u;
|
||||
// A size change without a new CONFIG would corrupt the merged layout: ignore.
|
||||
if (!s.haveBody || (s.bodySize == bl)) {
|
||||
if (s.bodyCap < bl) {
|
||||
if (s.body != NULL_PTR(uint8 *)) {
|
||||
delete[] s.body;
|
||||
}
|
||||
s.body = new uint8[(bl > 0u) ? bl : 1u];
|
||||
s.bodyCap = (bl > 0u) ? bl : 1u;
|
||||
}
|
||||
if (bl > 0u) {
|
||||
memcpy(s.body, &payload[8], bl);
|
||||
}
|
||||
s.bodySize = bl;
|
||||
s.haveBody = true;
|
||||
|
||||
if (active && configPublished && (static_cast<uint32>(idx) == master)) {
|
||||
uint64 total = 8u;
|
||||
bool ready = true;
|
||||
for (uint32 i = 0u; i < numSrc; i++) {
|
||||
ready = ready && src[i].haveBody;
|
||||
total += src[i].bodySize;
|
||||
}
|
||||
if (ready && (total > maxPayload)) {
|
||||
if (!sizeLogged) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"Join '%s': merged frame of %u bytes exceeds MaxPayloadSize.",
|
||||
outName.Buffer(), static_cast<uint32>(total));
|
||||
sizeLogged = true;
|
||||
}
|
||||
ready = false;
|
||||
}
|
||||
if (ready) {
|
||||
if (scratchCap < total) {
|
||||
if (scratch != NULL_PTR(uint8 *)) {
|
||||
delete[] scratch;
|
||||
}
|
||||
scratch = new uint8[static_cast<uint32>(total)];
|
||||
scratchCap = static_cast<uint32>(total);
|
||||
}
|
||||
memcpy(scratch, payload, 8u); // master timestamp
|
||||
uint32 pos = 8u;
|
||||
for (uint32 i = 0u; i < numSrc; i++) {
|
||||
if (src[i].bodySize > 0u) {
|
||||
memcpy(&scratch[pos], src[i].body, src[i].bodySize);
|
||||
}
|
||||
pos += src[i].bodySize;
|
||||
}
|
||||
outCounter++;
|
||||
if (out->SendData(outCounter, scratch, pos)) {
|
||||
emitted = emitted + 1u;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mtx.FastUnLock();
|
||||
}
|
||||
|
||||
CLASS_REGISTER(TCPStreamJoin, "1.0")
|
||||
|
||||
} /* namespace MARTe */
|
||||
@@ -0,0 +1,139 @@
|
||||
#ifndef TCPSTREAMJOIN_H_
|
||||
#define TCPSTREAMJOIN_H_
|
||||
|
||||
/**
|
||||
* @file TCPStreamJoin.h
|
||||
* @brief Publishes one new stream of a TCPStreamService that merges several other
|
||||
* streams of the same service.
|
||||
*
|
||||
* @code
|
||||
* +Svc = { Class = TCPStreamService Port = 44500 }
|
||||
* +Join = { Class = TCPStreamJoin Service = "Svc" StreamName = "all"
|
||||
* Sources = "fast,slow" Master = "fast" }
|
||||
* @endcode
|
||||
* Declare the join after the service. Consumers subscribe to "all" like to any stream.
|
||||
*
|
||||
* The merged stream is emitted at the pace of the Master source: each Master DATA frame
|
||||
* produces one merged frame holding the Master's signals and the last values received
|
||||
* from every other source (sample-and-hold). Nothing is emitted until every source has
|
||||
* delivered one DATA frame. No thread is added: the merged frame is built and queued on
|
||||
* the Master producer's thread.
|
||||
*
|
||||
* @par CONFIG
|
||||
* Concatenation of the source descriptors in Sources order, named
|
||||
* "<stream>_<signal>" (at most 63 characters), time-signal indexes rebased, publish mode
|
||||
* Strict. All sources must share the same HRT frequency (an unknown one matches any).
|
||||
*
|
||||
* @par DATA
|
||||
* [master timestamp][source0 body][source1 body]... where a body is that source's last
|
||||
* DATA payload without its 8-byte timestamp. A held value is therefore stamped with the
|
||||
* Master's time unless the source carries its own time signal.
|
||||
*
|
||||
* @par Limits
|
||||
* Only Strict and Decimate sources are accepted (Accumulate batches have varying
|
||||
* length); a source whose frame size changes without a new CONFIG is ignored; the merged
|
||||
* frame must fit MaxPayloadSize. The output stream is registered while every source is
|
||||
* registered and removed as soon as one leaves; it is rebuilt when a source re-registers
|
||||
* or changes its CONFIG.
|
||||
*
|
||||
* @par Parameters
|
||||
* | Parameter | Type | Default | Description |
|
||||
* |----------------|--------|-------------|-------------|
|
||||
* | Service | string | (required) | Name of the TCPStreamService object. |
|
||||
* | StreamName | string | object name | Name of the merged stream. |
|
||||
* | Sources | string | (required) | Comma separated source stream names (1..16). |
|
||||
* | Master | string | first source| Source whose frames pace the merged stream. |
|
||||
* | MaxPayloadSize | uint32 | 60000 | Largest merged frame payload. |
|
||||
*
|
||||
* @par Locking
|
||||
* Producer-side: source tapMutex, then the join mutex, then the output stream mutex, then
|
||||
* the connection queue mutex. Service notifications run outside its topology lock and
|
||||
* are serialised.
|
||||
*/
|
||||
|
||||
#include "FastPollingMutexSem.h"
|
||||
#include "Object.h"
|
||||
#include "ReferenceT.h"
|
||||
#include "StreamString.h"
|
||||
#include "StructuredDataI.h"
|
||||
#include "TCPSServiceStream.h"
|
||||
#include "TCPSStreamTapI.h"
|
||||
#include "TCPStreamService.h"
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
class TCPStreamJoin : public Object, public TCPSStreamTapI, public TCPSStreamObserverI {
|
||||
public:
|
||||
CLASS_REGISTER_DECLARATION()
|
||||
|
||||
/** Most source streams one join can merge. */
|
||||
static const uint32 TCPSJ_MAX_SOURCES = 16u;
|
||||
|
||||
TCPStreamJoin();
|
||||
virtual ~TCPStreamJoin();
|
||||
|
||||
virtual bool Initialise(StructuredDataI &data);
|
||||
|
||||
virtual void OnTapConfig(TCPSServiceStream *source, const uint8 *payload, uint32 payloadSize);
|
||||
virtual void OnTapData(TCPSServiceStream *source, uint32 counter, const uint8 *payload,
|
||||
uint32 payloadSize);
|
||||
virtual void OnStreamRegistered(TCPSServiceStream *stream);
|
||||
virtual void OnStreamUnregistered(TCPSServiceStream *stream);
|
||||
|
||||
/** @return true while the merged stream is registered with the service. */
|
||||
bool IsActive() const;
|
||||
/** @return true once a merged CONFIG has been published for the current sources. */
|
||||
bool HasConfig() const;
|
||||
/** @return merged DATA frames emitted. */
|
||||
uint64 GetFramesEmitted() const;
|
||||
uint32 GetNumSources() const;
|
||||
|
||||
private:
|
||||
struct Source {
|
||||
Source();
|
||||
~Source();
|
||||
StreamString name;
|
||||
TCPSServiceStream *stream; ///< non-NULL while registered and tapped
|
||||
bool configOk;
|
||||
uint8 *cfg;
|
||||
uint32 cfgBytes;
|
||||
uint32 numSigs;
|
||||
uint64 hrt;
|
||||
uint8 *body;
|
||||
uint32 bodyCap;
|
||||
uint32 bodySize;
|
||||
bool haveBody;
|
||||
};
|
||||
|
||||
int32 FindByName(const char8 *name) const;
|
||||
int32 FindByStream(const TCPSServiceStream *s) const;
|
||||
bool AllRegistered() const;
|
||||
void Evaluate();
|
||||
void PublishConfigLocked();
|
||||
bool ParseConfig(Source &s, const uint8 *payload, uint32 n);
|
||||
|
||||
ReferenceT<TCPStreamService> service;
|
||||
TCPSServiceStream *out;
|
||||
bool observing;
|
||||
StreamString outName;
|
||||
Source *src;
|
||||
uint32 numSrc;
|
||||
uint32 master;
|
||||
uint32 maxPayload;
|
||||
|
||||
FastPollingMutexSem mtx;
|
||||
bool active;
|
||||
bool configPublished;
|
||||
bool sizeLogged;
|
||||
uint32 outCounter;
|
||||
volatile uint64 emitted;
|
||||
uint8 *scratch;
|
||||
uint32 scratchCap;
|
||||
|
||||
TCPStreamJoin(const TCPStreamJoin &);
|
||||
TCPStreamJoin &operator=(const TCPStreamJoin &);
|
||||
};
|
||||
|
||||
} // namespace MARTe
|
||||
|
||||
#endif // TCPSTREAMJOIN_H_
|
||||
@@ -0,0 +1,502 @@
|
||||
/**
|
||||
* @file TCPStreamService.cpp
|
||||
* @brief Source file for class TCPStreamService
|
||||
* @date 06/11/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.
|
||||
*/
|
||||
|
||||
#define DLL_API
|
||||
|
||||
#include "TCPStreamService.h"
|
||||
|
||||
#include "AdvancedErrorManagement.h"
|
||||
#include "Atomic.h"
|
||||
#include "HighResolutionTimer.h"
|
||||
#include "TCPSConn.h"
|
||||
#include "TCPSServiceStream.h"
|
||||
#include "TCPSWorker.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <poll.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
static const int TCPS_ACCEPT_SLICE_MS = 50;
|
||||
|
||||
TCPStreamService::TCPStreamService()
|
||||
: Object(), EmbeddedServiceMethodBinderI(), port(44500u), boundPort(0u),
|
||||
numWorkers(2u), maxClients(64u), maxStreams(32u), queueDepth(8u),
|
||||
stallTimeoutS(5u), handshakeTimeoutS(5u), sendBufferSize(0u),
|
||||
cpuMask(0xFFFFFFFFu), stackSize(65536u), stallTicks(0u), handshakeTicks(0u),
|
||||
listenFd(-1), acceptThread(*this), acceptorStarted(false),
|
||||
workers(NULL_PTR(TCPSWorker **)), workersCreated(0u),
|
||||
numObservers(0u),
|
||||
streams(NULL_PTR(TCPSServiceStream **)), numStreams(0u),
|
||||
connCount(0), evictions(0), rejected(0) {
|
||||
(void)notifyMutex.Create(true);
|
||||
for (uint32 i = 0u; i < TCPS_MAX_OBSERVERS; i++) {
|
||||
observers[i] = NULL_PTR(TCPSStreamObserverI *);
|
||||
}
|
||||
}
|
||||
|
||||
TCPStreamService::~TCPStreamService() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void TCPStreamService::Shutdown() {
|
||||
if (acceptorStarted) {
|
||||
(void)acceptThread.Stop();
|
||||
acceptorStarted = false;
|
||||
}
|
||||
for (uint32 i = 0u; i < workersCreated; i++) {
|
||||
workers[i]->Stop();
|
||||
}
|
||||
if (listenFd >= 0) {
|
||||
(void)close(listenFd);
|
||||
listenFd = -1;
|
||||
}
|
||||
for (uint32 i = 0u; i < workersCreated; i++) {
|
||||
delete workers[i];
|
||||
}
|
||||
workersCreated = 0u;
|
||||
if (workers != NULL_PTR(TCPSWorker **)) {
|
||||
delete[] workers;
|
||||
workers = NULL_PTR(TCPSWorker **);
|
||||
}
|
||||
if (streams != NULL_PTR(TCPSServiceStream **)) {
|
||||
delete[] streams;
|
||||
streams = NULL_PTR(TCPSServiceStream **);
|
||||
}
|
||||
numStreams = 0u;
|
||||
}
|
||||
|
||||
bool TCPStreamService::Initialise(StructuredDataI &data) {
|
||||
bool ok = Object::Initialise(data);
|
||||
|
||||
port = 44500u;
|
||||
(void)data.Read("Port", port);
|
||||
if (port > 65535u) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError, "Port %u out of range.", port);
|
||||
ok = false;
|
||||
}
|
||||
numWorkers = 2u;
|
||||
(void)data.Read("Workers", numWorkers);
|
||||
if ((numWorkers == 0u) || (numWorkers > 32u)) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError, "Workers %u must be in 1..32.", numWorkers);
|
||||
ok = false;
|
||||
}
|
||||
maxClients = 64u;
|
||||
(void)data.Read("MaxClients", maxClients);
|
||||
if ((maxClients == 0u) || (maxClients > 1024u)) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError, "MaxClients %u must be in 1..1024.", maxClients);
|
||||
ok = false;
|
||||
}
|
||||
maxStreams = 32u;
|
||||
(void)data.Read("MaxStreams", maxStreams);
|
||||
if ((maxStreams == 0u) || (maxStreams > 256u)) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError, "MaxStreams %u must be in 1..256.", maxStreams);
|
||||
ok = false;
|
||||
}
|
||||
queueDepth = 8u;
|
||||
(void)data.Read("ClientQueueDepth", queueDepth);
|
||||
if ((queueDepth == 0u) || (queueDepth > 4096u)) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError, "ClientQueueDepth %u must be in 1..4096.", queueDepth);
|
||||
ok = false;
|
||||
}
|
||||
stallTimeoutS = 5u;
|
||||
(void)data.Read("ClientStallTimeout", stallTimeoutS);
|
||||
handshakeTimeoutS = 5u;
|
||||
(void)data.Read("HandshakeTimeout", handshakeTimeoutS);
|
||||
if (handshakeTimeoutS == 0u) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError, "HandshakeTimeout must be at least 1 second.");
|
||||
ok = false;
|
||||
}
|
||||
sendBufferSize = 0u;
|
||||
(void)data.Read("SendBufferSize", sendBufferSize);
|
||||
(void)data.Read("CPUMask", cpuMask);
|
||||
(void)data.Read("StackSize", stackSize);
|
||||
stallTicks = static_cast<uint64>(stallTimeoutS) * HighResolutionTimer::Frequency();
|
||||
handshakeTicks = static_cast<uint64>(handshakeTimeoutS) * HighResolutionTimer::Frequency();
|
||||
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Listening socket. */
|
||||
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
ok = (fd >= 0);
|
||||
if (!ok) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "socket() failed: %s.", strerror(errno));
|
||||
}
|
||||
if (ok) {
|
||||
int one = 1;
|
||||
(void)setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
addr.sin_port = htons(static_cast<uint16>(port));
|
||||
if (bind(fd, reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr)) != 0) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "bind(%u) failed: %s.", port, strerror(errno));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (ok && (listen(fd, 32) != 0)) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "listen() failed: %s.", strerror(errno));
|
||||
ok = false;
|
||||
}
|
||||
if (ok) {
|
||||
int flags = fcntl(fd, F_GETFL, 0);
|
||||
ok = (flags >= 0) && (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0);
|
||||
}
|
||||
if (ok) {
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = static_cast<socklen_t>(sizeof(addr));
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
boundPort = static_cast<uint16>(port);
|
||||
if (getsockname(fd, reinterpret_cast<struct sockaddr *>(&addr), &len) == 0) {
|
||||
boundPort = ntohs(addr.sin_port);
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
if (fd >= 0) {
|
||||
(void)close(fd);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
listenFd = fd;
|
||||
|
||||
streams = new TCPSServiceStream *[maxStreams];
|
||||
workers = new TCPSWorker *[numWorkers];
|
||||
for (uint32 i = 0u; (i < numWorkers) && ok; i++) {
|
||||
workers[i] = new TCPSWorker(*this, maxClients);
|
||||
workersCreated = i + 1u;
|
||||
ok = workers[i]->Start(cpuMask, stackSize);
|
||||
if (!ok) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "Could not start worker %u.", i);
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
acceptThread.SetCPUMask(cpuMask);
|
||||
acceptThread.SetStackSize(stackSize);
|
||||
ok = (acceptThread.Start() == ErrorManagement::NoError);
|
||||
acceptorStarted = ok;
|
||||
if (!ok) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "Could not start the acceptor thread.");
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
Shutdown();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
ErrorManagement::ErrorType TCPStreamService::Execute(ExecutionInfo &info) {
|
||||
if (info.GetStage() != ExecutionInfo::MainStage) {
|
||||
return ErrorManagement::NoError;
|
||||
}
|
||||
struct pollfd p;
|
||||
p.fd = listenFd;
|
||||
p.events = POLLIN;
|
||||
p.revents = 0;
|
||||
if (poll(&p, 1, TCPS_ACCEPT_SLICE_MS) <= 0) {
|
||||
return ErrorManagement::NoError;
|
||||
}
|
||||
for (;;) {
|
||||
int fd = accept(listenFd, NULL_PTR(struct sockaddr *), NULL_PTR(socklen_t *));
|
||||
if (fd < 0) {
|
||||
break;
|
||||
}
|
||||
if (static_cast<uint32>(connCount) >= maxClients) {
|
||||
REPORT_ERROR(ErrorManagement::Warning,
|
||||
"MaxClients (%u) reached; connection refused.", maxClients);
|
||||
(void)close(fd);
|
||||
continue;
|
||||
}
|
||||
int flags = fcntl(fd, F_GETFL, 0);
|
||||
if ((flags < 0) || (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0)) {
|
||||
(void)close(fd);
|
||||
continue;
|
||||
}
|
||||
int one = 1;
|
||||
(void)setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
|
||||
if (sendBufferSize > 0u) {
|
||||
int sz = static_cast<int>(sendBufferSize);
|
||||
(void)setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof(sz));
|
||||
}
|
||||
|
||||
TCPSWorker *best = workers[0];
|
||||
for (uint32 i = 1u; i < workersCreated; i++) {
|
||||
if (workers[i]->Load() < best->Load()) {
|
||||
best = workers[i];
|
||||
}
|
||||
}
|
||||
TCPSConn *c = new TCPSConn(fd, best, queueDepth,
|
||||
HighResolutionTimer::Counter() + handshakeTicks);
|
||||
Atomic::Increment(&connCount);
|
||||
if (!best->AddIncoming(c)) {
|
||||
delete c;
|
||||
Atomic::Decrement(&connCount);
|
||||
}
|
||||
}
|
||||
return ErrorManagement::NoError;
|
||||
}
|
||||
|
||||
uint16 TCPStreamService::GetBoundPort() const {
|
||||
return boundPort;
|
||||
}
|
||||
|
||||
uint32 TCPStreamService::GetClientCount() const {
|
||||
uint32 n = 0u;
|
||||
topology.FastLock();
|
||||
for (uint32 i = 0u; i < numStreams; i++) {
|
||||
n += streams[i]->GetClientCount();
|
||||
}
|
||||
topology.FastUnLock();
|
||||
return n;
|
||||
}
|
||||
|
||||
uint32 TCPStreamService::GetStreamCount() const {
|
||||
return numStreams;
|
||||
}
|
||||
|
||||
uint32 TCPStreamService::GetWorkerCount() const {
|
||||
return workersCreated;
|
||||
}
|
||||
|
||||
uint64 TCPStreamService::GetClientDrops() const {
|
||||
uint64 n = 0u;
|
||||
topology.FastLock();
|
||||
for (uint32 i = 0u; i < numStreams; i++) {
|
||||
n += streams[i]->GetClientDrops();
|
||||
}
|
||||
topology.FastUnLock();
|
||||
return n;
|
||||
}
|
||||
|
||||
uint32 TCPStreamService::GetStallEvictions() const {
|
||||
return static_cast<uint32>(evictions);
|
||||
}
|
||||
|
||||
uint32 TCPStreamService::GetRejectedSubscriptions() const {
|
||||
return static_cast<uint32>(rejected);
|
||||
}
|
||||
|
||||
bool TCPStreamService::RegisterStream(TCPSServiceStream *s) {
|
||||
bool ok = true;
|
||||
// Held across the registration so observers see (un)registrations in order.
|
||||
(void)notifyMutex.Lock();
|
||||
topology.FastLock();
|
||||
if (numStreams >= maxStreams) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"Cannot register stream '%s': MaxStreams (%u) reached.",
|
||||
s->GetStreamName(), maxStreams);
|
||||
ok = false;
|
||||
}
|
||||
for (uint32 i = 0u; (i < numStreams) && ok; i++) {
|
||||
if (strcmp(streams[i]->GetStreamName(), s->GetStreamName()) == 0) {
|
||||
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||
"A stream named '%s' is already registered.", s->GetStreamName());
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
streams[numStreams] = s;
|
||||
numStreams++;
|
||||
}
|
||||
topology.FastUnLock();
|
||||
if (ok) {
|
||||
for (uint32 i = 0u; i < numObservers; i++) {
|
||||
observers[i]->OnStreamRegistered(s);
|
||||
}
|
||||
}
|
||||
(void)notifyMutex.UnLock();
|
||||
return ok;
|
||||
}
|
||||
|
||||
void TCPStreamService::UnregisterStream(TCPSServiceStream *s) {
|
||||
(void)notifyMutex.Lock();
|
||||
bool wasRegistered = false;
|
||||
topology.FastLock();
|
||||
for (uint32 i = 0u; i < numStreams; i++) {
|
||||
if (streams[i] == s) {
|
||||
streams[i] = streams[numStreams - 1u];
|
||||
numStreams--;
|
||||
wasRegistered = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
s->DropAllConns();
|
||||
topology.FastUnLock();
|
||||
if (wasRegistered) {
|
||||
for (uint32 i = 0u; i < numObservers; i++) {
|
||||
observers[i]->OnStreamUnregistered(s);
|
||||
}
|
||||
}
|
||||
(void)notifyMutex.UnLock();
|
||||
}
|
||||
|
||||
bool TCPStreamService::AddObserver(TCPSStreamObserverI *obs) {
|
||||
bool ok = false;
|
||||
(void)notifyMutex.Lock();
|
||||
if (numObservers < TCPS_MAX_OBSERVERS) {
|
||||
observers[numObservers] = obs;
|
||||
numObservers++;
|
||||
ok = true;
|
||||
// Replay: streams cannot (un)register while notifyMutex is held.
|
||||
topology.FastLock();
|
||||
const uint32 n = numStreams;
|
||||
TCPSServiceStream **snap = new TCPSServiceStream *[(n > 0u) ? n : 1u];
|
||||
for (uint32 i = 0u; i < n; i++) {
|
||||
snap[i] = streams[i];
|
||||
}
|
||||
topology.FastUnLock();
|
||||
for (uint32 i = 0u; i < n; i++) {
|
||||
obs->OnStreamRegistered(snap[i]);
|
||||
}
|
||||
delete[] snap;
|
||||
}
|
||||
(void)notifyMutex.UnLock();
|
||||
return ok;
|
||||
}
|
||||
|
||||
void TCPStreamService::RemoveObserver(TCPSStreamObserverI *obs) {
|
||||
(void)notifyMutex.Lock();
|
||||
for (uint32 i = 0u; i < numObservers; i++) {
|
||||
if (observers[i] == obs) {
|
||||
observers[i] = observers[numObservers - 1u];
|
||||
numObservers--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
(void)notifyMutex.UnLock();
|
||||
}
|
||||
|
||||
bool TCPStreamService::Attach(TCPSConn *c, char8 *streamList) {
|
||||
TCPSServiceStream *found[TCPS_MAX_CONN_STREAMS];
|
||||
uint32 n = 0u;
|
||||
bool ok = true;
|
||||
|
||||
topology.FastLock();
|
||||
char8 *p = streamList;
|
||||
while (ok) {
|
||||
char8 *comma = strchr(p, ',');
|
||||
if (comma != NULL_PTR(char8 *)) {
|
||||
*comma = '\0';
|
||||
}
|
||||
const uint32 len = static_cast<uint32>(strlen(p));
|
||||
TCPSServiceStream *match = NULL_PTR(TCPSServiceStream *);
|
||||
if ((len == 0u) || (len > TCPS_MAX_STREAM_NAME) || (n >= TCPS_MAX_CONN_STREAMS)) {
|
||||
ok = false;
|
||||
}
|
||||
for (uint32 i = 0u; ok && (i < numStreams) && (match == NULL_PTR(TCPSServiceStream *)); i++) {
|
||||
if (strcmp(streams[i]->GetStreamName(), p) == 0) {
|
||||
match = streams[i];
|
||||
}
|
||||
}
|
||||
for (uint32 i = 0u; ok && (i < n); i++) {
|
||||
if (found[i] == match) {
|
||||
ok = false; // the same stream listed twice
|
||||
}
|
||||
}
|
||||
if (ok && (match == NULL_PTR(TCPSServiceStream *))) {
|
||||
ok = false;
|
||||
}
|
||||
if (ok) {
|
||||
found[n] = match;
|
||||
n++;
|
||||
if (comma == NULL_PTR(char8 *)) {
|
||||
break;
|
||||
}
|
||||
p = comma + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
c->qMutex.FastLock();
|
||||
c->q.Reserve(n);
|
||||
c->qMutex.FastUnLock();
|
||||
uint32 attached = 0u;
|
||||
for (uint32 i = 0u; ok && (i < n); i++) {
|
||||
ok = found[i]->AttachConn(c, static_cast<uint16>(i));
|
||||
if (ok) {
|
||||
attached++;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
for (uint32 i = 0u; i < attached; i++) {
|
||||
found[i]->DetachConn(c);
|
||||
}
|
||||
} else {
|
||||
for (uint32 i = 0u; i < n; i++) {
|
||||
c->streams[i] = found[i];
|
||||
}
|
||||
c->numStreams = n;
|
||||
}
|
||||
}
|
||||
topology.FastUnLock();
|
||||
return ok;
|
||||
}
|
||||
|
||||
void TCPStreamService::Detach(TCPSConn *c) {
|
||||
topology.FastLock();
|
||||
for (uint32 i = 0u; i < c->numStreams; i++) {
|
||||
if (c->streams[i] != NULL_PTR(TCPSServiceStream *)) {
|
||||
c->streams[i]->DetachConn(c);
|
||||
c->streams[i] = NULL_PTR(TCPSServiceStream *);
|
||||
}
|
||||
}
|
||||
topology.FastUnLock();
|
||||
}
|
||||
|
||||
void TCPStreamService::ConnClosed() {
|
||||
Atomic::Decrement(&connCount);
|
||||
}
|
||||
|
||||
void TCPStreamService::NoteEviction() {
|
||||
Atomic::Increment(&evictions);
|
||||
}
|
||||
|
||||
void TCPStreamService::NoteRejected() {
|
||||
Atomic::Increment(&rejected);
|
||||
}
|
||||
|
||||
uint32 TCPStreamService::QueueDepth() const {
|
||||
return queueDepth;
|
||||
}
|
||||
|
||||
uint64 TCPStreamService::StallTicks() const {
|
||||
return stallTicks;
|
||||
}
|
||||
|
||||
uint64 TCPStreamService::HandshakeTicks() const {
|
||||
return handshakeTicks;
|
||||
}
|
||||
|
||||
uint32 TCPStreamService::MaxClients() const {
|
||||
return maxClients;
|
||||
}
|
||||
|
||||
CLASS_REGISTER(TCPStreamService, "1.0")
|
||||
|
||||
} // namespace MARTe
|
||||
@@ -0,0 +1,174 @@
|
||||
#ifndef TCPSTREAMSERVICE_H_
|
||||
#define TCPSTREAMSERVICE_H_
|
||||
|
||||
/**
|
||||
* @file TCPStreamService.h
|
||||
* @brief One in-process TCP streaming server shared by any number of
|
||||
* TCPStreamer DataSources, served by a pool of worker threads.
|
||||
*
|
||||
* @details Declared once, at the root of the configuration:
|
||||
* <pre>
|
||||
* +StreamService = {
|
||||
* Class = TCPStreamService
|
||||
* Port = 44500
|
||||
* Workers = 2
|
||||
* }
|
||||
* </pre>
|
||||
* and referenced from any number of DataSources:
|
||||
* <pre>
|
||||
* +Fast = { Class = TCPStreamer Service = StreamService StreamName = Fast ... }
|
||||
* +Slow = { Class = TCPStreamer Service = StreamService StreamName = Slow ... }
|
||||
* </pre>
|
||||
*
|
||||
* Wire protocol: plain UDPS framing over TCP, exactly like TCPSServer, plus one
|
||||
* client-to-server frame. Right after connecting, a client sends a SUBSCRIBE
|
||||
* frame (UDPS_TYPE_SUBSCRIBE, payload = stream name, 1..255 bytes). The service
|
||||
* then sends that stream's CONFIG followed by its DATA frames. One connection =
|
||||
* one stream. A connection that does not subscribe within HandshakeTimeout
|
||||
* seconds, or that names an unknown stream, is closed (clients retry).
|
||||
*
|
||||
* Threads: one acceptor plus `Workers` I/O threads. A connection lives on one
|
||||
* worker. Producer threads never touch sockets: they copy each frame into every
|
||||
* subscriber's bounded queue and poke the owning worker through a self-pipe, so
|
||||
* a slow client only loses its own frames and never delays a producer or
|
||||
* another client.
|
||||
*
|
||||
* @par Parameters (all optional)
|
||||
* | Parameter | Type | Default | Description |
|
||||
* |--------------------|--------|---------|-------------|
|
||||
* | Port | uint32 | 44500 | TCP listen port; 0 = ephemeral (see GetBoundPort()). |
|
||||
* | Workers | uint32 | 2 | I/O threads (1..32). |
|
||||
* | MaxClients | uint32 | 64 | Simultaneous connections (1..1024). |
|
||||
* | MaxStreams | uint32 | 32 | Registered streams (1..256). |
|
||||
* | ClientQueueDepth | uint32 | 8 | DATA frames queued per client (1..4096). |
|
||||
* | ClientStallTimeout | uint32 | 5 | Seconds without progress before eviction; 0 disables. |
|
||||
* | HandshakeTimeout | uint32 | 5 | Seconds allowed to send SUBSCRIBE. |
|
||||
* | SendBufferSize | uint32 | 0 | SO_SNDBUF for client sockets; 0 keeps the OS default. |
|
||||
* | CPUMask | uint32 | 0xFFFFFFFF | Affinity of the service threads. |
|
||||
* | StackSize | uint32 | 65536 | Stack of the service threads. |
|
||||
*/
|
||||
|
||||
#include "EmbeddedServiceMethodBinderI.h"
|
||||
#include "ExecutionInfo.h"
|
||||
#include "FastPollingMutexSem.h"
|
||||
#include "MutexSem.h"
|
||||
#include "Object.h"
|
||||
#include "SingleThreadService.h"
|
||||
#include "StructuredDataI.h"
|
||||
#include "TCPSStreamTapI.h"
|
||||
#include "UDPSProtocol.h"
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
class TCPSWorker;
|
||||
class TCPSServiceStream;
|
||||
struct TCPSConn;
|
||||
|
||||
/** Longest stream name accepted in a SUBSCRIBE frame. */
|
||||
static const uint32 TCPS_MAX_STREAM_NAME = 255u;
|
||||
/** Most streams one connection may multiplex. */
|
||||
static const uint32 TCPS_MAX_CONN_STREAMS = UDPS_TCP_MAX_STREAMS;
|
||||
/** Longest SUBSCRIBE payload: a comma separated list of stream names. */
|
||||
static const uint32 TCPS_MAX_SUBSCRIBE_PAYLOAD = UDPS_TCP_MAX_SUBSCRIBE_PAYLOAD;
|
||||
|
||||
class TCPStreamService : public Object, public EmbeddedServiceMethodBinderI {
|
||||
public:
|
||||
CLASS_REGISTER_DECLARATION()
|
||||
|
||||
TCPStreamService();
|
||||
virtual ~TCPStreamService();
|
||||
|
||||
/** Reads the parameters, opens the listening socket and starts the threads. */
|
||||
virtual bool Initialise(StructuredDataI &data);
|
||||
|
||||
/** Acceptor thread entry point; do not call directly. */
|
||||
virtual ErrorManagement::ErrorType Execute(ExecutionInfo &info);
|
||||
|
||||
/** @return the port actually bound. */
|
||||
uint16 GetBoundPort() const;
|
||||
/** @return subscribed connections across all streams. */
|
||||
uint32 GetClientCount() const;
|
||||
uint32 GetStreamCount() const;
|
||||
uint32 GetWorkerCount() const;
|
||||
/** @return DATA frames dropped for slow clients, summed over registered streams. */
|
||||
uint64 GetClientDrops() const;
|
||||
/** @return connections closed by the stall timeout (all time). */
|
||||
uint32 GetStallEvictions() const;
|
||||
/** @return connections closed for a bad / unknown SUBSCRIBE (all time). */
|
||||
uint32 GetRejectedSubscriptions() const;
|
||||
|
||||
/* ---- stream side ---- */
|
||||
/** @return false if a stream with this name is already registered or the table is full. */
|
||||
bool RegisterStream(TCPSServiceStream *s);
|
||||
/** Remove the stream and make its subscribers close. */
|
||||
void UnregisterStream(TCPSServiceStream *s);
|
||||
|
||||
/**
|
||||
* Be told when streams register / unregister. The streams already registered are
|
||||
* replayed to the observer before AddObserver returns. Notifications are serialised
|
||||
* (and may nest on one thread), they never run under the topology lock, and once
|
||||
* RemoveObserver returns no callback is running or will start.
|
||||
* @return false if the observer table is full.
|
||||
*/
|
||||
bool AddObserver(TCPSStreamObserverI *obs);
|
||||
void RemoveObserver(TCPSStreamObserverI *obs);
|
||||
|
||||
/* ---- worker side (internal) ---- */
|
||||
/**
|
||||
* Bind a connection to the streams named in @p streamList (comma separated,
|
||||
* modified in place). The position in the list is the stream index stamped
|
||||
* on every frame. All-or-nothing: @return false if any name is unknown,
|
||||
* duplicated or malformed.
|
||||
*/
|
||||
bool Attach(TCPSConn *c, char8 *streamList);
|
||||
void Detach(TCPSConn *c);
|
||||
void ConnClosed();
|
||||
void NoteEviction();
|
||||
void NoteRejected();
|
||||
uint32 QueueDepth() const;
|
||||
uint64 StallTicks() const;
|
||||
uint64 HandshakeTicks() const;
|
||||
/** Max subscribers a stream may hold. */
|
||||
uint32 MaxClients() const;
|
||||
|
||||
private:
|
||||
void Shutdown();
|
||||
|
||||
uint32 port;
|
||||
uint16 boundPort;
|
||||
uint32 numWorkers;
|
||||
uint32 maxClients;
|
||||
uint32 maxStreams;
|
||||
uint32 queueDepth;
|
||||
uint32 stallTimeoutS;
|
||||
uint32 handshakeTimeoutS;
|
||||
uint32 sendBufferSize;
|
||||
uint32 cpuMask;
|
||||
uint32 stackSize;
|
||||
uint64 stallTicks;
|
||||
uint64 handshakeTicks;
|
||||
|
||||
int listenFd;
|
||||
SingleThreadService acceptThread;
|
||||
bool acceptorStarted;
|
||||
TCPSWorker **workers;
|
||||
uint32 workersCreated;
|
||||
|
||||
/** Most observers (TCPStreamJoin objects) one service can feed. */
|
||||
static const uint32 TCPS_MAX_OBSERVERS = 16u;
|
||||
MutexSem notifyMutex; ///< recursive; serialises observer calls with (un)registration
|
||||
TCPSStreamObserverI *observers[TCPS_MAX_OBSERVERS];
|
||||
uint32 numObservers;
|
||||
|
||||
mutable FastPollingMutexSem topology; ///< guards streams[] and every TCPSConn::stream
|
||||
TCPSServiceStream **streams;
|
||||
uint32 numStreams;
|
||||
|
||||
volatile int32 connCount;
|
||||
volatile int32 evictions;
|
||||
volatile int32 rejected;
|
||||
};
|
||||
|
||||
} // namespace MARTe
|
||||
|
||||
#endif // TCPSTREAMSERVICE_H_
|
||||
@@ -0,0 +1,353 @@
|
||||
../../../..//Build/x86-linux/Components/Interfaces/TCPStreamService/TCPSFrameQueue.o: TCPSFrameQueue.cpp TCPSFrameQueue.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/HighResolutionTimer.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/L1Portability/Environment/Linux/GeneralDefinitions.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
|
||||
../../../..//Build/x86-linux/Components/Interfaces/TCPStreamService/TCPSServiceStream.o: TCPSServiceStream.cpp TCPSServiceStream.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/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/L1Portability/Architecture/x86_gcc/AtomicA.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/TemplateParametersVerificator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.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/L1Portability/Sleep.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Reference.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.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/L2Objects/ClassProperties.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.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/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/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/../Generic/StandardHeap_Generic.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/MemoryOperationsHelper.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/L3Streams/StreamString.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.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/L1Portability/FormatDescriptor.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
||||
TCPStreamService.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/L2Objects/Object.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/BareMetal/L2Objects/ReferenceContainer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.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/StructuredDataI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThread.h \
|
||||
../../../..//Common/UDP/UDPSProtocol.h \
|
||||
../../../..//Source/Components/Interfaces/UDPStream/UDPSTransportI.h \
|
||||
/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/L3Streams/StreamMemoryReference.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectRegistryDatabase.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceT.h \
|
||||
TCPSConn.h TCPSFrameQueue.h TCPSWorker.h
|
||||
../../../..//Build/x86-linux/Components/Interfaces/TCPStreamService/TCPStreamService.o: TCPStreamService.cpp TCPStreamService.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.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/L0Types/BitBoolean.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.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/Scheduler/L1Portability/Threads.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ThreadsB.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/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/ExceptionHandler.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.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/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/ErrorInformation.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/L1Portability/Sleep.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.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/L2Objects/ClassProperties.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.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/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/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/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/../Generic/StandardHeap_Generic.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/MemoryOperationsHelper.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/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/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/L1Portability/TimeoutType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThread.h \
|
||||
../../../..//Common/UDP/UDPSProtocol.h \
|
||||
/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/ErrorManagement.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/L2Objects/AnyType.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/L1Portability/Atomic.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||
TCPSConn.h TCPSFrameQueue.h TCPSServiceStream.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
||||
../../../..//Source/Components/Interfaces/UDPStream/UDPSTransportI.h \
|
||||
TCPSWorker.h
|
||||
../../../..//Build/x86-linux/Components/Interfaces/TCPStreamService/TCPSWorker.o: TCPSWorker.cpp TCPSWorker.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.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/L0Types/BitBoolean.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.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/Scheduler/L1Portability/Threads.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ThreadsB.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/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/ExceptionHandler.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.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/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/ErrorInformation.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/L1Portability/Sleep.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/BareMetal/L2Objects/Object.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.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/L2Objects/ClassProperties.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.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/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/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/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/../Generic/StandardHeap_Generic.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/MemoryOperationsHelper.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/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/L1Portability/TimeoutType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThread.h \
|
||||
/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/ErrorManagement.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/L2Objects/AnyType.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/L1Portability/Atomic.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||
TCPSConn.h TCPSFrameQueue.h TCPStreamService.h \
|
||||
../../../..//Common/UDP/UDPSProtocol.h
|
||||
@@ -0,0 +1,353 @@
|
||||
TCPSFrameQueue.o: TCPSFrameQueue.cpp TCPSFrameQueue.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/HighResolutionTimer.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/L1Portability/Environment/Linux/GeneralDefinitions.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
|
||||
TCPSServiceStream.o: TCPSServiceStream.cpp TCPSServiceStream.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/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/L1Portability/Architecture/x86_gcc/AtomicA.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/TemplateParametersVerificator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.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/L1Portability/Sleep.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Reference.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.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/L2Objects/ClassProperties.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.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/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/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/../Generic/StandardHeap_Generic.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/MemoryOperationsHelper.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/L3Streams/StreamString.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.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/L1Portability/FormatDescriptor.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
||||
TCPStreamService.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/L2Objects/Object.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/BareMetal/L2Objects/ReferenceContainer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.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/StructuredDataI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThread.h \
|
||||
../../../..//Common/UDP/UDPSProtocol.h \
|
||||
../../../..//Source/Components/Interfaces/UDPStream/UDPSTransportI.h \
|
||||
/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/L3Streams/StreamMemoryReference.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectRegistryDatabase.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceT.h \
|
||||
TCPSConn.h TCPSFrameQueue.h TCPSWorker.h
|
||||
TCPStreamService.o: TCPStreamService.cpp TCPStreamService.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.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/L0Types/BitBoolean.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.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/Scheduler/L1Portability/Threads.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ThreadsB.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/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/ExceptionHandler.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.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/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/ErrorInformation.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/L1Portability/Sleep.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.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/L2Objects/ClassProperties.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.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/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/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/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/../Generic/StandardHeap_Generic.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/MemoryOperationsHelper.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/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/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/L1Portability/TimeoutType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThread.h \
|
||||
../../../..//Common/UDP/UDPSProtocol.h \
|
||||
/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/ErrorManagement.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/L2Objects/AnyType.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/L1Portability/Atomic.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||
TCPSConn.h TCPSFrameQueue.h TCPSServiceStream.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
||||
../../../..//Source/Components/Interfaces/UDPStream/UDPSTransportI.h \
|
||||
TCPSWorker.h
|
||||
TCPSWorker.o: TCPSWorker.cpp TCPSWorker.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.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/L0Types/BitBoolean.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.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/Scheduler/L1Portability/Threads.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ThreadsB.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/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/ExceptionHandler.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.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/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/ErrorInformation.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/L1Portability/Sleep.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/BareMetal/L2Objects/Object.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.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/L2Objects/ClassProperties.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.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/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/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/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/../Generic/StandardHeap_Generic.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/MemoryOperationsHelper.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/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/L1Portability/TimeoutType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThread.h \
|
||||
/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/ErrorManagement.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/L2Objects/AnyType.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/L1Portability/Atomic.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||
TCPSConn.h TCPSFrameQueue.h TCPStreamService.h \
|
||||
../../../..//Common/UDP/UDPSProtocol.h
|
||||
Reference in new issue
Block a user