I'm using GCDAsyncUdpSocket - https://github.com/robbiehanson/CocoaAsyncSocket to build a Simple Services Discovery Protocol utility into my app. I bind one socket (ssdpSock) to port 1900, and another one (ssdpSendSock) to port 0, using an error-checked version of the following:
[sock enableReusePort:YES error:&socketError];
[sock bindToPort:port error:&socketError];
[sock joinMulticastGroup:@"239.255.255.250" error:&socketError];
[sock enableBroadcast:TRUE error:&socketError];
[sock beginReceiving:&socketError];
This all runs without error.
I listen for any incoming UDP data:
(void)udpSocket:(GCDAsyncUdpSocket *)sock
didReceiveData:(NSData *)data
fromAddress:(NSData *)address
withFilterContext:(nullable id)filterContext {
NSString *theSock = @"unknown socket";
if (sock == _ssdpSock) theSock = @"_ssdpSock";
if (sock == _ssdpSendSock) theSock = @"_ssdpSendSock";
NSLog(@"%@ received from addr:%@ port:%d",
theSock,
[GCDAsyncUdpSocket hostFromAddress:address],
[GCDAsyncUdpSocket portFromAddress:address]);
I then send out SSDP queries on ssdpSendSock:
[_ssdpSendSock sendData:queryStr toHost:@"239.255.255.250" port:1900 withTimeout:2 tag:1];
which I receive back, because they're broadcasts:
_ssdpSock received from addr:192.168.0.2 port:59946
(192.168.0.2 is my sending iPhone's IP address).
and, when the device type I'm looking for exists on the local network, I get a reply from it back to ssdpSendSock:
_ssdpSendSock received from addr:192.168.0.30 port:1900
(192.168.0.30 is the device I'm listening for).
So far, so good.
However, the devices I'm looking for, and anything else on the 'net talking SSDP/UPnP, also broadcast unsolicited status updates, which I normally receive on ssdpSock:
_ssdpSock received from addr:192.168.0.30 port:60414
_ssdpSock received from addr:192.168.0.80 port:57546
_ssdpSock received from addr:192.168.0.3 port:59140
These are important, because that's how I can tell when a device comes online or disappears without explicitly querying for them.
And this all works fine on iOS versions prior to 14.5. On 14.5, I just don't see anything received on ssdpSock other than my initial queries.
I already have NSLocalNetworkUsageDescription and NSLocationUsageDescription set (since iOS 13); I get the "allow local network access" alert on first run; and Settings Privacy Local Network is confirmed as set for my app. So I applied for the com.apple.developer.networking.multicast
entitlement and was approved. I've set it up according to Quinn "the Eskimo!"'s excellent instructions - https://developer.apple.com/forums/thread/663271 for the New Process, and confirmed it's built into my app.
And I still don't see anything on ssdpSock, other than my initial queries!
Again, the same code works fine on iOS 9–13. It just falls down on iOS 14.5.
Additionally, the current App Store version of the app, using the same SSDP code but built with Xcode 12.4 or 12.3, seems to work fine when installed on 14.5. But building and running the code with Xcode 12, 12.2, and 12.4, after manually adding the iOS 14.5 device support files to those older versions of XCode, still fails on iOS 14.5.
What additional mystical incantations must I invoke on 14.5 to receive multicast messages from other devices on the local network?