I'm sending out the necessary SSDP discovery message as per the UPNP specification for device discovery. However the device fails to show up on UPnP testing software and refuses to show up on the network meaning it is not being discovered, thus i must be doing something wrong but i cant figure out what. This is my c# code for sending out the discovery messages:
UdpClient udpClient = new();
IPAddress multiCastAddress = IPAddress.Parse("239.255.255.250");
IPEndPoint iPEndPoint = new(IPAddress.Any, 1900);
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReuseAddress, true);
udpClient.ExclusiveAddressUse = false;
udpClient.Client.Bind(iPEndPoint);
udpClient.JoinMulticastGroup(multiCastAddress);
string discoveryMessage1 = "NOTIFY * HTTP/1.1\r\n" +
"HOST: 239.255.255.250:1900\r\n" +
"CACHE-CONTROL: max-age = 1800\r\n" +
"USER - AGENT: OS / version UPnP / 2.0 product / version\r\n"+
"LOCATION: http://192.168.100.9:8080/desc.xml\r\n" +
"NT: upnp:rootdevice\r\n" +
"NTS: ssdp:alive\r\n" +
"SERVER: Windows/10 UPnP/1.1 MyProduct/1.0\r\n" +
"USN: uuid:9ce5830f-1e08-48c4-a17e-0ddaa544c14d::upnp:rootdevice\r\n";
string discoveryMessage2 = "NOTIFY * HTTP/1.1\r\n" +
"HOST: 239.255.255.250:1900\r\n" +
"CACHE-CONTROL: max-age = 1800\r\n" +
"LOCATION: http://192.168.100.9:8080/desc.xml\r\n" +
"NT: uuid:9ce5830f-1e08-48c4-a17e-0ddaa544c14d\r\n" +
"NTS: ssdp:alive\r\n" +
"SERVER: Windows/10 UPnP/1.1 MyProduct/1.0\r\n" +
"USN: uuid:9ce5830f-1e08-48c4-a17e-0ddaa544c14d\r\n";
string discoveryMessage3 = "NOTIFY * HTTP/1.1\r\n" +
"HOST: 239.255.255.250:1900\r\n" +
"CACHE-CONTROL: max-age = 1800\r\n" +
"LOCATION: http://192.168.100.9:8080/desc.xml\r\n" +
"NT: urn:schemas-upnp-org:device:MediaServer:1\r\n" +
"NTS: ssdp:alive\r\n" +
"SERVER: Windows/10 UPnP/1.1 MyProduct/1.0\r\n" +
"USN: uuid:9ce5830f-1e08-48c4-a17e-0ddaa544c14d::urn:schemas-upnp-org:device:MediaServer:1\r\n";
string discoveryMessage4 = "NOTIFY * HTTP/1.1\r\n" +
"HOST: 239.255.255.250:1900\r\n" +
"CACHE-CONTROL: max-age = 1800\r\n" +
"LOCATION: http://192.168.100.9:8080/desc.xml\r\n" +
"NT: urn:schemas-upnp-org:service:ContentDirectory:1\r\n" +
"NTS: ssdp:alive\r\n" +
"SERVER: Windows/10 UPnP/1.1 MyProduct/1.0\r\n" +
"USN: uuid:9ce5830f-1e08-48c4-a17e-0ddaa544c14d::urn:schemas-upnp-org:service:ContentDirectory:1\r\n";
byte[] discoveryBytes1 = Encoding.ASCII.GetBytes(discoveryMessage1);
byte[] discoveryBytes2 = Encoding.ASCII.GetBytes(discoveryMessage2);
byte[] discoveryBytes3 = Encoding.ASCII.GetBytes(discoveryMessage3);
byte[] discoveryBytes4 = Encoding.ASCII.GetBytes(discoveryMessage4);
Task.Run(() =>
{
for (int i = 0; i <= 3; i++)
{
udpClient.Send(discoveryBytes1, discoveryBytes1.Length, new IPEndPoint(multiCastAddress, 1900));
udpClient.Send(discoveryBytes2, discoveryBytes2.Length, new IPEndPoint(multiCastAddress, 1900));
udpClient.Send(discoveryBytes3, discoveryBytes3.Length, new IPEndPoint(multiCastAddress, 1900));
udpClient.Send(discoveryBytes4, discoveryBytes4.Length, new IPEndPoint(multiCastAddress, 1900));
Thread.Sleep(2000);
}
});
This is the XML description:
<root xmlns=""urn:schemas-upnp-org:device-1-0"">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<device>
<deviceType>urn:schemas-upnp-org:device:MediaServer:1</deviceType>
<friendlyName>SwiftUPNP</friendlyName>
<manufacturer>Eugene Noble</manufacturer>
<manufacturerURL>URL to manufacturer site</manufacturerURL>
<modelDescription>long user-friendly title</modelDescription>
<modelName>model name</modelName>
<modelNumber>model number</modelNumber>
<modelURL>URL to model site</modelURL>
<serialNumber>manufacturer's serial number</serialNumber>
<UDN>uuid:9ce5830f-1e08-48c4-a17e-0ddaa544c14d</UDN>
<UPC>Universal Product Code</UPC>
<iconList>
<icon>
<mimetype>image/format</mimetype>
<width
>horizontal pixels</width>
<height>vertical pixels</height>
<depth>color depth</depth>
<url>URL to icon</url>
</icon>
XML to declare other icons, if any, go here
</iconList>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:ContentDirectory:1</serviceType>
<serviceId>urn:upnp-org:serviceId:ContentDirectory</serviceId>
<SCPDURL>/contentDirectory.xml</SCPDURL>
<controlURL>URL for control</controlURL>
<eventSubURL>URL for eventing</eventSubURL>
</service>
<service>
<serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
<serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
<SCPDURL>URL to service description</SCPDURL>
<controlURL>URL for control</controlURL>
<eventSubURL>URL for eventing</eventSubURL>
</service>
<service>
<serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType>
<serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
<SCPDURL>URL to service description</SCPDURL>
<controlURL>URL for control</controlURL>
<eventSubURL>URL for eventing</eventSubURL>
</service></serviceList>
<deviceList>
Description of embedded devices added by UPnP vendor (if any) go here
</deviceList>
<presentationURL>URL for presentation</presentationURL>
</device>
</root>
this description is being served from a c# server like so:
public static void CreateServer()
{
using(HttpListener listener = new())
{
listener.Prefixes.Add($"http://+:8080/");
listener.Start();
Console.WriteLine("Server is running");
while (true)
{
try
{
var context = listener.GetContext();
HandleContext(context);
}
catch { }
}
}
}
private static void HandleContext(HttpListenerContext context)
{
string route = context.Request.Url.AbsolutePath;
Console.WriteLine($"Request made to {route}");
switch (route)
{
case "/desc.xml":
string resp = DescriptionString();
byte[] respByte = Encoding.ASCII.GetBytes(resp);
context.Response.ContentType = "text/xml";
context.Response.OutputStream.Write(respByte,0, respByte.Length);
context.Response.OutputStream.Close();
break;
case "/contentDirectory.xml":
string cdresp = ContentDirectoryService();
byte[] cdrespByte = Encoding.ASCII.GetBytes(cdresp);
context.Response.ContentType = "text/xml";
context.Response.OutputStream.Write(cdrespByte, 0, cdrespByte.Length);
context.Response.OutputStream.Close();
break;
}
}
}
What am i doing wrong?