TL;DR: SSDP library not receiving datagram. Wireshark shows expected(?) traffic.
I am using the android-dlna library to support SSDP in an Android app. The goal is to discover a custom SSDP-enabled device, get its IP Address, then make RESTful API calls to it. This works well on iOS, but I am having some trouble receiving the datagram on Android.
Using Wireshark, I can determine that the SSDP search goes out, and the device returns with a status OK, but this loop never gets past the receive()
method:
SSDPSearchMsg search = new SSDPSearchMsg(SSDP.ST_ContentDirectory);
Log.e("SSDP", search.toString());
SSDPSocket sock = null;
try {
sock = new SSDPSocket();
sock.send(search.toString());
while (true) {
Log.e("SSDP", "Receive...");//only called once (stuck here)
DatagramPacket dp = sock.receive();
Log.e("SSDP", "Datagram Received with data " + new String(dp.getData()));
}
} catch (IOException e) {
e.printStackTrace();
}
finally {
Log.e("SSDP", "Closing Socket");
if (sock != null)
sock.close();
}
This is all done in anAsyncTask
. I see the following printed to logcat:
SSDP M-SEARCH * HTTP/1.1
SSDP Host:239.255.255.250:1900
SSDP Man:"ssdp:discover"
SSDP ST:urn:schemas-upnp-org:service:ContentDirectory:1
SSDP MX:3
SSDP
SSDP Receive...
Wireshark Reports the following related datagrams:
Source Destination Protocol Length Info
---------------------------------------------------------------------------
192.168.1.7 239.255.255.250 SSDP 175 M-SEARCH * HTTP/1.1
192.168.1.1 192.168.1.7 SSDP 356 HTTP/1.1 200 OK
Finally, I have the following Manifest Permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
What am I overlooking? Why aren't I receiving the Response Datagram?
DatagramPacket dp = sock.receive();
I use a byte array as a buffer and useDatagramPacket dp = new DatagramPacket(buf, buf.length);
. The byte array is simplybyte[] buf = new byte[1024];
. I then callmSSDPSocket.receive(dp);
wheremSSDPSocket
is myMulticastSocket
. – Squonk