|
MythTV
0.26-pre
|
00001 00002 // Program Name: mediarenderer.cpp 00003 // 00004 // Purpose - uPnp Media Renderer main Class 00005 // 00006 // Created By : David Blain Created On : Jan. 15, 2007 00007 // Modified By : Modified On: 00008 // 00010 00011 #include <QTextStream> 00012 00013 #include "upnpsubscription.h" 00014 #include "mediarenderer.h" 00015 #include "mythversion.h" 00016 #include "upnpscanner.h" 00017 #include "mythfexml.h" 00018 #include "compat.h" 00019 #include "mythmiscutil.h" 00020 00021 #include "serviceHosts/frontendServiceHost.h" 00022 00023 class MythFrontendStatus : public HttpServerExtension 00024 { 00025 public: 00026 MythFrontendStatus(const QString &sSharePath) 00027 : HttpServerExtension("MythFrontendStatus", sSharePath) { } 00028 00029 virtual QStringList GetBasePaths() { return QStringList( "/" ); } 00030 00031 virtual bool ProcessRequest(HTTPRequest *pRequest) 00032 { 00033 if (!pRequest) 00034 return false; 00035 00036 if (pRequest->m_sBaseUrl != "/") 00037 return false; 00038 00039 if (pRequest->m_sMethod == "getDeviceDesc") 00040 return false; 00041 00042 pRequest->m_eResponseType = ResponseTypeHTML; 00043 pRequest->m_mapRespHeaders["Cache-Control"] = 00044 "no-cache=\"Ext\", max-age = 5000"; 00045 00046 SSDPCacheEntries* cache = NULL; 00047 QString ipaddress = QString(); 00048 /* QStringList::const_iterator sit = UPnp::g_IPAddrList.begin(); 00049 for (; sit != UPnp::g_IPAddrList.end(); ++sit) 00050 { 00051 if (QHostAddress(*sit).protocol() == QAbstractSocket::IPv4Protocol) 00052 { 00053 ipaddress = *sit; 00054 break; 00055 } 00056 }*/ 00057 if (!UPnp::g_IPAddrList.isEmpty()) 00058 ipaddress = UPnp::g_IPAddrList.at(0); 00059 00060 QString hostname = gCoreContext->GetHostName(); 00061 QDateTime qdtNow = QDateTime::currentDateTime(); 00062 QString masterhost = gCoreContext->GetMasterHostName(); 00063 QString masterip = gCoreContext->GetSetting("MasterServerIP"); 00064 QString masterport = gCoreContext->GetSettingOnHost("BackendStatusPort", 00065 masterhost, "6544"); 00066 00067 QTextStream stream ( &pRequest->m_response ); 00068 stream.setCodec("UTF-8"); 00069 00070 stream 00071 << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " 00072 << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\n" 00073 << "<html xmlns=\"http://www.w3.org/1999/xhtml\"" 00074 << " xml:lang=\"en\" lang=\"en\">\r\n" 00075 << "<head>\r\n" 00076 << " <meta http-equiv=\"Content-Type\"" 00077 << "content=\"text/html; charset=UTF-8\" />\r\n" 00078 << " <title>MythFrontend Status - " 00079 << MythDateTimeToString(qdtNow, kDateTimeShort) << " - " 00080 << MYTH_BINARY_VERSION << "</title>\r\n" 00081 << " <link rel=\"stylesheet\" href=\"/css/site.css\" type=\"text/css\">\r\n" 00082 << " <link rel=\"stylesheet\" href=\"/css/Status.css\" type=\"text/css\">\r\n" 00083 << "</head>\r\n" 00084 << "<body>\r\n\r\n" 00085 << " <h1 class=\"status\">MythFrontend Status</h1>\r\n"; 00086 00087 // This frontend 00088 stream 00089 << " <div class=\"content\">\r\n" 00090 << " <h2 class=\"status\">This Frontend</h2>\r\n" 00091 << "Name : " << hostname << "<br />\r\n" 00092 << "Version : " << MYTH_BINARY_VERSION << "\r\n" 00093 << " </div>\r\n"; 00094 00095 // Other frontends 00096 00097 // This will not work with multiple frontends on the same machine (upnp 00098 // setup will fail on a second frontend anyway) and the ip address 00099 // filtering of the current frontend may not work in all situations 00100 00101 cache = SSDP::Find("urn:schemas-mythtv-org:service:MythFrontend:1"); 00102 if (cache) 00103 { 00104 stream 00105 << " <div class=\"content\">\r\n" 00106 << " <h2 class=\"status\">Other Frontends</h2>\r\n"; 00107 00108 EntryMap map; 00109 cache->GetEntryMap(map); 00110 cache->Release(); 00111 cache = NULL; 00112 00113 QMapIterator< QString, DeviceLocation * > i(map); 00114 while (i.hasNext()) 00115 { 00116 i.next(); 00117 QUrl url(i.value()->m_sLocation); 00118 if (url.host() != ipaddress) 00119 { 00120 stream << "<br />" << url.host() << " (<a href=\"" 00121 << url.toString(QUrl::RemovePath) 00122 << "\">Status page</a>)\r\n"; 00123 } 00124 i.value()->Release(); 00125 } 00126 stream << " </div>\r\n"; 00127 } 00128 00129 // Master backend 00130 stream 00131 << " <div class=\"content\">\r\n" 00132 << " <h2 class=\"status\">MythTV Backends</h2>\r\n" 00133 << "Master: " << masterhost << " (<a href=\"http://" 00134 << masterip << ":" << masterport 00135 << "\">Status page</a>)\r\n"; 00136 00137 // Slave backends 00138 cache = SSDP::Find("urn:schemas-mythtv-org:device:SlaveMediaServer:1"); 00139 if (cache) 00140 { 00141 EntryMap map; 00142 cache->GetEntryMap(map); 00143 cache->Release(); 00144 cache = NULL; 00145 00146 QMapIterator< QString, DeviceLocation * > i(map); 00147 while (i.hasNext()) 00148 { 00149 i.next(); 00150 QUrl url(i.value()->m_sLocation); 00151 stream << "<br />" << "Slave: " << url.host() 00152 << " (<a href=\"" 00153 << url.toString(QUrl::RemovePath) 00154 << "\">Status page</a>)\r\n"; 00155 i.value()->Release(); 00156 } 00157 } 00158 00159 stream 00160 << " </div>\r\n"; 00161 00162 stream 00163 << " <div class=\"content\">\r\n" 00164 << " <h2 class=\"status\">Services</h2>\r\n" 00165 << " <a href=\"MythFE/GetRemote\">Remote Control</a>\r\n" 00166 << " </div>\r\n"; 00167 00168 double load[3]; 00169 if (getloadavg(load, 3) != -1) 00170 { 00171 stream 00172 << " <div class=\"content\">\r\n" 00173 << " <h2 class=\"status\">Machine Information</h2>\r\n" 00174 << " <div class=\"loadstatus\">\r\n" 00175 << " This machine's load average:" 00176 << "\r\n <ul>\r\n <li>" 00177 << "1 Minute: " << QString::number(load[0]) << "</li>\r\n" 00178 << " <li>5 Minutes: " << QString::number(load[1]) << "</li>\r\n" 00179 << " <li>15 Minutes: " << QString::number(load[2]) 00180 << "</li>\r\n </ul>\r\n" 00181 << " </div>\r\n" 00182 << " </div>\r\n"; 00183 } 00184 00185 stream << "</body>\r\n</html>\r\n"; 00186 stream.flush(); 00187 00188 return true; 00189 } 00190 }; 00191 00194 // 00195 // UPnp MediaRenderer Class implementaion 00196 // 00199 00201 // 00203 00204 MediaRenderer::MediaRenderer() 00205 { 00206 LOG(VB_UPNP, LOG_INFO, "MediaRenderer::Begin"); 00207 00208 // ---------------------------------------------------------------------- 00209 // Initialize Configuration class (XML file for frontend) 00210 // ---------------------------------------------------------------------- 00211 00212 SetConfiguration( new XmlConfiguration( "config.xml" )); 00213 00214 // ---------------------------------------------------------------------- 00215 // Create mini HTTP Server 00216 // ---------------------------------------------------------------------- 00217 00218 int nPort = g_pConfig->GetValue( "UPnP/MythFrontend/ServicePort", 6547 ); 00219 00220 m_pHttpServer = new HttpServer(); 00221 00222 if (!m_pHttpServer) 00223 return; 00224 00225 if (!m_pHttpServer->listen(nPort)) 00226 { 00227 LOG(VB_GENERAL, LOG_ERR, "MediaRenderer::HttpServer Create Error"); 00228 delete m_pHttpServer; 00229 m_pHttpServer = NULL; 00230 return; 00231 } 00232 00233 // ---------------------------------------------------------------------- 00234 // Initialize UPnp Stack 00235 // ---------------------------------------------------------------------- 00236 00237 if (Initialize( nPort, m_pHttpServer )) 00238 { 00239 // ------------------------------------------------------------------ 00240 // Create device Description 00241 // ------------------------------------------------------------------ 00242 00243 LOG(VB_UPNP, LOG_INFO, "MediaRenderer::Creating UPnp Description"); 00244 00245 UPnpDevice &device = g_UPnpDeviceDesc.m_rootDevice; 00246 00247 device.m_sDeviceType = "urn:schemas-upnp-org:device:MediaRenderer:1"; 00248 device.m_sFriendlyName = "MythTV AV Renderer"; 00249 device.m_sManufacturer = "MythTV"; 00250 device.m_sManufacturerURL = "http://www.mythtv.org"; 00251 device.m_sModelDescription = "MythTV AV Media Renderer"; 00252 device.m_sModelName = "MythTV AV Media Renderer"; 00253 device.m_sModelURL = "http://www.mythtv.org"; 00254 device.m_sUPC = ""; 00255 device.m_sPresentationURL = "/"; 00256 00257 // ------------------------------------------------------------------ 00258 // Register any HttpServerExtensions... 00259 // ------------------------------------------------------------------ 00260 00261 LOG(VB_UPNP, LOG_INFO, 00262 "MediaRenderer::Registering MythFrontendStatus service."); 00263 m_pHttpServer->RegisterExtension( 00264 new MythFrontendStatus(m_pHttpServer->GetSharePath())); 00265 00266 QString sSinkProtocols = "http-get:*:image/gif:*," 00267 "http-get:*:image/jpeg:*," 00268 "http-get:*:image/png:*," 00269 "http-get:*:video/avi:*," 00270 "http-get:*:audio/mpeg:*," 00271 "http-get:*:audio/wav:*," 00272 "http-get:*:video/mpeg:*," 00273 "http-get:*:video/nupplevideo:*," 00274 "http-get:*:video/x-ms-wmv:*"; 00275 // ------------------------------------------------------------------ 00276 // Register the MythFEXML protocol... 00277 // ------------------------------------------------------------------ 00278 LOG(VB_UPNP, LOG_INFO, "MediaRenderer::Registering MythFEXML Service."); 00279 m_pHttpServer->RegisterExtension( 00280 new MythFEXML(RootDevice(), m_pHttpServer->GetSharePath())); 00281 00282 LOG(VB_UPNP, LOG_INFO, "MediaRenderer::Registering Status Service."); 00283 m_pHttpServer->RegisterExtension(new FrontendServiceHost(m_pHttpServer->GetSharePath())); 00284 00285 #if 0 00286 LOG(VB_UPNP, LOG_INFO, 00287 "MediaRenderer::Registering AVTransport Service."); 00288 m_pUPnpAVT = new UPnpAVTransport( RootDevice() ); 00289 m_pHttpServer->RegisterExtension( m_pUPnpAVT ); 00290 #endif 00291 00292 LOG(VB_UPNP, LOG_INFO, "MediaRenderer::Registering CMGR Service."); 00293 // HttpServer will be responsible for deleting UPnpCMGR 00294 m_pUPnpCMGR = new UPnpCMGR( 00295 RootDevice(), m_pHttpServer->GetSharePath(), "", sSinkProtocols); 00296 m_pHttpServer->RegisterExtension( m_pUPnpCMGR ); 00297 00298 #if 0 00299 LOG(VB_UPNP, LOG_INFO, 00300 "MediaRenderer::Registering RenderingControl Service."); 00301 m_pUPnpRCTL= new UPnpRCTL( RootDevice() ); 00302 m_pHttpServer->RegisterExtension( m_pUPnpRCTL ); 00303 #endif 00304 00305 UPNPSubscription *subscription = NULL; 00306 if (getenv("MYTHTV_UPNPSCANNER")) 00307 { 00308 LOG(VB_UPNP, LOG_INFO, 00309 "MediaRenderer: Registering subscription service."); 00310 00311 subscription = new UPNPSubscription( 00312 m_pHttpServer->GetSharePath(), nPort); 00313 m_pHttpServer->RegisterExtension(subscription); 00314 } 00315 00316 Start(); 00317 00318 // Start scanning for UPnP media servers 00319 if (subscription) 00320 UPNPScanner::Enable(true, subscription); 00321 00322 // ensure the frontend is aware of all backends (slave and master) and 00323 // other frontends 00324 SSDP::Instance()->PerformSearch("ssdp:all"); 00325 } 00326 else 00327 { 00328 LOG(VB_GENERAL, LOG_ERR, 00329 "MediaRenderer::Unable to Initialize UPnp Stack"); 00330 } 00331 00332 LOG(VB_UPNP, LOG_INFO, "MediaRenderer::End"); 00333 } 00334 00336 // 00338 00339 MediaRenderer::~MediaRenderer() 00340 { 00341 UPNPScanner::Enable(false); 00342 delete m_pHttpServer; 00343 }
1.7.6.1