Esempio n. 1
0
/*----------------------------------------------------------------------
|   PLT_StateVariable::Find
+---------------------------------------------------------------------*/
PLT_StateVariable*
PLT_StateVariable::Find(NPT_List<PLT_StateVariable*>& vars, const char* name)
{
    PLT_StateVariable* stateVariable = NULL;
    NPT_ContainerFind(vars, PLT_StateVariableNameFinder(name), stateVariable);
    return stateVariable;
}
Esempio n. 2
0
/*----------------------------------------------------------------------
|   PLT_MediaBrowser::OnDeviceRemoved
+---------------------------------------------------------------------*/
NPT_Result 
PLT_MediaBrowser::OnDeviceRemoved(PLT_DeviceDataReference& device)
{
    PLT_DeviceDataReference data;

    {
        NPT_AutoLock lock(m_MediaServers);

        // only release if we have kept it around
        NPT_String uuid = device->GetUUID();
        // is it a new device?
        if (NPT_FAILED(NPT_ContainerFind(m_MediaServers, PLT_DeviceDataFinder(uuid), data))) {
            NPT_LOG_WARNING_1("Device (%s) not found in our list!", (const char*)uuid);
            return NPT_FAILURE;
        }

        NPT_LOG_FINE("Device Removed:");
        device->ToLog(NPT_LOG_LEVEL_FINE);

        m_MediaServers.Remove(device);
    }

    if (m_Listener) {
        m_Listener->OnMSAddedRemoved(device, 0);
    }

    return NPT_SUCCESS;
}
Esempio n. 3
0
/*----------------------------------------------------------------------
|   PLT_MediaBrowser::OnDeviceRemoved
+---------------------------------------------------------------------*/
NPT_Result 
PLT_MediaBrowser::OnDeviceRemoved(PLT_DeviceDataReference& device)
{
    if (!device->GetType().StartsWith("urn:schemas-upnp-org:device:MediaServer"))
        return NPT_FAILURE;

    {
        NPT_AutoLock lock(m_MediaServers);

        // only release if we have kept it around
        PLT_DeviceDataReference data;
        NPT_String uuid = device->GetUUID();

        // Have we seen that device?
        if (NPT_FAILED(NPT_ContainerFind(m_MediaServers, PLT_DeviceDataFinder(uuid), data))) {
            NPT_LOG_WARNING_1("Device (%s) not found in our list!", (const char*)uuid);
            return NPT_FAILURE;
        }

        NPT_LOG_FINE_1("Device Removed: %s", (const char*)*device);

        m_MediaServers.Remove(device);
    }
    
    if (m_Delegate) {
        m_Delegate->OnMSRemoved(device);
    }

    return NPT_SUCCESS;
}
Esempio n. 4
0
/*----------------------------------------------------------------------
|   PLT_DeviceData::FindServiceByType
+---------------------------------------------------------------------*/
NPT_Result
PLT_DeviceData::FindServiceByType(const char* type, PLT_Service*& service)
{
    return NPT_ContainerFind(m_Services, 
                             PLT_ServiceTypeFinder(type), 
                             service);
}
/*----------------------------------------------------------------------
|   PLT_MicroMediaController::HandleCmd_info
+---------------------------------------------------------------------*/
void
PLT_MicroMediaController::HandleCmd_info()
{
    NPT_String              object_id;
    PLT_StringMap           tracks;
    PLT_DeviceDataReference device;

    // issue a browse
    DoBrowse();

    if (!m_MostRecentBrowseResults.IsNull()) {
        // create a map item id -> item title
        NPT_List<PLT_MediaObject*>::Iterator item = m_MostRecentBrowseResults->GetFirstItem();
        while (item) {
            if (!(*item)->IsContainer()) {
                tracks.Put((*item)->m_ObjectID, (*item)->m_Title);
            }
            ++item;
        }

        // let the user choose which one
        object_id = ChooseIDFromTable(tracks);

        if (object_id.GetLength()) {
            // issue a browse with metadata
            DoBrowse(object_id, true);

            // look back for the PLT_MediaItem in the results
            PLT_MediaObject* track = NULL;
            if (!m_MostRecentBrowseResults.IsNull() &&
                NPT_SUCCEEDED(NPT_ContainerFind(*m_MostRecentBrowseResults, PLT_MediaItemIDFinder(object_id), track))) {

                // display info
                printf("Title: %s \n", track->m_Title.GetChars());
                printf("OjbectID: %s\n", track->m_ObjectID.GetChars());
                printf("Class: %s\n", track->m_ObjectClass.type.GetChars());
                printf("Creator: %s\n", track->m_Creator.GetChars());
                printf("Date: %s\n", track->m_Date.GetChars());
                for (NPT_List<PLT_AlbumArtInfo>::Iterator iter = track->m_ExtraInfo.album_arts.GetFirstItem();
                     iter;
                     iter++) {
                    printf("Art Uri: %s\n", (*iter).uri.GetChars());
                    printf("Art Uri DLNA Profile: %s\n", (*iter).dlna_profile.GetChars());
                }
                for (NPT_Cardinal i=0;i<track->m_Resources.GetItemCount(); i++) {
                    printf("\tResource[%d].uri: %s\n", i, track->m_Resources[i].m_Uri.GetChars());
                    printf("\tResource[%d].profile: %s\n", i, track->m_Resources[i].m_ProtocolInfo.ToString().GetChars());
                    printf("\tResource[%d].duration: %d\n", i, track->m_Resources[i].m_Duration);
                    printf("\tResource[%d].size: %d\n", i, (int)track->m_Resources[i].m_Size);
                    printf("\n");
                }
                printf("Didl: %s\n", (const char*)track->m_Didl);
            } else {
                printf("Couldn't find the track\n");
            }
        }

        m_MostRecentBrowseResults = NULL;
    }
}
Esempio n. 6
0
/*----------------------------------------------------------------------
|   PLT_DeviceData::FindServiceById
+---------------------------------------------------------------------*/
NPT_Result
PLT_DeviceData::FindServiceById(const char* id, PLT_Service*& service)
{
    return NPT_ContainerFind(m_Services, 
                             PLT_ServiceIDFinder(id),
                             service);
}
Esempio n. 7
0
/*----------------------------------------------------------------------
|   CMediaCrawler::ProcessFileRequest
+---------------------------------------------------------------------*/
NPT_Result 
CMediaCrawler::ProcessFileRequest(NPT_HttpRequest&  request, 
                                  NPT_HttpResponse& response,
                                  NPT_SocketInfo&   info)
{
    NPT_COMPILER_UNUSED(info);

    NPT_LOG_FINE("CMediaCrawler::ProcessFileRequest Received Request:");
    PLT_LOG_HTTP_MESSAGE(NPT_LOG_LEVEL_FINE, &request);

    if (request.GetMethod().Compare("GET") && request.GetMethod().Compare("HEAD")) {
        response.SetStatus(500, "Internal Server Error");
        return NPT_SUCCESS;
    }

    // add the user agent header, some stupid media servers like YME needs it
    if (!request.GetHeaders().GetHeader(NPT_HTTP_HEADER_USER_AGENT)) {
        request.GetHeaders().SetHeader(NPT_HTTP_HEADER_USER_AGENT, 
            "Platinum/" PLT_PLATINUM_VERSION_STRING);
    }

    // File requested
    NPT_HttpResponse* out_response = NULL;
    NPT_HttpUrlQuery query(request.GetUrl().GetQuery());
    const char* url = query.GetField("url");
    if (url) {
        // look for handler
        CStreamHandler* handler = NULL;
        NPT_ContainerFind(m_StreamHandlers, CStreamHandlerFinder(NULL, url), handler);
        if (handler && NPT_SUCCEEDED(handler->ProcessFileRequest(request, out_response)) && out_response) {
            // copy response code and reason
            response.SetStatus(out_response->GetStatusCode(), out_response->GetReasonPhrase());

            // copy headers
            NPT_List<NPT_HttpHeader*>::Iterator headers = out_response->GetHeaders().GetHeaders().GetFirstItem();
            while (headers) {
                response.GetHeaders().SetHeader((*headers)->GetName(), (*headers)->GetValue());
                ++headers;
            }
            response.SetEntity(new NPT_HttpEntity(response.GetHeaders()));
            
            // update inputstream
            NPT_HttpEntity* out_entity;
            if ((out_entity = out_response->GetEntity()) != NULL) {
                NPT_InputStreamReference inputstream;
                out_entity->GetInputStream(inputstream);
                if (!inputstream.IsNull()) {
                    // set the stream but do not update the content length
                    response.GetEntity()->SetInputStream(inputstream, false);
                }
            }

            delete out_response;
            return NPT_SUCCESS;
        }
    }

    response.SetStatus(404, "File Not Found");
    return NPT_SUCCESS;
}
Esempio n. 8
0
/*----------------------------------------------------------------------
|   PLT_DeviceData::FindEmbeddedDeviceByType
+---------------------------------------------------------------------*/
NPT_Result
PLT_DeviceData::FindEmbeddedDeviceByType(const char*              type, 
                                         PLT_DeviceDataReference& device)
{
    return NPT_ContainerFind(m_EmbeddedDevices, 
                             PLT_DeviceDataFinderByType(type), 
                             device);
}
Esempio n. 9
0
/*----------------------------------------------------------------------
|   PLT_EventSubscriber::FindCallbackURL
+---------------------------------------------------------------------*/
NPT_Result
PLT_EventSubscriber::FindCallbackURL(const char* callback_url) 
{
    NPT_String res;
    return NPT_ContainerFind(m_CallbackURLs, 
                             NPT_StringFinder(callback_url), 
                             res);
}
Esempio n. 10
0
/*----------------------------------------------------------------------
|   PLT_MediaBrowser::OnDeviceAdded
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaBrowser::OnDeviceAdded(PLT_DeviceDataReference& device)
{
    // verify the device implements the function we need
    PLT_Service* serviceCDS;
    PLT_Service* serviceCMR;
    NPT_String   type;

    if (!device->GetType().StartsWith("urn:schemas-upnp-org:device:MediaServer"))
        return NPT_FAILURE;
    
    type = "urn:schemas-upnp-org:service:ContentDirectory:*";
    if (NPT_FAILED(device->FindServiceByType(type, serviceCDS))) {
        NPT_LOG_WARNING_2("Service %s not found in device \"%s\"", 
            type.GetChars(),
            device->GetFriendlyName().GetChars());
        return NPT_FAILURE;
    } else {
        // in case it's a newer upnp implementation, force to 1
        serviceCDS->ForceVersion(1);
    }
    
    type = "urn:schemas-upnp-org:service:ConnectionManager:*";
    if (NPT_FAILED(device->FindServiceByType(type, serviceCMR))) {
        NPT_LOG_WARNING_2("Service %s not found in device \"%s\"", 
            type.GetChars(), 
            device->GetFriendlyName().GetChars());
        return NPT_FAILURE;
    } else {
        // in case it's a newer upnp implementation, force to 1
        serviceCMR->ForceVersion(1);
    }
    
    {
        NPT_AutoLock lock(m_MediaServers);

        PLT_DeviceDataReference data;
        NPT_String uuid = device->GetUUID();
        
        // is it a new device?
        if (NPT_SUCCEEDED(NPT_ContainerFind(m_MediaServers, PLT_DeviceDataFinder(uuid), data))) {
            NPT_LOG_WARNING_1("Device (%s) is already in our list!", (const char*)uuid);
            return NPT_FAILURE;
        }

        NPT_LOG_FINE_1("Device Found: %s", (const char*)*device);

        m_MediaServers.Add(device);
    }

    if (m_Delegate && m_Delegate->OnMSAdded(device)) {
        m_CtrlPoint->Subscribe(serviceCDS);
        m_CtrlPoint->Subscribe(serviceCMR);
    }
    
    return NPT_SUCCESS;
}
Esempio n. 11
0
/*----------------------------------------------------------------------
|   PLT_DeviceData::FindServiceByName
+---------------------------------------------------------------------*/
NPT_Result
PLT_DeviceData::FindServiceByName(const char* name, PLT_Service*& service)
{
    // do not try to find it within embedded devices, since different
    // embedded devices could have an identical service
    return NPT_ContainerFind(m_Services, 
        PLT_ServiceNameFinder(name), 
        service);
}
Esempio n. 12
0
/*----------------------------------------------------------------------
|   PLT_DeviceData::FindServiceByEventSubURI
+---------------------------------------------------------------------*/
NPT_Result
PLT_DeviceData::FindServiceByEventSubURI(const char*   uri, 
                                         PLT_Service*& service)
{       
    if (NPT_SUCCEEDED(NPT_ContainerFind(m_Services, 
                                        PLT_ServiceEventSubURLFinder(uri), 
                                        service))) {
        return NPT_SUCCESS;
    }

    for (int i=0; i < (int)m_EmbeddedDevices.GetItemCount(); i++) {
        if (NPT_SUCCEEDED(NPT_ContainerFind(m_EmbeddedDevices[i]->m_Services, 
                                            PLT_ServiceEventSubURLFinder(uri), 
                                            service)))
            return NPT_SUCCESS;
    }
    return NPT_FAILURE;
}
/*----------------------------------------------------------------------
|   PLT_MicroMediaController::HandleCmd_open
+---------------------------------------------------------------------*/
void
PLT_MicroMediaController::HandleCmd_open()
{
    NPT_String              object_id;
    PLT_StringMap           tracks;
    PLT_DeviceDataReference device;

    GetCurMediaRenderer(device);
    if (!device.IsNull()) {
        // get the protocol info to try to see in advance if a track would play on the device

        // issue a browse
        DoBrowse();

        if (!m_MostRecentBrowseResults.IsNull()) {
            // create a map item id -> item title
            NPT_List<PLT_MediaObject*>::Iterator item = m_MostRecentBrowseResults->GetFirstItem();
            while (item) {
                if (!(*item)->IsContainer()) {
                    tracks.Put((*item)->m_ObjectID, (*item)->m_Title);
                }
                ++item;
            }

            // let the user choose which one
            object_id = ChooseIDFromTable(tracks);
            if (object_id.GetLength()) {
                // look back for the PLT_MediaItem in the results
                PLT_MediaObject* track = NULL;
                if (NPT_SUCCEEDED(NPT_ContainerFind(*m_MostRecentBrowseResults, PLT_MediaItemIDFinder(object_id), track))) {
                    if (track->m_Resources.GetItemCount() > 0) {
                        // look for best resource to use by matching each resource to a sink advertised by renderer
                        NPT_Cardinal resource_index = 0;
                        if (NPT_FAILED(FindBestResource(device, *track, resource_index))) {
                            printf("No matching resource\n");
                            return;
                        }

                        // invoke the setUri
                        printf("Issuing SetAVTransportURI with url=%s & didl=%s",
                            (const char*)track->m_Resources[resource_index].m_Uri,
                            (const char*)track->m_Didl);
                        SetAVTransportURI(device, 0, track->m_Resources[resource_index].m_Uri, track->m_Didl, NULL);
                    } else {
                        printf("Couldn't find the proper resource\n");
                    }

                } else {
                    printf("Couldn't find the track\n");
                }
            }

            m_MostRecentBrowseResults = NULL;
        }
    }
}
Esempio n. 14
0
/*----------------------------------------------------------------------
|   PLT_MediaBrowser::FindServer
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaBrowser::FindServer(const char* uuid, PLT_DeviceDataReference& device)
{
    NPT_AutoLock lock(m_MediaServers);

    if (NPT_FAILED(NPT_ContainerFind(m_MediaServers, PLT_DeviceDataFinder(uuid), device))) {
        NPT_LOG_FINE_1("Device (%s) not found in our list of servers", (const char*)uuid);
        return NPT_FAILURE;
    }

    return NPT_SUCCESS;
}
Esempio n. 15
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::OnAlbumArtRequest
+---------------------------------------------------------------------*/
NPT_Result 
PLT_FileMediaServer::OnAlbumArtRequest(NPT_HttpResponse& response,
                                       NPT_String        file_path)
{
    NPT_LargeSize            total_len;
    NPT_File                 file(file_path);
    NPT_InputStreamReference stream;

    // prevent hackers from accessing files outside of our root
    if ((file_path.Find("/..") >= 0) || (file_path.Find("\\..") >= 0)) {
        return NPT_FAILURE;
    }

    if (NPT_FAILED(file.Open(NPT_FILE_OPEN_MODE_READ)) || 
        NPT_FAILED(file.GetInputStream(stream))        || 
        NPT_FAILED(stream->GetSize(total_len)) || (total_len == 0)) {
        goto filenotfound;
    } else {
        NPT_String extension = NPT_FilePath::FileExtension(file_path);
        if (extension.GetLength() == 0) {
            goto filenotfound;
        }

        PLT_MetadataHandler* metadataHandler = NULL;
        char* caData;
        int   caDataLen;
        NPT_Result ret = NPT_ContainerFind(m_MetadataHandlers, 
                                           PLT_MetadataHandlerFinder(extension), 
                                           metadataHandler);
        if (NPT_FAILED(ret) || metadataHandler == NULL) {
            goto filenotfound;
        }
        // load the metadatahandler and read the cover art
        if (NPT_FAILED(metadataHandler->Load(*stream)) || 
            NPT_FAILED(metadataHandler->GetCoverArtData(caData, caDataLen))) {
            goto filenotfound;
        }
        
        PLT_HttpHelper::SetContentType(response, "application/octet-stream");
        PLT_HttpHelper::SetBody(response, caData, caDataLen);
        delete caData;
        return NPT_SUCCESS;
    }

filenotfound:
    response.SetStatus(404, "File Not Found");
    return NPT_SUCCESS;
}
Esempio n. 16
0
/*----------------------------------------------------------------------
|   PLT_MediaBrowser::OnDeviceAdded
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaBrowser::OnDeviceAdded(PLT_DeviceDataReference& device)
{
    // verify the device implements the function we need
    PLT_Service* serviceCDS;
    PLT_Service* serviceCMR;
    NPT_String type;
    
    type = "urn:schemas-upnp-org:service:ContentDirectory:1";
    if (NPT_FAILED(device->FindServiceByType(type, serviceCDS))) {
        NPT_LOG_WARNING_1("Service %s not found", (const char*)type);
        return NPT_FAILURE;
    }
    
    type = "urn:schemas-upnp-org:service:ConnectionManager:1";
    if (NPT_FAILED(device->FindServiceByType(type, serviceCMR))) {
        NPT_LOG_WARNING_1("Service %s not found", (const char*)type);
        return NPT_FAILURE;
    }    
    
    {
        NPT_AutoLock lock(m_MediaServers);

        PLT_DeviceDataReference data;
        NPT_String uuid = device->GetUUID();
        // is it a new device?
        if (NPT_SUCCEEDED(NPT_ContainerFind(m_MediaServers, PLT_DeviceDataFinder(uuid), data))) {
            NPT_LOG_WARNING_1("Device (%s) is already in our list!", (const char*)uuid);
            return NPT_FAILURE;
        }

        NPT_LOG_FINE("Device Found:");
        device->ToLog(NPT_LOG_LEVEL_FINE);

        m_MediaServers.Add(device);
    }

    if (m_Listener) {
        m_Listener->OnMSAddedRemoved(device, 1);
    }

    m_CtrlPoint->Subscribe(serviceCDS);
    m_CtrlPoint->Subscribe(serviceCMR);

    return NPT_SUCCESS;
}
Esempio n. 17
0
/*----------------------------------------------------------------------
|   PLT_DeviceData::FindEmbeddedDeviceByType
+---------------------------------------------------------------------*/
NPT_Result
PLT_DeviceData::FindEmbeddedDeviceByType(const char*              type, 
                                         PLT_DeviceDataReference& device)
{
    NPT_Result res = NPT_ContainerFind(m_EmbeddedDevices, 
        PLT_DeviceDataFinderByType(type), 
        device);
    if (NPT_SUCCEEDED(res)) return res;

    for (int i=0; i<(int)m_EmbeddedDevices.GetItemCount(); i++) {
        res = m_EmbeddedDevices[i]->FindEmbeddedDeviceByType(
            type, 
            device);
        if (NPT_SUCCEEDED(res)) return res;
    }

    return NPT_FAILURE;
}
Esempio n. 18
0
/*----------------------------------------------------------------------
|   PLT_MediaBrowser::OnEventNotify
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaBrowser::OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars)
{

    PLT_DeviceDataReference data;

    {
        NPT_AutoLock lock(m_MediaServers);
        NPT_String uuid = service->GetDevice()->GetUUID();
        if (NPT_FAILED(NPT_ContainerFind(m_MediaServers, PLT_DeviceDataFinder(uuid), data))) {
            NPT_LOG_WARNING_1("Device (%s) not found in our list!", (const char*)uuid);
            return NPT_FAILURE;
        }
    }

    if (m_Listener) m_Listener->OnMSStateVariablesChanged(service, vars);
    return NPT_SUCCESS;
}
Esempio n. 19
0
/*----------------------------------------------------------------------
|   PLT_MediaController::OnDeviceAdded
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaController::OnDeviceAdded(PLT_DeviceDataReference& device)
{
    PLT_DeviceDataReference data;
    NPT_String uuid = device->GetUUID();
    // is it a new device?
    if (NPT_SUCCEEDED(NPT_ContainerFind(m_MediaRenderers, PLT_DeviceDataFinder(uuid), data))) {
        NPT_LOG_FINE_1("Device (%s) is already in our list!", (const char*)uuid);
        return NPT_FAILURE;
    }

    NPT_LOG_FINE("Device Found:");
    device->ToLog(NPT_LOG_LEVEL_FINE);

    // verify the device implements the function we need
    PLT_Service* serviceAVT;
    PLT_Service* serviceCMR;
    NPT_String type;
    
    type = "urn:schemas-upnp-org:service:AVTransport:1";
    if (NPT_FAILED(device->FindServiceByType(type, serviceAVT))) {
        NPT_LOG_FINE_1("Service %s not found", (const char*)type);
        return NPT_FAILURE;
    }
    
    type = "urn:schemas-upnp-org:service:ConnectionManager:1";
    if (NPT_FAILED(device->FindServiceByType(type, serviceCMR))) {
        NPT_LOG_FINE_1("Service %s not found", (const char*)type);
        return NPT_FAILURE;
    }

    m_MediaRenderers.Add(device);
    if (m_Listener) {
        m_Listener->OnMRAddedRemoved(device, 1);
    }

    // subscribe to AVT eventing
    m_CtrlPoint->Subscribe(serviceAVT);
    return NPT_SUCCESS;
}
Esempio n. 20
0
/*----------------------------------------------------------------------
|   PLT_DeviceData::FindServiceByEventSubURL
+---------------------------------------------------------------------*/
NPT_Result
PLT_DeviceData::FindServiceByEventSubURL(const char*   url, 
                                         PLT_Service*& service, 
                                         bool          recursive /* = false */)
{       
    NPT_Result res = NPT_ContainerFind(m_Services, 
        PLT_ServiceEventSubURLFinder(url), 
        service);
    if (NPT_SUCCEEDED(res)) return res;

    if (recursive) {
        for (int i=0; i<(int)m_EmbeddedDevices.GetItemCount(); i++) {
            res = m_EmbeddedDevices[i]->FindServiceByEventSubURL(
                url, 
                service,
                recursive);
            if (NPT_SUCCEEDED(res)) return res;
        }
    }

    return NPT_FAILURE;
}
Esempio n. 21
0
/*----------------------------------------------------------------------
|   PLT_MediaBrowser::OnActionResponse
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaBrowser::OnActionResponse(NPT_Result res, PLT_ActionReference& action, void* userdata)
{
    PLT_DeviceDataReference device;

    {
        NPT_AutoLock lock(m_MediaServers);
        NPT_String uuid = action->GetActionDesc()->GetService()->GetDevice()->GetUUID();
        if (NPT_FAILED(NPT_ContainerFind(m_MediaServers, PLT_DeviceDataFinder(uuid), device))) {
            NPT_LOG_WARNING_1("Device (%s) not found in our list of servers", (const char*)uuid);
            return NPT_FAILURE;
        }
    }

    NPT_String actionName = action->GetActionDesc()->GetName();

    // Browse action response
    if (actionName.Compare("Browse", true) == 0) {
        return OnBrowseResponse(res, device, action, userdata);
    }

    return NPT_SUCCESS;
}
Esempio n. 22
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::OnAlbumArtRequest
+---------------------------------------------------------------------*/
NPT_Result 
PLT_FileMediaServer::OnAlbumArtRequest(NPT_String filepath, NPT_HttpResponse& response)
{
    NPT_Size total_len;
    NPT_File file(filepath);
    NPT_InputStreamReference stream;

    if (NPT_FAILED(file.Open(NPT_FILE_OPEN_MODE_READ)) || NPT_FAILED(file.GetInputStream(stream)) || 
        NPT_FAILED(stream->GetSize(total_len)) || (total_len == 0)) {
        goto filenotfound;
    } else {
        const char* extension = PLT_MediaItem::GetExtFromFilePath(filepath, m_DirDelimiter);
        if (extension == NULL) {
            goto filenotfound;
        }

        PLT_MetadataHandler* metadataHandler = NULL;
        char* caData;
        int   caDataLen;
        NPT_Result ret = NPT_ContainerFind(m_MetadataHandlers, PLT_MetadataHandlerFinder(extension), metadataHandler);
        if (NPT_FAILED(ret) || metadataHandler == NULL) {
            goto filenotfound;
        }
        // load the metadatahandler and read the cover art
        if (NPT_FAILED(metadataHandler->Load(*stream)) || NPT_FAILED(metadataHandler->GetCoverArtData(caData, caDataLen))) {
            goto filenotfound;
        }
        PLT_HttpHelper::SetContentType(&response, "application/octet-stream");
        PLT_HttpHelper::SetBody(&response, caData, caDataLen);
        delete caData;
        return NPT_SUCCESS;
    }

filenotfound:
    response.SetStatus(404, "File Not Found");
    return NPT_SUCCESS;
}
Esempio n. 23
0
/*----------------------------------------------------------------------
|   CMediaCrawler::OnBrowseDevice
+---------------------------------------------------------------------*/
NPT_Result
CMediaCrawler::OnBrowseDevice(PLT_ActionReference& action, 
                              const char*          server_uuid, 
                              const char*          server_object_id, 
                              NPT_SocketInfo*      info /* = NULL */)
{
    NPT_Result res;
    PLT_DeviceDataReference device;

    {
        // look for device first
        const NPT_Lock<PLT_DeviceDataReferenceList>& devices = GetMediaServers();
        //NPT_AutoLock lock(devices);

        if (NPT_FAILED(NPT_ContainerFind(devices, PLT_DeviceDataFinder(server_uuid), device))) {
            /* error */
            NPT_LOG_WARNING("CMediaCrawler::OnBrowseDevice - device not found.");
            action->SetError(701, "No Such Object.");
            return NPT_FAILURE;
        } 
    }

    // look for args and convert them
    NPT_String browseFlagValue;
    NPT_String startingInd;
    NPT_String reqCount;
    NPT_String filter;
    NPT_String sort;

    NPT_CHECK_SEVERE(action->GetArgumentValue("BrowseFlag", browseFlagValue));
    NPT_CHECK_SEVERE(action->GetArgumentValue("StartingIndex", startingInd));
    NPT_CHECK_SEVERE(action->GetArgumentValue("RequestedCount", reqCount));   
    NPT_CHECK_SEVERE(action->GetArgumentValue("Filter", filter));
    NPT_CHECK_SEVERE(action->GetArgumentValue("SortCriteria", sort));

    unsigned long start_index, req_count;
    if (NPT_FAILED(startingInd.ToInteger(start_index)) ||
        NPT_FAILED(reqCount.ToInteger(req_count))) {
        return NPT_FAILURE;
    } 

    // create a container for our result
    // this will be filled in by OnBrowseResponse
    CMediaCrawlerBrowseInfoReference browse_info(new CMediaCrawlerBrowseInfo());
    browse_info->shared_var.SetValue(0);

    // send off the browse packet.  Note that this will
    // not block.  The shared variable is used to block
    // until the response has been received.
    res = Browse(device,
        server_object_id,
        start_index,
        req_count,
        (browseFlagValue == "BrowseMetadata")?1:0,
        filter,
        sort,
        new CMediaCrawlerBrowseInfoReference(browse_info));		
    NPT_CHECK_SEVERE(res);

    // wait 30 secs for response
    res = browse_info->shared_var.WaitUntilEquals(1, 30000);
    NPT_CHECK_SEVERE(res);

    // did the browse fail?
    if (NPT_FAILED(browse_info->res)) {
        action->SetError(browse_info->code, "");
        return NPT_FAILURE;
    }    
   
    action->SetArgumentValue("Result", UpdateDidl(server_uuid, browse_info->didl, info));
    action->SetArgumentValue("NumberReturned", browse_info->nr);
    action->SetArgumentValue("TotalMatches", browse_info->tm);
    action->SetArgumentValue("UpdateId", browse_info->uid);
    action->SetArgumentValue("ObjectID", FormatObjectId(server_uuid, browse_info->object_id));
    
    return NPT_SUCCESS;
}
Esempio n. 24
0
/*----------------------------------------------------------------------
|   PLT_MediaController::OnDeviceAdded
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaController::OnDeviceAdded(PLT_DeviceDataReference& device)
{
    // verify the device implements the function we need
    PLT_Service* serviceAVT = NULL;
    PLT_Service* serviceCMR;
	PLT_Service* serviceRC;
    NPT_String   type;
    
    if (!device->GetType().StartsWith("urn:schemas-upnp-org:device:MediaRenderer"))
        return NPT_FAILURE;

    // optional service
    type = "urn:schemas-upnp-org:service:AVTransport:*";
    if (NPT_SUCCEEDED(device->FindServiceByType(type, serviceAVT))) {
        // in case it's a newer upnp implementation, force to 1
        NPT_LOG_FINE_1("Service %s found", (const char*)type);
        serviceAVT->ForceVersion(1);
    }
    
    // required services
    type = "urn:schemas-upnp-org:service:ConnectionManager:*";
    if (NPT_FAILED(device->FindServiceByType(type, serviceCMR))) {
        NPT_LOG_FINE_1("Service %s not found", (const char*)type);
        return NPT_FAILURE;
    } else {
        // in case it's a newer upnp implementation, force to 1
        serviceCMR->ForceVersion(1);
    }

	type = "urn:schemas-upnp-org:service:RenderingControl:*";
    if (NPT_FAILED(device->FindServiceByType(type, serviceRC))) {
        NPT_LOG_FINE_1("Service %s not found", (const char*)type);
        return NPT_FAILURE;
    } else {
        // in case it's a newer upnp implementation, force to 1
        serviceRC->ForceVersion(1);
    }

    {
        NPT_AutoLock lock(m_MediaRenderers);

        PLT_DeviceDataReference data;
        NPT_String uuid = device->GetUUID();
        
        // is it a new device?
        if (NPT_SUCCEEDED(NPT_ContainerFind(m_MediaRenderers, 
                                            PLT_DeviceDataFinder(uuid), data))) {
            NPT_LOG_WARNING_1("Device (%s) is already in our list!", (const char*)uuid);
            return NPT_FAILURE;
        }

        NPT_LOG_FINE_1("Device Found: %s", (const char*)*device);

        m_MediaRenderers.Add(device);
    }
    
    if (m_Delegate && m_Delegate->OnMRAdded(device)) {
        // subscribe to services eventing only if delegate wants it
        if (serviceAVT) m_CtrlPoint->Subscribe(serviceAVT);

        // subscribe to required services
		m_CtrlPoint->Subscribe(serviceCMR);
		m_CtrlPoint->Subscribe(serviceRC);
    }

    return NPT_SUCCESS;
}
Esempio n. 25
0
/*----------------------------------------------------------------------
|   PLT_MediaController::OnEventNotify
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaController::OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars)
{
    if (m_Listener) {
        // parse LastChange var into smaller vars
        PLT_StateVariable* lastChangeVar = NULL;
        if (NPT_SUCCEEDED(NPT_ContainerFind(*vars, PLT_ListStateVariableNameFinder("LastChange"), lastChangeVar))) {
            vars->Remove(lastChangeVar);
            PLT_Service* var_service = lastChangeVar->GetService();
            NPT_String text = lastChangeVar->GetValue();
            
            NPT_XmlNode* xml = NULL;
            NPT_XmlParser parser;
            if (NPT_FAILED(parser.Parse(text, xml)) || !xml || !xml->AsElementNode()) {
                delete xml;
                return NPT_FAILURE;
            }

            NPT_XmlElementNode* node = xml->AsElementNode();
            if (!node->GetTag().Compare("Event", true)) {
                // look for the instance with attribute id = 0
                NPT_XmlElementNode* instance = NULL;
                for (NPT_Cardinal i=0; i<node->GetChildren().GetItemCount(); i++) {
                    NPT_XmlElementNode* child;
                    if (NPT_FAILED(PLT_XmlHelper::GetChild(node, child, i)))
                        continue;

                    if (!child->GetTag().Compare("InstanceID", true)) {
                        // extract the "val" attribute value
                        NPT_String value;
                        if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(child, "val", value)) &&
                            !value.Compare("0")) {
                            instance = child;
                            break;
                        }
                    }
                }

                // did we find an instance with id = 0 ?
                if (instance != NULL) {
                    // all the children of the Instance node are state variables
                    for (NPT_Cardinal j=0; j<instance->GetChildren().GetItemCount(); j++) {
                        NPT_XmlElementNode* var_node;
                        if (NPT_FAILED(PLT_XmlHelper::GetChild(instance, var_node, j)))
                            continue;

                        // look for the state variable in this service
                        const NPT_String* value = var_node->GetAttribute("val");
                        PLT_StateVariable* var = var_service->FindStateVariable(var_node->GetTag());
                        if (value != NULL && var != NULL) {
                            // get the value and set the state variable
                            // if it succeeded, add it to the list of vars we'll event
                            if (NPT_SUCCEEDED(var->SetValue(*value, false))) {
                                vars->Add(var);
                                NPT_LOG_FINE_2("PLT_MediaController received var change for (%s): %s", (const char*)var->GetName(), (const char*)var->GetValue());
                            }
                        }
                    }
                }
            }
            delete xml;
        }

        if (vars->GetItemCount()) {
            m_Listener->OnMRStateVariablesChanged(service, vars);
        }
    }
    return NPT_SUCCESS;
}
Esempio n. 26
0
/*----------------------------------------------------------------------
|   CUPnPDirectory::GetDirectory
+---------------------------------------------------------------------*/
bool
CUPnPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
{
    CGUIDialogProgress* dlgProgress = NULL;

    CUPnP* upnp = CUPnP::GetInstance();

    /* upnp should never be cached, it has internal cache */
    items.SetCacheToDisc(CFileItemList::CACHE_NEVER);

    // start client if it hasn't been done yet
    bool client_started = upnp->IsClientStarted();
    upnp->StartClient();

    // We accept upnp://devuuid/[item_id/]
    NPT_String path = strPath.c_str();
    if (!path.StartsWith("upnp://", true)) {
        return false;
    }

    if (path.Compare("upnp://", true) == 0) {
        // root -> get list of devices
        const NPT_Lock<PLT_DeviceMap>& devices = upnp->m_MediaBrowser->GetMediaServers();
        const NPT_List<PLT_DeviceMapEntry*>& entries = devices.GetEntries();
        NPT_List<PLT_DeviceMapEntry*>::Iterator entry = entries.GetFirstItem();
        while (entry) {
            PLT_DeviceDataReference device = (*entry)->GetValue();
            NPT_String name = device->GetFriendlyName();
            NPT_String uuid = (*entry)->GetKey();

            CFileItemPtr pItem(new CFileItem((const char*)name));
            pItem->m_strPath = (const char*) "upnp://" + uuid + "/";
            pItem->m_bIsFolder = true;
            pItem->SetThumbnailImage((const char*)device->GetIconUrl("image/jpeg"));

            items.Add(pItem);

            ++entry;
        }
    } else {
        if (!path.EndsWith("/")) path += "/";

        // look for nextslash
        int next_slash = path.Find('/', 7);

        NPT_String uuid = (next_slash==-1)?path.SubString(7):path.SubString(7, next_slash-7);
        NPT_String object_id = (next_slash==-1)?"":path.SubString(next_slash+1);
        object_id.TrimRight("/");
        if (object_id.GetLength()) {
            CStdString tmp = (char*) object_id;
            CUtil::UrlDecode(tmp);
            object_id = tmp;
        }

        // look for device in our list
        // (and wait for it to respond for 5 secs if we're just starting upnp client)
        NPT_TimeStamp watchdog;
        NPT_System::GetCurrentTimeStamp(watchdog);
        watchdog += 5.f;

        PLT_DeviceDataReference* device;
        for (;;) {
            const NPT_Lock<PLT_DeviceMap>& devices = upnp->m_MediaBrowser->GetMediaServers();
            if (NPT_SUCCEEDED(devices.Get(uuid, device)) && device)
                break;

            // fail right away if device not found and upnp client was already running
            if (client_started)
                goto failure;

            // otherwise check if we've waited long enough without success
            NPT_TimeStamp now;
            NPT_System::GetCurrentTimeStamp(now);
            if (now > watchdog)
                goto failure;

            // sleep a bit and try again
            NPT_System::Sleep(NPT_TimeInterval(1, 0));
        }

        // issue a browse request with object_id
        // if object_id is empty use "0" for root
        object_id = object_id.IsEmpty()?"0":object_id;

        // just a guess as to what types of files we want
        bool video = true;
        bool audio = true;
        bool image = true;
        m_strFileMask.TrimLeft("/");
        if (!m_strFileMask.IsEmpty()) {
            video = m_strFileMask.Find(".wmv") >= 0;
            audio = m_strFileMask.Find(".wma") >= 0;
            image = m_strFileMask.Find(".jpg") >= 0;
        }

        // special case for Windows Media Connect and WMP11 when looking for root
        // We can target which root subfolder we want based on directory mask
        if (object_id == "0" && (((*device)->GetFriendlyName().Find("Windows Media Connect", 0, true) >= 0) ||
                                 ((*device)->m_ModelName == "Windows Media Player Sharing"))) {

            // look for a specific type to differentiate which folder we want
            if (audio && !video && !image) {
                // music
                object_id = "1";
            } else if (!audio && video && !image) {
                // video
                object_id = "2";
            } else if (!audio && !video && image) {
                // pictures
                object_id = "3";
            }
        }

#ifdef DISABLE_SPECIALCASE
        // same thing but special case for XBMC
        if (object_id == "0" && (((*device)->m_ModelName.Find("XBMC", 0, true) >= 0) ||
                                 ((*device)->m_ModelName.Find("Xbox Media Center", 0, true) >= 0))) {
            // look for a specific type to differentiate which folder we want
            if (audio && !video && !image) {
                // music
                object_id = "virtualpath://upnpmusic";
            } else if (!audio && video && !image) {
                // video
                object_id = "virtualpath://upnpvideo";
            } else if (!audio && !video && image) {
                // pictures
                object_id = "virtualpath://upnppictures";
            }
        }
#endif
        // bring up dialog if object is not cached
        if (!upnp->m_MediaBrowser->IsCached(uuid, object_id)) {
            dlgProgress = (CGUIDialogProgress*)m_gWindowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
            if (dlgProgress) {
                dlgProgress->ShowProgressBar(false);
                dlgProgress->SetCanCancel(false);
                dlgProgress->SetHeading(20334);
                dlgProgress->SetLine(0, 194);
                dlgProgress->SetLine(1, "");
                dlgProgress->SetLine(2, "");
                dlgProgress->StartModal();
            }
        }

        // if error, return now, the device could have gone away
        // this will make us go back to the sources list
        PLT_MediaObjectListReference list;
        NPT_Result res = upnp->m_MediaBrowser->Browse(*device, object_id, list);
        if (NPT_FAILED(res)) goto failure;

        // empty list is ok
        if (list.IsNull()) goto cleanup;

        PLT_MediaObjectList::Iterator entry = list->GetFirstItem();
        while (entry) {
            // disregard items with wrong class/type
            if( (!video && (*entry)->m_ObjectClass.type.CompareN("object.item.videoitem", 21,true) == 0)
             || (!audio && (*entry)->m_ObjectClass.type.CompareN("object.item.audioitem", 21,true) == 0)
             || (!image && (*entry)->m_ObjectClass.type.CompareN("object.item.imageitem", 21,true) == 0) )
            {
                ++entry;
                continue;
            }

            // never show empty containers in media views
            if((*entry)->IsContainer()) {
                if( (audio || video || image)
                 && ((PLT_MediaContainer*)(*entry))->m_ChildrenCount == 0) {
                    ++entry;
                    continue;
                }
            }

            CFileItemPtr pItem(new CFileItem((const char*)(*entry)->m_Title));
            pItem->SetLabelPreformated(true);
            pItem->m_bIsFolder = (*entry)->IsContainer();

            // if it's a container, format a string as upnp://uuid/object_id
            if (pItem->m_bIsFolder) {
                CStdString id = (char*) (*entry)->m_ObjectID;
                CUtil::URLEncode(id);
                pItem->m_strPath = (const char*) "upnp://" + uuid + "/" + id.c_str() + "/";
            } else {
                if ((*entry)->m_Resources.GetItemCount()) {
                    PLT_MediaItemResource& resource = (*entry)->m_Resources[0];

                    // look for a resource with "xbmc-get" protocol
                    // if we can't find one, keep the first resource
                    NPT_ContainerFind((*entry)->m_Resources,
                                      CProtocolFinder("xbmc-get"),
                                      resource);

                    CLog::Log(LOGDEBUG, "CUPnPDirectory::GetDirectory - resource protocol info '%s'", (const char*)(resource.m_ProtocolInfo));

                    // if it's an item, path is the first url to the item
                    // we hope the server made the first one reachable for us
                    // (it could be a format we dont know how to play however)
                    pItem->m_strPath = (const char*) resource.m_Uri;

                    // set metadata
                    if (resource.m_Size > 0) {
                        pItem->m_dwSize  = resource.m_Size;
                    }

                    // set a general content type
                    CStdString type = (const char*)(*entry)->m_ObjectClass.type.Left(21);
                    if     (type.Equals("object.item.videoitem"))
                        pItem->SetContentType("video/octet-stream");
                    else if(type.Equals("object.item.audioitem"))
                        pItem->SetContentType("audio/octet-stream");
                    else if(type.Equals("object.item.imageitem"))
                        pItem->SetContentType("image/octet-stream");

                    // look for content type in protocol info
                    if (resource.m_ProtocolInfo.GetLength()) {
                        char proto[1024];
                        char dummy1[1024];
                        char ct[1204];
                        char dummy2[1024];
                        int fields = sscanf(resource.m_ProtocolInfo, "%[^:]:%[^:]:%[^:]:%[^:]", proto, dummy1, ct, dummy2);
                        if (fields == 4) {
                            if (strcmp(ct, "application/octet-stream") != 0) {
                                pItem->SetContentType(ct);
                            }
                        } else {
                            CLog::Log(LOGERROR, "CUPnPDirectory::GetDirectory - invalid protocol info '%s'", (const char*)(resource.m_ProtocolInfo));
                        }
                    }

                    // look for date?
                    if((*entry)->m_Description.date.GetLength()) {
                        SYSTEMTIME time = {};
                        sscanf((*entry)->m_Description.date, "%hu-%hu-%huT%hu:%hu:%hu",
                               &time.wYear, &time.wMonth, &time.wDay, &time.wHour, &time.wMinute, &time.wSecond);
                        pItem->m_dateTime = time;
                    }

                    // look for metadata
                    if( (*entry)->m_ObjectClass.type.CompareN("object.item.videoitem", 21,true) == 0 ) {
                        pItem->SetLabelPreformated(false);
                        CUPnP::PopulateTagFromObject(*pItem->GetVideoInfoTag(), *(*entry), &resource);
                    } else if( (*entry)->m_ObjectClass.type.CompareN("object.item.audioitem", 21,true) == 0 ) {
                        pItem->SetLabelPreformated(false);
                        CUPnP::PopulateTagFromObject(*pItem->GetMusicInfoTag(), *(*entry), &resource);
                    } else if( (*entry)->m_ObjectClass.type.CompareN("object.item.imageitem", 21,true) == 0 ) {
                      //CPictureInfoTag* tag = pItem->GetPictureInfoTag();
                    }
                }
            }

            // if there is a thumbnail available set it here
            if((*entry)->m_ExtraInfo.album_art_uri.GetLength())
                pItem->SetThumbnailImage((const char*) (*entry)->m_ExtraInfo.album_art_uri);
            else if((*entry)->m_Description.icon_uri.GetLength())
                pItem->SetThumbnailImage((const char*) (*entry)->m_Description.icon_uri);

            items.Add(pItem);

            ++entry;
        }
    }

cleanup:
    if (dlgProgress) dlgProgress->Close();
    return true;

failure:
    if (dlgProgress) dlgProgress->Close();
    return false;
}
Esempio n. 27
0
/*----------------------------------------------------------------------
|   PLT_MediaController::OnActionResponse
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaController::OnActionResponse(NPT_Result res, PLT_ActionReference& action, void* userdata)
{
    if (m_Listener == NULL) {
        return NPT_SUCCESS;
    }

    /* make sure device is a renderer we've previously found */
    PLT_DeviceDataReference device;
    NPT_String uuid = action->GetActionDesc()->GetService()->GetDevice()->GetUUID();
    if (NPT_FAILED(NPT_ContainerFind(m_MediaRenderers, PLT_DeviceDataFinder(uuid), device))) {
        NPT_LOG_FINE_1("Device (%s) not found in our list of renderers", (const char*)uuid);
        res = NPT_FAILURE;
    }
       
    /* extract action name */
    NPT_String actionName = action->GetActionDesc()->GetName();

    /* AVTransport response ? */
    if (actionName.Compare("GetCurrentTransportActions", true) == 0) {
        return OnGetCurrentTransportActionsResponse(res, device, action, userdata);
    }
    else if (actionName.Compare("GetDeviceCapabilities", true) == 0) {
        return OnGetDeviceCapabilitiesResponse(res, device, action, userdata);
    }
    else if (actionName.Compare("GetMediaInfo", true) == 0) {
        return OnGetMediaInfoResponse(res, device, action, userdata);
    }
    else if (actionName.Compare("GetPositionInfo", true) == 0) {
        return OnGetPositionInfoResponse(res, device, action, userdata);
    }
    else if (actionName.Compare("GetTransportInfo", true) == 0) {
        return OnGetTransportInfoResponse(res, device, action, userdata);
    }
    else if (actionName.Compare("GetTransportSettings", true) == 0) {
        return OnGetTransportSettingsResponse(res, device, action, userdata);
    }
    else if (actionName.Compare("Next", true) == 0) {
        m_Listener->OnNextResult(res, device, userdata);
    }
    else if (actionName.Compare("Pause", true) == 0) {
        m_Listener->OnPauseResult(res, device, userdata);
    }
    else if (actionName.Compare("Play", true) == 0) {
        m_Listener->OnPlayResult(res, device, userdata);
    }
    else if (actionName.Compare("Previous", true) == 0) {
        m_Listener->OnPreviousResult(res, device, userdata);
    }
    else if (actionName.Compare("Seek", true) == 0) {
        m_Listener->OnSeekResult(res, device, userdata);
    }
    else if (actionName.Compare("SetAVTransportURI", true) == 0) {
        m_Listener->OnSetAVTransportURIResult(res, device, userdata);
    }
    else if (actionName.Compare("SetPlayMode", true) == 0) {
        m_Listener->OnSetPlayModeResult(res, device, userdata);
    }
    else if (actionName.Compare("Stop", true) == 0) {
        m_Listener->OnStopResult(res, device, userdata);
    }
    else if (actionName.Compare("GetCurrentConnectionIDs", true) == 0) {
        return OnGetCurrentConnectionIDsResponse(res, device, action, userdata);
    }
    else if (actionName.Compare("GetCurrentConnectionInfo", true) == 0) {
        return OnGetCurrentConnectionInfoResponse(res, device, action, userdata);
    }
    else if (actionName.Compare("GetProtocolInfo", true) == 0) {
        return OnGetProtocolInfoResponse(res, device, action, userdata);
    }

    return NPT_SUCCESS;
}
Esempio n. 28
0
/*----------------------------------------------------------------------
|   CUPnPDirectory::GetDirectory
+---------------------------------------------------------------------*/
bool CUPnPDirectory::GetResource(const CURL& path, CFileItem &item)
{
    if(path.GetProtocol() != "upnp")
        return false;

    CUPnP* upnp = CUPnP::GetInstance();
    if(!upnp)
        return false;

    CStdString uuid   = path.GetHostName();
    CStdString object = path.GetFileName();
    object.TrimRight("/");
    CURL::Decode(object);

    PLT_DeviceDataReference device;
    if(!FindDeviceWait(upnp, uuid.c_str(), device))
        return false;

    PLT_MediaObjectListReference list;
    if (NPT_FAILED(upnp->m_MediaBrowser->BrowseSync(device, object.c_str(), list, true)))
        return false;

    PLT_MediaObjectList::Iterator entry = list->GetFirstItem();
    if (entry == 0)
        return false;

    PLT_MediaItemResource resource;

    // look for a resource with "xbmc-get" protocol
    // if we can't find one, keep the first resource
    if(NPT_FAILED(NPT_ContainerFind((*entry)->m_Resources,
                                    CProtocolFinder("xbmc-get"), resource))) {
        if((*entry)->m_Resources.GetItemCount())
            resource = (*entry)->m_Resources[0];
        else
            return false;
    }

    // store original path so we remember it
    item.SetProperty("original_listitem_url",  item.GetPath());
    item.SetProperty("original_listitem_mime", item.GetMimeType(false));

    // if it's an item, path is the first url to the item
    // we hope the server made the first one reachable for us
    // (it could be a format we dont know how to play however)
    item.SetPath((const char*) resource.m_Uri);

    // look for content type in protocol info
    if (resource.m_ProtocolInfo.IsValid()) {
        CLog::Log(LOGDEBUG, "CUPnPDirectory::GetResource - resource protocol info '%s'",
                  (const char*)(resource.m_ProtocolInfo.ToString()));

        if (resource.m_ProtocolInfo.GetContentType().Compare("application/octet-stream") != 0) {
            item.SetMimeType((const char*)resource.m_ProtocolInfo.GetContentType());
        }
    } else {
        CLog::Log(LOGERROR, "CUPnPDirectory::GetResource - invalid protocol info '%s'",
                  (const char*)(resource.m_ProtocolInfo.ToString()));
    }

    // look for subtitles
    unsigned subs = 0;
    for(unsigned r = 0; r < (*entry)->m_Resources.GetItemCount(); r++)
    {
        PLT_MediaItemResource& res  = (*entry)->m_Resources[r];
        PLT_ProtocolInfo&      info = res.m_ProtocolInfo;
        static const char* allowed[] = { "text/srt"
                                         , "text/ssa"
                                         , "text/sub"
                                         , "text/idx"
                                       };
        for(unsigned type = 0; type < sizeof(allowed)/sizeof(allowed[0]); type++)
        {
            if(info.Match(PLT_ProtocolInfo("*", "*", allowed[type], "*")))
            {
                CStdString prop;
                prop.Format("upnp:subtitle:%d", ++subs);
                item.SetProperty(prop, (const char*)res.m_Uri);
                break;
            }
        }
    }

    return true;
}
Esempio n. 29
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::BuildFromFilePath
+---------------------------------------------------------------------*/
PLT_MediaObject*
PLT_FileMediaServer::BuildFromFilePath(const NPT_String&        filepath, 
                                       bool                     with_count /* = true */,
                                       const NPT_SocketAddress* req_local_address /* = NULL */,
                                       bool                     keep_extension_in_title /* = false */)
{
    NPT_String            root = m_Path;
    PLT_MediaItemResource resource;
    PLT_MediaObject*      object = NULL;

    /* retrieve the entry type (directory or file) */
    NPT_FileInfo info; 
    NPT_CHECK_LABEL_FATAL(NPT_File::GetInfo(filepath, &info), failure);

    if (info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR) {
        object = new PLT_MediaItem();

        /* Set the title using the filename for now */
        object->m_Title = NPT_FilePath::BaseName(filepath, keep_extension_in_title);
        if (object->m_Title.GetLength() == 0) goto failure;

        /* Set the protocol Info from the extension */
        resource.m_ProtocolInfo = PLT_MediaItem::GetProtInfoFromExt(NPT_FilePath::FileExtension(filepath));
        if (resource.m_ProtocolInfo.GetLength() == 0)  goto failure;

        /* Set the resource file size */
        resource.m_Size = info.m_Size;
 
        /* format the resource URI */
        NPT_String url = filepath.SubString(root.GetLength()+1);

        // get list of ip addresses
        NPT_List<NPT_String> ips;
        NPT_CHECK_LABEL_SEVERE(PLT_UPnPMessageHelper::GetIPAddresses(ips), failure);

        // if we're passed an interface where we received the request from
        // move the ip to the top
        if (req_local_address && req_local_address->GetIpAddress().ToString() != "0.0.0.0") {
            ips.Remove(req_local_address->GetIpAddress().ToString());
            ips.Insert(ips.GetFirstItem(), req_local_address->GetIpAddress().ToString());
        }

        // iterate through list and build list of resources
        NPT_List<NPT_String>::Iterator ip = ips.GetFirstItem();
        while (ip) {
            /* prepend the base URI and url encode it */ 
            //resource.m_Uri = NPT_Uri::Encode(uri.ToString(), NPT_Uri::UnsafeCharsToEncode);
            resource.m_Uri = BuildResourceUri(m_FileBaseUri, *ip, url);

            /* Look to see if a metadatahandler exists for this extension */
            PLT_MetadataHandler* handler = NULL;
            NPT_Result res = NPT_ContainerFind(
                m_MetadataHandlers, 
                PLT_MetadataHandlerFinder(NPT_FilePath::FileExtension(filepath)), 
                handler);
            if (NPT_SUCCEEDED(res) && handler) {
                /* if it failed loading data, reset the metadatahandler so we don't use it */
                if (NPT_SUCCEEDED(handler->LoadFile(filepath))) {
                    /* replace the title with the one from the Metadata */
                    NPT_String newTitle;
                    if (handler->GetTitle(newTitle) != NULL) {
                        object->m_Title = newTitle;
                    }

                    /* assign description */
                    handler->GetDescription(object->m_Description.long_description);

                    /* assign album art uri if we haven't yet */
                    /* prepend the album art base URI and url encode it */ 
                    if (object->m_ExtraInfo.album_art_uri.GetLength() == 0) {
                        object->m_ExtraInfo.album_art_uri = 
                            NPT_Uri::PercentEncode(BuildResourceUri(m_AlbumArtBaseUri, *ip, url), 
                                                   NPT_Uri::UnsafeCharsToEncode);
                    }

                    /* duration */
                    handler->GetDuration(resource.m_Duration);

                    /* protection */
                    handler->GetProtection(resource.m_Protection);
                }
            }

            object->m_ObjectClass.type = PLT_MediaItem::GetUPnPClassFromExt(NPT_FilePath::FileExtension(filepath));
            object->m_Resources.Add(resource);

            ++ip;
        }
    } else {
        object = new PLT_MediaContainer;

        /* Assign a title for this container */
        if (filepath.Compare(root, true) == 0) {
            object->m_Title = "Root";
        } else {
            object->m_Title = NPT_FilePath::BaseName(filepath, keep_extension_in_title);
            if (object->m_Title.GetLength() == 0) goto failure;
        }

        /* Get the number of children for this container */
        NPT_Cardinal count = 0;
        if (with_count && NPT_SUCCEEDED(NPT_File::GetCount(filepath, count))) {
            ((PLT_MediaContainer*)object)->m_ChildrenCount = count;
        }

        object->m_ObjectClass.type = "object.container";
    }

    /* is it the root? */
    if (filepath.Compare(root, true) == 0) {
        object->m_ParentID = "-1";
        object->m_ObjectID = "0";
    } else {
        NPT_String directory = NPT_FilePath::DirectoryName(filepath);
        /* is the parent path the root? */
        if (directory.GetLength() == root.GetLength()) {
            object->m_ParentID = "0";
        } else {
            object->m_ParentID = "0" + filepath.SubString(root.GetLength(), directory.GetLength() - root.GetLength());
        }
        object->m_ObjectID = "0" + filepath.SubString(root.GetLength());
    }

    return object;

failure:
    delete object;
    return NULL;
}
Esempio n. 30
0
/*----------------------------------------------------------------------
|   CMediaCrawler::UpdateDidl
+---------------------------------------------------------------------*/
NPT_String
CMediaCrawler::UpdateDidl(const char* server_uuid, const NPT_String& didl, NPT_SocketInfo* info)
{
    NPT_String     new_didl;
    NPT_String     str;
    NPT_XmlNode*   node = NULL;
    NPT_XmlWriter  writer;
    NPT_OutputStreamReference stream(new NPT_StringOutputStream(&new_didl));

    NPT_LOG_FINE("Parsing Didl...");

    NPT_XmlElementNode* tree = NULL;
    NPT_XmlParser parser;
    if (NPT_FAILED(parser.Parse(didl, node)) || !node || !node->AsElementNode()) {
        goto cleanup;
    }

    tree = node->AsElementNode();

    NPT_LOG_FINE("Processing Didl xml...");
    if (tree->GetTag().Compare("DIDL-Lite", true)) {
        goto cleanup;
    }

    // iterate through children
    NPT_Result res;
    for (NPT_List<NPT_XmlNode*>::Iterator children = tree->GetChildren().GetFirstItem(); children; children++) {
        NPT_XmlElementNode* child = (*children)->AsElementNode();
        if (!child) continue;

        // object id remapping
        NPT_XmlAttribute* attribute_id;
        res = PLT_XmlHelper::GetAttribute(child, "id", attribute_id);
        if (NPT_SUCCEEDED(res) && attribute_id) {
            attribute_id->SetValue(FormatObjectId(server_uuid, attribute_id->GetValue()));
        }

        // parent ID remapping
        NPT_XmlAttribute* attribute_parent_id;
        res = PLT_XmlHelper::GetAttribute(child, "parentID", attribute_parent_id);
        if (NPT_SUCCEEDED(res)) {
            attribute_parent_id->SetValue(attribute_parent_id->GetValue().Compare("-1")?FormatObjectId(server_uuid, attribute_parent_id->GetValue()):"0");
        }

        // resources remapping
        NPT_Array<NPT_XmlElementNode*> res;
        PLT_XmlHelper::GetChildren(child, res, "res");
        if (res.GetItemCount() > 0) {
            for (unsigned int i=0; i<res.GetItemCount(); i++) {
                NPT_XmlElementNode* resource = res[i];
                NPT_XmlAttribute*   attribute_prot;
                const NPT_String*   url;
                if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(resource, "protocolInfo", attribute_prot)) && (url = resource->GetText())) {
                    // special case for Windows Media Connect
                    // When a browse is done on the same machine, WMC uses localhost 
                    // instead of the IP for all resources urls which means we cannot advertise that 
                    // since it would be useless for a remote device 
                    // so we try to replace it with the right IP address by looking at which interface we received the
                    // initial browse request on to make sure the remote device will be able to access the modified resource
                    // urls (in case the local PC has more than 1 NICs)

                    // replace the url
                    NPT_List<NPT_XmlNode*>& children = resource->GetChildren();
                    NPT_HttpUrl http_url(NPT_Uri::PercentDecode(*url));
                    if ((http_url.GetHost() == "localhost" || http_url.GetHost() == "127.0.0.1") && info) {
                        if (info->local_address.GetIpAddress().AsLong()) {
                            http_url.SetHost(info->local_address.GetIpAddress().ToString());

                            // replace text
                            children.Apply(NPT_ObjectDeleter<NPT_XmlNode>());
                            children.Clear();
                            resource->AddText(http_url.ToString());
                            url = resource->GetText();
                        }
                    }

                    CStreamHandler* handler = NULL;
                    NPT_Result res = NPT_ContainerFind(m_StreamHandlers, CStreamHandlerFinder(attribute_prot->GetValue(), *url), handler);
                    if (NPT_SUCCEEDED(res)) {
                        handler->ModifyResource(resource);
                    }
                }
            }
        }
    }

    // serialize modified node into new didl
    writer.Serialize(*node, *stream);
    delete node;
    return new_didl;

cleanup:
    delete node;
    return didl;
}