Esempio n. 1
0
void BackendSelection::customEvent(QEvent *event)
{
    if (((MythEvent::Type)(event->type())) == MythEvent::MythEventMessage)
    {
        MythEvent *me      = (MythEvent *)event;
        QString    message = me->Message();
        QString    URI     = me->ExtraData(0);
        QString    URN     = me->ExtraData(1);
        QString    URL     = me->ExtraData(2);


        LOG(VB_UPNP, LOG_DEBUG,
                 QString("BackendSelection::customEvent(%1, %2, %3, %4)")
                .arg(message).arg(URI).arg(URN).arg(URL));

        if (message.startsWith("SSDP_ADD") &&
            URI.startsWith("urn:schemas-mythtv-org:device:MasterMediaServer:"))
        {
            DeviceLocation *devLoc = SSDP::Instance()->Find(URI, URN);
            if (devLoc)
            {
                AddItem(devLoc);
                devLoc->DecrRef();
            }
        }
        else if (message.startsWith("SSDP_REMOVE"))
        {
            //-=>Note: This code will never get executed until
            //         SSDPCache is changed to handle NotifyRemove correctly
            RemoveItem(URN);
        }
    }
    else if (event->type() == DialogCompletionEvent::kEventType)
    {
        DialogCompletionEvent *dce = dynamic_cast<DialogCompletionEvent*>(event);

        if (!dce)
            return;

        QString resultid = dce->GetId();

        if (resultid == "password")
        {
            m_pinCode = dce->GetResultText();
            Accept();
        }
    }
}
Esempio n. 2
0
void BackendSelection::RemoveItem(QString USN)
{
    m_mutex.lock();

    ItemMap::iterator it = m_devices.find(USN);

    if (it != m_devices.end())
    {
        DeviceLocation *dev = *it;

        if (dev)
            dev->Release();

        m_devices.erase(it);
    }

    m_mutex.unlock();
}
Esempio n. 3
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()
    }
}
Esempio n. 4
0
void SSDPCache::Dump()
{
    int nCount = 0;

    if (VERBOSE_LEVEL_CHECK(VB_UPNP))
    {

        Lock();

        // ----------------------------------------------------------------------
        // Build List of items to be removed
        // ----------------------------------------------------------------------

        VERBOSE( VB_UPNP, "===============================================================================" );
        VERBOSE( VB_UPNP, QString(  " URI (type) - Found: %1 Entries - %2 have been Allocated. " )
                             .arg( m_cache.count() )
                             .arg( SSDPCacheEntries::g_nAllocated ));
        VERBOSE( VB_UPNP, "   \t\tUSN (unique id)\t\t | Expires\t | Location" );
        VERBOSE( VB_UPNP, "-------------------------------------------------------------------------------" );

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

            if (pEntries != NULL)
            {
                VERBOSE( VB_UPNP, it.key() );

                pEntries->Lock();

                EntryMap *pMap = pEntries->GetEntryMap();

                for (EntryMap::Iterator itEntry  = pMap->begin();
                                        itEntry != pMap->end();
                                      ++itEntry )
                {

                    DeviceLocation *pEntry = *itEntry;

                    if (pEntry != NULL)
                    {
                        nCount++;

                        pEntry->AddRef();

                        VERBOSE( VB_UPNP, QString( " * \t\t%1\t | %2\t | %3 " ) 
                                             .arg( pEntry->m_sUSN )
                                             .arg( pEntry->ExpiresInSecs() )
                                             .arg( pEntry->m_sLocation ));

                        pEntry->Release();
                    }
                }

                VERBOSE( VB_UPNP, " "); 

                pEntries->Unlock();
            }
        }

        VERBOSE( VB_UPNP, "-------------------------------------------------------------------------------" );
        VERBOSE( VB_UPNP, QString(  " Found: %1 Entries - %2 have been Allocated. " )
                             .arg( nCount )
                             .arg( DeviceLocation::g_nAllocated ));
        VERBOSE( VB_UPNP, "===============================================================================" );

        Unlock();
    }
}
Esempio n. 5
0
void SSDPExtension::GetDeviceList( HTTPRequest *pRequest )
{
    SSDPCache*    pCache  = SSDPCache::Instance();
    int           nCount = 0;
    NameValues    list;

    VERBOSE( VB_UPNP, "SSDPExtension::GetDeviceList" );

    pCache->Lock();

    QString     sXML = "";
    QTextStream os( &sXML, QIODevice::WriteOnly );

    for (SSDPCacheEntriesMap::Iterator it  = pCache->Begin();
                                       it != pCache->End();
                                     ++it )
    {
        SSDPCacheEntries *pEntries = *it;

        if (pEntries != NULL)
        {
            os << "<Device uri='" << it.key() << "'>" << endl;

            pEntries->Lock();

            EntryMap *pMap = pEntries->GetEntryMap();

            for (EntryMap::Iterator itEntry  = pMap->begin();
                                    itEntry != pMap->end();
                                  ++itEntry )
            {

                DeviceLocation *pEntry = *itEntry;

                if (pEntry != NULL)
                {
                    nCount++;

                    pEntry->AddRef();

                    os << "<Service usn='" << pEntry->m_sUSN 
                       << "' expiresInSecs='" << pEntry->ExpiresInSecs()
                       << "' url='" << pEntry->m_sLocation << "' />" << endl;

                    pEntry->Release();
                }
            }

            os << "</Device>" << endl;

            pEntries->Unlock();
        }
    }
    os << flush;

    list.push_back( NameValue("DeviceCount"          , pCache->Count()               ));
    list.push_back( NameValue("DevicesAllocated"     , SSDPCacheEntries::g_nAllocated));
    list.push_back( NameValue("CacheEntriesFound"    , nCount                        ));
    list.push_back( NameValue("CacheEntriesAllocated", DeviceLocation::g_nAllocated  ));
    list.push_back( NameValue("DeviceList"           , sXML                          ));

    pCache->Unlock();

    pRequest->FormatActionResponse( list );

    pRequest->m_eResponseType   = ResponseTypeXML;
    pRequest->m_nResponseStatus = 200;
}
Esempio n. 6
0
/**
 * Get the default backend from config.xml, use UPnP to find it.
 *
 * Sets a string if there any connection problems
 */
bool MythContextPrivate::DefaultUPnP(QString &error)
{
    QString            loc = "DefaultUPnP() - ";
    QString            PIN = m_pConfig->GetValue(kDefaultPIN, "");
    QString            USN = m_pConfig->GetValue(kDefaultUSN, "");

    if (USN.isEmpty())
    {
        LOG(VB_UPNP, LOG_INFO, loc + "No default UPnP backend");
        return false;
    }

    LOG(VB_UPNP, LOG_INFO, loc + "config.xml has default " +
             QString("PIN '%1' and host USN: %2") .arg(PIN).arg(USN));

    // ----------------------------------------------------------------------

    int timeout_ms = 2000;
    LOG(VB_GENERAL, LOG_INFO, QString("UPNP Search up to %1 secs")
        .arg(timeout_ms / 1000));
    SSDP::Instance()->PerformSearch(gBackendURI, timeout_ms / 1000);

    // ----------------------------------------------------------------------
    // We need to give the server time to respond...
    // ----------------------------------------------------------------------

    DeviceLocation *pDevLoc = NULL;
    MythTimer totalTime; totalTime.start();
    MythTimer searchTime; searchTime.start();
    while (totalTime.elapsed() < timeout_ms)
    {
        pDevLoc = SSDP::Instance()->Find( gBackendURI, USN );

        if (pDevLoc)
            break;

        usleep(25000);

        int ttl = timeout_ms - totalTime.elapsed();
        if ((searchTime.elapsed() > 249) && (ttl > 1000))
        {
            LOG(VB_GENERAL, LOG_INFO, QString("UPNP Search up to %1 secs")
                .arg(ttl / 1000));
            SSDP::Instance()->PerformSearch(gBackendURI, ttl / 1000);
            searchTime.start();
        }
    }

    // ----------------------------------------------------------------------

    if (!pDevLoc)
    {
        error = "Cannot find default UPnP backend";
        return false;
    }

    if (UPnPconnect(pDevLoc, PIN))
    {
        pDevLoc->DecrRef();
        return true;
    }

    pDevLoc->DecrRef();

    error = "Cannot connect to default backend via UPnP. Wrong saved PIN?";
    return false;
}
Esempio n. 7
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)
{
    LOG(VB_GENERAL, LOG_INFO, QString("UPNP Search %1 secs")
        .arg(milliSeconds / 1000));

    SSDP::Instance()->PerformSearch(gBackendURI, milliSeconds / 1000);

    // Search for a total of 'milliSeconds' ms, sending new search packet
    // about every 250 ms until less than one second remains.
    MythTimer totalTime; totalTime.start();
    MythTimer searchTime; searchTime.start();
    while (totalTime.elapsed() < milliSeconds)
    {
        usleep(25000);
        int ttl = milliSeconds - totalTime.elapsed();
        if ((searchTime.elapsed() > 249) && (ttl > 1000))
        {
            LOG(VB_GENERAL, LOG_INFO, QString("UPNP Search %1 secs")
                .arg(ttl / 1000));
            SSDP::Instance()->PerformSearch(gBackendURI, ttl / 1000);
            searchTime.start();
        }
    }

    SSDPCacheEntries *backends = SSDP::Instance()->Find(gBackendURI);

    if (!backends)
    {
        LOG(VB_GENERAL, LOG_INFO, "No UPnP backends found");
        return 0;
    }

    int count = backends->Count();
    if (count)
    {
        LOG(VB_GENERAL, LOG_INFO,
            QString("Found %1 UPnP backends").arg(count));
    }
    else
    {
        LOG(VB_GENERAL, LOG_ERR,
            "No UPnP backends found, but SSDP::Find() not NULL");
    }

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

    // Get this backend's location:
    DeviceLocation *BE = backends->GetFirst();
    backends->DecrRef();
    backends = NULL;

    // 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)
    int ret = (UPnPconnect(BE, QString::null)) ? 1 : -1;

    BE->DecrRef();

    return ret;
}