This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6457 Multicasting on NDK 2.0

We need to receive multicast UDP packets using NDK 2.0 on a C6457.

The "IGMPJoinHostGroup" etc API is no longer available in the SDK so the example document SPRAAI3 "Using IP Multicasting with the TMS320C6000 Network Developers Kit (NDK)" is not completely applicable.

We have attempted to use the IP_ADD_MEMBERSHIP socket options in two ways:

(1) In the dtask_udp Daemon task function: This does not work because multicast packets coming in do not cause the Daemon task to start and, therefore, the socket is not set up for multicast - a chicken and egg situation.

(2) Setting up a socket by calling "socket" and using "setsockopt" and "bind" etc. This code is called from the "NetworkOpen" callback. When the code reaches "fdSelect" which waits for multicast packets to arrive the "fdSelect" never returns.

So ...

(a) Does NDK 2.0 support multicast reception on the C6457? On any C6000 DSP?

(b) If so, how do I do it? Does anybody have example code for NDK 2.0 that does this?

  • Rob,

    As you noticed, the SPRAAI3 is valid for NDK 1.93 and older where the Multicast group was joined via API and not in the standard way by means of a socket option.

    However, with the new release you should use the second option - as you mentioned, the first scenario is not possible since by design the daemon tasks only respond to unicast sockets.

    In the second scenario you must create a regular task (using TaskCreate()) and perform all the initialization code according to a standard BSD-like initialization. A nice usage example can be found in the function MulticastTest() as part of the console application. Check the file <contest.c> typically installed at %NDK_INSTALL_DIR%\packages\ti\ndk\example\tools\common\console

    Apart from this, I am not aware of any limitations with multicast on the C6457 device.

    Hope this information helps,

    Rafael

  • I basically used the "contest.c" source for my option (2).

    I found that unless the socket was preceded by "fdOpenSession(TaskSelf())" then the socket was not created. If I added this line then everything was OK until "fdSelect" as described previously.

    I call the code that is basically the "contest.c" MulticastTest method from NetworkOpen, which is itself a callback entered in the "NC_NetStart" call when the network is set up.

    Is this OK or am I doing something wrong?

  • Rob,

    When "NetworkOpen ()" callback is called, the NDK stack is in a state where it has been initialized with the configuration you have specified, but an IP address assignment has not yet been done at this point. If you'd like to send/receive packets, as it is in the case of Multicast group join, you must initiate this task of yours after an IP address has been configured on the stack, i.e., in your NetworkIPAddr () callback.

    Hope this helps!

     

    Thanks,

    Sruthi

     

     

  • Thanks for the suggesion. At the end of the "NetworkIPAddr" I now creat a task as follows:

     Attributes = TSK_ATTRS;
     Attributes.stacksize = 8192;
     Attributes.name = "SpecialNetworkTask";
     Attributes.priority = 5;
     Attributes.stackseg = MEM->MALLOCSEG;
     Handle = TSK_create((Fxn)NetworkManager::TaskFunction, &Attributes, (void*)0);

    The TaskFunction code is as follows:

    void NetworkManager::TaskFunction(Arg id_arg)
    {
        SOCKET     sudp1 = INVALID_SOCKET;
        struct sockaddr_in sin1;
        char       buffer[2000];
     int     reuse = 1;
     struct ip_mreq group;
        fd_set          msockets;
        int             cnt;
        CI_IPNET        NA;

     fdOpenSession(TaskSelf());

        // Create our UDP Multicast socket1
        sudp1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

        if( sudp1 == INVALID_SOCKET )
        {
            //ConPrintf ("Error: Unable to create socket\n");
            return;
        }

        // Set Port = 10000, leaving IP address = Any
        bzero( &sin1, sizeof(struct sockaddr_in) );
        sin1.sin_family = AF_INET;
        sin1.sin_len    = sizeof( sin1 );
        sin1.sin_port   = htons(10000);

        // Print the IP address information only if one is present.
        if (CfgGetImmediate( 0, CFGTAG_IPNET, 1, 1, sizeof(NA), (UINT8 *)&NA) != sizeof(NA))
        {
            //ConPrintf ("Error: Unable to get IP Address Information\n");
            fdClose (sudp1);
            return;
        }

     // Set the Reuse Ports Socket Option for both the sockets. 
     if (setsockopt(sudp1, SOL_SOCKET, SO_REUSEPORT, (char *)&reuse, sizeof(reuse)) < 0)
        {
            //ConPrintf ("Error: Unable to set the reuse port socket option\n");
            fdClose (sudp1);
            return;
        }   

        // Now bind both the sockets.
        if (bind (sudp1, (PSA) &sin1, sizeof(sin1)) < 0)
        {
            //ConPrintf ("Error: Unable to bind the socket.\n");
            fdClose (sudp1);
            return;
        }

     group.imr_multiaddr.s_addr = inet_addr("230.1.50.210");
     group.imr_interface.s_addr = NA.IPAddr;

     int multicastOptResult = setsockopt (sudp1, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&group, sizeof(group));

     if (multicastOptResult == -1)
     {
      int resultError = fdError();

      switch(resultError)
      {
       case EBADF: {} break;
       case ENOTSOCK: {} break;
       case EINVAL: {} break;
       default: {} break;
      } // switch
     } // if

     if (multicastOptResult < 0)
     {
      //ConPrintf ("Error: Unable to join multicast group\n");
      Logging::Instance()->Add(Logging::LOG_INFO, "Error: Unable to join multicast group");
            fdClose (sudp1);
            return;
     }

        while (1)
        {
            // Initialize the FD Set.
            FD_ZERO(&msockets);
            FD_SET(sudp1, &msockets);

            // Wait for the multicast packets to arrive.
      // NOTE: According to "spru524g.pdf page 45 the first parameter of fdSelect is not used.
            cnt = fdSelect( (int)sudp1, &msockets, 0, 0 , 0);

      if (cnt == -1)
      {
       int resultError = fdError();

       switch(resultError)
       {
        case EBADF: {} break;
        case ENOTSOCK: {} break;
        case EINVAL: {} break;
        default: {} break;
       } // switch
      }
      else
      {
       Logging::Instance()->Add(Logging::LOG_INFO, "fdSelect was OK");
      } // if

            if(FD_ISSET(sudp1, &msockets))
            {
          cnt = (int)recv (sudp1, (void *)&buffer, sizeof(buffer), 0);
          if( cnt >= 0 )
       {
           //ConPrintf ("Socket Identifier %d received %d bytes of multicast data\n", sudp1, cnt);
        Logging::Instance()->Add(Logging::LOG_INFO, "Received MULTICAST data");
       }
          else
       {
           //ConPrintf ("Error: Unable to receive data\n");
        Logging::Instance()->Add(Logging::LOG_INFO, "ERROR receiving MULTICAST data");
       } // if
            } // if

      //TSK_sleep(1);
        } // while

    ... etc

    This code comes directly from contest.c example. All the setups work (no error returns) and then the code goes into the fdSelect (which waits for an event) and does not come out. Other than some sort of lack of hardware support is there anything here that I am not doing or not doing correctly?

  • Hi Rob,

    I am looking at this issue now. I am waiting on getting the drivers. I will update you regarding you issue soon.

     

    Arun.

  • Hi Rob,

    I couldn't get a curie board. but I got hold of a tomahawk and tried. Seems like I ma encountering the same issue. but I have sent a mail to the NDK developer to verify my setup. I will keep you posted. I might even get hold of a curie board on Monday. Can you give some informationlike what CCS you are using and bit about your setup. This will help me to produce the scenario as close to yours as possible.

     

     

    Arun.

  • Here's my setup ...

    CCS 3.3.82.13

    Integrated development 5.98.0.393

    DSP/BIOS 5.33.06

    Code generation tools v6.1.12

    NDK v2.0.0

    I'm using the Lyrtech C6457 EVM which shows up as board revision 00.00.00 and target silicon revision 00.00.05 in the CCS help "About Code Composer Studio"

    Hope this helps.

  • Hi Rob,

    Thanks for the update and for the patience. I have found that the IGMP join information packet has a frame check sequence error. It might be causing the problem when you are sending the echo message to the multicast IP.  I checking this and will update soon.

    Arun.

  • Hi Rob,

    Sorry for the delay. Atlast I found out that the packet is discarded by the EMAC for not matching the MAC IP pair. This might be because some configuration is missing. I am trying to debug this issue with IP guys and will get back to you as soon as I have a solution.

     

    Thanks,

    Arun

  • Hi Rob,

    I talked with the IP team engineers and we found out that multicast feature is broken in NSP2.0. I am trying to figure out the root cause and will keep you updated.

     

    Thanks,

    Arun.

  • The problem (or at least one problem) is in usertype.h line 81.  When calling setsockopt, the endian of the address is flipped by using inet_addr (see contest.c line 565).  Within setsockopt, IN_MULTICAST is called to check that the address sent is a multicast address.  This macro checks the address with the assumption that the address hasn't had its endian changed.  It fails the test.

    My question is:

    Can I get the project file (.pjt) for the stk6_jumbo.lib and os_jumbo.lib so I can implement a fix for multicast and test it out?

     

    Thanks,

    Tony

  • Hi Tony,

    I can get the DUT join the multicast group, so this shouldn't be the problem. but i am not able to receive any igmp packets.

     

    Thanks,

    Arun

  • Has TI got any rough ideas of if or when the multicast feature will be fixed? Will it be a patch to NDK 2.0?

  • Hi Rob,

    Yes we are working on it and we will try to post a pactch soon.

     

    thanks,

    arun.

  • We got our multicast to work.  We are receiving messages on four different ports from 6 muticast groups. 

  • That is cool. Did you made any changes to the example code?

  • I did it essentially in the same manner as in contest.c  lines 530 to 573.  Each task had only one socket opened and one port bound to the socket (unlike in the example) and there were multiple multicast groups associated with each socket, but other than that I stuck pretty close to the example.  I even used the same names for the structures.  We can clearly see the IGMP messages flowing on WireShark and the tasks received the multicast messages without difficulty.

    One thing that helped was creating a project with the stack files.  I then built them with full symbolic debug turned on.  Then I could step in and see what was actually going on within the stack.

  • Any idea when the fix to NDK 2.0 (or NSP) will be available to fix the multicasting problem?

  • There is NO multicast problem.  It works just fine.

  • Where you using NDK 2.0 when you got the multicast to work, Anthony?

    If so, would you be able to attach sample code because (now almost 2 years ago) I could not get it operational on a C6457 using NDK 2.0 and we will need to re-visit multicast again some time in the next few months.

    Thanks.

  • I have been trying to get multicast to work on a C6748 platform, using the 2.0 NDK, release without any success.  The hardware sees the packet (the multicast count in the EMAC increments), but they are never delivered to the multicast joined socket.

    Did TI ever fix this, and did they every release a patch?

    -- Jerry

  • Is there any update for multicast support with NDK 2.0? I too would live to host multicast support on a C6748. I have tried the multiple example available on the net and this site with no avail. 

    Texas Insturments (or anybody): is there any example code available that implements a multicast host on NDK 2.x on C6748?

    Thanks,

    Matt

  • Just an update...

    I was able to get multicast running on a C6748. To do this, I installed the console example found within the NDK 2.20.  To install the console example, I simply added this code before the NC_NetStart() call:

        {
          extern SOCKET ConsoleOpen( PSA pClient );
         
          CI_SERVICE_TELNET telnet;
         
          // Specify TELNET service for our Console example
         
          bzero( &telnet, sizeof(telnet) );

          telnet.cisargs.IPAddr = INADDR_ANY;
         
          telnet.cisargs.pCbSrv = &ServiceReport;
         
          telnet.param.MaxCon   = 2;
         
          telnet.param.Callback = &ConsoleOpen;
         
          CfgAddEntry( hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_TELNET, 0,
     sizeof(telnet), (UINT8 *)&telnet, 0 );  
        }

    I also had to build the following files into my application:

    VPATH = \
    $(NGCC_DIR)/Libraries/Networking/ndk_2_20_04_26/src/stack/res \
    $(NGCC_DIR)/Libraries/Networking/ndk_2_20_04_26/src/stack/pppoe \
    $(NGCC_DIR)/Libraries/Networking/ndk_2_20_04_26/src/tools/console \
    $(NGCC_DIR)/Libraries/Networking/ndk_2_20_04_26/src/hal/eth_stub \
    $(NGCC_DIR)/Libraries/Networking/ndk_2_20_04_26/src/stack/ether \
    $(NGCC_DIR)/Libraries/Networking/ndk_2_20_04_26/src/stack/ppp

    C_SRCS += \
    console.c \
    contest.c \
    conacct.c \
    conecho.c \
    conlli.c \
    condns.c \
    conping.c \
    conroute.c \
    consock.c \
    constat.c \
    contftp.c \
    if.c \
    pppoe.c \
    ppp.c \
    llpktstb.c \
    ether.c \
    lcp.c \
    ipcp.c \
    auth.c

    After this, I was able to run the following command from the telnet console:

    test multicast

    After this, I was able to use an external program to connect to the multicast group.

    Regards,

    Matt

     

     

  • Hi Rob,

    Is this possible in NDK 2.23 latest version?

    Regards,

    Pradeep.P