00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #include "upnp.h"
00012 #include "upnptaskcache.h"
00013 #include "multicast.h"
00014 #include "broadcast.h"
00015
00017
00019
00020 UPnpDeviceDesc UPnp::g_UPnpDeviceDesc;
00021 TaskQueue *UPnp::g_pTaskQueue = NULL;
00022 SSDP *UPnp::g_pSSDP = NULL;
00023 SSDPCache UPnp::g_SSDPCache;
00024 QStringList UPnp::g_IPAddrList;
00025
00026 Configuration *UPnp::g_pConfig = NULL;
00027
00030
00031
00032
00035
00037
00039
00040 UPnp::UPnp()
00041 {
00042 VERBOSE( VB_UPNP, "UPnp - Constructor" );
00043 }
00044
00046
00048
00049 UPnp::~UPnp()
00050 {
00051 VERBOSE( VB_UPNP, "UPnp - Destructor" );
00052 CleanUp();
00053 }
00054
00056
00058
00059 void UPnp::SetConfiguration( Configuration *pConfig )
00060 {
00061 if (g_pConfig)
00062 delete g_pConfig;
00063
00064 g_pConfig = pConfig;
00065 }
00066
00068
00070
00071 bool UPnp::Initialize( int nServicePort, HttpServer *pHttpServer )
00072 {
00073 QStringList sList;
00074
00075 GetIPAddressList( sList );
00076
00077 return Initialize( sList, nServicePort, pHttpServer );
00078 }
00079
00081
00083
00084 bool UPnp::Initialize( QStringList &sIPAddrList, int nServicePort, HttpServer *pHttpServer )
00085 {
00086 VERBOSE(VB_UPNP, "UPnp::Initialize - Begin");
00087
00088 if (g_pConfig == NULL)
00089 {
00090 VERBOSE(VB_IMPORTANT, "UPnp::Initialize - Must call SetConfiguration.");
00091 return false;
00092 }
00093
00094 if ((m_pHttpServer = pHttpServer) == NULL)
00095 {
00096 VERBOSE(VB_IMPORTANT,
00097 "UPnp::Initialize - Invalid Parameter (pHttpServer == NULL)");
00098 return false;
00099 }
00100
00101 g_IPAddrList = sIPAddrList;
00102 m_nServicePort = nServicePort;
00103
00104
00105
00106
00107
00108 VERBOSE(VB_UPNP, "UPnp::Initialize - Starting TaskQueue");
00109
00110 g_pTaskQueue = new TaskQueue();
00111 g_pTaskQueue->start();
00112
00113
00114
00115
00116
00117 m_pHttpServer->RegisterExtension( new SSDPExtension( m_nServicePort ));
00118
00119
00120
00121
00122
00123 UPnp::g_pTaskQueue->AddTask( new SSDPCacheTask() );
00124
00125
00126
00127
00128
00129 VERBOSE(VB_UPNP, "UPnp::Initialize - Creating SSDP Thread at port "
00130 + QString::number(m_nServicePort));
00131
00132 g_pSSDP = new SSDP( m_nServicePort );
00133
00134 VERBOSE(VB_UPNP, "UPnp::Initialize - End");
00135
00136 return true;
00137 }
00138
00140
00142
00143 void UPnp::Start()
00144 {
00145 if (g_pSSDP != NULL)
00146 {
00147 VERBOSE(VB_UPNP, "UPnp::Start - Starting SSDP Thread (Multicast)");
00148 g_pSSDP->start();
00149 VERBOSE(VB_UPNP, "UPnp::Start - Enabling Notifications");
00150 g_pSSDP->EnableNotifications();
00151 }
00152
00153 VERBOSE(VB_UPNP, "UPnp::Start - Returning");
00154 }
00155
00157
00159
00160 void UPnp::CleanUp( void )
00161 {
00162 if (g_pSSDP)
00163 {
00164 VERBOSE(VB_UPNP, "UPnp::CleanUp() - disabling SSDP notifications");
00165
00166 delete g_pSSDP;
00167 g_pSSDP = NULL;
00168 VERBOSE(VB_UPNP, "UPnp::CleanUp() - deleted SSDP");
00169 }
00170
00171
00172
00173
00174
00175 if (g_pTaskQueue)
00176 {
00177 g_pTaskQueue->Clear();
00178
00179 delete g_pTaskQueue;
00180 g_pTaskQueue = NULL;
00181 }
00182
00183 if (g_pConfig)
00184 {
00185 delete g_pConfig;
00186 g_pConfig = NULL;
00187 }
00188
00189 }
00190
00192
00194
00195 SSDPCacheEntries *UPnp::Find( const QString &sURI )
00196 {
00197 return g_SSDPCache.Find( sURI );
00198 }
00199
00201
00203 DeviceLocation *UPnp::Find( const QString &sURI, const QString &sUSN )
00204 {
00205 return g_SSDPCache.Find( sURI, sUSN );
00206 }
00207
00209
00211
00212 UPnpDeviceDesc *UPnp::GetDeviceDesc( QString &sURL, bool bInQtThread )
00213 {
00214 return UPnpDeviceDesc::Retrieve( sURL, bInQtThread );
00215 }
00216
00218
00220
00221 QString UPnp::GetResultDesc( UPnPResultCode eCode )
00222 {
00223 switch( eCode )
00224 {
00225 case UPnPResult_Success : return "Success";
00226 case UPnPResult_InvalidAction : return "Invalid Action";
00227 case UPnPResult_InvalidArgs : return "Invalid Args";
00228 case UPnPResult_ActionFailed : return "Action Failed";
00229 case UPnPResult_ArgumentValueInvalid : return "Argument Value Invalid";
00230 case UPnPResult_ArgumentValueOutOfRange : return "Argument Value Out Of Range";
00231 case UPnPResult_OptionalActionNotImplemented: return "Optional Action Not Implemented";
00232 case UPnPResult_OutOfMemory : return "Out Of Memory";
00233 case UPnPResult_HumanInterventionRequired : return "Human Intervention Required";
00234 case UPnPResult_StringArgumentTooLong : return "String Argument Too Long";
00235 case UPnPResult_ActionNotAuthorized : return "Action Not Authorized";
00236 case UPnPResult_SignatureFailure : return "Signature Failure";
00237 case UPnPResult_SignatureMissing : return "Signature Missing";
00238 case UPnPResult_NotEncrypted : return "Not Encrypted";
00239 case UPnPResult_InvalidSequence : return "Invalid Sequence";
00240 case UPnPResult_InvalidControlURL : return "Invalid Control URL";
00241 case UPnPResult_NoSuchSession : return "No Such Session";
00242 case UPnPResult_MS_AccessDenied : return "Access Denied";
00243
00244 case UPnPResult_CDS_NoSuchObject : return "No Such Object";
00245 case UPnPResult_CDS_InvalidCurrentTagValue : return "Invalid CurrentTagValue";
00246 case UPnPResult_CDS_InvalidNewTagValue : return "Invalid NewTagValue";
00247 case UPnPResult_CDS_RequiredTag : return "Required Tag";
00248 case UPnPResult_CDS_ReadOnlyTag : return "Read Only Tag";
00249 case UPnPResult_CDS_ParameterMismatch : return "Parameter Mismatch";
00250 case UPnPResult_CDS_InvalidSearchCriteria : return "Invalid Search Criteria";
00251 case UPnPResult_CDS_InvalidSortCriteria : return "Invalid Sort Criteria";
00252 case UPnPResult_CDS_NoSuchContainer : return "No Such Container";
00253 case UPnPResult_CDS_RestrictedObject : return "Restricted Object";
00254 case UPnPResult_CDS_BadMetadata : return "Bad Metadata";
00255 case UPnPResult_CDS_ResrtictedParentObject : return "Resrticted Parent Object";
00256 case UPnPResult_CDS_NoSuchSourceResource : return "No Such Source Resource";
00257 case UPnPResult_CDS_ResourceAccessDenied : return "Resource Access Denied";
00258 case UPnPResult_CDS_TransferBusy : return "Transfer Busy";
00259 case UPnPResult_CDS_NoSuchFileTransfer : return "No Such File Transfer";
00260 case UPnPResult_CDS_NoSuchDestRes : return "No Such Destination Resource";
00261 case UPnPResult_CDS_DestResAccessDenied : return "Destination Resource Access Denied";
00262 case UPnPResult_CDS_CannotProcessRequest : return "Cannot Process The Request";
00263
00264
00265
00266
00267
00268
00269
00270 case UPnPResult_CMGR_NotInNetwork : return "Not In Network";
00271
00272 }
00273
00274 return "Unkown";
00275 }
00276
00278
00280
00281 void UPnp::FormatErrorResponse( HTTPRequest *pRequest,
00282 UPnPResultCode eCode,
00283 const QString &msg )
00284 {
00285 QString sMsg( msg );
00286
00287 if (pRequest != NULL)
00288 {
00289 QString sDetails = "";
00290
00291 if (pRequest->m_bSOAPRequest)
00292 sDetails = "<UPnPResult xmlns=\"urn:schemas-upnp-org:control-1-0\">";
00293
00294 if (sMsg.length() == 0)
00295 sMsg = GetResultDesc( eCode );
00296
00297 HTTPRequest::Encode( sMsg );
00298
00299 sDetails += QString( "<errorCode>%1</errorCode>"
00300 "<errorDescription>%2</errorDescription>" )
00301 .arg( eCode )
00302 .arg( sMsg );
00303
00304 if (pRequest->m_bSOAPRequest)
00305 sDetails += "</UPnPResult>";
00306
00307
00308 pRequest->FormatErrorResponse ( true,
00309 "UPnPResult",
00310 sDetails );
00311 }
00312 else
00313 VERBOSE( VB_IMPORTANT, "UPnp::FormatErrorResponse : Response not created - pRequest == NULL" );
00314 }