Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Make sure UPnP autoconfiguration allows backends time to respond.

According to the UPnP spec the backends have up to the timeout value to respond
but we don't wait that long for all backends to respond so long as one backend
has responded.

Our backends try to respond ASAP so this isn't as bad as doing this with other
UPnP devices, but there is a race condition which results in us connecting to
the first backend to respond instead of popping up the chooser when there is
more than one backend on the network.

This also resends the search request every 250 ms. When testing this I ran into
some problems due to lost packets. When the broadcast search packet doesn't make
it onto the network we obviously never get a response. This just resends that
packet every 250 ms until only one second remains for the backends to respond.
This increases the odds that we get a response in the presence of an unreliable
network (in my case WiFi with Ubuntu Precise & bug 836250).
  • Loading branch information...
commit f9e869f36979513572f64687fcad4941b0d38e3c 1 parent ac04246
daniel-kristjansson daniel-kristjansson authored
Showing with 28 additions and 28 deletions.
  1. +28 −28 mythtv/libs/libmyth/mythcontext.cpp
56 mythtv/libs/libmyth/mythcontext.cpp
View
@@ -795,46 +795,46 @@ int MythContextPrivate::ChooseBackend(const QString &error)
*/
int MythContextPrivate::UPnPautoconf(const int milliSeconds)
{
- SSDPCacheEntries *backends = NULL;
- int count;
- QString loc = "UPnPautoconf() - ";
- QTime timer;
+ LOG(VB_GENERAL, LOG_INFO, QString("UPNP Search %1 secs")
+ .arg(milliSeconds / 1000));
- SSDP::Instance()->PerformSearch( gBackendURI );
+ SSDP::Instance()->PerformSearch(gBackendURI, milliSeconds / 1000);
- for (timer.start(); timer.elapsed() < milliSeconds; )
+ // Search for a total of 'milliSeconds' ms, sending new search packet
+ // about every 250 ms until less than one second remains.
+ MythTimer totalTime; totalTime.start();
+ MythTimer searchTime; searchTime.start();
+ while (totalTime.elapsed() < milliSeconds)
{
usleep(25000);
- backends = SSDP::Instance()->Find( gBackendURI );
- if (backends)
- break;
-#if 0
- putchar('.');
-#endif
+ int ttl = milliSeconds - totalTime.elapsed();
+ if ((searchTime.elapsed() > 249) && (ttl > 1000))
+ {
+ LOG(VB_GENERAL, LOG_INFO, QString("UPNP Search %1 secs")
+ .arg(ttl / 1000));
+ SSDP::Instance()->PerformSearch(gBackendURI, ttl / 1000);
+ searchTime.start();
+ }
}
-#if 0
- putchar('\n');
-#endif
+
+ SSDPCacheEntries *backends = SSDP::Instance()->Find(gBackendURI);
if (!backends)
{
- LOG(VB_GENERAL, LOG_INFO, loc + "No UPnP backends found");
+ LOG(VB_GENERAL, LOG_INFO, "No UPnP backends found");
return 0;
}
- count = backends->Count();
- switch (count)
+ int count = backends->Count();
+ if (count)
{
- case 0:
- LOG(VB_GENERAL, LOG_ALERT, loc +
- "No UPnP backends found, but SSDP::Find() not NULL!");
- break;
- case 1:
- LOG(VB_GENERAL, LOG_INFO, loc + "Found one UPnP backend");
- break;
- default:
- LOG(VB_GENERAL, LOG_INFO, loc +
- QString("More than one UPnP backend found (%1)") .arg(count));
+ LOG(VB_GENERAL, LOG_INFO,
+ QString("Found %1 UPnP backends").arg(count));
+ }
+ else
+ {
+ LOG(VB_GENERAL, LOG_ERR,
+ "No UPnP backends found, but SSDP::Find() not NULL");
}
if (count != 1)
Please sign in to comment.
Something went wrong with that request. Please try again.