void BackendSelection::Init(void) { SSDPCacheEntries *pEntries = SSDPCache::Instance()->Find(gBackendURI); if (pEntries) { EntryMap ourMap; pEntries->GetEntryMap(ourMap); pEntries->DecrRef(); EntryMap::const_iterator it; for (it = ourMap.begin(); it != ourMap.end(); ++it) { AddItem(*it); (*it)->DecrRef(); } } }
/** * If there is only a single UPnP backend, use it. * * This does <i>not</i> prompt for PIN entry. If the backend requires one, * it will fail, and the caller needs to put up a UI to ask for one. */ int MythContextPrivate::UPnPautoconf(const int milliSeconds) { LOG(VB_GENERAL, LOG_INFO, QString("UPNP Search %1 secs") .arg(milliSeconds / 1000)); SSDP::Instance()->PerformSearch(gBackendURI, milliSeconds / 1000); // 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); 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(); } } SSDPCacheEntries *backends = SSDP::Instance()->Find(gBackendURI); if (!backends) { LOG(VB_GENERAL, LOG_INFO, "No UPnP backends found"); return 0; } int count = backends->Count(); if (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) { backends->DecrRef(); return count; } // Get this backend's location: DeviceLocation *BE = backends->GetFirst(); backends->DecrRef(); backends = NULL; // We don't actually know the backend's access PIN, so this will // only work for ones that have PIN access disabled (i.e. 0000) int ret = (UPnPconnect(BE, QString::null)) ? 1 : -1; BE->DecrRef(); return ret; }
virtual bool ProcessRequest(HTTPRequest *pRequest) { if (!pRequest) return false; if (pRequest->m_sBaseUrl != "/") return false; if (pRequest->m_sMethod == "getDeviceDesc") return false; pRequest->m_eResponseType = ResponseTypeHTML; pRequest->m_mapRespHeaders["Cache-Control"] = "no-cache=\"Ext\", max-age = 5000"; SSDPCacheEntries* cache = NULL; QString ipaddress = QString(); /* QStringList::const_iterator sit = UPnp::g_IPAddrList.begin(); for (; sit != UPnp::g_IPAddrList.end(); ++sit) { if (QHostAddress(*sit).protocol() == QAbstractSocket::IPv4Protocol) { ipaddress = *sit; break; } }*/ if (!UPnp::g_IPAddrList.isEmpty()) ipaddress = UPnp::g_IPAddrList.at(0); QString hostname = gCoreContext->GetHostName(); QDateTime qdtNow = MythDate::current(); QString masterhost = gCoreContext->GetMasterHostName(); QString masterip = gCoreContext->GetSetting("MasterServerIP"); QString masterport = gCoreContext->GetSettingOnHost("BackendStatusPort", masterhost, "6544"); QTextStream stream ( &pRequest->m_response ); stream.setCodec("UTF-8"); stream << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\n" << "<html xmlns=\"http://www.w3.org/1999/xhtml\"" << " xml:lang=\"en\" lang=\"en\">\r\n" << "<head>\r\n" << " <meta http-equiv=\"Content-Type\"" << "content=\"text/html; charset=UTF-8\" />\r\n" << " <title>MythFrontend Status - " << MythDate::toString(qdtNow, MythDate::kDateTimeShort) << " - " << MYTH_BINARY_VERSION << "</title>\r\n" << " <link rel=\"stylesheet\" href=\"/css/site.css\" type=\"text/css\">\r\n" << " <link rel=\"stylesheet\" href=\"/css/Status.css\" type=\"text/css\">\r\n" << "</head>\r\n" << "<body>\r\n\r\n" << " <h1 class=\"status\">MythFrontend Status</h1>\r\n"; // This frontend stream << " <div class=\"content\">\r\n" << " <h2 class=\"status\">This Frontend</h2>\r\n" << "Name : " << hostname << "<br />\r\n" << "Version : " << MYTH_BINARY_VERSION << "\r\n" << " </div>\r\n"; // Other frontends // This will not work with multiple frontends on the same machine (upnp // setup will fail on a second frontend anyway) and the ip address // filtering of the current frontend may not work in all situations cache = SSDP::Find("urn:schemas-mythtv-org:service:MythFrontend:1"); if (cache) { stream << " <div class=\"content\">\r\n" << " <h2 class=\"status\">Other Frontends</h2>\r\n"; EntryMap map; cache->GetEntryMap(map); cache->DecrRef(); cache = NULL; for (EntryMap::iterator it = map.begin(); it != map.end(); ++it) { QUrl url((*it)->m_sLocation); if (url.host() != ipaddress) { stream << "<br />" << url.host() << " (<a href=\"" << url.toString(QUrl::RemovePath) << "\">Status page</a>)\r\n"; } (*it)->DecrRef(); } stream << " </div>\r\n"; } // Master backend stream << " <div class=\"content\">\r\n" << " <h2 class=\"status\">MythTV Backends</h2>\r\n" << "Master: " << masterhost << " (<a href=\"http://" << masterip << ":" << masterport << "\">Status page</a>)\r\n"; // Slave backends cache = SSDP::Find("urn:schemas-mythtv-org:device:SlaveMediaServer:1"); if (cache) { EntryMap map; cache->GetEntryMap(map); cache->DecrRef(); cache = NULL; for (EntryMap::iterator it = map.begin(); it != map.end(); ++it) { QUrl url((*it)->m_sLocation); stream << "<br />" << "Slave: " << url.host() << " (<a href=\"" << url.toString(QUrl::RemovePath) << "\">Status page</a>)\r\n"; (*it)->DecrRef(); } } stream << " </div>\r\n"; stream << " <div class=\"content\">\r\n" << " <h2 class=\"status\">Services</h2>\r\n" << " <a href=\"MythFE/GetRemote\">Remote Control</a>\r\n" << " </div>\r\n"; double load[3]; if (getloadavg(load, 3) != -1) { stream << " <div class=\"content\">\r\n" << " <h2 class=\"status\">Machine Information</h2>\r\n" << " <div class=\"loadstatus\">\r\n" << " This machine's load average:" << "\r\n <ul>\r\n <li>" << "1 Minute: " << QString::number(load[0]) << "</li>\r\n" << " <li>5 Minutes: " << QString::number(load[1]) << "</li>\r\n" << " <li>15 Minutes: " << QString::number(load[2]) << "</li>\r\n </ul>\r\n" << " </div>\r\n" << " </div>\r\n"; } stream << "</body>\r\n</html>\r\n"; stream.flush(); return true; }