W5500 Broadcast Server

Tried many days for UDP-Broadcast function and no success…

The Hardware: TI-C2000 DSP + W5500.
The function (from GitHub - Wiznet/ioLibrary_Driver: ioLibrary_Driver can be used for the application design of WIZnet TCP/IP chips as W5500, W5300, W5200, W5100 W5100S.) works good for DHCP and TCP after minimal adjustment.
DHCP can get a free IP from sub-net (eg. 192.168.178.22)
PC can send/recieve data with DSP via TCP.

In order to know the IP address, PC sends Broadcast to address like: 192.168.178.255. The Problem is how to configure the W5500 to response? (already tried the function loopback_udps())
Any example for that?

Thanks!

To receive broadcast packets in UDP mode you must ensure to reset BCASTB of Sn_MR. However it is a good question if W5500 supports 192.168.178.255 to be broadcast address for network 255.255.255.0 - I did not try it. But should work this way.

What do you want W5500 to respond with? And UDP broadcast does also have the UDP port #.

Thanks for the quick answer!
I believe that it must be a trivial error :slight_smile: But difficult to figure out why getSn_RX_RSR(UDP_SOCK_NR) always returns zero.
Below is the C Code for testing: any idea ?

#define UDP_SOCK_NR 0
#define TCP_SOCK_NR 1
#define DHCP_SOCK_NR 2

#define TCP_PORT 51000
#define UDP_PORT 51000
#define UDP_FLAG Sn_MR_BCASTB

wiz_NetInfo gWIZNETINFO = { .mac = {0x00, 0x08, 0xdc, 0xab, 0xcd, 0xef}, // just for testing
.ip = {192, 168, 178, 2},
.sn = {255, 255, 255, 0},
.gw = {192, 168, 178, 1},
.dns = {0, 0, 0, 0},
.dhcp = NETINFO_DHCP };

void eth_init(void)
{

ctlnetwork(CN_SET_NETINFO, (void*) &gWIZNETINFO);
wizchip_sw_reset();

socket(TCP_SOCK_NR, Sn_MR_TCP, TCP_PORT, 0x00);
while(getSn_SR(TCP_SOCK_NR) != SOCK_INIT);

{
    u8 inaddr_any[4]={0, 0, 0, 0}; // also tried 192.168.178.255, 255.255.255.255
    setSn_DIPR(UDP_SOCK_NR, inaddr_any); 
    setSn_DPORT(UDP_SOCK_NR, UDP_PORT);
}
socket(UDP_SOCK_NR, Sn_MR_UDP, UDP_PORT, UDP_FLAG);

}

void udp_task(void)
{

switch(getSn_SR(UDP_SOCK_NR))
{
case SOCK_UDP :
if((size = getSn_RX_RSR(UDP_SOCK_NR)) > 0) // goes here: and size=0 ?
{
if(size > TX_RX_MAX_BUF_SIZE) size = TX_RX_MAX_BUF_SIZE;
if( recvfrom(UDP_SOCK_NR, buf, size, destip, (uint16_t*)&destport) <= 0) break;

		....
}

}

I was wrong, this bit Sn_MR_BCASTB must be reset! (I corrected my previous post). So effective UDP_FLAG should be 0.

From datasheet:

Broadcast Blocking in MACRAW and UDP mode
0 : disable Broadcast Blocking
1 : enable Broadcast Blocking

I can confirm that it is working. I calculate the broadcast address as following:
m_Node.IPAddressBroadcast = m_Node.IPAddressLocal | ~(Network::Get()->GetNetmask());

where the m_Node.IPAddressLocal is 192.168.2.x and the netmask is 255.255.255.0

Both sending and receiving UDP broadcast is working fine.

So what is the problem then?

If

Then I guess you must write code which will respond to these broadcast datagrams.

The Problem is getSn_RX_RSR(UDP_SOCK_NR) is always Zero.
Also tested with free UDP Tools.

Before several posts above you said

and now you say that RSR is always 0. So it is NOT working? And please explain what is not working, how it does not work, how you think it must work, and attach wireshark logs of what is going on the W5500 interface to prove that there’re actual packets to be received by the W5500 (not wireshark log from another endpoint, but wireshark log from the last device in the chain just before W5500 - you may need to draw the diagram of your network).

Hi Eugeny, please note that there are 2 different users replying here. I was confirming your remark. Zhang has the issue.

1 Like

Thank you very much for pointing me, should have seen it before!

Thus if you have it working properly, it means that things should work, and Zhang should have some mistake - in chip configuration or in the wire.

udp.zip (198,2 KB)

this is the Wireshark log file.
PC: 192.168.178.21
W5500: 192.168.178.2

Also verified that data can be sent from W5500 to PC with sendto(UDP_SOCK_NR, Buf, 4, destip, destport); (UDP Tools received the message.)

But getSn_RX_RSR(UDP_SOCK_NR) is 0 when PC send message to W5500 (even dest-IP 192.168.178.2 or 192.168.178.255) .

As already mentioned, TCP works.

Ok, seems packet is ok (however length of 12 looks strange, maybe wireshark does not show padding). Looking into your code:

socket(TCP_SOCK_NR, Sn_MR_TCP, TCP_PORT, 0x00);
while(getSn_SR(TCP_SOCK_NR) != SOCK_INIT);
{
    u8 inaddr_any[4]={0, 0, 0, 0}; // also tried 192.168.178.255, 255.255.255.255
    setSn_DIPR(UDP_SOCK_NR, inaddr_any); 
    setSn_DPORT(UDP_SOCK_NR, UDP_PORT);
}
socket(UDP_SOCK_NR, Sn_MR_UDP, UDP_PORT, UDP_FLAG);

Why do you make socket for TCP first, then set up destination address of 0, and then, without closing the socket, trying to reinint it in UDP mode?
Why not open socket in UDP mode from the beginning (issuing CLOSE command beforehand to ensure that socket is closed properly)? There’s specific sequence to make things properly, look at W5100 datasheet chapter 5.

Just changed the order like this:

socket(UDP_SOCK_NR, Sn_MR_UDP, UDP_PORT, 0x00);
socket(TCP_SOCK_NR, Sn_MR_TCP, TCP_PORT, 0x00);
while(getSn_SR(TCP_SOCK_NR) != SOCK_INIT);

It works now (do not know why). Great!
Thank you very much.

Why do you open socket in one mode, and then open in another? If you use UDP, you do not need socket(TCP_SOCK_NR, Sn_MR_TCP, TCP_PORT, 0x00);!

I see these are two different sockets :slight_smile:
It is actually strange because operation of different sockets must be independent, and given you open one for UDP and another in TCP there should be no conflicts.