W5100 broadcast TX

Hi guys,

is it possible to send a broadcast packet from W5100? The datasheet doesn’t say anything about that, only multicast.
The application is something like:
1 Master + many slaves on the same network. Master doesn’t know addresses of slaves - that is why I need to broadcast a “ping request” to find out which nodes are connected.

Hi,
there is the DHCP client example [url]http://www.wiznet.co.kr/wp-content/uploads/wiznethome/Chip/W5100/Application%20Note/W5100_Application_Note.zip[/url] where the client sends a broadcast (UDP discover) packet “at all” and the only DHCP server responds.
Clearly you can not use this example “in toto” (as it is used by DHCP :wink: ), but you may use its model.

It should be quite easy : all devices listening on a particular port and when receiving a packet (from let’s call master) can send back a response packet on same socket and they are also able to extract IP and MAC of who sent the request :smiley: (so can know master end point) .
Please note that the response packet being UDP has in his head MAC, IP and port.
Master side processing incoming packets extracts information about slaves.

Thank you Coccoliso, I’ll take a look.
I have the whole system working(slave response, extracting MAC…). But I was not able to send the broadcast packet. At the moment I have a very ugly solution, where the master basically sends a ping request to every single IP address(one by one) in the subnet :smiley: It works, but the broadcast solution would be much better.

Hi,
keep in mind that it would be good that the “master” send 1 to nSlaves broadcast query to which responds only the “slave” interrogated (the first byte sent was the “slave” number who must answer … for example).
So you are able to get the list of “slaves” connected (at “master” side) only with a round of requests and all the “slaves” know who is the “master” with only a round.
Broadcast packets occupies a lot of bandwidth and so is the case of using it as little as possible :wink:

Hi,
I am looking at the example you told me about, I found the broadcast packet, but unfortunately it is for TCP/IP, where it is very easy, just send the packet to 255. Job done.
I am using UDP protocol, do you have any idea how to do that there?? :slight_smile:

Hi,
look what you’re wrong … you must look DHCP example … and uses UDP, the ports are the 67 recorded for the server and 68 for the client.

Folder :

W5100_Appnote_DHCP\Src\inet

Source file:

dhcp.c

Function:

check_DHCP_state 

You find a beautiful call at the socket function :

socket(s, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00)

And it is precisely what you need a beautiful UDP broadcast to all … :wink:
Clearly you will need:

  1. send in the package the number of “slave” by which you want the answer
  2. only one correct “slave” must understand that you want to talk to him and he alone must answer
    with a round of broadcast for nSlave you can find the list of all the “slave” in network.
    Remember that IP and MAC of the respondent are not in the TCP registers … are inside the packet header!
    See Sn_MR_UDP select case in recvfrom function.
    [url]http://www.wiznet.co.kr/wp-content/uploads/wiznethome/Chip/W5100/Software/W5100_Driver_V180(0).zip[/url]

Under folder :

W5100_DV_V180\

Source file:

socket.c

Function:

recvfrom
uint16 recvfrom(
  SOCKET s,   /**< the socket number */
  uint8 * buf,  /**< a pointer to copy the data to be received */
  uint16 len,   /**< the data size to read */
  uint8 * addr,   /**< a pointer to store the peer's IP address */
  uint16 *port  /**< a pointer to store the peer's port number. */
  )
{
  uint8 head[8];
  uint16 data_len=0;
  uint16 ptr=0;

  if ( len > 0 )
  {
    ptr = IINCHIP_READ(Sn_RX_RD0(s));
    ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);

    switch (IINCHIP_READ(Sn_MR(s)) & 0x07)
    {
    case Sn_MR_UDP :                       
        read_data(s, (uint8 *)ptr, head, 0x08);
        ptr += 8;
        // read peer's IP address, port number.
        addr[0] = head[0];
        addr[1] = head[1];
        addr[2] = head[2];
        addr[3] = head[3];
        *port = head[4];
        *port = (*port << 8) + head[5];
        data_len = head[6];
        data_len = (data_len << 8) + head[7];

      read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
      ptr += data_len;

      IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
      IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
        break;

    case Sn_MR_IPRAW :
        read_data(s, (uint8 *)ptr, head, 0x06);
        ptr += 6;

        addr[0] = head[0];
        addr[1] = head[1];
        addr[2] = head[2];
        addr[3] = head[3];
        data_len = head[4];
        data_len = (data_len << 8) + head[5];

      read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
      ptr += data_len;

      IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
      IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
        break;
    case Sn_MR_MACRAW :
        read_data(s,(uint8*)ptr,head,2);
        ptr+=2;
        data_len = head[0];
        data_len = (data_len<<8) + head[1] - 2;

        read_data(s,(uint8*) ptr,buf,data_len);
        ptr += data_len;
        IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
        IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
      break;

    default :
        break;
    }
    IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);

    /* +20071122[chungs]:wait to process the command... */
    while( IINCHIP_READ(Sn_CR(s)) )
      ;
    /* ------- */
  }
  return data_len;
}