|
MythTV
0.26-pre
|
00001 00002 // Program Name: upnp.cpp 00003 // Created : Oct. 24, 2005 00004 // 00005 // Purpose : UPnp Main Class 00006 // 00007 // Copyright (c) 2005 David Blain <dblain@mythtv.org> 00008 // 00009 // Licensed under the GPL v2 or later, see COPYING for details 00010 // 00012 00013 #include "upnptaskcache.h" 00014 #include "mythlogging.h" 00015 #include "upnp.h" 00016 00018 // Global/Class Static variables 00020 00021 UPnpDeviceDesc UPnp::g_UPnpDeviceDesc; 00022 QStringList UPnp::g_IPAddrList; 00023 00024 Configuration *UPnp::g_pConfig = NULL; 00025 00028 // 00029 // UPnp Class implementaion 00030 // 00033 00035 // 00037 00038 UPnp::UPnp() 00039 : m_pHttpServer(NULL), m_nServicePort(0) 00040 { 00041 LOG(VB_UPNP, LOG_DEBUG, "UPnp - Constructor"); 00042 } 00043 00045 // 00047 00048 UPnp::~UPnp() 00049 { 00050 LOG(VB_UPNP, LOG_DEBUG, "UPnp - Destructor"); 00051 CleanUp(); 00052 } 00053 00055 // 00057 00058 void UPnp::SetConfiguration( Configuration *pConfig ) 00059 { 00060 if (g_pConfig) 00061 delete g_pConfig; 00062 00063 g_pConfig = pConfig; 00064 } 00065 00067 // 00069 00070 Configuration *UPnp::GetConfiguration() 00071 { 00072 // If someone is asking for a config and it's NULL, create a 00073 // new XmlConfiguration since we don't have database info yet. 00074 00075 if (g_pConfig == NULL) 00076 g_pConfig = new XmlConfiguration( "config.xml" ); 00077 00078 return g_pConfig; 00079 } 00080 00082 // 00084 00085 bool UPnp::Initialize( int nServicePort, HttpServer *pHttpServer ) 00086 { 00087 QStringList sList; 00088 00089 GetIPAddressList( sList ); 00090 00091 return Initialize( sList, nServicePort, pHttpServer ); 00092 } 00093 00095 // 00097 00098 bool UPnp::Initialize( QStringList &sIPAddrList, int nServicePort, HttpServer *pHttpServer ) 00099 { 00100 LOG(VB_UPNP, LOG_DEBUG, "UPnp::Initialize - Begin"); 00101 00102 if (g_pConfig == NULL) 00103 { 00104 LOG(VB_GENERAL, LOG_ERR, 00105 "UPnp::Initialize - Must call SetConfiguration."); 00106 return false; 00107 } 00108 00109 if ((m_pHttpServer = pHttpServer) == NULL) 00110 { 00111 LOG(VB_GENERAL, LOG_ERR, 00112 "UPnp::Initialize - Invalid Parameter (pHttpServer == NULL)"); 00113 return false; 00114 } 00115 00116 g_IPAddrList = sIPAddrList; 00117 m_nServicePort = nServicePort; 00118 00119 // ---------------------------------------------------------------------- 00120 // Register any HttpServerExtensions 00121 // ---------------------------------------------------------------------- 00122 00123 m_pHttpServer->RegisterExtension( 00124 new SSDPExtension(m_nServicePort, m_pHttpServer->GetSharePath())); 00125 00126 LOG(VB_UPNP, LOG_DEBUG, "UPnp::Initialize - End"); 00127 00128 return true; 00129 } 00130 00132 // Delay startup of Discovery Threads until all Extensions are registered. 00134 00135 void UPnp::Start() 00136 { 00137 LOG(VB_UPNP, LOG_DEBUG, "UPnp::Start - Enabling SSDP Notifications"); 00138 // ---------------------------------------------------------------------- 00139 // Turn on Device Announcements 00140 // (this will also create/startup SSDP if not already done) 00141 // ---------------------------------------------------------------------- 00142 00143 SSDP::Instance()->EnableNotifications( m_nServicePort ); 00144 00145 LOG(VB_UPNP, LOG_DEBUG, "UPnp::Start - Returning"); 00146 } 00147 00149 // 00151 00152 void UPnp::CleanUp() 00153 { 00154 LOG(VB_UPNP, LOG_INFO, "UPnp::CleanUp() - disabling SSDP notifications"); 00155 00156 SSDP::Instance()->DisableNotifications(); 00157 00158 if (g_pConfig) 00159 { 00160 delete g_pConfig; 00161 g_pConfig = NULL; 00162 } 00163 00164 } 00165 00167 // 00169 00170 UPnpDeviceDesc *UPnp::GetDeviceDesc( QString &sURL, bool bInQtThread ) 00171 { 00172 return UPnpDeviceDesc::Retrieve( sURL, bInQtThread ); 00173 } 00174 00176 // 00178 00179 QString UPnp::GetResultDesc( UPnPResultCode eCode ) 00180 { 00181 switch( eCode ) 00182 { 00183 case UPnPResult_Success : return "Success"; 00184 case UPnPResult_InvalidAction : return "Invalid Action"; 00185 case UPnPResult_InvalidArgs : return "Invalid Args"; 00186 case UPnPResult_ActionFailed : return "Action Failed"; 00187 case UPnPResult_ArgumentValueInvalid : return "Argument Value Invalid"; 00188 case UPnPResult_ArgumentValueOutOfRange : return "Argument Value Out Of Range"; 00189 case UPnPResult_OptionalActionNotImplemented: return "Optional Action Not Implemented"; 00190 case UPnPResult_OutOfMemory : return "Out Of Memory"; 00191 case UPnPResult_HumanInterventionRequired : return "Human Intervention Required"; 00192 case UPnPResult_StringArgumentTooLong : return "String Argument Too Long"; 00193 case UPnPResult_ActionNotAuthorized : return "Action Not Authorized"; 00194 case UPnPResult_SignatureFailure : return "Signature Failure"; 00195 case UPnPResult_SignatureMissing : return "Signature Missing"; 00196 case UPnPResult_NotEncrypted : return "Not Encrypted"; 00197 case UPnPResult_InvalidSequence : return "Invalid Sequence"; 00198 case UPnPResult_InvalidControlURL : return "Invalid Control URL"; 00199 case UPnPResult_NoSuchSession : return "No Such Session"; 00200 case UPnPResult_MS_AccessDenied : return "Access Denied"; 00201 00202 case UPnPResult_CDS_NoSuchObject : return "No Such Object"; 00203 case UPnPResult_CDS_InvalidCurrentTagValue : return "Invalid CurrentTagValue"; 00204 case UPnPResult_CDS_InvalidNewTagValue : return "Invalid NewTagValue"; 00205 case UPnPResult_CDS_RequiredTag : return "Required Tag"; 00206 case UPnPResult_CDS_ReadOnlyTag : return "Read Only Tag"; 00207 case UPnPResult_CDS_ParameterMismatch : return "Parameter Mismatch"; 00208 case UPnPResult_CDS_InvalidSearchCriteria : return "Invalid Search Criteria"; 00209 case UPnPResult_CDS_InvalidSortCriteria : return "Invalid Sort Criteria"; 00210 case UPnPResult_CDS_NoSuchContainer : return "No Such Container"; 00211 case UPnPResult_CDS_RestrictedObject : return "Restricted Object"; 00212 case UPnPResult_CDS_BadMetadata : return "Bad Metadata"; 00213 case UPnPResult_CDS_ResrtictedParentObject : return "Resrticted Parent Object"; 00214 case UPnPResult_CDS_NoSuchSourceResource : return "No Such Source Resource"; 00215 case UPnPResult_CDS_ResourceAccessDenied : return "Resource Access Denied"; 00216 case UPnPResult_CDS_TransferBusy : return "Transfer Busy"; 00217 case UPnPResult_CDS_NoSuchFileTransfer : return "No Such File Transfer"; 00218 case UPnPResult_CDS_NoSuchDestRes : return "No Such Destination Resource"; 00219 case UPnPResult_CDS_DestResAccessDenied : return "Destination Resource Access Denied"; 00220 case UPnPResult_CDS_CannotProcessRequest : return "Cannot Process The Request"; 00221 00222 //case UPnPResult_CMGR_IncompatibleProtocol = 701, 00223 //case UPnPResult_CMGR_IncompatibleDirections = 702, 00224 //case UPnPResult_CMGR_InsufficientNetResources = 703, 00225 //case UPnPResult_CMGR_LocalRestrictions = 704, 00226 //case UPnPResult_CMGR_AccessDenied = 705, 00227 //case UPnPResult_CMGR_InvalidConnectionRef = 706, 00228 case UPnPResult_CMGR_NotInNetwork : return "Not In Network"; 00229 00230 } 00231 00232 return "Unknown"; 00233 } 00234 00236 // 00238 00239 void UPnp::FormatErrorResponse( HTTPRequest *pRequest, 00240 UPnPResultCode eCode, 00241 const QString &msg ) 00242 { 00243 QString sMsg( msg ); 00244 00245 if (pRequest != NULL) 00246 { 00247 QString sDetails = ""; 00248 00249 if (pRequest->m_bSOAPRequest) 00250 sDetails = "<UPnPResult xmlns=\"urn:schemas-upnp-org:control-1-0\">"; 00251 00252 if (sMsg.length() == 0) 00253 sMsg = GetResultDesc( eCode ); 00254 00255 sDetails += QString( "<errorCode>%1</errorCode>" 00256 "<errorDescription>%2</errorDescription>" ) 00257 .arg( eCode ) 00258 .arg( HTTPRequest::Encode( sMsg ) ); 00259 00260 if (pRequest->m_bSOAPRequest) 00261 sDetails += "</UPnPResult>"; 00262 00263 00264 pRequest->FormatErrorResponse ( true, // -=>TODO: Should make this dynamic 00265 "UPnPResult", 00266 sDetails ); 00267 } 00268 else 00269 LOG(VB_GENERAL, LOG_ERR, "Response not created - pRequest == NULL" ); 00270 } 00271 00273 // 00275 00276 void UPnp::FormatRedirectResponse( HTTPRequest *pRequest, 00277 const QString &hostName ) 00278 { 00279 pRequest->m_eResponseType = ResponseTypeOther; 00280 pRequest->m_nResponseStatus = 301; 00281 00282 QStringList sItems = pRequest->m_sRawRequest.split( ' ' ); 00283 QString sUrl = "http://" + pRequest->m_mapHeaders[ "host" ] + sItems[1]; 00284 QUrl url( sUrl ); 00285 url.setHost( hostName ); 00286 00287 pRequest->m_mapRespHeaders[ "Location" ] = url.toString(); 00288 00289 LOG(VB_UPNP, LOG_INFO, QString("Sending http redirect to: %1") 00290 .arg(url.toString())); 00291 00292 pRequest->SendResponse(); 00293 }
1.7.6.1