Communication between Windows DDS Micro and Embedded Board

8 posts / 0 new
Last post
Offline
Last seen: 4 years 11 months ago
Joined: 07/02/2019
Posts: 5
Communication between Windows DDS Micro and Embedded Board

Hi all,

It will be really great if someone could answer my questions, because I have been trying to get the communication working successfully between my Windows PC and Embedded Board using Connext DDS Micro 3.0.0.

Any kind of help will be more than appreciated to get the communication working between my Embedded Board(Publisher) and my Windows PC(Subscriber) for HelloWorld_dpde example in C.

I am using Connext DDS Micro 3.0.0 and trying to communicate between Windows 7 machine and an ARM based Real Time Architecture microcontroller board with FreeRTOS and lwIP.

To begin with Embedded Board settings:-

1) I have successfully been able to send and receive the message on the same Embedded Board.

The structure of the code is as follows in the main thread:-

  • Get the RT Registry from the DomainParticipantFactory singleton
  • Register Writer History
  • Register Reader History
  • Register DPDE
  • Unregister the pre-registered UDP component
  • Configure UDP transport properties
  • Re-register UDP component with updated properties
  • Participant is created
  • Register Data types that have been generated from IDL with the DomainParticipants
  • Create topic
  • Subscriber is created
  • DataReader is created
  • Publisher is created
  • DataWriter is created

Q-1) With respect to UDP transport as I am using FreeRTOS, what should I define the allow_interface as? As, for DDS Micro in Windows, it is defined as the required interface name according to my Machine which is necessary I suppose for the locators to be set. So, does it have any impact directly setting my locators automatically on the board?

Code used on Embedded Board:-

 /* Unregister the pre-registered UDP component */

       if (!RT_Registry_unregister(registry, "_udp", NULL, NULL))

       {

           /* failure */ printf("Unregistration of pre-registered UDP component failed\n");

       }

 

/*Configure UDP transport properties:*/

       printf("STARTED Configure UDP transport properties\n");

       struct UDP_InterfaceFactoryProperty *udp_property = NULL;

        udp_property = (struct UDP_InterfaceFactoryProperty *)

           malloc(sizeof(struct UDP_InterfaceFactoryProperty));

       if (udp_property != NULL)

       {

               *udp_property = UDP_INTERFACE_FACTORY_PROPERTY_DEFAULT;

 /* allow_interface: Names of network interfaces allowed to send/receive.

                   * Allow one loopback (lo) and one NIC (eth0).

                   */

                  REDA_StringSeq_set_maximum(&udp_property->allow_interface,1);

                  REDA_StringSeq_set_length(&udp_property->allow_interface,1);

                  *REDA_StringSeq_get_reference(&udp_property->allow_interface,0) = DDS_String_dup("eth0");

        }                                                                                                                                                              

       else

       {

           /* failure */ printf("UDP Property is NULL\n");

       }

        printf("CLEARED DEBUG Configure UDP transport properties\n");

 

 

       /*Re-register UDP component with updated properties:*/

 

       if (!RT_Registry_register(registry, NETIO_DEFAULT_UDP_NAME,

                            UDP_InterfaceFactory_get_interface(),

                           (struct RT_ComponentFactoryProperty*)udp_property, NULL))

       {

           /* failure */ printf("Re-registration of UDP component with updated properties failed\n");

       }

 

 

Q-2) Earlier my discovery message DATA(p) coming out of my Embedded Board did not contain locators information at all. So, then I manually activated the locators namely with kind 1 (UDPv4) to all:-

 a)       &participant->builtin_data.metatraffic_multicast_locators._contiguous_buffer

(set with Port #7412, Address: 239.255.0.1)

b)      &participant->builtin_data.metatraffic_unicast_locators

(set with Port #7420, Address: <ip address of my embedded device>)

c)       &participant->builtin_data.default_unicast_locators

(set with Port #7418, Address: <ip address of my embedded device>)

d)      &participant->builtin_data.default_multicast_locators

(set with Port #7401, Address: 239.255.0.1)

Is the above correct?

Information: Locators of my Windows7 DDS Micro DPDE Subscribe App: -

PID_MULTICAST_LOCATOR (LOCATOR_KIND_UDPV4, 239.255.0.1:7401)

PID_METATRAFFIC_UNICAST_LOCATOR (LOCATOR_KIND_UDPV4, <ip address of my Windows7 PC> : 7410)

 

PID_METATRAFFIC_MULTICAST_LOCATOR (LOCATOR_KIND_UDPV4, 239.255.0.1: 7400)

Q-3) Does Locators mean the source address of a Participant  or the destination it is trying to send? For example, as we see, in the DATA(p) messages Locator Information, does it mean that is announcing to all, that that particular IP address or Port is MY Address, where others can REACH ME .. OR it means the location where participant will REACH OUT and GO TO ?

Information: Currently I have enabled all the transports manually like the following on my Embedded Board. If I do not enable all the transports, only then I am able to see on my serial interface that the Msg Is received: “Hello World” for my Embedded Board (which has both the publisher and subscriber created, As per the code structure explained in first).

       REDA_StringSeq_set_maximum(&dp_qos.transports.enabled_transports,1);

           REDA_StringSeq_set_length(&dp_qos.transports.enabled_transports,1);

           *REDA_StringSeq_get_reference(&dp_qos.transports.enabled_transports,0) =

                   DDS_String_dup("_udp");

 

           /* Discovery enabled_transports */

           DDS_StringSeq_set_maximum(&dp_qos.discovery.enabled_transports, 1);

           DDS_StringSeq_set_length(&dp_qos.discovery.enabled_transports, 1);

           *DDS_StringSeq_get_reference(&dp_qos.discovery.enabled_transports, 0) =

                DDS_String_dup("_udp://239.255.0.1");

 

           /* User Traffic enabled_transports */

           DDS_StringSeq_set_maximum(&dp_qos.user_traffic.enabled_transports, 1);

           DDS_StringSeq_set_length(&dp_qos.user_traffic.enabled_transports, 1);

           *DDS_StringSeq_get_reference(&dp_qos.user_traffic.enabled_transports, 0) =

                DDS_String_dup("_udp://239.255.0.1");

***********************************************************************************************************************************************************************

Windows DDS Micro Settings:-

2) I have successfully been able to get HelloWorld_dpde working using Connext DDS Micro on Windows in C using the UDP interface.

Here only the following transport is set manually in application:-

/* User Traffic enabled_transports */

DDS_StringSeq_set_maximum(&dp_qos.user_traffic.enabled_transports, 1);

       DDS_StringSeq_set_length(&dp_qos.user_traffic.enabled_transports, 1);

       *DDS_StringSeq_get_reference(&dp_qos.user_traffic.enabled_transports, 0) =

              DDS_String_dup("_udp://239.255.0.1");

 

Now, I wish to communicate the DDS Micro on Windows as SUBSCRIBER with the Embedded Board which will be PUBLISHER using ethernet cables plugged in network switch.

Therefore, I have commented out the subscriber creation and datareader creater parts on the Embedded Board to make it act as a Publisher.

 

Now, in order to communicate using Connext DDS Micro 3.0.0. Example code HelloWorld_dpde in C language with my Embedded Board, I am first starting only the Subscriber app using the following flags in my Command Line:-

HelloSubscriber.exe –udp_intf <MyInterfaceName> -peer 235.255.0.1

LOCATORS Information ON WINDOWS SUBSCRIBER FROM THE DISCOVERY PARTICIPANT message:- PID_MULTICAST_LOCATOR (LOCATOR_KIND_UDPV4, 239:255:0:1:7401)

PID_METATRAFFIC_UNICAST_LOCATOR (LOCATOR_KIND_UDPV4, myPC_IP_Address:7410)

PID_METATRAFFIC_MULTICAST_LOCATOR (LOCATOR_KIND_UDPV4, 239:255:0:1:7400)

And then, I start the Code on the Embedded Board.

But the Publisher and Subscriber do not match.

 

To let know in advance:-  I have tried to ensure that the QoS settings are same for participants, datawriter and datareader.

Information: IDL file in Windows HelloWorld_dpde in C is:-

struct HelloWorld {

    long                  id;    //@key

    string<128>           msg;

    sequence<octet, 1000> image;

};

 

 

And IDL file used on my Embedded Board is:-

struct HelloWorld {

       string<128> msg;

};

Kindly help me as I have been trying for a while now and not exactly sure what is the issue, or how can it be approached. I have tried to follow the documentations and few community works but unfortunately unable to find an answer for the same.

Thank you in advance for the support.

 

 

 

 

 

Offline
Last seen: 4 years 11 months ago
Joined: 07/02/2019
Posts: 5

I tried to make the IDL files also the same now as like the Subscriber/Windows DDS Micro, but still no matching of Publisher and Subscriber is happening between Connext DDS Micro HelloWorld DPDE Subscriber.exe running on Windows and Publisher running on the Embedded Board. Mainly I am not sure what infrastructure of code is required to make it communicate other than the above mentioned(Subscriber and Datareader are commented out in the Embedded Board, because I want to Publish data through it). So, my basic question would even be that, is there a possibility of such a scenrio working or if someone has tried to achieve DDS Micro communication between PC and embedded board, then kindly put your valuable inputs.

Offline
Last seen: 9 months 4 days ago
Joined: 11/19/2015
Posts: 21

Hello,

I think that the problem is that FreeRTOS is not able to return the list of local network interfaces. This is why the list of locators in the data(p) is empty. Connext DDS Micro includes a static UDP configuration API for this kind of OSs. That is UDP_InterfaceTable_add_entry() https://community.rti.com/static/documentation/connext-micro/3.0.0/doc/api_c/html/group__UDPPluginModule.html#gaa4eb35c3990b9e4139c77a4c069e5fdd.

You can find an example on example\windows\C\HelloWorld_static_udp. Using that API you can add the configuration in Connext DDS Micro regarding the local network interfaces.

Important fields to set are:

1)    udp_property->disable_auto_interface_config = RTI_TRUE;
To indicate that Connext DDS Micro shouldn't query the OS for the local network interfaces. Instead the static configuration will be used.

2)     if (!UDP_InterfaceTable_add_entry(&udp_property->if_table,
                                      0x7f000001,0xff000000,"loopback",
                                      UDP_INTERFACE_INTERFACE_UP_FLAG |
                                      UDP_INTERFACE_INTERFACE_MULTICAST_FLAG))

0x7f000001 -> change it with your local IP address. In the example the loopback address is set 127.0.0.1

0xff000000 -> change it with your network mask.

"loopback" -> local network interface name. This name is not interpreted by Connext DDS Micro. In case you configure udp_property->allow_interface ensure that this name is in the allow list.

UDP_INTERFACE_INTERFACE_UP_FLAG | UDP_INTERFACE_INTERFACE_MULTICAST_FLAG : interface flags. Remove multicast if your interface doesn't support multicast.

You need to use that in the application running on FreeRTOS. Application running on Windows is able to automatically get the list of local networks.

 

Please try that change and let me know if that worked.

 

Best Regards,

Francisco Merino.

 

 

Offline
Last seen: 4 years 11 months ago
Joined: 07/02/2019
Posts: 5

Hi Fancisco,

 

First of all thank you very much for your reply.

1) Yes, you are very much true, which even I had realized and implemented earlier, but did not work unfortunately. I again tried to it now in a clean way. Here, I am posting the static UDP Interface definition code. But, it still does not get the locators out of the Embedded Board.

 

2) For that reason, I had made changes, and manually, added all the locators and then defined them with Kind = UDPv4, IP and Port number for all 4 types of locators (multicast metatraffic, default multicast, unicast metatraffic, default unicast).

 

3) Should that it be correct? Because, if only we are supposed to let the locators out, then partial communications happen, wherein the WindowsPC as a subscriber sends both the HEARTBEAT and ACKNACK to the Embedded Board which is the publisher. Technically, the WindowsPC should send the ACKNACK to Embedded Board as a reply to the HEARTBEAT which is not observed in the current communications.

 

4) Moreover, I am not using “app gen”, for the embedded board. I hope that is not the issue, as there is a .exe file for Subscriber in Windows DDS Micro. Also, the directory structure is different, as in all the entities are in the main thread only, like participant create, topic, publisher and data writer to name a few rather than, application.c, publisher.c and subscriber.c defined differently in the example programs.

 

5) Also, Locators coming out of Windows Machine mean that it sends out others the address to reach the Windows Machine? Or it acts as a destination address where to go to, or whom to locate where (i.e., IP of the Embedded Board)?

6) Do you think that if there is a forced INTRA participant communication, then locators will not be out ? But my main suspect remains the same that maybe FreeRTOS is not able to know the board.

Please find the code below:-

 

/************************************************************************************      

                                                       STATIC UDP INTERFACE DEFINITIONS

                  ************************************************************************************/

 

        /* Unregister the pre-registered UDP component */

                if (!RT_Registry_unregister(registry, "_udp", NULL, NULL))

                {

                    /* failure */ printf("Unregistration of pre-registered UDP component failed\n");

                }

                struct UDP_InterfaceFactoryProperty *udp_property = NULL;

                udp_property = (struct UDP_InterfaceFactoryProperty *)

                                malloc(sizeof(struct UDP_InterfaceFactoryProperty));

                        if (udp_property == NULL)

                        {

                                printf("failed to allocate udp properties\n");

 

                        }

                        *udp_property = UDP_INTERFACE_FACTORY_PROPERTY_DEFAULT;

        /* In this example we manually configure what interfaces are available.

         * First we disable reading out the interface list. Note that on some

         * platforms reading out the interface list has been compiled out, so

         * this property has no effect.

         */

        udp_property->disable_auto_interface_config = RTI_TRUE;

 

        /* Allow and deny lists are still valid. If none are specified then

         * all interfaces are valid.

         */

        if (!DDS_StringSeq_set_maximum(&udp_property->allow_interface,1))

        {

            printf("failed to set allow_interface maximum\n");

 

        }

        if (!DDS_StringSeq_set_length(&udp_property->allow_interface,1))

        {

            printf("failed to set allow_interface length\n");

 

        }

 

        /* The name of the interface can be the anything, upto

         * UDP_INTERFACE_MAX_IFNAME characters including the '\0' character

         */

        *DDS_StringSeq_get_reference(&udp_property->allow_interface,0) =

            DDS_String_dup("eth0");

 

        /* This function takes the following arguments:

         * Param 1 is the iftable in the UDP property

         * Param 2 is the IP address of the interface in host order

         * Param 3 is the Netmask of the interface

         * Param 4 is the name of the interface

         * Param 5 are flags. The following flags are supported (use OR for multiple):

         *      UDP_INTERFACE_INTERFACE_UP_FLAG - Interface is up

         *      UDP_INTERFACE_INTERFACE_MULTICAST_FLAG - Interface supports multicast

         */

        if (!UDP_InterfaceTable_add_entry(&udp_property->if_table,

       <Hex_Address_IP_of_Embedded_Board>,<Netmask_Address_IP_of_Embedded_Board>,"eth0",

                          UDP_INTERFACE_INTERFACE_UP_FLAG | UDP_INTERFACE_INTERFACE_MULTICAST_FLAG ))

 

        {

            printf("failed to add interface\n");

 

        }

        printf("Successfully added the static UDP interface\n\r");

 

        /* Add an entry for the eth0 interface */

 

        if (!RT_Registry_register(registry, NETIO_DEFAULT_UDP_NAME,

                             UDP_InterfaceFactory_get_interface(),

                            (struct RT_ComponentFactoryProperty*)udp_property, NULL))

        {

            printf("failed to register udp\n");

 

        }

 

        printf("Successfully registered the static UDP interface\n\r");

 

Best Regards,

rgajjar

Offline
Last seen: 9 months 4 days ago
Joined: 11/19/2015
Posts: 21

Hello Rgajjar,

1) The code with the static UDP configuration that you posted seems to be OK. Would you mind to attach a Wireshark trace when you apply this configuration? What do you mean with "it still does not get the locators out of the Embedded Board."?

That should be enough to get the data(p) packets with the right locators. Did yoy made any change to the HelloWorld_static_udp?

Do you get a ping reply from the board?

2) How did you do that? You shouldn't need to manually add any locator.

3) As I said, you are not suppossed to manually add any locator.

4) Whether you use appgen or not is not a problem. There is no problem to communicate an application built using appgen with another built without appgen.

5) Locators sent by the Windows machine (or any other machine) mean the addresses and ports where remote applications can reach the local application which sends the data(p). Replies are sent to addresses and ports indicated by locators, not the origin address.

6) Forced INTRA participant communication? I am not sure what you mean by that.

 

Regards,

Francis.

Offline
Last seen: 4 years 11 months ago
Joined: 07/02/2019
Posts: 5

Hi Francisco,
First of all thank you very much for your reply.

Just to make sure we are on the same page.
I am trying to get locators information flowing out of the microcontroller board as part of DATA(p) packets. I am using and have been getting the locators on the Windows7 PC automatically for the HelloWorld_dpde_subscriber in C.
Please find in the attachement the images of wireshark trace and what I have been trying to do considering inputs.

1)The code with the static UDP Configuration is used on the embedded board (microcontroller board). I am following the code
reference from the RTI Connext DDS Micro 3.0.0 Getting Started documentation. So, at the moment I am using the static UDP configuration
for my microcontroller board. I have commented out the "create subscriber" and "create DataReader" parts from the code as
I want to have the microcontroller board acting as the Publisher.

Current code structure:-
The structure of the code is as follows in the main thread:-

Get the RT Registry from the DomainParticipantFactory singleton
Register Writer History
Register Reader History
Register DPDE
Unregister the pre-registered UDP component
Static UDP Configuration -------------------------------------------> (STATIC UDP Configuration)
Re-register UDP component with updated properties
Participant is created
Register Data types that have been generated from IDL with the DomainParticipants
Create topic
Subscriber is commented ------------------------------------------->(Commented)
DataReader is commented------------------------------------------->(Commented)
Publisher is created
DataWriter is created

So, I meant, after making the above changes (which is adding of the static UDP configuration on the microcontroller board), in the wireshark trace field:-
Real-Time Publish-Subscribe Wire Protocol -> submessageId:DATA(0x15) -> serializedData -> serializedData:
I DO NOT see the PID_DEFAULT_UNICAST_LOCATOR, PID_METATRAFFIC_UNICAST_LOCATOR, PID_METATRAFFIC_MULTICAST_LOCATOR
What I see is only following fields:-
1)PID_PARTICIPANT_GUID
2)PID_ENTITY_NAME
3)PID_BUILTIN_ENDPOINT_SET
4)PID_VENDOR_ID
5)PID_PARTICIPANT_LEASE_DURATION
6)PID_PRODUCT_VERSION
7)PID_PROPERTY_LIST
8)PID_ENABLE_ENCRYPTION
9)PID_SENTINEL

So, on wireshark:-
Source: <IP_Address_of_my_Microcontroller_Board>
Destination: 239.255.0.1
Protocol: RTPS
Length: 394
Info: INFO_TS, DATA(p)

I did not make any changes in the HelloWorld_static_udp in the Windows Code because in Windows I am getting the locators
automatically with the Windows:HelloWorld_dpde_subscriber. The code I used in the microcontroller board just has a
different name of the interface (as per my choice of interface name).
Netmask and IP address of the microcontroller board are set.

Yes, I can ping my current microcontroller board. It has set IP address, netmask.

2)I added the locators manually to the microcontroller board by first of all reserving at least 1 locator in DomainParticipant.c for all 4 types.

Then, I added definitions to participant's builtin_data->metatraffic_multicast_locators->contiguous_buffer:-
namely, Kind as 1, which is UDPv4.
Port Number
address
Similarly, for the remaining 3 types of locators DEFAULT_UNICAST_LOCATOR, METATRAFFIC_UNICAST_LOCATOR, DEFAULT_MULTICAST_LOCATOR

3) Okay, understood, that it is not needed or it is wrong to set the locators on the microcontroller board manually. So, I just want to confirm, that is it wrong if we manually setup the locators on the microcontroller board? Because, atleast when I have the locators set manually available, they atleast try to begin the communications, but the publisher and subscriber will not match because of which the data does not flow. (Will attach the wireshark images in the meanwhile).
4) Okay, understood.
5) Okay, understood.

6)So, I was wondering that even if the transports are enabled as udp, then is there possibility, that INTRA participant communication is still used (overriding the "_udp") which does not allow any locators information to be available in DATA(p)?

Best Regards,
Romin

 

 

 

 

 

 

Offline
Last seen: 4 years 11 months ago
Joined: 07/02/2019
Posts: 5

Hi Francisco, 

Kindly find the remaining 2 images of the HEARTBEAT and ACKNACK sent by Windows_dpde (HelloSubscriber.exe) to Microcontroller µC (which is a publisher) in context to the previous reply (as it was unable to take in more attached images). Which is incomplete and wrong because, HEARTBEAT needs to be sent by the Publisher to Subscriber. After which the ACKNACK must be sent from the Subscriber to Publisher. After which the Publisher should send the real data as DATA message. But as you saw in the above reply, OpenOrder:6: Wireshark Incomplete-Wrong Communication after setting the locators manually on micrcontroller board with code, we do not see such type of communications happening at all as the publisher and subscriber also do not match.

Please let me know what can be done through these observations so as to make the communications work nicely between Windows Subscriber dpde C code and the µC board running the publisher code.

Best Regards,

Romin

Offline
Last seen: 9 months 4 days ago
Joined: 11/19/2015
Posts: 21

Hello Romin,

Example HelloWorld_static_udp should work in the embedded target with minor modifications to start a FreeRTOS task (instaed of creating a main function) and IP address used in call to function UDP_InterfaceTable_add_entry(). Note that the IP address needs to be in host order as written in the documentation.,

https://community.rti.com/static/documentation/connext-micro/2.4.11/doc/html/group__UDPPluginModule.html#gaa4eb35c3990b9e4139c77a4c069e5fdd

Regards,

Francis