00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #include "upnp.h"
00012 #include "upnptasksearch.h"
00013 #include "compat.h"
00014
00015 #include <unistd.h>
00016 #include <stdlib.h>
00017 #include <qstringlist.h>
00018 #include <quuid.h>
00019 #include <qdom.h>
00020 #include <qfile.h>
00021 #include <sys/time.h>
00022
00025
00026
00027
00030
00032
00034
00035 UPnpSearchTask::UPnpSearchTask( int nServicePort,
00036 QHostAddress peerAddress,
00037 int nPeerPort,
00038 QString sST,
00039 QString sUDN )
00040 {
00041 m_PeerAddress = peerAddress;
00042 m_nPeerPort = nPeerPort;
00043 m_sST = sST;
00044 m_sUDN = sUDN;
00045 m_nServicePort= nServicePort;
00046 m_nMaxAge = UPnp::g_pConfig->GetValue( "UPnP/SSDP/MaxAge" , 3600 );
00047
00048 }
00049
00051
00053
00054 UPnpSearchTask::~UPnpSearchTask()
00055 {
00056 }
00057
00059
00061
00062 void UPnpSearchTask::SendMsg( QSocketDevice *pSocket,
00063 QString sST,
00064 QString sUDN )
00065 {
00066 QString sUSN;
00067
00068 if (( sUDN.length() > 0) && ( sUDN != sST ))
00069 sUSN = sUDN + "::" + sST;
00070 else
00071 sUSN = sST;
00072
00073 QString sDate = QDateTime::currentDateTime().toString( "d MMM yyyy hh:mm:ss" );
00074
00075 QString sData = QString ( "CACHE-CONTROL: max-age=%1\r\n"
00076 "DATE: %2\r\n"
00077 "EXT:\r\n"
00078 "Server: %3, UPnP/1.0, MythTv %4\r\n"
00079 "ST: %5\r\n"
00080 "USN: %6\r\n"
00081 "Content-Length: 0\r\n\r\n" )
00082 .arg( m_nMaxAge )
00083 .arg( sDate )
00084 .arg( HttpServer::g_sPlatform )
00085 .arg( MYTH_BINARY_VERSION )
00086 .arg( sST )
00087 .arg( sUSN );
00088
00089
00090
00091
00092
00093
00094
00095 for ( QStringList::Iterator it = m_addressList.begin();
00096 it != m_addressList.end();
00097 ++it )
00098 {
00099 QString sHeader = QString ( "HTTP/1.1 200 OK\r\n"
00100 "LOCATION: http://%1:%2/getDeviceDesc\r\n" )
00101 .arg( *it )
00102 .arg( m_nServicePort);
00103
00104
00105 QString sPacket = sHeader + sData;
00106 QCString scPacket = sPacket.utf8();
00107
00108
00109
00110
00111
00112 pSocket->writeBlock( scPacket, scPacket.length(), m_PeerAddress, m_nPeerPort );
00113 usleep( rand() % 250000 );
00114 pSocket->writeBlock( scPacket, scPacket.length(), m_PeerAddress, m_nPeerPort );
00115 }
00116
00117 }
00118
00120
00122
00123 void UPnpSearchTask::Execute( TaskQueue * )
00124 {
00125 QSocketDevice *pSocket = new QSocketDevice( QSocketDevice::Datagram );
00126
00127
00128
00129
00130
00131 m_addressList = UPnp::g_IPAddrList;
00132
00133
00134
00135
00136
00137 UPnpDevice &device = UPnp::g_UPnpDeviceDesc.m_rootDevice;
00138
00139 if ((m_sST == "upnp:rootdevice") || (m_sST == "ssdp:all" ))
00140 {
00141 SendMsg( pSocket, "upnp:rootdevice", device.GetUDN() );
00142
00143 if (m_sST == "ssdp:all")
00144 ProcessDevice( pSocket, &device );
00145 }
00146 else
00147 {
00148
00149
00150
00151
00152 SendMsg( pSocket, m_sST, m_sUDN );
00153 }
00154
00155 delete pSocket;
00156 pSocket = NULL;
00157 }
00158
00160
00162
00163 void UPnpSearchTask::ProcessDevice( QSocketDevice *pSocket, UPnpDevice *pDevice )
00164 {
00165
00166
00167
00168
00169
00170
00171
00172 SendMsg( pSocket, pDevice->GetUDN(), "" );
00173 SendMsg( pSocket, pDevice->m_sDeviceType, pDevice->GetUDN() );
00174
00175
00176
00177
00178
00179 for ( UPnpService *pService = pDevice->m_listServices.first();
00180 pService != NULL;
00181 pService = pDevice->m_listServices.next() )
00182 {
00183 SendMsg( pSocket, pService->m_sServiceType, pDevice->GetUDN() );
00184 }
00185
00186
00187
00188
00189
00190 for ( UPnpDevice *pEmbeddedDevice = pDevice->m_listDevices.first();
00191 pEmbeddedDevice != NULL;
00192 pEmbeddedDevice = pDevice->m_listDevices.next() )
00193 {
00194 ProcessDevice( pSocket, pEmbeddedDevice );
00195 }
00196 }
00197