예제 #1
0
파일: content_dir.c 프로젝트: Boxee/djmount
/*****************************************************************************
 * ContentDir_GetSearchCapabilities
 *****************************************************************************/
const char*
ContentDir_GetSearchCapabilities (ContentDir* self, void* unused)
{
	if (self == NULL)
		return NULL; // ---------->
	
	// Send Action if result not already cached
	if (self->search_caps == NULL) {

		IXML_Document* doc = NULL;
		int rc = Service_SendActionVa
			(OBJECT_SUPER_CAST(self), &doc,
			 "GetSearchCapabilities",
			 NULL, NULL);
		if (rc == UPNP_E_SUCCESS && doc != NULL) {
			self->search_caps = talloc_strdup 
				(self, XMLUtil_FindFirstElementValue
				 (XML_D2N (doc), "SearchCaps", true, true));
			
			Log_Printf (LOG_DEBUG, 
				    "ContentDir_GetSearchCapabilities = '%s'",
				    NN(self->search_caps));
		}
		ixmlDocument_free (doc);
	}
	
	return self->search_caps;
}
예제 #2
0
int YX_CD_GetMetadata(pClassContentDirectory me, char *id, char **metadata)
{
	int ret = -1;

	HT_DBG_FUNC_START(HT_MOD_DMC, HT_BIT_FEW,(int)me, id);

	me->SyncBrowseMetedata(me, id);
	if( me->nb_returned > 0)
	{
		const char *result = XMLUtil_FindFirstElementValue(XML_D2N (me->ActionResult), "Result", true, true);
		*metadata = Dlna_strdup(result);
		ret = 0;
	}
	
	HT_DBG_FUNC_END(ret, *metadata);
	return ret;
}
예제 #3
0
파일: content_dir.c 프로젝트: Boxee/djmount
/******************************************************************************
 * BrowseAction
 *****************************************************************************/
static int
BrowseOrSearchAction (ContentDir* cds,
		      void* result_context,
		      const char* objectId, 
		      const char* criteria,
		      Index starting_index,
		      Count requested_count,
		      Count* nb_matched,
		      Count* nb_returned,
		      PtrArray* objects)
{
	if (cds == NULL || objectId == NULL || criteria == NULL) {
		Log_Printf (LOG_ERROR, 
			    "BrowseOrSearchAction NULL parameter");
		return UPNP_E_INVALID_PARAM; // ---------->
	}
	
	// Create a working context for temporary allocations
	void* tmp_ctx = talloc_new (NULL);
	
	const bool browse = is_browse (criteria);
	IXML_Document* doc = NULL;
	int rc = Service_SendActionVa
		(OBJECT_SUPER_CAST(cds), &doc, 
		 (browse ? "Browse" : "Search"),
		 (browse ? "ObjectID" : "ContainerID"),		objectId,
		 (browse ? "BrowseFlag" : "SearchCriteria"),	criteria,
		 "Filter", 	      "*",
		 "StartingIndex",     int_to_string (tmp_ctx, starting_index),
		 "RequestedCount",    int_to_string (tmp_ctx, requested_count),
		 "SortCriteria",      "",
		 NULL, 		      NULL);
	if (doc == NULL && rc == UPNP_E_SUCCESS)
		rc = UPNP_E_BAD_RESPONSE;
	if (rc != UPNP_E_SUCCESS) {
		Log_Printf (LOG_ERROR, "BrowseOrSearchAction ObjectId='%s'",
			    NN(objectId));
		goto cleanup; // ---------->
	}
	
	const char* s = XMLUtil_FindFirstElementValue 
		(XML_D2N (doc), "TotalMatches", true, true);
	STRING_TO_INT (s, *nb_matched, 0);
	
	s = XMLUtil_FindFirstElementValue 
		(XML_D2N (doc), "NumberReturned", true, true);
	STRING_TO_INT (s, *nb_returned, 0);
	
	Log_Printf (LOG_DEBUG, "+++BROWSE RESULT+++\n%s\n", 
		    XMLUtil_GetDocumentString (tmp_ctx, doc));
	
	const char* const resstr = XMLUtil_FindFirstElementValue
		(XML_D2N (doc), "Result", true, true);
	if (resstr == NULL) {
		Log_Printf (LOG_ERROR, "BrowseOrSearchAction ObjectId=%s : "
			    "can't get 'Result' in doc=%s",
			    objectId, 
			    XMLUtil_GetDocumentString (tmp_ctx, doc));
		rc = UPNP_E_BAD_RESPONSE;
		goto cleanup; // ---------->
	}

	IXML_Document* const subdoc = 
		ixmlParseBuffer (discard_const_p (char, resstr));
	if (subdoc == NULL) {
		Log_Printf (LOG_ERROR, "BrowseOrSearchAction ObjectId=%s : "
			    "can't parse 'Result'=%s", objectId, resstr);
		rc = UPNP_E_BAD_RESPONSE;
	} else {
		IXML_NodeList* containers = ixmlDocument_getElementsByTagName
			(subdoc, "container"); 
		ContentDir_Count const nb_containers = 
			ixmlNodeList_length (containers);
		IXML_NodeList* items =
			ixmlDocument_getElementsByTagName (subdoc, "item"); 
		ContentDir_Count const nb_items = ixmlNodeList_length (items);
		if (nb_containers + nb_items != *nb_returned) {
			Log_Printf (LOG_ERROR, 
				    "BrowseOrSearchAction ObjectId=%s "
				    "got %d containers + %d items, "
				    "expected %d", objectId, 
				    (int) nb_containers, (int) nb_items,
				    (int) *nb_returned);
			*nb_returned = nb_containers + nb_items;
		}
		if (criteria == CRITERIA_BROWSE_METADATA && *nb_returned != 1){
			Log_Printf (LOG_ERROR, "ContentDir_Browse Metadata : "
				    "not 1 result exactly ! Id=%s", 
				    NN(objectId));
		}

		ContentDir_Count i; 
		for (i = 0; i < *nb_returned; i++) {
			bool const is_container = (i < nb_containers);
			IXML_Element* const elem = (IXML_Element*) 
				ixmlNodeList_item
				(is_container ? containers : items, 
				 is_container ? i : i - nb_containers);
			DIDLObject* o = DIDLObject_Create (result_context, 
							   elem, is_container);
			if (o) {
				PtrArray_Append (objects, o);
			}
		}
		
		if (containers)
			ixmlNodeList_free (containers);
		if (items)
			ixmlNodeList_free (items);
		ixmlDocument_free (subdoc);
	}
	
 cleanup:
	
	ixmlDocument_free (doc);
	doc = NULL;
	
	// Delete all temporary storage
	talloc_free (tmp_ctx);
	tmp_ctx = NULL;
	
	if (rc != UPNP_E_SUCCESS)
		*nb_returned = *nb_matched = 0;
	
	return rc;
}
예제 #4
0
static int s_ParseBrowseOrSearchResult (Upnp_EventType EventType, void *Event, void *cookie)
{
	int kill = 0;
	pClassContentDirectory me = (pClassContentDirectory)cookie;
	struct Upnp_Action_Complete *pEvt = (struct Upnp_Action_Complete *)Event;
	IXML_Document *doc;

	HT_DBG_FUNC_START(HT_MOD_DMC, HT_BIT_MANY,EventType, "EventType = ");

	SEM_WAIT();
	
	me->sdk_err  = 0;
	me->http_err = 0;
	me->upnp_err = 0;
	
	if(me->ActionResult)
		ixmlDocument_free(me->ActionResult);
	me->ActionResult = NULL;
	if(me->subdoc)
		ixmlDocument_free(me->subdoc);
	me->subdoc = NULL;
	me->nb_matched = 0;
	me->nb_returned= 0;
	me->updateID = 0;

	if( Event==NULL || cookie==NULL )
		goto cleanup;

	HT_DBG_FUNC(pEvt->ErrCode, "ErrCode = ");
	me->sdk_err = pEvt->ErrCode;

	me->ActionResult = pEvt->ActionResult;
	pEvt->ActionResult = NULL;
	doc = me->ActionResult;
	if(!doc)
		goto cleanup;
	
	const char* s = XMLUtil_FindFirstElementValue(XML_D2N (doc), "UpdateID", true, false);
	STRING_TO_INT (s, me->updateID, 0);
	HT_DBG_FUNC(me->updateID, "updateID = ");
	s = XMLUtil_FindFirstElementValue(XML_D2N (doc), "TotalMatches", true, false);
	STRING_TO_INT (s, me->nb_matched, 0);
	HT_DBG_FUNC(me->nb_matched, "TotalMatches = ");
	s = XMLUtil_FindFirstElementValue(XML_D2N (doc), "NumberReturned", true, false);
	STRING_TO_INT (s, me->nb_returned, 0);
	HT_DBG_FUNC(me->nb_returned, "NumberReturned = ");
	if(s)
	{
		const char* const resstr = XMLUtil_FindFirstElementValue(XML_D2N (doc), "Result", true, false);
		if(me->nb_returned == 0)
		{
			HT_DBG_FUNC(0, resstr);
		}
		if (resstr) 
		{
			me->subdoc = ixmlParseBuffer (discard_const_p (char, resstr));
			HT_DBG_FUNC((int)(me->subdoc), "me->subdoc = ");		
		}
		goto cleanup;
	}
	
	s = XMLUtil_FindFirstElementValue(XML_D2N (doc), "faultstring", true, false);
	if(s && !strcmp(s, "UPnPError"))
	{
		s = XMLUtil_FindFirstElementValue(XML_D2N (doc), "errorDescription", true, false);
		HT_DBG_FUNC(0, s);
		s = XMLUtil_FindFirstElementValue(XML_D2N (doc), "errorCode", true, false);
		if(s)
			me->upnp_err = atoi(s);
	}
	

cleanup:

	kill = me->killMeInCallback;
	
	if( me->syncBrowsing == 1 )
	{
		me->syncBrowsing = 0;
		sem_post( &(me->semResultOK) );
	}
	else
	{
		if( me->OnBrowseResult && me->parent ) 
			me->OnBrowseResult(me->nb_returned, me->parent);
	}

	me->busy = 0;
	SEM_POST();

	if( kill )
		me->Release(me);
	
	HT_DBG_FUNC_END(kill, NULL);
	return kill;
}