fix: UDPSClient uses two-arg Join so multicast receiver lands on the right interface
UDPSClient::ConnectMulticast was calling the single-arg BasicUDPSocket::Join, which forwards NULL as the local interface and lets the kernel bind to INADDR_ANY. On a multi-homed host (or when the server sends on loopback via Interface = "127.0.0.1") the client joins the wrong interface and silently receives nothing. Fix: read the optional Interface key inside the useMulticast block in UDPSClient::Initialise; in ConnectMulticast call the two-arg Join(group, interface) when Interface is set, and fall back to the one-arg call otherwise to preserve the existing INADDR_ANY behaviour for configs that omit it. Forward the new optional Interface key through UDPStreamerClient (read from DataSource config, written into the UDPSClient ConfigurationDatabase only when non-empty). Extend the "Joined multicast group" log to report the interface name or "default". Regression test TestExecute_MulticastReceivesDataOnInterface: mock TCP control listener + multicast UDP DATA socket with IP_MULTICAST_IF set to 127.0.0.1, verifying a uint32 value of 424242 reaches DataSource signal memory. Confirmed FAILED without the Join fix and PASSED with it. Suite: 133/133 (was 132/132 before this commit). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
61a2aa3988
commit
14d5351a81
@@ -298,6 +298,50 @@ PrepareNextState() ← opens UDP server socket, starts background threa
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## UDPStreamerClient DataSource
|
||||
|
||||
`UDPStreamerClient` is a MARTe2 **input** DataSource that receives signals from a `UDPStreamer`
|
||||
server. Transport, fragment reassembly, and auto-reconnect are delegated to `UDPSClient`; the
|
||||
DataSource only decodes CONFIG/DATA payloads into real-time signal memory.
|
||||
|
||||
### Configuration
|
||||
|
||||
```
|
||||
+ClientDS = {
|
||||
Class = UDPStreamerClient
|
||||
ServerAddress = "192.168.1.10" // UDPStreamer server IP
|
||||
Port = 44500 // Server port
|
||||
|
||||
// Multicast (optional — omit for unicast)
|
||||
MulticastGroup = "239.0.0.1"
|
||||
DataPort = 44501 // UDP data port (default: Port+1)
|
||||
Interface = "192.168.1.10" // See table below
|
||||
|
||||
MaxPayloadSize = 1400
|
||||
|
||||
Signals = {
|
||||
Counter = { Type = uint32 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| --------------- | ------- | ---------- | ----------- |
|
||||
| `ServerAddress` | string | 127.0.0.1 | IPv4 address of the `UDPStreamer` server. |
|
||||
| `Port` | uint16 | 44500 | Server UDP port (unicast) or TCP control port (multicast). |
|
||||
| `MulticastGroup`| string | *(absent)* | IPv4 multicast address. Presence enables multicast mode. |
|
||||
| `DataPort` | uint16 | Port+1 | UDP port for multicast DATA datagrams. |
|
||||
| `Interface` | string | *(absent)* | Local IPv4 dotted-quad address (e.g. `"127.0.0.1"`) of the interface to join the multicast group on. **Optional**: omitting it uses the default-route interface (INADDR_ANY), which silently receives nothing if the server sends on a different interface. Not an interface name — `"eth0"` is invalid. |
|
||||
| `MaxPayloadSize`| uint32 | 1400 | Max payload bytes per datagram (must match the server). |
|
||||
| `SilenceTimeout`| float32 | 1.0 | Seconds of no data before auto-reconnect. 0 disables. |
|
||||
| `KeepAliveInterval` | uint32 | 15 | Seconds between unicast keepalive ACKs. 0 disables. |
|
||||
| `CPUMask` | uint32 | 0xFFFFFFFF | CPU affinity for the background receiver thread. |
|
||||
| `StackSize` | uint32 | default | Stack size in bytes for the receiver thread. |
|
||||
|
||||
With `MaxPayloadSize = 1400`, a single 1000-element float32 signal produces:
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user