00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00012
00013 #include "upnptaskcache.h"
00014 #include "mythlogging.h"
00015 #include "upnp.h"
00016
00018
00020
00021 UPnpDeviceDesc UPnp::g_UPnpDeviceDesc;
00022 QStringList UPnp::g_IPAddrList;
00023
00024 Configuration *UPnp::g_pConfig = NULL;
00025
00028
00029
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
00073
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
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
00134
00135 void UPnp::Start()
00136 {
00137 LOG(VB_UPNP, LOG_DEBUG, "UPnp::Start - Enabling SSDP Notifications");
00138
00139
00140
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
00223
00224
00225
00226
00227
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,
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 }