I'm trying to build a very rudimentary SSDP task on the Netburner.
I've found the very simple example provided in examples (\nburn\examples\multicast\multitest.cpp), and I'm trying to modify it.
The changes I've made are as follows:
void UserMain( void *pd )
{
int portnum = 1900;
char buffer[80] = "239.255.255.250";
...
iprintf( "Input the Multicast group port number: " );
//scanf( "%d", &portnum );
iprintf( "\r\nEnter the Multicast IP Address: " );
//buffer[0] = 0;
//while ( buffer[0] == 0 )
//{
// gets( buffer );
//}
...
}
basically, I've hard coded the Multicast address, and port.
When I execute the program, it prompts to send some string, and that works. But it will never receive anything.
While trying to debug this, I put the scanf() back in, but stored the result in an unused variable. Having done this, I can again receive Multicast packets. if I comment out the scanf(), and put the gets() back in, but store it's output in an unused variable, I can receive Multicast packets.
I'm using Rel24_rc2.
Is anyone able to reproduce this, or offer a workaround? I'm willing to update if that will solve my problem.
Keith
Multicast example
Re: Multicast example
Hi Keith,
You didn't post all your code, but are you returning from UserMain(). To cover all the bases, why do you think a tools revision would make a difference? Looks like a coding issue from what was presented.
You didn't post all your code, but are you returning from UserMain(). To cover all the bases, why do you think a tools revision would make a difference? Looks like a coding issue from what was presented.
Re: Multicast example
rnixon, you are correct, the modified multitest.cpp code is below.Hi Keith,
You didn't post all your code, but are you returning from UserMain(). To cover all the bases, why do you think a tools revision would make a difference? Looks like a coding issue from what was presented.
If some sort of input is requested prior to RegisterMulticastFifo, the code works as expected.
the code sends the multicast messages, but does not appear to receive any multicast messages.
Here is the fully modified code;
Code: Select all
/* Rev:$Revision: 1.8 $ */
/******************************************************************************
* Copyright 1998-2009 NetBurner, Inc. ALL RIGHTS RESERVED
* Permission is hereby granted to purchasers of NetBurner Hardware
* to use or modify this computer program for any use as long as the
* resultant program is only executed on NetBurner provided hardware.
*
* No other rights to use this program or it's derivatives in part or
* in whole are granted.
*
* NetBurner makes no representation or warranties with respect to the
* performance of this computer program, and specifically disclaims any
* responsibility for any damages, special or consequential, connected
* with the use of this program.
*
* NetBurner, Inc
* 5405 Morehouse Drive
* San Diego Ca, 92121
* http://www.netburner.com
*
*****************************************************************************/
/*-------------------------------------------------------------------
* This example program enables you to add a netburner device to
* a multicast group by specifing the multicast ip address and
* port number in MTTTY when prompted. You can then send data
* by typeing it in MTTTY, or view received data.
*-------------------------------------------------------------------*/
#include "predef.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <startnet.h>
#include <ucos.h>
#include <udp.h>
#include <multicast.h>
#include <autoupdate.h>
#include <taskmon.h>
#include <dhcpclient.h>
extern "C"
{
void UserMain( void *pd );
}
const char *AppName = "Multicast Example";
//Make sure they're 4 byte aligned to keep the ColdFire happy
DWORD MultiTestStk[USER_TASK_STK_SIZE] __attribute__( ( aligned( 4 ) ) );
IPADDR MulticastIpAddr;
BOOL shutdown;
/*-------------------------------------------------------------------
* Task to process incoming multicast packets
*------------------------------------------------------------------*/
void MultiReaderMain( void *pd )
{
int port = ( int ) pd;
iprintf( "Reading from port %d\r\n", port );
OS_FIFO fifo;
OSFifoInit( &fifo );
// Register to listen for Multi packets on port number 'port'
RegisterMulticastFifo( MulticastIpAddr, port, &fifo );
while ( !shutdown )
{
// We construct a UDP packet object using the FIFO.
// This constructor will only return when we have received a packet
UDPPacket upkt( &fifo, TICKS_PER_SECOND );
// Did we get a valid packet? or just time out?
if ( upkt.Validate() )
{
WORD len = upkt.GetDataSize();
iprintf( "Recd UDP packet with %d Bytes From :", ( int ) len );
ShowIP( upkt.GetSourceAddress() );
iprintf( "\r\n" );
ShowData( upkt.GetDataBuffer(), len );
iprintf( "\r\n" );
}
}
iprintf( "Unregistering from group\r\n" );
UnregisterMulticastFifo( MulticastIpAddr, port );
iprintf( "Done unregistering\r\n" );
}
/*-------------------------------------------------------------------
* UserMain
*-----------------------------------------------------------------*/
void UserMain( void *pd )
{
int x;
//int portnum;
//char buffer[80];
int portnum = 1900;
char buffer[80] = "239.255.255.250";
InitializeStack();
if ( EthernetIP == 0 )
{
iprintf( "Trying DHCP\r\n" );
GetDHCPAddress();
iprintf( "DHCP assigned the IP address of :" );
ShowIP( EthernetIP );
iprintf( "\r\n" );
}
else
{
iprintf( "Static IP address set to :" );
ShowIP( EthernetIP );
iprintf( "\r\n" );
}
EnableAutoUpdate();
EnableTaskMonitor();
OSChangePrio( MAIN_PRIO );
iprintf( "Input the Multicast group port number: " );
//scanf( "%d", &portnum );
//scanf( "%d", &x ); // --- uncomment for code to work.
iprintf( "\r\nEnter the Multicast IP Address: " );
//buffer[0] = 0;
//while ( buffer[0] == 0 )
//{
// gets( buffer );
//}
MulticastIpAddr = AsciiToIp( buffer );
iprintf( "\r\nListening/Sending on Port %d of Group:", portnum );
ShowIP( MulticastIpAddr );
iprintf( "\r\n" );
// Create task to listen for incoming packets
OSTaskCreate( MultiReaderMain,
( void * ) portnum,
&MultiTestStk[USER_TASK_STK_SIZE],
MultiTestStk,
MAIN_PRIO - 1 );
while ( 1 )
{
iprintf( "Enter the text to send in the packet. (Empty string to unregister listener)\r\n" );
gets( buffer );
if ( strlen( buffer ) == 0 )
{
// iprintf( "Unregistering the listener\r\n" );
// iprintf( "You must reset the board to continue\r\n" );
// shutdown = TRUE;
// while ( 1 )
// {
// OSTimeDly( TICKS_PER_SECOND );
// }
}
else
{
iprintf( "Sending %s on UDP port %d to IP Address ", buffer, portnum );
ShowIP( MulticastIpAddr );
{
UDPPacket pkt;
pkt.SetSourcePort( portnum );
pkt.SetDestinationPort( portnum );
pkt.AddData( buffer );
pkt.AddDataByte( 0 );
pkt.Send( MulticastIpAddr );
}
iprintf( "\r\n" );
}
}
}
Re: Multicast example
Its not a user input, but time delay...
To get multicast input the system registers with the local router to receive stuff from the multicast group.
If you don't wait till DHCP has finished and you have a link etc... then this might not happen.
Try just adding a 5 second wait before registering the FIFO.
IS
OSTimeDly(TICKS_PER_SECOND*5);
Paul
To get multicast input the system registers with the local router to receive stuff from the multicast group.
If you don't wait till DHCP has finished and you have a link etc... then this might not happen.
Try just adding a 5 second wait before registering the FIFO.
IS
OSTimeDly(TICKS_PER_SECOND*5);
Paul
Re: Multicast example
Thanks, Paul.pbreed wrote:Its not a user input, but time delay...
To get multicast input the system registers with the local router to receive stuff from the multicast group.
If you don't wait till DHCP has finished and you have a link etc... then this might not happen.
Try just adding a 5 second wait before registering the FIFO.
IS
OSTimeDly(TICKS_PER_SECOND*5);
Paul
This worked! I'm not using DHCP; the netburner has a static IP address. Is there someway I can determine if the Multicast join has worked or not? If I can be guaranteed that a 5 second delay will always work, then this is ok, but I doubt I can trust this...
Keith
Re: Multicast example
To start with, make sure you have ethernet link....
#include <ethernet.h>
BOOL EtherLink( void );
Another test is to ping something on the network....
The Multicast join is not "Reliable" I don't mean the code is broken, I mean reliable in the terms like TCP is reliable and UDP is not.
So if you have to have joined a multicast group.....
Another failure modes is what may happen if the multicast router reboots and looses your join....
The best thing I can think of is to have some idea how often you should see traffic and doing a rejoin* when you don't see traffic.
Take a look at the code in nburn\system\multicast.cpp and specifically the
void RegisterMulticastFifo( IPADDR group, WORD dest_port, OS_FIFO *pfifo )
I might be tempted to split that code in half, and register and allocate a group once....
IE all the code up to the final line is internal and only needs to be called once EVER...
The last line is the part that sends out the router join...
SendIGMPBelong( group ); call from time to time....
Do a google search for "Reliable multicast" and you will see much discussion about the unreliable nature of the UDP multicast system as deployed.
#include <ethernet.h>
BOOL EtherLink( void );
Another test is to ping something on the network....
The Multicast join is not "Reliable" I don't mean the code is broken, I mean reliable in the terms like TCP is reliable and UDP is not.
So if you have to have joined a multicast group.....
Another failure modes is what may happen if the multicast router reboots and looses your join....
The best thing I can think of is to have some idea how often you should see traffic and doing a rejoin* when you don't see traffic.
Take a look at the code in nburn\system\multicast.cpp and specifically the
void RegisterMulticastFifo( IPADDR group, WORD dest_port, OS_FIFO *pfifo )
I might be tempted to split that code in half, and register and allocate a group once....
IE all the code up to the final line is internal and only needs to be called once EVER...
The last line is the part that sends out the router join...
SendIGMPBelong( group ); call from time to time....
Do a google search for "Reliable multicast" and you will see much discussion about the unreliable nature of the UDP multicast system as deployed.
Re: Multicast example
Thanks Paul,To start with, make sure you have ethernet link....
#include <ethernet.h>
BOOL EtherLink( void );
...
This is working nicely for me.
Keith