Beispiel #1
0
/*----------------------------------------------------------------------
|   NPT_ZipFile::GetInputStream
+---------------------------------------------------------------------*/
NPT_Result
NPT_ZipFile::GetInputStream(Entry& entry, NPT_InputStreamReference& zip_stream, NPT_InputStream*& file_stream)
{
    // default return value
    file_stream = NULL;

    // we don't support encrypted files
    if (entry.m_Flags & NPT_ZIP_FILE_FLAG_ENCRYPTED) {
        return NPT_ERROR_NOT_SUPPORTED;
    }

    // check that we support the compression method
#if NPT_CONFIG_ENABLE_ZIP
    if (entry.m_CompressionMethod != NPT_ZIP_FILE_COMPRESSION_METHOD_NONE &&
            entry.m_CompressionMethod != NPT_ZIP_FILE_COMPRESSION_METHOD_DEFLATE) {
        return NPT_ERROR_NOT_SUPPORTED;
    }
#else
    if (entry.m_CompressionMethod != NPT_ZIP_FILE_COMPRESSION_METHOD_NONE) {
        return NPT_ERROR_NOT_SUPPORTED;
    }
#endif

    // seek to the start of the file entry
    NPT_Result result = zip_stream->Seek(entry.m_RelativeOffset);
    if (NPT_FAILED(result)) {
        NPT_LOG_WARNING_1("seek failed (%d)", result);
        return result;
    }

    // read the fixed part of the header
    unsigned char header[30];
    result = zip_stream->ReadFully(header, 30);
    if (NPT_FAILED(result)) {
        NPT_LOG_WARNING_1("read failed (%d)", result);
        return result;
    }

    NPT_UInt16 file_name_length   = NPT_BytesToInt16Le(&header[26]);
    NPT_UInt16 extra_field_length = NPT_BytesToInt16Le(&header[28]);

    unsigned int header_size = 30+file_name_length+extra_field_length;
    NPT_LargeSize zip_stream_size = 0;
    zip_stream->GetSize(zip_stream_size);
    if (entry.m_RelativeOffset+header_size+entry.m_CompressedSize > zip_stream_size) {
        // something's wrong here
        return NPT_ERROR_INVALID_FORMAT;
    }

    file_stream = new NPT_SubInputStream(zip_stream, entry.m_RelativeOffset+header_size, entry.m_CompressedSize);

#if NPT_CONFIG_ENABLE_ZIP
    if (entry.m_CompressionMethod == NPT_ZIP_FILE_COMPRESSION_METHOD_DEFLATE) {
        NPT_InputStreamReference file_stream_ref(file_stream);
        file_stream = new NPT_ZipInflatingInputStream(file_stream_ref, true);
    }
#endif

    return NPT_SUCCESS;
}
Beispiel #2
0
/*----------------------------------------------------------------------
|   PLT_MediaContainer::FromDidl
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaContainer::FromDidl(NPT_XmlElementNode* entry)
{
    NPT_String str;

    /* reset first */
    Reset();

    // check entry type
    if (entry->GetTag().Compare("Container", true) != 0) 
        return NPT_ERROR_INTERNAL;

    // check if item is searchable (is default true?)
    if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(entry, "searchable", str, "", 5))) {
        m_Searchable = PLT_Service::IsTrue(str);
    }

    // look for childCount
    if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(entry, "childCount", str, "", 256))) {
        NPT_UInt32 count;
        NPT_CHECK_SEVERE(str.ToInteger(count));
        m_ChildrenCount = count;
    }

	// upnp:searchClass child elements
    NPT_Array<NPT_XmlElementNode*> children;
	PLT_XmlHelper::GetChildren(entry, children, "upnp:searchClass");

    for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) {
        PLT_SearchClass search_class;

        // extract url
        if (children[i]->GetText() == NULL) {
            NPT_LOG_WARNING_1("No searchClass text found in: %s", 
				(const char*)PLT_XmlHelper::Serialize(*children[i]));
			continue;
        }
		
        // DLNA 7.3.17.4
		search_class.type = children[i]->GetText()->SubString(0, 256);

		// extract optional attribute name
		PLT_XmlHelper::GetAttribute(children[i], "name", search_class.friendly_name);
		    
		// includeDerived property
		if (NPT_FAILED(PLT_XmlHelper::GetAttribute(children[i], "includeDerived", str))) {
            NPT_LOG_WARNING_1("No required attribute searchClass@includeDerived found in: %s", 
				(const char*)PLT_XmlHelper::Serialize(*children[i]));
			continue;
		}

		search_class.include_derived = PLT_Service::IsTrue(str);
		m_SearchClasses.Add(search_class);
	}

    return PLT_MediaObject::FromDidl(entry);
}
Beispiel #3
0
/*----------------------------------------------------------------------
|   PLT_MediaServer::ParseSort
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaServer::ParseSort(const NPT_String& sort, NPT_List<NPT_String>& list)
{
    // reset output params first
    list.Clear();
    
    // easy out
    if (sort.GetLength() == 0 || sort == "*") return NPT_SUCCESS;
    
    list = sort.Split(",");
    
    // verify each property has a namespace
    NPT_List<NPT_String>::Iterator property = list.GetFirstItem();
    while (property) {
        NPT_List<NPT_String> parsed_property = (*property).Split(":");
        if (parsed_property.GetItemCount() != 2)
          parsed_property = (*property).Split("@");
        if (parsed_property.GetItemCount() != 2 || 
            (!(*property).StartsWith("-") && !(*property).StartsWith("+"))) {
            NPT_LOG_WARNING_1("Invalid SortCriteria property %s", (*property).GetChars());
            return NPT_FAILURE;
        }
        property++;
    }
    
    return NPT_SUCCESS;
}
Beispiel #4
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;
}
Beispiel #5
0
/*----------------------------------------------------------------------
|   NPT_Win32Thread::SetThreadPriority
+---------------------------------------------------------------------*/
NPT_Result
NPT_Win32Thread::SetThreadPriority(HANDLE thread, int priority)
{
	int win32_priority;
	if (priority < NPT_THREAD_PRIORITY_LOWEST) {
		win32_priority = THREAD_PRIORITY_IDLE;
	} else if (priority < NPT_THREAD_PRIORITY_BELOW_NORMAL) {
		win32_priority = THREAD_PRIORITY_LOWEST;
	} else if (priority < NPT_THREAD_PRIORITY_NORMAL) {
		win32_priority = THREAD_PRIORITY_BELOW_NORMAL;
	} else if (priority < NPT_THREAD_PRIORITY_ABOVE_NORMAL) {
		win32_priority = THREAD_PRIORITY_NORMAL;
	} else if (priority < NPT_THREAD_PRIORITY_HIGHEST) {
		win32_priority = THREAD_PRIORITY_ABOVE_NORMAL;
	} else if (priority < NPT_THREAD_PRIORITY_TIME_CRITICAL) {
		win32_priority = THREAD_PRIORITY_HIGHEST;
	} else {
		win32_priority = THREAD_PRIORITY_TIME_CRITICAL;
	}
	BOOL result = ::SetThreadPriority(thread, win32_priority);
	if (!result) {
		NPT_LOG_WARNING_1("SetThreadPriority failed (%x)", GetLastError());
		return NPT_FAILURE;
	}

	return NPT_SUCCESS;
}
Beispiel #6
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;
}
Beispiel #7
0
/*----------------------------------------------------------------------
|   PLT_StateVariable::ValidateValue
+---------------------------------------------------------------------*/
NPT_Result
PLT_StateVariable::ValidateValue(const char* value)
{
    if (m_DataType.Compare("string", true) == 0) {
        // if we have a value allowed restriction, make sure the value is in our list
        if (m_AllowedValues.GetItemCount()) {
            // look for a comma separated list
            NPT_String _value = value;
            NPT_List<NPT_String> values = _value.Split(",");
            NPT_List<NPT_String>::Iterator val = values.GetFirstItem();
            while (val) {
                val->Trim(" ");
                if (!m_AllowedValues.Find(NPT_StringFinder(*val))) {
#if defined(NPT_CONFIG_ENABLE_LOGGING)
                    NPT_LOG_WARNING_2("Invalid value of %s for state variable %s",
                        (const char*)*val,
                        (const char*)m_Name);
                    for (unsigned long i=0; i < m_AllowedValues.GetItemCount(); i++) {
                        NPT_String *val2 = *m_AllowedValues.GetItem(i);
                        NPT_LOG_WARNING_1("Allowed: %s", (const char*)*val2);
                    }
#endif
                    return NPT_ERROR_INVALID_PARAMETERS;
                }
                ++val;
            }
        }
    }

    // TODO: there are more to it than allowed values, we need to test for range, etc..
    return NPT_SUCCESS;    
}
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::GetEntryCount
+---------------------------------------------------------------------*/
NPT_Result
PLT_FileMediaServer::GetEntryCount(const char* path, NPT_Cardinal& count) 
{
    NPT_String dir_path = path;

    // reset output params
    count = 0;

    // ensure path ends with a delimiter
    if (!dir_path.EndsWith(m_DirDelimiter)) {
        dir_path += m_DirDelimiter;
    }

    NPT_Directory directory(dir_path);
    NPT_String entryName;
    NPT_Result res = directory.GetNextEntry(entryName);
    if (NPT_FAILED(res)) {
        NPT_LOG_WARNING_1("PLT_FileMediaServer::OnBrowseDirectChildren - failed to open dir %s", (const char*) path);
        return res;
    }

    do {
        /* Check if the item would be ok to add to a didl */
//         NPT_Reference<PLT_MediaObject> item(BuildFromFilePath(dir_path + entryName, false));
//         if (!item.IsNull()) {
//             count++;
//         }
        NPT_DirectoryEntryInfo info; 
        if (ProceedWithEntry(dir_path + entryName, info)) count++;
        res = directory.GetNextEntry(entryName);
    } while (NPT_SUCCEEDED(res));

    return NPT_SUCCESS;
}
Beispiel #9
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;
}
Beispiel #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;
}
Beispiel #11
0
/*----------------------------------------------------------------------
|   NPT_Win32Thread::GetThreadPriority
+---------------------------------------------------------------------*/
NPT_Result
NPT_Win32Thread::GetThreadPriority(HANDLE thread, int& priority)
{
    int win32_priority = ::GetThreadPriority(thread);
	if (win32_priority == THREAD_PRIORITY_ERROR_RETURN) {
		NPT_LOG_WARNING_1("GetThreadPriority failed (%x)", GetLastError());
		return NPT_FAILURE;
	}

    priority = win32_priority;
	return NPT_SUCCESS;
}
Beispiel #12
0
/*----------------------------------------------------------------------
|   PLT_FileMediaConnectDelegate::OnSearchContainer
+---------------------------------------------------------------------*/
NPT_Result
PLT_FileMediaConnectDelegate::OnSearchContainer(PLT_ActionReference&          action, 
                                                const char*                   object_id, 
                                                const char*                   search_criteria,
                                                const char*                   filter,
                                                NPT_UInt32                    starting_index,
                                                NPT_UInt32                    requested_count,
                                                const char*                   sort_criteria,
                                                const PLT_HttpRequestContext& context)
{
    /* parse search criteria */
    
    /* TODO: HACK TO PASS DLNA */
    if (search_criteria && NPT_StringsEqual(search_criteria, "Unknownfieldname")) {
        /* error */
        NPT_LOG_WARNING_1("Unsupported or invalid search criteria %s", search_criteria);
        action->SetError(708, "Unsupported or invalid search criteria");
        return NPT_FAILURE;
    }
    
    /* locate the file from the object ID */
    NPT_String dir;
    if (NPT_FAILED(GetFilePath(object_id, dir))) {
        /* error */
        NPT_LOG_WARNING("ObjectID not found.");
        action->SetError(710, "No Such Container.");
        return NPT_FAILURE;
    }
    
    /* retrieve the item type */
    NPT_FileInfo info;
    NPT_Result res = NPT_File::GetInfo(dir, &info);
    if (NPT_FAILED(res) || (info.m_Type != NPT_FileInfo::FILE_TYPE_DIRECTORY)) {
        /* error */
        NPT_LOG_WARNING("No such container");
        action->SetError(710, "No such container");
        return NPT_FAILURE;
    }
    
    /* hack for now to return something back to XBox 360 */
    return OnBrowseDirectChildren(action, 
                                  object_id, 
                                  filter, 
                                  starting_index, 
                                  requested_count, 
                                  sort_criteria, 
                                  context);
}
Beispiel #13
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;
}
Beispiel #14
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;
}
Beispiel #15
0
/*----------------------------------------------------------------------
|   PLT_MediaBrowser::Browse
+---------------------------------------------------------------------*/
NPT_Result 
PLT_MediaBrowser::Browse(PLT_DeviceDataReference&   device, 
                         const char*                obj_id,
                         NPT_UInt32                 start_index,
                         NPT_UInt32                 count,
                         bool                       browse_metadata,
                         const char*                filter,
                         const char*                sort_criteria,
                         void*                      userdata)
{
    // look for the service
    PLT_Service* service;
    NPT_String type;

    type = "urn:schemas-upnp-org:service:ContentDirectory:1";
    if (NPT_FAILED(device->FindServiceByType(type, service))) {
        NPT_LOG_WARNING_1("Service %s not found", (const char*)type);
        return NPT_FAILURE;
    }

    PLT_ActionDesc* action_desc = service->FindActionDesc("Browse");
    if (action_desc == NULL) {
        NPT_LOG_WARNING("Action Browse not found in service");
        return NPT_FAILURE;
    }

    PLT_ActionReference action(new PLT_Action(action_desc));

    // Set the object id
    PLT_Arguments args;
    if (NPT_FAILED(action->SetArgumentValue("ObjectID", obj_id))) {
        return NPT_ERROR_INVALID_PARAMETERS;
    }

    // set the browse_flag
    if (NPT_FAILED(action->SetArgumentValue("BrowseFlag", browse_metadata?"BrowseMetadata":"BrowseDirectChildren"))) {
        return NPT_ERROR_INVALID_PARAMETERS;
    }
 
    // set the Filter
    if (NPT_FAILED(action->SetArgumentValue("Filter", filter))) {
        return NPT_ERROR_INVALID_PARAMETERS;
    }

    // set the Starting Index
    if (NPT_FAILED(action->SetArgumentValue("StartingIndex", NPT_String::FromInteger(start_index)))) {
        return NPT_ERROR_INVALID_PARAMETERS;
    }

    // set the Requested Count
    if (NPT_FAILED(action->SetArgumentValue("RequestedCount", NPT_String::FromInteger(count)))) {
        return NPT_ERROR_INVALID_PARAMETERS;
    }

    // set the Requested Count
    if (NPT_FAILED(action->SetArgumentValue("SortCriteria", sort_criteria))) {
        return NPT_ERROR_INVALID_PARAMETERS;
    }

    // set the arguments on the action, this will check the argument values
    if (NPT_FAILED(m_CtrlPoint->InvokeAction(action, userdata))) {
        return NPT_ERROR_INVALID_PARAMETERS;
    }

    return NPT_SUCCESS;
}
Beispiel #16
0
/*----------------------------------------------------------------------
|   PLT_MediaObject::FromDidl
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaObject::FromDidl(NPT_XmlElementNode* entry)
{
    NPT_String str, xml;
    NPT_Array<NPT_XmlElementNode*> children;
    NPT_Result res;

    // check if item is restricted (is default true?)
    if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(entry, "restricted", str, "", 5))) {
        m_Restricted = PLT_Service::IsTrue(str);
    }
    
    // read non-required elements
    PLT_XmlHelper::GetChildText(entry, "creator", m_Creator, didl_namespace_dc, 256);
    PLT_XmlHelper::GetChildText(entry, "date", m_Date, didl_namespace_dc, 256);
    
    // parse date and make sure it's valid
    NPT_String parsed_date;
    for (int format=0; format<=NPT_DateTime::FORMAT_RFC_1036; format++) {
        NPT_DateTime date;
        if (NPT_SUCCEEDED(date.FromString(m_Date, (NPT_DateTime::Format)format))) {
            parsed_date = date.ToString((NPT_DateTime::Format)format);
            break;
        }
    }
    m_Date = parsed_date;

    res = PLT_XmlHelper::GetAttribute(entry, "id", m_ObjectID);
    NPT_CHECK_SEVERE(res);

    res = PLT_XmlHelper::GetAttribute(entry, "parentID", m_ParentID);
    NPT_CHECK_SEVERE(res);

    PLT_XmlHelper::GetAttribute(entry, "refID", m_ReferenceID);

    res = PLT_XmlHelper::GetChildText(entry, "title", m_Title, didl_namespace_dc);
    NPT_CHECK_SEVERE(res);
    
    res = PLT_XmlHelper::GetChildText(entry, "class", m_ObjectClass.type, didl_namespace_upnp);
    NPT_CHECK_SEVERE(res);
    
    // DLNA 7.3.17.3 max bytes for dc:title and upnp:class is 256 bytes
    m_Title = m_Title.SubString(0, 256);    
    m_ObjectClass.type =  m_ObjectClass.type.SubString(0, 256);

    children.Clear();
    PLT_XmlHelper::GetChildren(entry, children, "artist", didl_namespace_upnp);
    m_People.artists.FromDidl(children);
    
    children.Clear();
    PLT_XmlHelper::GetChildren(entry, children, "author", didl_namespace_upnp);
    m_People.authors.FromDidl(children);
    
    children.Clear();
    PLT_XmlHelper::GetChildren(entry, children, "actors", didl_namespace_upnp);
    m_People.actors.FromDidl(children);

    children.Clear();
    PLT_XmlHelper::GetChildren(entry, children, "director", didl_namespace_upnp);
    m_People.directors.FromDidl(children);

    PLT_XmlHelper::GetChildText(entry, "album", m_Affiliation.album, didl_namespace_upnp, 256);
    PLT_XmlHelper::GetChildText(entry, "programTitle", m_Recorded.program_title, didl_namespace_upnp);
    PLT_XmlHelper::GetChildText(entry, "seriesTitle", m_Recorded.series_title, didl_namespace_upnp);
    PLT_XmlHelper::GetChildText(entry, "episodeNumber", str, didl_namespace_upnp);
    NPT_UInt32 value;
    if (NPT_FAILED(str.ToInteger(value))) value = 0;
    m_Recorded.episode_number = value;

    children.Clear();
    PLT_XmlHelper::GetChildren(entry, children, "genre", didl_namespace_upnp);
    for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) {
        if (children[i]->GetText()) {
            m_Affiliation.genres.Add(children[i]->GetText()->SubString(0, 256));
        }
    }
    
    PLT_XmlHelper::GetChildText(entry, "description", m_Description.description, didl_namespace_dc);
    PLT_XmlHelper::GetChildText(entry, "longDescription", m_Description.long_description, didl_namespace_upnp);
    PLT_XmlHelper::GetChildText(entry, "icon", m_Description.icon_uri, didl_namespace_upnp);
    PLT_XmlHelper::GetChildText(entry, "rating", m_Description.rating, didl_namespace_upnp);
	PLT_XmlHelper::GetChildText(entry, "toc", m_MiscInfo.toc, didl_namespace_upnp);
    
    // album arts
    children.Clear();
    PLT_XmlHelper::GetChildren(entry, children, "albumArtURI", didl_namespace_upnp);
    for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) {
        if (children[i]->GetText()) {
            PLT_AlbumArtInfo info;
            info.uri = children[i]->GetText()->SubString(0, 1024);
            PLT_XmlHelper::GetAttribute(children[i], "profileID", info.dlna_profile, didl_namespace_dlna);
            m_ExtraInfo.album_arts.Add(info);
        }
    }
    
    PLT_XmlHelper::GetChildText(entry, "originalTrackNumber", str, didl_namespace_upnp);
    if (NPT_FAILED(str.ToInteger(value))) value = 0;
    m_MiscInfo.original_track_number = value;

    PLT_XmlHelper::GetChildText(entry, "lastPlaybackPosition", str, didl_namespace_upnp);
    if (NPT_FAILED(str.ToInteger(value))) value = 0;
    m_MiscInfo.last_position = value;

    PLT_XmlHelper::GetChildText(entry, "lastPlaybackTime", m_MiscInfo.last_time, didl_namespace_dc, 256);
    NPT_String parsed_last_time;
    for (int format=0; format<=NPT_DateTime::FORMAT_RFC_1036; format++) {
        NPT_DateTime date;
        if (NPT_SUCCEEDED(date.FromString(m_MiscInfo.last_time, (NPT_DateTime::Format)format))) {
            parsed_last_time = date.ToString((NPT_DateTime::Format)format);
            break;
        }
    }
    m_MiscInfo.last_time = parsed_last_time;

    PLT_XmlHelper::GetChildText(entry, "playbackCount", str, didl_namespace_upnp);
    if (NPT_FAILED(str.ToInteger(value))) value = -1;
    m_MiscInfo.play_count = value;

    children.Clear();
    PLT_XmlHelper::GetChildren(entry, children, "res");
    for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) {
        PLT_MediaItemResource resource;

        // extract url
        if (children[i]->GetText() == NULL) {
            NPT_LOG_WARNING_1("No resource text found in: %s", (const char*)PLT_XmlHelper::Serialize(*children[i]));
        } else {
            resource.m_Uri = children[i]->GetText()->SubString(0, 1024);

            // basic uri validation, ignoring scheme (could be rtsp)
            NPT_HttpUrl url(resource.m_Uri, true);
            if (!url.IsValid()) {
                NPT_LOG_WARNING_1("Invalid resource uri: %s", (const char*)resource.m_Uri);
                continue;
            }
        }

        // extract protocol info
        NPT_String protocol_info;
        res = PLT_XmlHelper::GetAttribute(children[i], "protocolInfo", protocol_info, "", 256);
        if (NPT_FAILED(res)) {
            NPT_LOG_WARNING_1("No protocol info found in: %s", (const char*)PLT_XmlHelper::Serialize(*children[i]));
        } else {
            resource.m_ProtocolInfo = PLT_ProtocolInfo(protocol_info);
            if (!resource.m_ProtocolInfo.IsValid()) {
                NPT_LOG_WARNING_1("Invalid resource protocol info: %s", (const char*)protocol_info);
            }
        }

        // extract known attributes
        PLT_XmlHelper::GetAttribute(children[i], "protection", resource.m_Protection, "", 256);
        PLT_XmlHelper::GetAttribute(children[i], "resolution", resource.m_Resolution, "", 256);

        if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(children[i], "size", str, "", 256))) {
            if (NPT_FAILED(str.ToInteger64(resource.m_Size))) resource.m_Size = (NPT_Size)-1;
        }

        if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(children[i], "duration", str, "", 256))) {
            if (NPT_FAILED(PLT_Didl::ParseTimeStamp(str, resource.m_Duration))) {
                // if error while converting, ignore and set to -1 to indicate we don't know the duration
                resource.m_Duration = (NPT_UInt32)-1;
                PLT_XmlHelper::RemoveAttribute(children[i], "duration");
            } else {
                // DLNA: reformat duration in case it was not compliant
                str = PLT_Didl::FormatTimeStamp(resource.m_Duration);
                PLT_XmlHelper::SetAttribute(children[i], "duration", str); 
            }
        }    
        m_Resources.Add(resource);
    }

    // re serialize the entry didl as a we might need to pass it to a renderer
    // we may have modified the tree to "fix" issues, so as not to break a renderer
    // (don't write xml prefix as this didl could be part of a larger document)
    //res = PLT_XmlHelper::Serialize(*entry, xml, false);
    m_Didl = "";
    res = ToDidl(PLT_FILTER_MASK_ALL, m_Didl);
    NPT_CHECK_SEVERE(res);
    
    m_Didl = didl_header + m_Didl + didl_footer;    
    return NPT_SUCCESS;
}
Beispiel #17
0
/*----------------------------------------------------------------------
|   PLT_HttpServerSocketTask::DoRun
+---------------------------------------------------------------------*/
void
PLT_SsdpSearchTask::DoRun()
{
    NPT_HttpResponse*      response = NULL;
    PLT_HttpClient         client;
    NPT_Timeout            timeout = 30;
    NPT_HttpRequestContext context;

    do {
        // get the address of the server
        NPT_IpAddress server_address;
        NPT_CHECK_LABEL_SEVERE(server_address.ResolveName(
                                   m_Request->GetUrl().GetHost(), 
                                   timeout), 
                               done);
        NPT_SocketAddress address(server_address, 
                                  m_Request->GetUrl().GetPort());

        // send 2 requests in a row
        NPT_OutputStreamReference output_stream(
            new PLT_OutputDatagramStream(m_Socket, 
                                         4096, 
                                         &address));
        NPT_CHECK_LABEL_SEVERE(client.SendRequest(
                                   output_stream, 
                                   *m_Request), 
                               done);
        NPT_CHECK_LABEL_SEVERE(client.SendRequest(
                                   output_stream, 
                                   *m_Request), 
                               done);
        output_stream = NULL;

        // keep track of when we sent the request
        NPT_TimeStamp last_send;
        NPT_System::GetCurrentTimeStamp(last_send);

        while (!IsAborting(0)) {
            // read response
            PLT_InputDatagramStreamReference input_stream(
                new PLT_InputDatagramStream(m_Socket));

            NPT_InputStreamReference stream = input_stream;
            NPT_Result res = client.WaitForResponse(stream, 
                                                    *m_Request, 
                                                    context, 
                                                    response);
            // callback to process response
            if (NPT_SUCCEEDED(res)) {
                // get source info    
                NPT_SocketInfo info;
                input_stream->GetInfo(info);

                context.SetLocalAddress(info.local_address);
                context.SetRemoteAddress(info.remote_address);

                // process response
                ProcessResponse(NPT_SUCCESS, m_Request, context, response);
                delete response;
                response = NULL;
            } else if (res != NPT_ERROR_TIMEOUT) {
                NPT_LOG_WARNING_1("PLT_SsdpSearchTask got an error (%d) waiting for response", res);
            }

            input_stream = NULL;

            // check if it's time to resend request
            NPT_TimeStamp now;
            NPT_System::GetCurrentTimeStamp(now);
            if (now >= last_send + (long)m_Timeout/1000)
                break;
        }
    } while (!IsAborting(0) && m_Repeat);

done:
    return;
}
Beispiel #18
0
/*----------------------------------------------------------------------
|   PLT_MediaObject::FromDidl
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaObject::FromDidl(NPT_XmlElementNode* entry)
{
    NPT_String str, xml;
    NPT_Array<NPT_XmlElementNode*> children;
    NPT_Result res;

    // check if item is restricted (is default true?)
    if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(entry, "restricted", str))) {
        m_Restricted = PLT_Service::IsTrue(str);
    }

    res = PLT_XmlHelper::GetAttribute(entry, "id", m_ObjectID);
    NPT_CHECK_LABEL_SEVERE(res, cleanup);

    res = PLT_XmlHelper::GetAttribute(entry, "parentID", m_ParentID);
    NPT_CHECK_LABEL_SEVERE(res, cleanup);

    res = PLT_XmlHelper::GetAttribute(entry, "refID", m_ReferenceID);

    res = PLT_XmlHelper::GetChildText(entry, "title", m_Title, didl_namespace_dc);
    NPT_CHECK_LABEL_SEVERE(res, cleanup);

    res = PLT_XmlHelper::GetChildText(entry, "class", m_ObjectClass.type, didl_namespace_upnp);
    NPT_CHECK_LABEL_SEVERE(res, cleanup);

    // read non-required elements
    PLT_XmlHelper::GetChildText(entry, "creator", m_Creator, didl_namespace_dc);
    PLT_XmlHelper::GetChildText(entry, "date", m_Date, didl_namespace_dc);

    PLT_XmlHelper::GetChildren(entry, children, "artist", didl_namespace_upnp);
    m_People.artists.FromDidl(children);

    PLT_XmlHelper::GetChildText(entry, "album", m_Affiliation.album, didl_namespace_upnp);
    PLT_XmlHelper::GetChildText(entry, "programTitle", m_Recorded.program_title, didl_namespace_upnp);
    PLT_XmlHelper::GetChildText(entry, "seriesTitle", m_Recorded.series_title, didl_namespace_upnp);
    PLT_XmlHelper::GetChildText(entry, "episodeNumber", str, didl_namespace_upnp);
    NPT_UInt32 value;
    if (NPT_FAILED(str.ToInteger(value))) value = 0;
    m_Recorded.episode_number = value;

    children.Clear();
    PLT_XmlHelper::GetChildren(entry, children, "genre", didl_namespace_upnp);
    for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) {
        if (children[i]->GetText()) {
            m_Affiliation.genres.Add(*children[i]->GetText());
        }
    }

    PLT_XmlHelper::GetChildText(entry, "albumArtURI", m_ExtraInfo.album_art_uri, didl_namespace_upnp);
    PLT_XmlHelper::GetChildText(entry, "longDescription", m_Description.long_description, didl_namespace_upnp);
	PLT_XmlHelper::GetChildText(entry, "toc", m_MiscInfo.toc, didl_namespace_upnp);

    PLT_XmlHelper::GetChildText(entry, "originalTrackNumber", str, didl_namespace_upnp);
    if (NPT_FAILED(str.ToInteger(value))) value = 0;
    m_MiscInfo.original_track_number = value;

    children.Clear();
    PLT_XmlHelper::GetChildren(entry, children, "res");
    for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) {
        PLT_MediaItemResource resource;

        // extract url
        if (children[i]->GetText() == NULL) {
            NPT_LOG_WARNING_1("No resource text found in: %s", (const char*)PLT_XmlHelper::Serialize(*children[i]));
        } else {
            resource.m_Uri = *children[i]->GetText();

            // basic uri validation, ignoring scheme (could be rtsp)
            NPT_HttpUrl url(resource.m_Uri, true);
            if (!url.IsValid()) {
                NPT_LOG_WARNING_1("Invalid resource uri: %s", (const char*)resource.m_Uri);
            }
        }

        // extract protocol info
        NPT_String protocol_info;
        res = PLT_XmlHelper::GetAttribute(children[i], "protocolInfo", protocol_info);
        if (NPT_FAILED(res)) {
            NPT_LOG_WARNING_1("No protocol info found in: %s", (const char*)PLT_XmlHelper::Serialize(*children[i]));
        } else {
            resource.m_ProtocolInfo = PLT_ProtocolInfo(protocol_info);
            if (!resource.m_ProtocolInfo.IsValid()) {
                NPT_LOG_WARNING_1("Invalid resource protocol info: %s", (const char*)protocol_info);
            }
        }

        // extract known attributes
        PLT_XmlHelper::GetAttribute(children[i], "protection", resource.m_Protection);
        PLT_XmlHelper::GetAttribute(children[i], "resolution", resource.m_Resolution);

        if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(children[i], "size", str))) {
            if (NPT_FAILED(str.ToInteger64(resource.m_Size))) resource.m_Size = (NPT_Size)-1;
        }

        if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(children[i], "duration", str))) {
            if (NPT_FAILED(PLT_Didl::ParseTimeStamp(str, resource.m_Duration))) {
                // if error while converting, ignore and set to -1 to indicate we don't know the duration
                resource.m_Duration = (NPT_UInt32)-1;
                PLT_XmlHelper::RemoveAttribute(children[i], "duration");
            } else {
                // DLNA: reformat duration in case it was not compliant
                str = PLT_Didl::FormatTimeStamp(resource.m_Duration);
                PLT_XmlHelper::SetAttribute(children[i], "duration", str); 
            }
        }    
        m_Resources.Add(resource);
    }

    // re serialize the entry didl as a we might need to pass it to a renderer
    // we may have modified the tree to "fix" issues, so as not to break a renderer
    // (don't write xml prefix as this didl could be part of a larger document)
    res = PLT_XmlHelper::Serialize(*entry, xml, false);
    NPT_CHECK_LABEL_SEVERE(res, cleanup);
    
    m_Didl = didl_header + xml + didl_footer;    
    return NPT_SUCCESS;

cleanup:
    return res;
}
/*----------------------------------------------------------------------
|   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;
}
Beispiel #20
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::OnBrowseDirectChildren
+---------------------------------------------------------------------*/
NPT_Result
PLT_FileMediaServer::OnBrowseDirectChildren(PLT_ActionReference&          action, 
                                            const char*                   object_id, 
                                            const NPT_HttpRequestContext& context)
{
    /* locate the file from the object ID */
    NPT_String dir;
    if (NPT_FAILED(GetFilePath(object_id, dir))) {
        /* error */
        NPT_LOG_WARNING("PLT_FileMediaServer::OnBrowse - ObjectID not found.");
        action->SetError(701, "No Such Object.");
        return NPT_FAILURE;
    }

    /* retrieve the item type */
    NPT_FileInfo info;
    NPT_Result res = NPT_File::GetInfo(dir, &info);
    if (NPT_FAILED(res)) {
        /* Object does not exist */
        NPT_LOG_WARNING_1("PLT_FileMediaServer::OnBrowse - BROWSEDIRECTCHILDREN failed for item %s", dir.GetChars());
        action->SetError(800, "Can't retrieve info " + dir);
        return NPT_FAILURE;
    }

    if (info.m_Type != NPT_FileInfo::FILE_TYPE_DIRECTORY) {
        /* error */
        NPT_LOG_WARNING("PLT_FileMediaServer::OnBrowse - BROWSEDIRECTCHILDREN not allowed on an item.");
        action->SetError(710, "item is not a container.");
        return NPT_FAILURE;
    }

    NPT_String filter;
    NPT_String startingInd;
    NPT_String reqCount;

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

    NPT_UInt32 start_index, req_count;
    if (NPT_FAILED(startingInd.ToInteger(start_index)) ||
        NPT_FAILED(reqCount.ToInteger(req_count))) {        
        action->SetError(412, "Precondition failed");
        return NPT_FAILURE;
    }

    NPT_List<NPT_String> entries;
    res = NPT_File::ListDirectory(dir, entries, 0, 0);
    if (NPT_FAILED(res)) {
        NPT_LOG_WARNING_1("PLT_FileMediaServer::OnBrowseDirectChildren - failed to open dir %s", (const char*) dir);
        return res;
    }

    unsigned long cur_index = 0;
    unsigned long num_returned = 0;
    unsigned long total_matches = 0;
    NPT_String didl = didl_header;

    PLT_MediaObjectReference item;
    for (NPT_List<NPT_String>::Iterator it = entries.GetFirstItem();
        it;
        ++it) {
        NPT_String& filename = *it;
        item = BuildFromFilePath(
            NPT_FilePath::Create(dir, filename), 
            true, 
            &context.GetLocalAddress());

        if (!item.IsNull()) {
            if ((cur_index >= start_index) && ((num_returned < req_count) || (req_count == 0))) {
                NPT_String tmp;
                NPT_CHECK_SEVERE(PLT_Didl::ToDidl(*item.AsPointer(), filter, tmp));

                didl += tmp;
                num_returned++;
            }
            cur_index++;
            total_matches++;        
        }
    };

    didl += didl_footer;

    NPT_CHECK_SEVERE(action->SetArgumentValue("Result", didl));
    NPT_CHECK_SEVERE(action->SetArgumentValue("NumberReturned", NPT_String::FromInteger(num_returned)));
    NPT_CHECK_SEVERE(action->SetArgumentValue("TotalMatches", NPT_String::FromInteger(total_matches))); // 0 means we don't know how many we have but most browsers don't like that!!
    NPT_CHECK_SEVERE(action->SetArgumentValue("UpdateId", "1"));

    return NPT_SUCCESS;
}
Beispiel #21
0
/*----------------------------------------------------------------------
|   PLT_MediaServer::OnSearch
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaServer::OnSearch(PLT_ActionReference&          action, 
                          const PLT_HttpRequestContext& context)
{
    NPT_COMPILER_UNUSED(context);

    NPT_Result res;
    NPT_String container_id;
    NPT_String search;
	NPT_String filter;
    NPT_String start;
    NPT_String count;
    NPT_String sort;
    NPT_List<NPT_String> sort_list;

    if (NPT_FAILED(action->GetArgumentValue("ContainerId", container_id)) ||
        NPT_FAILED(action->GetArgumentValue("SearchCriteria", search)) || 
		NPT_FAILED(action->GetArgumentValue("Filter",  filter)) ||
        NPT_FAILED(action->GetArgumentValue("StartingIndex",  start)) || 
        NPT_FAILED(action->GetArgumentValue("RequestedCount",  count)) || 
        NPT_FAILED(action->GetArgumentValue("SortCriteria",  sort))) {
        NPT_LOG_WARNING("Missing arguments");
        action->SetError(402, "Invalid args");
        return NPT_SUCCESS;
    }
    
    /* convert index and counts to int */
    NPT_UInt32 starting_index, requested_count;
    if (NPT_FAILED(start.ToInteger(starting_index)) ||
        NPT_FAILED(count.ToInteger(requested_count))) {       
        NPT_LOG_WARNING_2("Invalid arguments (%s, %s)", 
            start.GetChars(), count.GetChars());
        action->SetError(402, "Invalid args");
        return NPT_FAILURE;
    }
    
    /* parse sort criteria */
    if (NPT_FAILED(ParseSort(sort, sort_list))) {
        NPT_LOG_WARNING_1("Unsupported or invalid sort criteria error (%s)", 
            sort.GetChars());
        action->SetError(709, "Unsupported or invalid sort criteria error");
        return NPT_FAILURE;
    }
    
    NPT_LOG_INFO_5("Processing Search from %s with id=\"%s\", search=\"%s\", start=%d, count=%d", 
                   (const char*)context.GetRemoteAddress().GetIpAddress().ToString(),
                   (const char*)container_id,
                   (const char*)search,
                   starting_index,
                   requested_count);
                       
    if (search.IsEmpty() || search == "*") {
        res = OnBrowseDirectChildren(
            action, 
            container_id,
			filter,
            starting_index, 
            requested_count, 
            sort, 
            context);
    } else {
        res = OnSearchContainer(
            action, 
            container_id, 
            search, 
			filter,
            starting_index, 
            requested_count, 
            sort,
            context);
    }

    if (NPT_FAILED(res) && (action->GetErrorCode() == 0)) {
        action->SetError(800, "Internal error");
    }

    return res;
}
Beispiel #22
0
/*----------------------------------------------------------------------
|   PLT_MediaServer::OnBrowse
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaServer::OnBrowse(PLT_ActionReference&          action, 
                          const PLT_HttpRequestContext& context)
{
    NPT_Result res;
    NPT_String object_id;
    NPT_String browse_flag_val;    
    NPT_String filter;
    NPT_String start;
    NPT_String count;
    NPT_String sort;
    NPT_List<NPT_String> sort_list;

    if (NPT_FAILED(action->GetArgumentValue("ObjectId", object_id)) || 
        NPT_FAILED(action->GetArgumentValue("BrowseFlag",  browse_flag_val)) || 
        NPT_FAILED(action->GetArgumentValue("Filter",  filter)) || 
        NPT_FAILED(action->GetArgumentValue("StartingIndex",  start)) || 
        NPT_FAILED(action->GetArgumentValue("RequestedCount",  count)) || 
        NPT_FAILED(action->GetArgumentValue("SortCriteria",  sort))) {
        NPT_LOG_WARNING("Missing arguments");
        action->SetError(402, "Invalid args");
        return NPT_SUCCESS;
    }

    /* extract flag */
    BrowseFlags flag;
    if (NPT_FAILED(ParseBrowseFlag(browse_flag_val, flag))) {
        /* error */
        NPT_LOG_WARNING_1("BrowseFlag value not allowed (%s)", (const char*)browse_flag_val);
        action->SetError(402, "Invalid args");
        return NPT_SUCCESS;
    }
    
    /* convert index and counts to int */
    NPT_UInt32 starting_index, requested_count;
    if (NPT_FAILED(start.ToInteger(starting_index)) ||
        NPT_FAILED(count.ToInteger(requested_count)) ||
        PLT_Didl::ConvertFilterToMask(filter) == 0) {       
        NPT_LOG_WARNING_3("Invalid arguments (%s, %s, %s)", 
            start.GetChars(), count.GetChars(), filter.GetChars());
        action->SetError(402, "Invalid args");
        return NPT_FAILURE;
    }
    
    /* parse sort criteria for validation */
    if (NPT_FAILED(ParseSort(sort, sort_list))) {
        NPT_LOG_WARNING_1("Unsupported or invalid sort criteria error (%s)", 
            sort.GetChars());
        action->SetError(709, "Unsupported or invalid sort criteria error");
        return NPT_FAILURE;
    }
    
    NPT_LOG_FINE_6("Processing %s from %s with id=\"%s\", filter=\"%s\", start=%d, count=%d", 
                   (const char*)browse_flag_val, 
                   (const char*)context.GetRemoteAddress().GetIpAddress().ToString(),
                   (const char*)object_id,
                   (const char*)filter,
                   starting_index,
                   requested_count);

    /* Invoke the browse function */
    if (flag == BROWSEMETADATA) {
        res = OnBrowseMetadata(
            action, 
            object_id, 
            filter, 
            starting_index, 
            requested_count, 
            sort, 
            context);
    } else {
        res = OnBrowseDirectChildren(
            action, 
            object_id, 
            filter, 
            starting_index, 
            requested_count, 
            sort, 
            context);
    }

    if (NPT_FAILED(res) && (action->GetErrorCode() == 0)) {
        action->SetError(800, "Internal error");
    }

    return res;
}
Beispiel #23
0
/*----------------------------------------------------------------------
|   NPT_ZipFile::Parse
+---------------------------------------------------------------------*/
NPT_Result
NPT_ZipFile::Parse(NPT_InputStream& stream, NPT_ZipFile*& file)
{
    // defautl return value
    file = NULL;

    // check that we know the size of the stream
    NPT_LargeSize stream_size = 0;
    NPT_Result result = stream.GetSize(stream_size);
    if (NPT_FAILED(result)) {
        NPT_LOG_WARNING_1("cannot get stream size (%d)", result);
        return result;
    }
    if (stream_size < 22) {
        NPT_LOG_WARNING("input stream too short");
        return NPT_ERROR_INVALID_FORMAT;
    }

    // seek to the most likely start of the end of central directory record
    unsigned int max_eocdr_size = 22+65536;
    if (max_eocdr_size > stream_size) {
        max_eocdr_size = (unsigned int)stream_size;
    }
    unsigned char eocdr[22];
    bool record_found = false;
    NPT_Position position = 0;
    for (unsigned int i=0; i<max_eocdr_size; i++) {
        position = stream_size-22-i;
        result = stream.Seek(position);
        if (NPT_FAILED(result)) {
            NPT_LOG_WARNING_1("seek failed (%d)", result);
            return result;
        }
        result = stream.ReadFully(eocdr, 22);
        if (NPT_FAILED(result)) {
            NPT_LOG_WARNING_1("read failed (%d)", result);
            return result;
        }
        NPT_UInt32 signature = NPT_BytesToInt32Le(eocdr);
        if (signature == NPT_ZIP_END_OF_CENTRAL_DIRECTORY_SIGNATURE) {
            record_found = true;
            break;
        }
    }
    if (!record_found) {
        NPT_LOG_WARNING("eocd record not found at end of stream");
        return NPT_ERROR_INVALID_FORMAT;
    }

    // parse the eocdr
    NPT_UInt32   this_disk                = NPT_BytesToInt16Le(&eocdr[ 4]);
    NPT_UInt32   start_disk               = NPT_BytesToInt16Le(&eocdr[ 6]);
    NPT_UInt64   this_disk_entry_count    = NPT_BytesToInt16Le(&eocdr[ 8]);
    NPT_UInt64   total_entry_count        = NPT_BytesToInt16Le(&eocdr[10]);
    NPT_UInt64   central_directory_size   = NPT_BytesToInt32Le(&eocdr[12]);
    NPT_Position central_directory_offset = NPT_BytesToInt32Le(&eocdr[16]);

    // format check
    if (this_disk != 0 || start_disk != 0) {
        return NPT_ERROR_NOT_SUPPORTED;
    }
    if (this_disk_entry_count != total_entry_count) {
        return NPT_ERROR_NOT_SUPPORTED;
    }

    // check if this is a zip64 file
    if (central_directory_offset == 0xFFFFFFFF) {
        unsigned char zip64_locator[20];
        result = stream.Seek(position-20);
        if (NPT_FAILED(result)) {
            NPT_LOG_WARNING_1("seek failed (%d)", result);
            return result;
        }
        result = stream.ReadFully(zip64_locator, 20);
        if (NPT_FAILED(result)) {
            NPT_LOG_WARNING_1("read failed (%d)", result);
            return result;
        }

        NPT_UInt32 signature = NPT_BytesToInt32Le(&zip64_locator[0]);
        if (signature != NPT_ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE) {
            NPT_LOG_WARNING("zip64 directory locator signature not found");
            return NPT_ERROR_INVALID_FORMAT;
        }
        NPT_UInt32 zip64_disk_start       = NPT_BytesToInt32Le(&zip64_locator[ 4]);
        NPT_UInt64 zip64_directory_offset = NPT_BytesToInt64Le(&zip64_locator[ 8]);
        NPT_UInt32 zip64_disk_count       = NPT_BytesToInt32Le(&zip64_locator[16]);

        // format check
        if (zip64_disk_start != 0 || zip64_disk_count != 1) {
            return NPT_ERROR_NOT_SUPPORTED;
        }

        // size check
        if (zip64_directory_offset > stream_size) {
            NPT_LOG_WARNING("zip64 directory offset too large");
            return NPT_ERROR_INVALID_FORMAT;
        }

        // load and parse the eocdr64
        unsigned char eocdr64[56];
        result = stream.Seek(zip64_directory_offset);
        if (NPT_FAILED(result)) {
            NPT_LOG_WARNING_1("seek failed (%d)", result);
            return result;
        }
        result = stream.ReadFully(eocdr64, 56);
        if (NPT_FAILED(result)) {
            NPT_LOG_WARNING_1("read failed (%d)", result);
            return result;
        }

        signature = NPT_BytesToInt32Le(&eocdr64[0]);
        if (signature != NPT_ZIP64_END_OF_CENTRAL_DIRECTORY_SIGNATURE) {
            NPT_LOG_WARNING("zip64 directory signature not found");
            return NPT_ERROR_INVALID_FORMAT;
        }

        this_disk                = NPT_BytesToInt32Le(&eocdr64[16]);
        start_disk               = NPT_BytesToInt32Le(&eocdr64[20]);
        this_disk_entry_count    = NPT_BytesToInt64Le(&eocdr64[24]);
        total_entry_count        = NPT_BytesToInt64Le(&eocdr64[32]);
        central_directory_size   = NPT_BytesToInt64Le(&eocdr64[40]);
        central_directory_offset = NPT_BytesToInt64Le(&eocdr64[48]);
    }

    // format check
    if (this_disk != 0 || start_disk != 0) {
        return NPT_ERROR_NOT_SUPPORTED;
    }
    if (this_disk_entry_count != total_entry_count) {
        return NPT_ERROR_NOT_SUPPORTED;
    }

    // check that the size looks reasonable
    if (central_directory_size > NPT_ZIP_MAX_DIRECTORY_SIZE) {
        NPT_LOG_WARNING("central directory larger than max supported");
        return NPT_ERROR_OUT_OF_RANGE;
    }
    if (total_entry_count > NPT_ZIP_MAX_ENTRY_COUNT) {
        NPT_LOG_WARNING("central directory larger than max supported");
        return NPT_ERROR_OUT_OF_RANGE;
    }

    // read the central directory
    NPT_DataBuffer central_directory_buffer;
    result = central_directory_buffer.SetDataSize((NPT_Size)central_directory_size);
    if (NPT_FAILED(result)) {
        NPT_LOG_WARNING_1("central directory too large (%lld)", central_directory_size);
        return result;
    }
    result = stream.Seek(central_directory_offset);
    if (NPT_FAILED(result)) {
        NPT_LOG_WARNING_1("seek failed (%d)", result);
        return result;
    }
    result = stream.ReadFully(central_directory_buffer.UseData(), (NPT_Size)central_directory_size);
    if (NPT_FAILED(result)) {
        NPT_LOG_WARNING_1("failed to read central directory (%d)", result);
        return result;
    }

    // create a new file object
    file = new NPT_ZipFile();
    file->m_Entries.Reserve((NPT_Cardinal)total_entry_count);

    // parse all entries
    const unsigned char* buffer = (const unsigned char*)central_directory_buffer.GetData();
    for (unsigned int i=0; i<total_entry_count; i++) {
        NPT_UInt32 signature = NPT_BytesToInt32Le(buffer);
        if (signature != NPT_ZIP_CENTRAL_FILE_HEADER_SIGNATURE) {
            NPT_LOG_WARNING("unexpected signature in central directory");
            break;
        }

        NPT_ZipFile::Entry entry(buffer);

        if (entry.m_DirectoryEntrySize > central_directory_size) {
            NPT_LOG_WARNING_1("entry size too large (%d)", entry.m_DirectoryEntrySize);
            break;
        }

        file->GetEntries().Add(entry);

        central_directory_size -= entry.m_DirectoryEntrySize;
        buffer                 += entry.m_DirectoryEntrySize;
    }

    return NPT_SUCCESS;
}
Beispiel #24
0
/*----------------------------------------------------------------------
|   PLT_Didl::FromDidl
+---------------------------------------------------------------------*/
NPT_Result  
PLT_Didl::FromDidl(const char* xml, PLT_MediaObjectListReference& objects)
{
    NPT_String          str;
    PLT_MediaObject*    object = NULL;
    NPT_XmlNode*        node = NULL;
    NPT_XmlElementNode* didl = NULL;
	NPT_XmlParser		parser;

    NPT_LOG_FINE("Parsing Didl...");

	NPT_CHECK_LABEL_SEVERE(parser.Parse(xml, node), cleanup);
    if (!node || !node->AsElementNode()) {
		NPT_LOG_SEVERE("Invalid node type");
        goto cleanup;
    }

    didl = node->AsElementNode();

	if (didl->GetTag().Compare("DIDL-Lite", true)) {
		NPT_LOG_SEVERE("Invalid node tag");
        goto cleanup;
    }

    // create entry list
    objects = new PLT_MediaObjectList();

    // for each child, find out if it's a container or not
    // and then invoke the FromDidl on it
    for (NPT_List<NPT_XmlNode*>::Iterator children = didl->GetChildren().GetFirstItem(); children; children++) {
        NPT_XmlElementNode* child = (*children)->AsElementNode();
        if (!child) continue;

        if (child->GetTag().Compare("Container", true) == 0) {
            object = new PLT_MediaContainer();
        } else if (child->GetTag().Compare("item", true) == 0) {
            object = new PLT_MediaItem();
		} else {
			NPT_LOG_WARNING("Invalid node tag");
            continue;
        }

        if (NPT_FAILED(object->FromDidl(child))) {
            NPT_LOG_WARNING_1("Invalid didl for object: %s", 
                (const char*) PLT_XmlHelper::Serialize(*child, false));
          	continue;
        }

        objects->Add(object);
        object = NULL; // reset to make sure it doesn't get deleted twice in case of error
    }

    delete node;
    return NPT_SUCCESS;

cleanup:
    objects = NULL;
    delete node;
    delete object;
    return NPT_FAILURE;
}
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::OnBrowseDirectChildren
+---------------------------------------------------------------------*/
NPT_Result
PLT_FileMediaServer::OnBrowseDirectChildren(PLT_ActionReference& action, 
                                            const char*          object_id, 
                                            NPT_SocketInfo*      info /* = NULL */)
{
    /* locate the file from the object ID */
    NPT_String dir;
    if (NPT_FAILED(GetFilePath(object_id, dir))) {
        /* error */
        NPT_LOG_WARNING("PLT_FileMediaServer::OnBrowse - ObjectID not found.");
        action->SetError(701, "No Such Object.");
        return NPT_FAILURE;
    }

    /* retrieve the item type */
    NPT_DirectoryEntryInfo entry_info;
    NPT_Result res = NPT_DirectoryEntry::GetInfo(dir, entry_info);
    if (NPT_FAILED(res)) {
        /* Object does not exist */
        action->SetError(800, "Can't retrieve info " + dir);
        return NPT_FAILURE;
    }

    if (entry_info.type != NPT_DIRECTORY_TYPE) {
        /* error */
        NPT_LOG_WARNING("PLT_FileMediaServer::OnBrowse - BROWSEDIRECTCHILDREN not allowed on an item.");
        action->SetError(710, "item is not a container.");
        return NPT_FAILURE;
    }

    NPT_String filter;
    NPT_String startingInd;
    NPT_String reqCount;

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

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

    NPT_String path = dir;
    if (!path.EndsWith(m_DirDelimiter)) {
        path += m_DirDelimiter;
    }

    /* start iterating through the directory */
    NPT_Directory directory(path);
    NPT_String    entryName;
    res = directory.GetNextEntry(entryName);
    if (NPT_FAILED(res)) {
        NPT_LOG_WARNING_1("PLT_FileMediaServer::OnBrowseDirectChildren - failed to open dir %s", (const char*) path);
        return res;
    }

    unsigned long cur_index = 0;
    unsigned long num_returned = 0;
    unsigned long total_matches = 0;
    //unsigned long update_id = 0;
    NPT_String didl = didl_header;
    PLT_MediaObjectReference item;
    do {
        item = BuildFromFilePath(path + entryName, true, info);
        if (!item.IsNull()) {
            if ((cur_index >= start_index) && ((num_returned < req_count) || (req_count == 0))) {
                NPT_String tmp;
                NPT_CHECK_SEVERE(PLT_Didl::ToDidl(*item.AsPointer(), filter, tmp));

                didl += tmp;
                num_returned++;
            }
            cur_index++;
            total_matches++;        
        }
        res = directory.GetNextEntry(entryName);
    } while (NPT_SUCCEEDED(res));

    didl += didl_footer;

    NPT_CHECK_SEVERE(action->SetArgumentValue("Result", didl));

    NPT_CHECK_SEVERE(action->SetArgumentValue("NumberReturned", NPT_String::FromInteger(num_returned)));

    NPT_CHECK_SEVERE(action->SetArgumentValue("TotalMatches", NPT_String::FromInteger(total_matches)));

    NPT_CHECK_SEVERE(action->SetArgumentValue("UpdateId", "1"));

    return NPT_SUCCESS;
}