Beispiel #1
0
void SSDPCache::Add( const QString &sURI,
                     const QString &sUSN,
                     const QString &sLocation,
                     long           sExpiresInSecs )
{    
    // --------------------------------------------------------------
    // Calculate when this cache entry should expire.
    // --------------------------------------------------------------

    TaskTime ttExpires;
    gettimeofday        ( (&ttExpires), NULL );
    AddSecondsToTaskTime(  ttExpires, sExpiresInSecs );

    // --------------------------------------------------------------
    // Get a Pointer to a Entries QDict... (Create if not found)
    // --------------------------------------------------------------

    SSDPCacheEntries *pEntries = Find( sURI );

    if (pEntries == NULL)
    {
        pEntries = new SSDPCacheEntries();
        pEntries->AddRef();
        m_cache.insert( sURI, pEntries );
    }

    pEntries->AddRef();

    // --------------------------------------------------------------
    // See if the Entries Collection contains our USN... (Create if not found)
    // --------------------------------------------------------------

    DeviceLocation *pEntry = pEntries->Find( sUSN );

    if (pEntry == NULL)
    {
        pEntry = new DeviceLocation( sURI, sUSN, sLocation, ttExpires );

        Lock();
        pEntries->Insert( sUSN, pEntry );
        Unlock();

        NotifyAdd( sURI, sUSN, sLocation );
    }
    else
    {
        pEntry->AddRef();
        pEntry->m_sLocation = sLocation;
        pEntry->m_ttExpires = ttExpires;
        pEntry->Release();
    }

    pEntries->Release();
}
Beispiel #2
0
int SSDPCache::RemoveStale()
{
    int          nCount = 0;
    TaskTime     ttNow;
    QStringList  lstKeys;

    gettimeofday( (&ttNow), NULL );

    Lock();

    // ----------------------------------------------------------------------
    // Iterate through all Type URI's and build list of stale entries keys
    // ----------------------------------------------------------------------

    for (SSDPCacheEntriesMap::Iterator it  = m_cache.begin();
                                       it != m_cache.end();
                                     ++it )
    {
        SSDPCacheEntries *pEntries = *it;

        if (pEntries != NULL)
        {
            pEntries->AddRef();

            nCount += pEntries->RemoveStale( ttNow );
     
            if (pEntries->Count() == 0)
                lstKeys.append( it.key() );

            pEntries->Release();
        }
    }

    Unlock();

    nCount = lstKeys.count();

    // ----------------------------------------------------------------------
    // Iterate through list of keys and remove them.
    // (This avoids issues when removing from a QMap while iterating it)
    // ----------------------------------------------------------------------

    for ( QStringList::Iterator itKey = lstKeys.begin();
                                itKey != lstKeys.end();
                              ++itKey ) 
    {
        SSDPCacheEntriesMap::iterator it = m_cache.find( *itKey );
        if (it == m_cache.end())
            continue;

        if (*it)
        {
            (*it)->Release();
            m_cache.erase(it);
        }
    }

    return nCount;
}
Beispiel #3
0
DeviceLocation *SSDPCache::Find( const QString &sURI, const QString &sUSN )
{
    DeviceLocation   *pEntry   = NULL;
    SSDPCacheEntries *pEntries = Find( sURI );

    if (pEntries != NULL)
    {
        pEntries->AddRef();
        pEntry = pEntries->Find( sUSN );
        pEntries->Release();
    }

    return pEntry;
}
Beispiel #4
0
void BackendSelection::Init(void)
{
    EntryMap::Iterator  it;
    EntryMap            ourMap;
    DeviceLocation     *pDevLoc;

    SSDPCacheEntries *pEntries = SSDPCache::Instance()->Find( gBackendURI );

    if (!pEntries)
    {
        VERBOSE(VB_GENERAL, "Found zero backends, bailing");
        return;
    }

    pEntries->AddRef();
    pEntries->Lock();

    EntryMap *pMap = pEntries->GetEntryMap();

    for (it = pMap->begin(); it != pMap->end(); ++it)
    {
        pDevLoc = (DeviceLocation *)*it;

        if (!pDevLoc)
            continue;

        pDevLoc->AddRef();
        ourMap.insert(pDevLoc->m_sUSN, pDevLoc);
    }

    pEntries->Unlock();
    pEntries->Release();

    for (it = ourMap.begin(); it != ourMap.end(); ++it)
    {
        pDevLoc = (DeviceLocation *)*it;
        AddItem(pDevLoc);   // this does a Release()
    }
}
Beispiel #5
0
void SSDPCache::Remove( const QString &sURI, const QString &sUSN )
{    
    Lock();

    // --------------------------------------------------------------
    // Get a Pointer to a Entries QDict... (Create if not found)
    // --------------------------------------------------------------

    SSDPCacheEntriesMap::Iterator it = m_cache.find( sURI );

    if (it != m_cache.end())
    {
        SSDPCacheEntries *pEntries = *it;

        if (pEntries != NULL)
        {
            pEntries->AddRef();

            pEntries->Remove( sUSN );

            if (pEntries->Count() == 0)
            {
                pEntries->Release();
                m_cache.erase(it);
            }

            pEntries->Release();
        }
    }

    Unlock();

    // -=>TODO:
    // Should this only by notified if we actually had any entry removed?

    NotifyRemove( sURI, sUSN );
}
Beispiel #6
0
/**
 * If there is only a single UPnP backend, use it.
 *
 * This does <i>not</i> prompt for PIN entry. If the backend requires one,
 * it will fail, and the caller needs to put up a UI to ask for one.
 */
int MythContextPrivate::UPnPautoconf(const int milliSeconds)
{
    SSDPCacheEntries *backends = NULL;
    int               count;
    QString           loc = "UPnPautoconf() - ";
    QTime             timer;

    SSDP::Instance()->PerformSearch( gBackendURI );

    for (timer.start(); timer.elapsed() < milliSeconds; usleep(25000))
    {
        backends = SSDP::Instance()->Find( gBackendURI );
        if (backends)
        {
            backends->AddRef();
            break;
        }
        putchar('.');
    }
    putchar('\n');

    if (!backends)
    {
        VERBOSE(VB_GENERAL, loc + "No UPnP backends found");
        return 0;
    }

    count = backends->Count();
    switch (count)
    {
        case 0:
            VERBOSE(VB_IMPORTANT,
                    loc + "No UPnP backends found, but SSDP::Find() not NULL!");
            break;
        case 1:
            VERBOSE(VB_GENERAL, loc + "Found one UPnP backend");
            break;
        default:
            VERBOSE(VB_GENERAL,
                    (loc + "More than one UPnP backend found (%1)").arg(count));
    }

    if (count != 1)
    {
        backends->Release();
        return count;
    }


    // Get this backend's location:
    backends->Lock();
    DeviceLocation *BE = *(backends->GetEntryMap()->begin());
    backends->Unlock();
    backends->Release();

    // We don't actually know the backend's access PIN, so this will
    // only work for ones that have PIN access disabled (i.e. 0000)
    if (UPnPconnect(BE, QString::null))
        return 1;

    return -1;   // Try to force chooser & PIN
}