eProsima / Fast-DDS

The most complete DDS - Proven: Plenty of success cases. Looking for commercial support? Contact info@eprosima.com
https://eprosima.com
Apache License 2.0
2.12k stars 757 forks source link

Issues disabling multicast for WIFI use case [12505] #2201

Closed mcelhennyi closed 2 years ago

mcelhennyi commented 2 years ago

I am having trouble getting two sides of my application to talk to one another over a wifi network where one is running on the AP (Jetson AGX) and the other side is running on a client (Laptop). I have a high data rate use case and need to disable multicast as I presume its causing my delays.

I have, on both sides, set the following qos policies.

eprosima::fastrtps::rtps::Locator_t locator; // default locator means all interfaces to DDS
pqos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(locator);
...
pqos.wire_protocol().builtin.discovery_config.initial_announcements.count = 5;
pqos.wire_protocol().builtin.discovery_config.initial_announcements.period = Duration_t(0, 100000000u);
...
eprosima::fastrtps::rtps::Locator_t initial_peer;
eprosima::fastrtps::rtps::IPLocator::setIPv4(initial_peer, peerIp);
pqos.wire_protocol().builtin.initialPeersList.push_back(eprosima::fastrtps::rtps::IPLocator::setIPv4(initial_peer, "10.10.0.1")); // or 10.10.0.3 depending on the side of the application. This is set to the other persons IP

However I see no RTPS traffic or even UDP traffic between these two devices on wireshark.

Any ideas? Did I miss something? From what I could gather from the docs its the initial peers list and the unicast discovery that needs to be set.

I should say, that when my application is running (and not running) I do see ARP messages between the AP and my laptop on wireshark which tells me the two devices want to talk to each other.

mcelhennyi commented 2 years ago

In addition I am also setting these qos policies:

// Set the transports - all is buggy on jetson
std::shared_ptr<eprosima::fastdds::rtps::TCPv4TransportDescriptor> tcp4Transport =
        std::make_shared<fastdds::rtps::TCPv4TransportDescriptor>();
std::shared_ptr<eprosima::fastdds::rtps::UDPv4TransportDescriptor> udp4Transport =
        std::make_shared<fastdds::rtps::UDPv4TransportDescriptor>();

pqos.transport().user_transports.emplace_back(tcp4Transport);
pqos.transport().user_transports.emplace_back(udp4Transport);
pqos.transport().use_builtin_transports = false; // disable all - use only specified above ones

pqos.wire_protocol().builtin.discovery_config.ignoreParticipantFlags =
        static_cast<eprosima::fastrtps::rtps::ParticipantFilteringFlags_t>(
                fastrtps::rtps::ParticipantFilteringFlags_t::FILTER_SAME_PROCESS
            );

I also tried pqos.wire_protocol().builtin.avoid_builtin_multicast = true;

MiguelCompany commented 2 years ago

@mcelhennyi I think the main problem here is the way you are setting the initial peers.

Instead of pqos.wire_protocol().builtin.initialPeersList.push_back(eprosima::fastrtps::rtps::IPLocator::setIPv4(initial_peer, "10.10.0.1")); just do pqos.wire_protocol().builtin.initialPeersList.push_back(initial_peer)

That part of the code would finally look as follows:

eprosima::fastrtps::rtps::Locator_t initial_peer;
eprosima::fastrtps::rtps::IPLocator::setIPv4(initial_peer, "10.10.0.1"); // or 10.10.0.3 depending on the side of the application. This is set to the other persons IP
pqos.wire_protocol().builtin.initialPeersList.push_back(initial_peer); 

I would also only use UDP transport. TCP transport is not going to be used with the initial peers you are setting up here.

mcelhennyi commented 2 years ago

That was exactly it, must have been a bad copy paste. Thanks!

Might be a good idea to mark the constructors of the Locator_t as explicit to make sure copy constructor of a bool to a Locator_t does not happen like this.

mcelhennyi commented 2 years ago

The only thing that doesnt seem to work is that I cannot set the initial peer after I setup my participant/publisher/subscriber.

Some time after I set those up, I then set the initial peer like so:

std::string _remoteIp = "10.10.0.3"; // or 10.10.0.1 depending on side
...
eprosima::fastrtps::rtps::Locator_t initial_peer;
eprosima::fastrtps::rtps::IPLocator::setIPv4(initial_peer, _remoteIp);
auto qos = _participant->get_qos();
qos.wire_protocol().builtin.initialPeersList.push_back(initial_peer);
if(_participant->set_qos(qos) != ReturnCode_t::RETCODE_OK)
{
    SPDLOG_ERROR(getModuleTag() + "Failed to add peers to initial peer list. {}", ipAddress);
    return false;
}

I get Retcode RETCODE_IMMUTABLE_POLICY.

Do I need to do something to the publisher/subscriber for this to work? Or is this method not supported (i thought I had read it was somewhere)?

MiguelCompany commented 2 years ago

I get Retcode RETCODE_IMMUTABLE_POLICY

As depicted in the documentation, the wire_protocol qos is not mutable, and cannot be changed after the participant has been enabled.

If you know in advance the list of addresses where a participant could be, you could add them all to the initial-peers list before enabling the participant.

In order to avoid multicast discovery on a system where the participants may be on unknown addresses, you may consider using discovery server

JLBuenoLopez commented 2 years ago

I am going to close the issue because it has been answered and it has not been any feedback in the last few months. Please, feel free to reopen if there is any related issue or open a new ticket if needed.