OpenDDS / OpenDDS

OpenDDS is an open source C++ implementation of the Object Management Group (OMG) Data Distribution Service (DDS). OpenDDS also supports Java bindings through JNI.
http://www.opendds.org
Other
1.29k stars 465 forks source link

Right configuration for DDS communication between two apps in android #2148

Closed itej89 closed 2 years ago

itej89 commented 3 years ago

Hi, I'm trying to establish DDS communication between two android apps. I've tried multiple combinations of configuration. But, none able to send the actual message to the subscriber app from the publisher app.

when i run publisher and subscriber in the same app, the data is being received by subscriber.

I'm using same Idl generated libraries and code inside both the apps.

I see below message in publisher log. Does it mean it is unable to discover the subscriber?

TransportClient::send_i: no links for publication 0103fbfe.96255494.660ce64a.00000002(2b29a9ae), not sending element 0x8dd125c8 for transaction: 0.

With below configuration I see SAMPLE DATA exchanging between two apps. But, actual message is not recieved.

Subscriber Config:

[common]
DCPSGlobalTransportConfig=$file
DCPSDebugLevel=10
DCPSTransportDebugLevel=5
ORBVerboseLogging=1
ORBDebugLevel=10

[domain/42]
DiscoveryConfig=uni_rtps

[rtps_discovery/uni_rtps]
SedpMulticast=0
ResendPeriod=2
SedpLocalAddress=localhost:8895
SpdpSendAddrs=localhost:8894, localhost:8813

[transport/the_rtps_transport]
transport_type=rtps_udp
use_multicast=0
local_address=localhost:8812

Publisher Config:

[common]
DCPSGlobalTransportConfig=$file
DCPSDebugLevel=10
DCPSTransportDebugLevel=5
ORBVerboseLogging=1
ORBDebugLevel=10

[domain/42]
DiscoveryConfig=uni_rtps

[rtps_discovery/uni_rtps]
SedpMulticast=0
ResendPeriod=2
SedpLocalAddress=localhost:8894
SpdpSendAddrs=localhost:8895, localhost:8812

[transport/the_rtps_transport]
transport_type=rtps_udp
use_multicast=0
local_address=localhost:8813

Please find the publisher and subscriber logs attached below

Publisher.log Subscriber.log

OpenDDS Version : This is OpenDDS version 3.14.1, released Nov 20 2020 ARM arch : arm-v7a API : 24 NDK : r21

I would be great full, if anyone would suggest what might be wrong with my configuration.

Thanks in advance!

jrw972 commented 3 years ago

I don't know if localhost will work on Android but your config has other issues. First, some "theory." RTPS discovery uses two ports: one for SPDP and one for SEDP. An RTPS transport uses one port. SEDP for the subscriber is on port 8895 and SEDP for the publisher is on port 8894. SPDP is using the default address.

The SPDP for the subscriber is sending to ports 8894 and 8813. This is incorrect since these ports aren't speaking SPDP. The SPDP for the publisher is sending to ports 8895 and 8812. This is incorrect since these ports aren't speaking SPDP. In general, it is not necessary to specify all of these addresses. OpenDDS will use dynamic ports which will be exchanged through discovery.

Your log files contain the same error where both the publisher and subscriber could not join the multicast group for SPDP. Search for ERROR. I'm not sure if this is a limitation on Android but I recommend cleaning up your config files and trying again.

itej89 commented 3 years ago

@jrw972

As suggested I've cleaned up the config and switch to dynamic configuration.

I still observed the multicast join error.

I looked up for android multicast support. Android java documentation says it supports multicast as below. https://developer.android.com/reference/java/net/MulticastSocket

Could this be an ACE multicast compatibility issue with android?

This is the simple config i've used for both subscriber and publisher apps

[common]
DCPSGlobalTransportConfig=$file
DCPSDebugLevel=10
DCPSTransportDebugLevel=5
ORBVerboseLogging=1
ORBDebugLevel=10

[domain/42]
DiscoveryConfig=uni_rtps

[rtps_discovery/uni_rtps]
ResendPeriod=2

[transport/the_rtps_transport]
transport_type=rtps_udp

and these are the logs generated by the application Publisher.log Subscriber.log

I've gone through the "dds/DCPS/RTPS/spdp.cpp" implementation, it is calling ACE join method. Is there anything I can change there to test further?

Any suggestions on what my next steps should be? :)

Thank you!

iguessthislldo commented 3 years ago
2020-12-12 00:56:33.410 22001-22001/fm.ani.ddsserver I/ACE: (22001|22001) Spdp::SpdpTransport::join_multicast_group joining group lo 239.255.0.1:17900
2020-12-12 00:56:33.410 22001-22001/fm.ani.ddsserver E/ACE: (22001|22001) ERROR: Spdp::SpdpTransport::join_multicast_group() - failed to join multicast group 239.255.0.1:17900 ACE_SOCK_Dgram_Mcast::join: Operation not supported on transport endpoint

The error is for the failing to join the multicast group of the loopback interface and I get the same error with an older OpenDDS messenger example I have on my phone when I put it into airplane mode. So it looks like loopback on Android doesn't support multicast, at least how we're trying to do. Also I don't think that's unusual for Linux since multicast is something routers are normally in charge of doing. This shouldn't really shouldn't be a problem in most cases because OpenDDS will join another interface's multicast group, like wifi in your case:

2020-12-12 00:56:33.410 22001-22001/fm.ani.ddsserver I/ACE: (22001|22001) Spdp::SpdpTransport::join_multicast_group joining group wlan0 239.255.0.1:17900

Else it will wait for an interface to come up.

itej89 commented 3 years ago

@iguessthislldo hi, thanks for the info. you are right. I've observed the rtps multicast messges broadcasted over wifi network.

But no events are being triggered in participant listener that I've provided to create_participant.

Sorry if i'm asking too many queries. Is there anyway to figure out where spdp/sedp might be failing?

I can confirm that publish subscribe works fine when i run from the same app (or in this case same participant).

Thank you!

iguessthislldo commented 3 years ago
2020-12-12 00:58:26.016 22233-22233/fm.ani.ddsclient D/ACE: (22233|22233) TransportClient::send_i: no links for publication 01037a00.83e1d3e3.56d9defe.00000002(b1a5dfe8), not sending element 0x800ccdc8 for transaction: 0.

So this means the reader still wasn't discovered.

Looking at the timestamps from the last two logs the times are different. Subscriber goes from 00:56:33 to 00:56:35 and then Publisher goes from 00:57:17 to 00:58:26. Are the clocks of the two devices that different or are the Subscriber logs just incomplete?

itej89 commented 3 years ago

Looking at the timestamps from the last two logs the times are different. Subscriber goes from 00:56:33 to 00:56:35 and then Publisher goes from 00:57:17 to 00:58:26. Are the clocks of the two devices that different or are the Subscriber logs just incomplete?

@iguessthislldo the logs are generated from two different apps running on same device. The publisher is running in one app and subscriber in another using same IDL generated files for topic creation. The difference in time might have occured because i've started the second app after some time.

I'm debugging both apps at the same time. So I ran the subscriber app first and then the publisher app

This is the OpenDDS Service on subscriber side I've implemented using Smart lock app code.

OpenDDsService.txt

The same code i'm using on publisher app with a call to CreatePublisher instead of CreateSubscriber.

I'm doubting on QOS policies. Because the ones defined in smartlock are for RTPSRelay. I've removed the "OpenDDS.RtpsRelay.Group" property to check if its causing any problem. But, It did not work.

I've tried using PARTICIPANT_DEFAULT_QOS as well. Please recommend if i need to change QOS settings of any other entities.

iguessthislldo commented 3 years ago

I'm debugging both apps at the same time. So I ran the subscriber app first and then the publisher app

Could you clarify what you mean by the same time? If you're using something like multi-window mode it should work. If you're just running one app, then asking Android Studio to start the other, then I'm not sure that's going to work even with the service, or at least it wasn't a goal we had in mind. The goal of the service was just to keep OpenDDS running during something like a change in orientation.

itej89 commented 3 years ago

Could you clarify what you mean by the same time? If you're using something like multi-window mode it should work.

@iguessthislldo Thank you for the response! No i'm not running in multi window mode.

Please correct me if i'm wrong. I understand your concern about one of the service running in the background app. To solve the problem I've used "JobService". I believe that should keep it running in the background.

My usecase does not allow me to use multiple windows. I'm writing a system app with a service that is interfaced to a USB hardware. The normal apps will talk to this service to control that hardware

With OpenDDS the same service could talk to apps hosted on same host and external hosts as well. So, I thought of using OpenDDS as IPC instead of Android Binder IPC framework.

lqxandxl commented 3 years ago

I also encountered a similar problem. It's just that I am using the example under the path of OpenDDS-3.15\tests\DCPS\Messenger on two windows machines. Use rtps.ini configuration file for communication. Two programs can communicate on one machine, but not on different machines. Is it because the multicast protocol does not work properly under the router? What is the reason for not being able to discover each other?

[common]
DCPSGlobalTransportConfig=$file
DCPSDefaultDiscovery=DEFAULT_RTPS

[transport/the_rtps_transport]
transport_type=rtps_udp
jrw972 commented 3 years ago

It could be problem with the router. Have you examined the logs for errors?

lqxandxl commented 3 years ago

@jrw972 Finally, I found the reason, because the vmware on the machine installed a virtual network card which caused interference. If the machine has a virtual network card, how to set up opendds?

jrw972 commented 3 years ago

In general, an OpenDDS participant publishes locators (IP address:port) that describe where it can be contacted. This means that

  1. OpenDDS must be configured correctly for your environment. I recommend reading the relevant sections in the developer's guide about the transport(s) that you are using http://download.objectcomputing.com/OpenDDS/OpenDDS-latest.pdf
  2. Firewalls, routers, NAT, etc. need to configured correctly and/or addressed.
spiffware commented 2 years ago

I had this same issue - even the simplest RTPS configuration would not work. It turned out my CentOS 8 VM had the firewall turned on, and it was filtering out all multicast traffic. I opted to disable the firewall.

I have not tried this, but it might also have been corrected by adding the appropriate iptables rules:

sudo iptables -A INPUT -s 224.0.0.0/4 -j ACCEPT
sudo iptables -A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT
sudo iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT