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