Implemented new C++ logic
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
#ifndef UDPS_CLIENT_H_
|
||||
#define UDPS_CLIENT_H_
|
||||
|
||||
/**
|
||||
* @file UDPSClient.h
|
||||
* @brief Auto-reconnecting UDPS receiver client (C++ MARTe2 library class).
|
||||
*
|
||||
* UDPSClient runs its own background thread (via SingleThreadService).
|
||||
* On start it connects to a UDPSServer, receives CONFIG + DATA packets, and
|
||||
* reassembles fragmented updates. If the server goes silent for longer than
|
||||
* SilenceTimeout, it automatically disconnects and retries.
|
||||
*
|
||||
* Unicast mode: sends CONNECT to server UDP port; receives on an ephemeral UDP port.
|
||||
* Multicast mode: TCP to server port for CONFIG; joins UDP multicast group for DATA.
|
||||
*
|
||||
* Threading: UDPSClientListener callbacks are invoked from the internal receive
|
||||
* thread — the implementation must be thread-safe with respect to the caller.
|
||||
*/
|
||||
|
||||
#include "BasicTCPSocket.h"
|
||||
#include "BasicUDPSocket.h"
|
||||
#include "EmbeddedServiceMethodBinderI.h"
|
||||
#include "ExecutionInfo.h"
|
||||
#include "HighResolutionTimer.h"
|
||||
#include "InternetHost.h"
|
||||
#include "SingleThreadService.h"
|
||||
#include "StreamString.h"
|
||||
#include "StructuredDataI.h"
|
||||
#include "UDPSProtocol.h"
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Listener interface
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Callback interface for UDPSClient events.
|
||||
*
|
||||
* Implement this interface and pass an instance to UDPSClient::SetListener().
|
||||
* All callbacks are invoked from the UDPSClient internal thread.
|
||||
*/
|
||||
class UDPSClientListener {
|
||||
public:
|
||||
virtual ~UDPSClientListener() {}
|
||||
|
||||
/** Called when a fully-reassembled CONFIG payload is available. */
|
||||
virtual void OnUDPSConfig(const uint8 *payload, uint32 payloadSize) {}
|
||||
|
||||
/** Called when a fully-reassembled DATA payload is available. */
|
||||
virtual void OnUDPSData(const uint8 *payload, uint32 payloadSize) {}
|
||||
|
||||
/**
|
||||
* @brief Called for every received DATA datagram (fragment).
|
||||
* @param counter DATA packet counter from the UDPS header.
|
||||
* @param nBytes Raw datagram size (header + payload).
|
||||
* @param complete True iff this fragment completed the DATA reassembly.
|
||||
*/
|
||||
virtual void OnUDPSFragment(uint32 counter, uint32 nBytes, bool complete) {}
|
||||
|
||||
/** Called when the connection to the server has been established. */
|
||||
virtual void OnUDPSConnected() {}
|
||||
|
||||
/** Called when the connection has been lost or closed. */
|
||||
virtual void OnUDPSDisconnected() {}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// UDPSClient
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief UDPS receiver client with auto-reconnect and fragment reassembly.
|
||||
*/
|
||||
class UDPSClient : public EmbeddedServiceMethodBinderI {
|
||||
public:
|
||||
|
||||
/** Maximum number of concurrent in-flight reassembly slots. */
|
||||
static const uint32 UDPS_CLIENT_MAX_REASSEMBLY_SLOTS = 4u;
|
||||
|
||||
/** Default silence timeout before reconnect (seconds). */
|
||||
static const uint32 UDPS_CLIENT_DEFAULT_SILENCE_TIMEOUT_S = 5u;
|
||||
|
||||
/** Default delay between reconnect attempts (seconds). */
|
||||
static const uint32 UDPS_CLIENT_DEFAULT_RECONNECT_DELAY_S = 2u;
|
||||
|
||||
/** Default maximum payload size (bytes, excluding 17-byte header). */
|
||||
static const uint32 UDPS_CLIENT_DEFAULT_MAX_PAYLOAD = 1400u;
|
||||
|
||||
UDPSClient();
|
||||
virtual ~UDPSClient();
|
||||
|
||||
/**
|
||||
* @brief Read configuration from a StructuredDataI node.
|
||||
*
|
||||
* Expected keys:
|
||||
* - ServerAddr (char*) Server IPv4 address. Required.
|
||||
* - Port (uint16) Server UDP port (unicast) or TCP listen port (multicast). Required.
|
||||
* - MulticastGroup (char*) IPv4 multicast address; presence enables multicast mode.
|
||||
* - DataPort (uint16) UDP multicast data port (defaults to Port+1).
|
||||
* - SilenceTimeout (uint32) Seconds of no data before reconnect. Default 5.
|
||||
* - ReconnectDelay (uint32) Seconds to wait between reconnect attempts. Default 2.
|
||||
* - MaxPayloadSize (uint32) Max payload bytes per datagram, excluding header. Default 1400.
|
||||
* - CPUMask (uint32) CPU affinity mask for the receive thread. Default 0xFFFFFFFF.
|
||||
* - StackSize (uint32) Stack size for the receive thread. Default 65536.
|
||||
*/
|
||||
bool Initialise(StructuredDataI &data);
|
||||
|
||||
/**
|
||||
* @brief Register the event listener. Must be called before Start().
|
||||
*/
|
||||
void SetListener(UDPSClientListener *listener);
|
||||
|
||||
/**
|
||||
* @brief Start the receive thread.
|
||||
* @return true on success.
|
||||
*/
|
||||
bool Start();
|
||||
|
||||
/**
|
||||
* @brief Stop the receive thread and close all sockets.
|
||||
* @return true on success.
|
||||
*/
|
||||
bool Stop();
|
||||
|
||||
/**
|
||||
* @brief Internal thread entry point (EmbeddedServiceMethodBinderI).
|
||||
* @details Do NOT call directly.
|
||||
*/
|
||||
virtual ErrorManagement::ErrorType Execute(ExecutionInfo &info);
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Fragment reassembly slot
|
||||
// -------------------------------------------------------------------------
|
||||
struct UDPSReassemblySlot {
|
||||
uint32 counter; ///< Packet counter this slot belongs to
|
||||
uint8 type; ///< UDPS_TYPE_DATA or UDPS_TYPE_CONFIG
|
||||
uint16 totalFragments; ///< Expected fragment count
|
||||
uint16 receivedFragments; ///< How many we have so far
|
||||
uint8 recvMask[32]; ///< Bitmask: bit f set iff fragment f received
|
||||
uint8 payload[65535]; ///< Assembled payload buffer
|
||||
uint64 firstSeenTicks; ///< For GC (2 s stale detection)
|
||||
bool active; ///< Slot in use
|
||||
uint32 chunkSize; ///< Payload bytes per fragment (from first fragment)
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Connection state machine helpers
|
||||
// -------------------------------------------------------------------------
|
||||
bool Connect();
|
||||
void Disconnect();
|
||||
bool ReceiveAndProcess();
|
||||
|
||||
bool ConnectUnicast();
|
||||
bool ConnectMulticast();
|
||||
|
||||
void ProcessDatagram(const uint8 *buf, uint32 size);
|
||||
/** Read one full UDPS frame (header + payload) from the TCP control socket. */
|
||||
bool ReceiveTCPFrame();
|
||||
/** Read exactly n bytes from the TCP control socket. */
|
||||
bool ReadExactTCP(uint8 *dst, uint32 n);
|
||||
/** @return true iff this fragment completed the reassembly (payload delivered). */
|
||||
bool PlaceFragment(const UDPSPacketHeader *hdr, const uint8 *payload, uint32 payloadBytes);
|
||||
void GcReassemblySlots();
|
||||
void DeliverAssembled(UDPSReassemblySlot &slot);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Configuration
|
||||
// -------------------------------------------------------------------------
|
||||
StreamString serverAddr;
|
||||
uint16 serverPort;
|
||||
StreamString multicastGroup;
|
||||
uint16 dataPort;
|
||||
bool useMulticast;
|
||||
uint64 silenceTimeoutTicks;
|
||||
uint64 reconnectDelayTicks;
|
||||
uint32 maxPayloadSize;
|
||||
uint32 cpuMask;
|
||||
uint32 stackSize;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Runtime state
|
||||
// -------------------------------------------------------------------------
|
||||
UDPSClientListener *listener;
|
||||
SingleThreadService threadService;
|
||||
bool connected;
|
||||
uint64 lastDataTicks; ///< Ticks at last received DATA/CONFIG
|
||||
uint64 disconnectTick; ///< Ticks when we disconnected (for delay)
|
||||
|
||||
// Unicast
|
||||
BasicUDPSocket recvSocket; ///< Bound to ephemeral port; receives DATA
|
||||
uint16 localPort; ///< Ephemeral port we're listening on
|
||||
|
||||
// Multicast
|
||||
BasicTCPSocket tcpSocket; ///< TCP connection to server (for CONNECT + CONFIG)
|
||||
BasicUDPSocket mcastSocket; ///< Joined multicast group
|
||||
|
||||
// Reassembly
|
||||
UDPSReassemblySlot reassemblySlots[UDPS_CLIENT_MAX_REASSEMBLY_SLOTS];
|
||||
uint64 lastGcTicks; ///< Ticks at last GC run
|
||||
|
||||
// Receive scratch buffer
|
||||
uint8 recvBuf[65535u + UDPS_HEADER_SIZE];
|
||||
};
|
||||
|
||||
} // namespace MARTe
|
||||
|
||||
#endif // UDPS_CLIENT_H_
|
||||
Reference in New Issue
Block a user