Arduino in windows network overview - SSDP almost working

hi,

I wonder why I didn’t think of this before but it is nice to see your arduino pop up in the Windows network overview amongst devices that were automatically discovered. Attached pics show what I mean.

Issue is the discovery works but the Arduino disappears from the overview as I cannot send the keep-alive udp (multicast I assume) to destination 239.255.255.250 port 1900

How this works is discribed in http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf

Step 1: Respond to “Search request with M-SEARCH”

Code copied from http://arduino.cc/en/Tutorial/UDPSendReceiveString example:

// if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if(packetSize)
  {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i =0; i < 4; i++)
    {
      Serial.print(remote[i], DEC);
      if (i < 3)
      {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer1,UDP_TX_PACKET_MAX_SIZE);
    Serial.println("Contents:");
    Serial.println(packetBuffer1);
    Serial.println(second());

    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write("HTTP/1.1 200 OK\r\nSERVER:Cream/3.1,UPnP/1.0,UPnP/1.0\r\nCACHE-CONTROL:max-age=360\r\nLOCATION:http://");
    Udp.write("192.168.2.125");    // this really should be Ethernet.LocalIP()
    Udp.write("/devdesc.xml\r\nST:upnp:rootdevice\r\nUSN:uuid:b629a14a-d342-3c5c-bc8c-f7417arduino::upnp:rootdevice\r\nEXT:\r\n\r\n");
    Udp.endPacket();
  }

→ content of UDP message inspired on an Okidata laserprinter.

Step 2: Send a reply to a device querying your /devdesc.xml (device description)

        first do a http 200 ok response and then...

         if (strstr(inData, "devdesc.xml") != 0) {          
          Serial.println("send device description");
          WebSrv.println("Content-Type: text/xml");
          WebSrv.println();
          WebSrv.print("<?xml version=\"1.0\"?>\r\n");
          WebSrv.print("<root xmlns=\"urn:schemas-upnp-org:device-1-0\">\r\n");
          WebSrv.print("  <specVersion>\r\n");
          WebSrv.print("    <major>1</major>\r\n");
          WebSrv.print("    <minor>0</minor>\r\n");
          WebSrv.print("  </specVersion>\r\n");
          WebSrv.print("  <URLBase>http://");
          WebSrv.print(Ethernet.localIP());
          WebSrv.print("</URLBase>\r\n");
          WebSrv.print("  <device>\r\n");
          WebSrv.print("    <deviceType>urn:AcmePlus-com:device:Arduino:1</deviceType>\r\n");
          WebSrv.print("    <friendlyName>Arduino Beregening</friendlyName>\r\n");
          WebSrv.print("    <manufacturer>JHH</manufacturer>\r\n");
          WebSrv.print("    <manufacturerURL>http://arduino.cc</manufacturerURL>\r\n");
          WebSrv.print("    <modelDescription>EthernetBoard Beregening</modelDescription>\r\n");
          WebSrv.print("    <modelName>AcmePlus Rainmaker</modelName>\r\n");
          WebSrv.print("    <modelNumber>De Luxe :+)</modelNumber>\r\n");
          WebSrv.print("    <serialNumber></serialNumber>\r\n");
          WebSrv.print("    <UDN>uuid:b629a14a-d342-3c5c-bc8c-f7417arduino</UDN>\r\n");
         WebSrv.print("    <presentationURL>http://");
          WebSrv.print(Ethernet.localIP());
          WebSrv.print("/info</presentationURL>\r\n");   //BaseURL + /info is device homepage.
          WebSrv.print("  </device>\r\n");
          WebSrv.print("</root>\r\n");
        }

Step 3: Send keep-alive messages

   Notify and localport are: destination 239.255.255.250 port 1900

    Udp.beginPacket(Notify, localPort);
    Udp.write("NOTIFY * HTTP/1.1 200 OK\r\nSERVER:Cream/3.1,UPnP/1.0,UPnP/1.0\r\nCACHE-CONTROL:max-age=360\r\nLOCATION:http://");
    Udp.write("192.168.2.125");
    Udp.write("/devdesc.xml\r\nNT:uuid:b629a14a-d342-3c5c-bc8c-f7417arduino\r\nNTS:ssdp:alive\r\nUSN:uuid:b629a14a-d342-3c5c-bc8c-f7417arduino\r\n\r\n");
    Udp.endPacket();

→ last step is where it goes wrong: I suppose the address is a multicast and it doesn’t get sent. Result is that while the Arduino shows up in the network overview it disappears after a short while which is a shame as it is rather cool that you can right-click the icon and open the Arduino web page from there.

→ I’m using the standard ethernet library from 1.0.5 windows distribution of the Arduino ide with a W5100 ethernet shield.

→ this is where it ends for my limited knowledge…

Is there a library that has multicast in? I’ve been considering an ENC28J60 network card but there are so many libraries it gets confusing. In the end I hope that W5100 ethernet shield is more widely used so my chances of getting somewhere are higher.

Thanks for reading so far! Help/suggestions very much appreciated…

ps: Beregening is Dutch for Sprinkler (controller)

Jhh

overview.PNG

Hello,

I've been researching how to implement an M-SEARCH request using multicasting and UDP.

The library that I found "supposedly" enables multicasting on bit 7 of the Sn_MR register of the W5100 WizNet Chip.

Here is where I found this library and the code I am trying to compile. I keep getting the error: NOTIFY_SSDP_RECEIVE_UPNP_UDP.ino: In function 'void setup()': NOTIFY_SSDP_RECEIVE_UPNP_UDP.ino:31:2: error: 'Udp' was not declared in this scope

Source: https://tkkrlab.nl/wiki/Arduino_UDP_multicast

I can help a little. The include file and library has changed for udp.

#include <EthernetUdp.h>

// create an instance of EthernetUdp
EthernetUdp Udp;

You would need to modify the new ethernet library with the multicast begin function.