00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #include "upnp.h"
00012 #include "mythevent.h"
00013
00014 int SSDPCacheEntries::g_nAllocated = 0;
00015
00018
00019
00020
00023
00024
00025 SSDPCacheEntries::SSDPCacheEntries()
00026 {
00027
00028 g_nAllocated++;
00029 }
00030
00032
00034
00035 SSDPCacheEntries::~SSDPCacheEntries()
00036 {
00037 Clear();
00038
00039
00040 g_nAllocated--;
00041 }
00042
00044
00046
00047 void SSDPCacheEntries::Clear()
00048 {
00049 Lock();
00050
00051 for (EntryMap::Iterator it = m_mapEntries.begin();
00052 it != m_mapEntries.end();
00053 ++it )
00054 {
00055 DeviceLocation *pEntry = (DeviceLocation *)it.data();
00056
00057 if (pEntry != NULL)
00058 pEntry->Release();
00059 }
00060
00061 m_mapEntries.clear();
00062
00063 Unlock();
00064 }
00065
00067
00069
00070 DeviceLocation *SSDPCacheEntries::Find( const QString &sUSN )
00071 {
00072 DeviceLocation *pEntry = NULL;
00073
00074 Lock();
00075 EntryMap::Iterator it = m_mapEntries.find( sUSN );
00076
00077 if ( it != m_mapEntries.end() )
00078 pEntry = (DeviceLocation *)it.data();
00079
00080 Unlock();
00081
00082 return pEntry;
00083 }
00084
00086
00088
00089 void SSDPCacheEntries::Insert( const QString &sUSN, DeviceLocation *pEntry )
00090 {
00091 Lock();
00092
00093 pEntry->AddRef();
00094
00095
00096
00097
00098
00099 EntryMap::Iterator it = m_mapEntries.find( sUSN );
00100
00101 if (it != m_mapEntries.end())
00102 {
00103 if (it.data() != NULL)
00104 ((DeviceLocation *)it.data())->Release();
00105 }
00106
00107 m_mapEntries.insert( sUSN, pEntry );
00108
00109 Unlock();
00110 }
00111
00113
00115
00116 void SSDPCacheEntries::Remove( const QString &sUSN )
00117 {
00118 Lock();
00119
00120 EntryMap::Iterator it = m_mapEntries.find( sUSN );
00121
00122 if (it != m_mapEntries.end())
00123 {
00124 if (it.data() != NULL)
00125 ((DeviceLocation *)it.data())->Release();
00126
00127
00128
00129 m_mapEntries.remove( it );
00130 }
00131
00132 Unlock();
00133 }
00134
00136
00138
00139 int SSDPCacheEntries::RemoveStale( const TaskTime &ttNow )
00140 {
00141 int nCount = 0;
00142 QStringList lstKeys;
00143
00144 Lock();
00145
00146
00147
00148
00149
00150 for (EntryMap::Iterator it = m_mapEntries.begin();
00151 it != m_mapEntries.end();
00152 ++it )
00153 {
00154 DeviceLocation *pEntry = (DeviceLocation *)it.data();
00155
00156 if (pEntry != NULL)
00157 {
00158 pEntry->AddRef();
00159
00160 if ( pEntry->m_ttExpires < ttNow )
00161 lstKeys.append( it.key() );
00162
00163 pEntry->Release();
00164 }
00165 }
00166
00167 Unlock();
00168
00169 nCount = lstKeys.count();
00170
00171
00172
00173
00174
00175
00176 for ( QStringList::Iterator it = lstKeys.begin(); it != lstKeys.end(); ++it )
00177 Remove( *it );
00178
00179 return nCount;
00180 }
00181
00184
00185
00186
00189
00190 SSDPCache::SSDPCache()
00191 {
00192 VERBOSE( VB_UPNP, "SSDPCache - Constructor" );
00193 }
00194
00196
00198
00199 SSDPCache::~SSDPCache()
00200 {
00201
00202
00203
00204 Clear();
00205 }
00206
00208
00210
00211 void SSDPCache::Clear()
00212 {
00213 Lock();
00214
00215 for (SSDPCacheEntriesMap::Iterator it = m_cache.begin();
00216 it != m_cache.end();
00217 ++it )
00218 {
00219 SSDPCacheEntries *pEntries = (SSDPCacheEntries *)it.data();
00220
00221 if (pEntries != NULL)
00222 pEntries->Release();
00223 }
00224
00225 m_cache.clear();
00226
00227 Unlock();
00228 }
00229
00231
00233
00234 SSDPCacheEntries *SSDPCache::Find( const QString &sURI )
00235 {
00236 SSDPCacheEntries *pEntries = NULL;
00237
00238 Lock();
00239 SSDPCacheEntriesMap::Iterator it = m_cache.find( sURI );
00240
00241 if ( it != m_cache.end() )
00242 pEntries = (SSDPCacheEntries *)it.data();
00243
00244 Unlock();
00245
00246 return pEntries;
00247 }
00248
00250
00252
00253 DeviceLocation *SSDPCache::Find( const QString &sURI, const QString &sUSN )
00254 {
00255 DeviceLocation *pEntry = NULL;
00256 SSDPCacheEntries *pEntries = Find( sURI );
00257
00258 if (pEntries != NULL)
00259 {
00260 pEntries->AddRef();
00261 pEntry = pEntries->Find( sUSN );
00262 pEntries->Release();
00263 }
00264
00265 return pEntry;
00266 }
00267
00269
00271
00272 void SSDPCache::Add( const QString &sURI,
00273 const QString &sUSN,
00274 const QString &sLocation,
00275 long sExpiresInSecs )
00276 {
00277
00278
00279
00280
00281 TaskTime ttExpires;
00282 gettimeofday ( &ttExpires, NULL );
00283 AddSecondsToTaskTime( ttExpires, sExpiresInSecs );
00284
00285
00286
00287
00288
00289 SSDPCacheEntries *pEntries = Find( sURI );
00290
00291 if (pEntries == NULL)
00292 {
00293 pEntries = new SSDPCacheEntries();
00294 pEntries->AddRef();
00295 m_cache.insert( sURI, pEntries );
00296 }
00297
00298 pEntries->AddRef();
00299
00300
00301
00302
00303
00304 DeviceLocation *pEntry = pEntries->Find( sUSN );
00305
00306 if (pEntry == NULL)
00307 {
00308 pEntry = new DeviceLocation( sURI, sUSN, sLocation, ttExpires );
00309
00310 Lock();
00311 pEntries->Insert( sUSN, pEntry );
00312 Unlock();
00313
00314 NotifyAdd( sURI, sUSN, sLocation );
00315 }
00316 else
00317 {
00318 pEntry->AddRef();
00319 pEntry->m_sLocation = sLocation;
00320 pEntry->m_ttExpires = ttExpires;
00321 pEntry->Release();
00322 }
00323
00324 pEntries->Release();
00325 }
00326
00328
00330
00331 void SSDPCache::Remove( const QString &sURI, const QString &sUSN )
00332 {
00333 Lock();
00334
00335
00336
00337
00338
00339 SSDPCacheEntriesMap::Iterator it = m_cache.find( sURI );
00340
00341 if (it != m_cache.end())
00342 {
00343 SSDPCacheEntries *pEntries = (SSDPCacheEntries *)it.data();
00344
00345 if (pEntries != NULL)
00346 {
00347 pEntries->AddRef();
00348
00349 pEntries->Remove( sUSN );
00350
00351 if (pEntries->Count() == 0)
00352 {
00353 pEntries->Release();
00354 m_cache.remove( it );
00355 }
00356
00357 pEntries->Release();
00358 }
00359 }
00360
00361 Unlock();
00362
00363
00364
00365 NotifyRemove( sURI, sUSN );
00366 }
00367
00369
00371
00372 int SSDPCache::RemoveStale()
00373 {
00374 int nCount = 0;
00375 TaskTime ttNow;
00376 QStringList lstKeys;
00377
00378 gettimeofday( &ttNow, NULL );
00379
00380 Lock();
00381
00382
00383
00384
00385
00386 for (SSDPCacheEntriesMap::Iterator it = m_cache.begin();
00387 it != m_cache.end();
00388 ++it )
00389 {
00390 SSDPCacheEntries *pEntries = (SSDPCacheEntries *)it.data();
00391
00392 if (pEntries != NULL)
00393 {
00394 pEntries->AddRef();
00395
00396 nCount += pEntries->RemoveStale( ttNow );
00397
00398 if (pEntries->Count() == 0)
00399 lstKeys.append( it.key() );
00400
00401 pEntries->Release();
00402 }
00403 }
00404
00405 Unlock();
00406
00407 nCount = lstKeys.count();
00408
00409
00410
00411
00412
00413
00414 for ( QStringList::Iterator itKey = lstKeys.begin(); itKey != lstKeys.end(); ++itKey )
00415 {
00416 SSDPCacheEntriesMap::Iterator it = m_cache.find( *itKey );
00417
00418 if (it != m_cache.end())
00419 {
00420 SSDPCacheEntries *pEntries = (SSDPCacheEntries *)it.data();
00421
00422 if (pEntries != NULL)
00423 {
00424 pEntries->Release();
00425 m_cache.remove( it );
00426 }
00427 }
00428 }
00429
00430 return nCount;
00431 }
00432
00434
00436
00437 void SSDPCache::NotifyAdd( const QString &sURI,
00438 const QString &sUSN,
00439 const QString &sLocation )
00440 {
00441 QStringList values;
00442
00443 values.append( sURI );
00444 values.append( sUSN );
00445 values.append( sLocation );
00446
00447 MythEvent me( "SSDP_ADD", values );
00448
00449 dispatch( me );
00450 }
00451
00453
00455
00456 void SSDPCache::NotifyRemove( const QString &sURI, const QString &sUSN )
00457 {
00458 QStringList values;
00459
00460 values.append( sURI );
00461 values.append( sUSN );
00462
00463 MythEvent me( "SSDP_REMOVE", values );
00464
00465 dispatch( me );
00466 }
00467
00469
00471
00472 void SSDPCache::Dump()
00473 {
00474 int nCount = 0;
00475
00476 if ( print_verbose_messages & VB_UPNP)
00477 {
00478
00479 Lock();
00480
00481
00482
00483
00484
00485 VERBOSE( VB_UPNP, "===============================================================================" );
00486 VERBOSE( VB_UPNP, QString( " URI (type) - Found: %1 Entries - %2 have been Allocated. " )
00487 .arg( m_cache.count() )
00488 .arg( SSDPCacheEntries::g_nAllocated ));
00489 VERBOSE( VB_UPNP, " \t\tUSN (unique id)\t\t | Expires\t | Location" );
00490 VERBOSE( VB_UPNP, "-------------------------------------------------------------------------------" );
00491
00492 for (SSDPCacheEntriesMap::Iterator it = m_cache.begin();
00493 it != m_cache.end();
00494 ++it )
00495 {
00496 SSDPCacheEntries *pEntries = (SSDPCacheEntries *)it.data();
00497
00498 if (pEntries != NULL)
00499 {
00500 VERBOSE( VB_UPNP, it.key() );
00501
00502 pEntries->Lock();
00503
00504 EntryMap *pMap = pEntries->GetEntryMap();
00505
00506 for (EntryMap::Iterator itEntry = pMap->begin();
00507 itEntry != pMap->end();
00508 ++itEntry )
00509 {
00510
00511 DeviceLocation *pEntry = (DeviceLocation *)itEntry.data();
00512
00513 if (pEntry != NULL)
00514 {
00515 nCount++;
00516
00517 pEntry->AddRef();
00518
00519 VERBOSE( VB_UPNP, QString( " * \t\t%1\t | %2\t | %3 " )
00520 .arg( pEntry->m_sUSN )
00521 .arg( pEntry->ExpiresInSecs() )
00522 .arg( pEntry->m_sLocation ));
00523
00524 pEntry->Release();
00525 }
00526 }
00527
00528 VERBOSE( VB_UPNP, " ");
00529
00530 pEntries->Unlock();
00531 }
00532 }
00533
00534 VERBOSE( VB_UPNP, "-------------------------------------------------------------------------------" );
00535 VERBOSE( VB_UPNP, QString( " Found: %1 Entries - %2 have been Allocated. " )
00536 .arg( nCount )
00537 .arg( DeviceLocation::g_nAllocated ));
00538 VERBOSE( VB_UPNP, "===============================================================================" );
00539
00540 Unlock();
00541 }
00542 }