MythTV  0.26-pre
upnp.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends