示例#1
0
/********************************************************************************
 * upnp_igd_send_action
 *
 * Description:
 *       Send an Action request to the specified service of a device.
 *
 * Parameters:
 *   igd_ctxt    -- The upnp igd context
 *   device_node -- The device
 *   service     -- The service
 *   actionname  -- The name of the action.
 *   param_name  -- An array of parameter names
 *   param_val   -- The corresponding parameter values
 *   param_count -- The number of parameters
 *   fun         -- Callback function
 *   cookie      -- Callback cookie
 *
 ********************************************************************************/
int upnp_igd_send_action(upnp_igd_context* igd_ctxt, upnp_igd_device_node *device_node, int service,
		const char *actionname, const char **param_name, const char **param_val, int param_count,
		Upnp_FunPtr fun, const void *cookie) {
	IXML_Document *actionNode = NULL;
	int ret = 0;
	int param;
	if (0 == param_count) {
		actionNode = UpnpMakeAction(actionname, IGDServiceType[service], 0, NULL);
	} else {
		for (param = 0; param < param_count; param++) {
			if (UpnpAddToAction(&actionNode, actionname, IGDServiceType[service], param_name[param], param_val[param]) != UPNP_E_SUCCESS) {
				upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "ERROR: upnp_igd_send_action: Trying to add action param");
			}
		}
	}

	ret = UpnpSendActionAsync(igd_ctxt->upnp_handle, device_node->device.services[service].control_url,
				 IGDServiceType[service], NULL, actionNode, fun, cookie);

	if (ret != UPNP_E_SUCCESS) {
		upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error in UpnpSendActionAsync -- %d", ret);
		ret = -1;
	}

	if (actionNode)
		ixmlDocument_free(actionNode);

	return ret;
}
示例#2
0
文件: tv_ctrlpt.c 项目: Tieske/pupnp
/********************************************************************************
 * TvCtrlPointSendAction
 *
 * Description: 
 *       Send an Action request to the specified service of a device.
 *
 * Parameters:
 *   service -- The service
 *   devnum -- The number of the device (order in the list,
 *             starting with 1)
 *   actionname -- The name of the action.
 *   param_name -- An array of parameter names
 *   param_val -- The corresponding parameter values
 *   param_count -- The number of parameters
 *
 ********************************************************************************/
int TvCtrlPointSendAction(
	int service,
	int devnum,
	const char *actionname,
	const char **param_name,
	char **param_val,
	int param_count)
{
	struct TvDeviceNode *devnode;
	IXML_Document *actionNode = NULL;
	int rc = TV_SUCCESS;
	int param;

	ithread_mutex_lock(&DeviceListMutex);

	rc = TvCtrlPointGetDevice(devnum, &devnode);
	if (TV_SUCCESS == rc) {
		if (0 == param_count) {
			actionNode =
			    UpnpMakeAction(actionname, TvServiceType[service],
					   0, NULL);
		} else {
			for (param = 0; param < param_count; param++) {
				if (UpnpAddToAction
				    (&actionNode, actionname,
				     TvServiceType[service], param_name[param],
				     param_val[param]) != UPNP_E_SUCCESS) {
					SampleUtil_Print
					    ("ERROR: TvCtrlPointSendAction: Trying to add action param\n");
					/*return -1; // TBD - BAD! leaves mutex locked */
				}
			}
		}

		rc = UpnpSendActionAsync(ctrlpt_handle,
					 devnode->device.
					 TvService[service].ControlURL,
					 TvServiceType[service], NULL,
					 actionNode,
					 TvCtrlPointCallbackEventHandler, NULL);

		if (rc != UPNP_E_SUCCESS) {
			SampleUtil_Print("Error in UpnpSendActionAsync -- %d\n",
					 rc);
			rc = TV_ERROR;
		}
	}

	ithread_mutex_unlock(&DeviceListMutex);

	if (actionNode)
		ixmlDocument_free(actionNode);

	return rc;
}
/********************************************************************************
 * WscUPnPCPSendAction
 *
 * Description: 
 *       Send an Action request to the specified service of a device.
 *
 * Parameters:
 *   devnum -- The number of the device (order in the list,
 *             starting with 1)
 *   actionname -- The name of the action.
 *   param_name -- An array of parameter names
 *   param_val -- The corresponding parameter values
 *   param_count -- The number of parameters
 *
 ********************************************************************************/
int WscUPnPCPSendAction(
	IN uint32 ipAddr,
	IN char *actionname,
	IN char **param_name,
	IN char **param_val,
	IN int param_count)
{
	struct upnpDeviceNode *devnode;
	IXML_Document *actionNode = NULL;
	int rc = WSC_SYS_SUCCESS;
	int param;

    rc = WscUPnPCPGetDevice(ipAddr, &devnode);
	if (rc == WSC_SYS_SUCCESS)
	{
		if (param_count == 0) 
		{
			actionNode = UpnpMakeAction(actionname, WscServiceTypeStr, 0, NULL);
		}
		else
		{
			for (param = 0; param < param_count; param++)
			{
				rc = UpnpAddToAction(actionNode, actionname, WscServiceTypeStr, 
										param_name[param], param_val[param]);
				if (rc != UPNP_E_SUCCESS ) 
				{
					DBGPRINTF(RT_DBG_ERROR, "ERROR: WscUPnPCPSendAction: Trying to add action param, rc=%d!\n", rc);
					//return -1; // TBD - BAD! leaves mutex locked
				}
			}
		}
		DBGPRINTF(RT_DBG_INFO, "ControlURL=%s!\n", devnode->device.services.ControlURL);
		rc = UpnpSendActionAsync( WscCPHandle, devnode->device.services.ControlURL, 
									WscServiceTypeStr, NULL, actionNode, 
									WscUPnPCPDeviceHandler, NULL);

        if (rc != UPNP_E_SUCCESS)
		{
			DBGPRINTF(RT_DBG_ERROR, "Error in UpnpSendActionAsync -- %d\n", rc);
			rc = WSC_SYS_ERROR;
		}
	}
	else 
	{
		DBGPRINTF(RT_DBG_ERROR, "WscUPnPCPGetDevice failed!\n");
	}
	
	if (actionNode)
		ixmlDocument_free(actionNode);

	return rc;
}
示例#4
0
IXML_Document* MediaServer::_browseAction( const char* pObjectID,
                                           const char* pBrowseFlag,
                                           const char* pFilter,
                                           const char* pStartingIndex,
                                           const char* pRequestedCount,
                                           const char* pSortCriteria )
{
    IXML_Document* action = 0;
    IXML_Document* response = 0;
    const char* url = getContentDirectoryControlURL();
    
    if ( !url || strcmp( url, "" ) == 0 )
    {
        msg_Dbg( _p_sd, "No subscription url set!" );
        return 0;
    }

    char* ObjectID = strdup( pObjectID );
    char* BrowseFlag = strdup( pBrowseFlag );
    char* Filter = strdup( pFilter );
    char* StartingIndex = strdup( pStartingIndex );
    char* RequestedCount = strdup( pRequestedCount );
    char* SortCriteria = strdup( pSortCriteria );
    char* serviceType = strdup( CONTENT_DIRECTORY_SERVICE_TYPE );

    int res;

    res = UpnpAddToAction( &action, "Browse",
            serviceType, "ObjectID", ObjectID );
    
    if ( res != UPNP_E_SUCCESS ) 
    {
        msg_Dbg( _p_sd,
                 "%s:%d: ERROR: %s", __FILE__, __LINE__,
                 UpnpGetErrorMessage( res ) );
        goto browseActionCleanup;
    }

    res = UpnpAddToAction( &action, "Browse",
            serviceType, "BrowseFlag", BrowseFlag );
    
    if ( res != UPNP_E_SUCCESS )
    {
        msg_Dbg( _p_sd,
             "%s:%d: ERROR: %s", __FILE__, __LINE__,
             UpnpGetErrorMessage( res ) );
        goto browseActionCleanup;
    }

    res = UpnpAddToAction( &action, "Browse",
            serviceType, "Filter", Filter );
    
    if ( res != UPNP_E_SUCCESS )
    {
        msg_Dbg( _p_sd,
             "%s:%d: ERROR: %s", __FILE__, __LINE__,
             UpnpGetErrorMessage( res ) );
        goto browseActionCleanup;
    }

    res = UpnpAddToAction( &action, "Browse",
            serviceType, "StartingIndex", StartingIndex );

    if ( res != UPNP_E_SUCCESS )
    {
        msg_Dbg( _p_sd,
             "%s:%d: ERROR: %s", __FILE__, __LINE__,
             UpnpGetErrorMessage( res ) );
        goto browseActionCleanup;
    }

    res = UpnpAddToAction( &action, "Browse",
            serviceType, "RequestedCount", RequestedCount );

    if ( res != UPNP_E_SUCCESS )
    {
        msg_Dbg( _p_sd,
                "%s:%d: ERROR: %s", __FILE__, __LINE__,
                UpnpGetErrorMessage( res ) ); goto browseActionCleanup; }

    res = UpnpAddToAction( &action, "Browse",
            serviceType, "SortCriteria", SortCriteria );
    
    if ( res != UPNP_E_SUCCESS )
    {
        msg_Dbg( _p_sd,
             "%s:%d: ERROR: %s", __FILE__, __LINE__,
             UpnpGetErrorMessage( res ) );
        goto browseActionCleanup;
    }

    res = UpnpSendAction( _p_sd->p_sys->clientHandle,
              url,
              CONTENT_DIRECTORY_SERVICE_TYPE,
              0,
              action,
              &response );
    
    if ( res != UPNP_E_SUCCESS )
    {
        msg_Dbg( _p_sd,
                "%s:%d: ERROR: %s when trying the send() action with URL: %s",
                __FILE__, __LINE__,
                UpnpGetErrorMessage( res ), url );

        ixmlDocument_free( response );
        response = 0;
    }

 browseActionCleanup:

    free( ObjectID );
    free( BrowseFlag );
    free( Filter );
    free( StartingIndex );
    free( RequestedCount );
    free( SortCriteria );

    free( serviceType );

    ixmlDocument_free( action );
    return response;
}
示例#5
0
文件: upnp.cpp 项目: videolan/vlc
/* Access part */
IXML_Document* MediaServer::_browseAction( const char* psz_object_id_,
        const char* psz_browser_flag_,
        const char* psz_filter_,
        const char* psz_requested_count_,
        const char* psz_sort_criteria_ )
{
    IXML_Document* p_action = NULL;
    IXML_Document* p_response = NULL;
    Upnp_i11e_cb *i11eCb = NULL;
    access_sys_t *sys = (access_sys_t *)m_access->p_sys;

    int i_res;

    if ( vlc_killed() )
        return NULL;

    i_res = UpnpAddToAction( &p_action, "Browse",
                             CONTENT_DIRECTORY_SERVICE_TYPE, "ObjectID", psz_object_id_ ? psz_object_id_ : "0" );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( m_access, "AddToAction 'ObjectID' failed: %s",
                 UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
                             CONTENT_DIRECTORY_SERVICE_TYPE, "BrowseFlag", psz_browser_flag_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( m_access, "AddToAction 'BrowseFlag' failed: %s",
                 UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
                             CONTENT_DIRECTORY_SERVICE_TYPE, "Filter", psz_filter_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( m_access, "AddToAction 'Filter' failed: %s",
                 UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
                             CONTENT_DIRECTORY_SERVICE_TYPE, "StartingIndex", "0" );
    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( m_access, "AddToAction 'StartingIndex' failed: %s",
                 UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
                             CONTENT_DIRECTORY_SERVICE_TYPE, "RequestedCount", psz_requested_count_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( m_access, "AddToAction 'RequestedCount' failed: %s",
                 UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
                             CONTENT_DIRECTORY_SERVICE_TYPE, "SortCriteria", psz_sort_criteria_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( m_access, "AddToAction 'SortCriteria' failed: %s",
                 UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    /* Setup an interruptible callback that will call sendActionCb if not
     * interrupted by vlc_interrupt_kill */
    i11eCb = new Upnp_i11e_cb( sendActionCb, &p_response );
    i_res = UpnpSendActionAsync( sys->p_upnp->handle(),
                                 m_psz_root,
                                 CONTENT_DIRECTORY_SERVICE_TYPE,
                                 NULL, /* ignored in SDK, must be NULL */
                                 p_action,
                                 Upnp_i11e_cb::run, i11eCb );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Err( m_access, "%s when trying the send() action with URL: %s",
                 UpnpGetErrorMessage( i_res ), m_access->psz_location );
    }
    /* Wait for the callback to fill p_response or wait for an interrupt */
    i11eCb->waitAndRelease();

browseActionCleanup:
    ixmlDocument_free( p_action );
    return p_response;
}
示例#6
0
文件: upnp.cpp 项目: Flameeyes/vlc
/*
 * Constructs UpnpAction to browse available content.
 */
IXML_Document* MediaServer::_browseAction( const char* psz_object_id_,
                                           const char* psz_browser_flag_,
                                           const char* psz_filter_,
                                           const char* psz_starting_index_,
                                           const char* psz_requested_count_,
                                           const char* psz_sort_criteria_ )
{
    IXML_Document* p_action = 0;
    IXML_Document* p_response = 0;
    const char* psz_url = getContentDirectoryControlURL();

    if ( !psz_url )
    {
        msg_Dbg( _p_sd, "No subscription url set!" );
        return 0;
    }

    char* psz_service_type = strdup( CONTENT_DIRECTORY_SERVICE_TYPE );

    psz_service_type[strlen( psz_service_type ) - 1] =
	_i_content_directory_service_version;

    int i_res;

    i_res = UpnpAddToAction( &p_action, "Browse",
            psz_service_type, "ObjectID", psz_object_id_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( _p_sd, "AddToAction 'ObjectID' failed: %s",
                UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
            psz_service_type, "BrowseFlag", psz_browser_flag_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( _p_sd, "AddToAction 'BrowseFlag' failed: %s", 
                UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
            psz_service_type, "Filter", psz_filter_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( _p_sd, "AddToAction 'Filter' failed: %s",
                UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
            psz_service_type, "StartingIndex", psz_starting_index_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( _p_sd, "AddToAction 'StartingIndex' failed: %s",
                UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
            psz_service_type, "RequestedCount", psz_requested_count_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( _p_sd, "AddToAction 'RequestedCount' failed: %s",
                UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
            psz_service_type, "SortCriteria", psz_sort_criteria_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( _p_sd, "AddToAction 'SortCriteria' failed: %s",
                UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpSendAction( _p_sd->p_sys->client_handle,
              psz_url,
              psz_service_type,
              0, /* ignored in SDK, must be NULL */
              p_action,
              &p_response );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Err( _p_sd, "%s when trying the send() action with URL: %s",
                UpnpGetErrorMessage( i_res ), psz_url );

        ixmlDocument_free( p_response );
        p_response = 0;
    }

browseActionCleanup:

    free( psz_service_type );

    ixmlDocument_free( p_action );
    return p_response;
}
示例#7
0
int
Cyber_Addmapport( int service,
                        char *cyber_ctrolUARL,
                     
                       char *actionname,
                      
                    
                       int param_count )
{
    struct TvDeviceNode *devnode;
    IXML_Document *actionNode = NULL;
    int rc = TV_SUCCESS;
    int param;
    char cyber_param_name1[]="NewRemoteHost";
    char cyber_param_name2[]="NewExternalPort";
    char cyber_param_name3[]="NewProtocol";
    char cyber_param_name4[]="NewInternalPort";
    char cyber_param_name5[]="NewInternalClient";
    char cyber_param_name6[]="NewEnabled";
    char cyber_param_name7[]="NewPortMappingDescription";
    char cyber_param_name8[]="NewLeaseDuration";
    
    char cyber_param_var1[]="";
    char cyber_param_var2[]="56050";
    char cyber_param_var3[]="tcp";
    char cyber_param_var4[]="80";
    char cyber_param_var5[]="192.168.0.231";
    char cyber_param_var6[]="";
    char cyber_param_var7[]="";
    char cyber_param_var8[]="";
    printf("cyber_param_name1[]=%s\n",cyber_param_name1);
    printf("cyber_param_name2[]=%s\n",cyber_param_name2);
    printf("cyber_param_name3[]=%s\n",cyber_param_name3);
    printf("cyber_param_name4[]=%s\n",cyber_param_name4);
    printf("cyber_param_name5[]=%s\n",cyber_param_name5);
    printf("cyber_param_name6[]=%s\n",cyber_param_name6);
    printf("cyber_param_name7[]=%s\n",cyber_param_name7);
    printf("cyber_param_name8[]=%s\n",cyber_param_name8);
    
     printf("cyber_param_var1[]=%s\n",cyber_param_var1);
     printf("cyber_param_var2[]=%s\n",cyber_param_var2);
     printf("cyber_param_var3[]=%s\n",cyber_param_var3);
     printf("cyber_param_var4[]=%s\n",cyber_param_var4);
     printf("cyber_param_var5[]=%s\n",cyber_param_var5);
     printf("cyber_param_var6[]=%s\n",cyber_param_var6);
     printf("cyber_param_var7[]=%s\n",cyber_param_var7);
     printf("cyber_param_var8[]=%s\n",cyber_param_var8);    
      
  ///  cyber_param_var[]={"","8898","tcp","80","192.168.0.231","","CTL IPCAM",""};
    
    ithread_mutex_lock( &DeviceListMutex );
    printf("actionname=%s\n",actionname);
        if(UpnpAddToAction( &actionNode, actionname, TvServiceType[service],cyber_param_name1,cyber_param_var1 ) != UPNP_E_SUCCESS ) 
    {                    printf( "ERROR: TvCtrlPointSendAction: Trying to add action param" );
    }
    
       if( UpnpAddToAction( &actionNode, actionname, TvServiceType[service],
                       cyber_param_name2,cyber_param_var2 ) != UPNP_E_SUCCESS ) 
    {                     printf( "ERROR: TvCtrlPointSendAction: Trying to add action param" );
    }
       if( UpnpAddToAction( &actionNode, actionname, TvServiceType[service],
                       cyber_param_name3,cyber_param_var3 ) != UPNP_E_SUCCESS ) 
    {                    printf( "ERROR: TvCtrlPointSendAction: Trying to add action param" );
    }
       if( UpnpAddToAction( &actionNode, actionname, TvServiceType[service],
                       cyber_param_name4,cyber_param_var4 ) != UPNP_E_SUCCESS ) 
    {                    printf( "ERROR: TvCtrlPointSendAction: Trying to add action param" );
    }
       if( UpnpAddToAction( &actionNode, actionname, TvServiceType[service],
                       cyber_param_name5,cyber_param_var5 ) != UPNP_E_SUCCESS ) 
    {                    printf
                        ( "ERROR: TvCtrlPointSendAction: Trying to add action param" );
    }
       if( UpnpAddToAction( &actionNode, actionname, TvServiceType[service],
                       cyber_param_name6,cyber_param_var6 ) != UPNP_E_SUCCESS ) 
    {                    printf( "ERROR: TvCtrlPointSendAction: Trying to add action param" );
    }
       if( UpnpAddToAction( &actionNode, actionname, TvServiceType[service],
                       cyber_param_name7,cyber_param_var7 ) != UPNP_E_SUCCESS ) 
    {                    printf( "ERROR: TvCtrlPointSendAction: Trying to add action param" );
    }
       if( UpnpAddToAction( &actionNode, actionname, TvServiceType[service],
                       cyber_param_name8,cyber_param_var8 ) != UPNP_E_SUCCESS ) 
    {                    printf( "ERROR: TvCtrlPointSendAction: Trying to add action param" );
    }
   
    
/*
   // rc = TvCtrlPointGetDevice( devnum, &devnode );
            for( param = 0; param < param_count; param++ ) {
                if( UpnpAddToAction
                    ( &actionNode, actionname, TvServiceType[service],
                      cyber_param_name[param],
                      cyber_param_var[param] ) != UPNP_E_SUCCESS ) {
                    printf
                        ( "ERROR: TvCtrlPointSendAction: Trying to add action param" );
                    //return -1; // TBD - BAD! leaves mutex locked
                }
            }
     
*/
printf("actionNode=%s\n",actionNode);
printf("send the action point\n");
        rc = UpnpSendActionAsync( ctrlpt_handle,
                                  cyber_ctrolUARL, TvServiceType[service],
                                  NULL, actionNode,
                                  TvCtrlPointCallbackEventHandler, NULL );

        if( rc != UPNP_E_SUCCESS ) {
            printf( "Error in UpnpSendActionAsync -- %d", rc );
            rc = TV_ERROR;
        }
        printf("portmappting ok");
  

    ithread_mutex_unlock( &DeviceListMutex );

    if( actionNode )
        ixmlDocument_free( actionNode );

    return rc;
}
示例#8
0
文件: upnp.cpp 项目: ZMacer/vlc
/* Access part */
IXML_Document* MediaServer::_browseAction( const char* psz_object_id_,
                                           const char* psz_browser_flag_,
                                           const char* psz_filter_,
                                           const char* psz_requested_count_,
                                           const char* psz_sort_criteria_ )
{
    IXML_Document* p_action = NULL;
    IXML_Document* p_response = NULL;
    const char* psz_url = url_.c_str();

    if ( url_.empty() )
    {
        msg_Dbg( access_, "No subscription url set!" );
        return NULL;
    }

    int i_res;

    i_res = UpnpAddToAction( &p_action, "Browse",
            CONTENT_DIRECTORY_SERVICE_TYPE, "ObjectID", psz_object_id_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( access_, "AddToAction 'ObjectID' failed: %s",
                UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
            CONTENT_DIRECTORY_SERVICE_TYPE, "StartingIndex", "0" );
    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( access_, "AddToAction 'StartingIndex' failed: %s",
                UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
            CONTENT_DIRECTORY_SERVICE_TYPE, "BrowseFlag", psz_browser_flag_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( access_, "AddToAction 'BrowseFlag' failed: %s",
                UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
            CONTENT_DIRECTORY_SERVICE_TYPE, "Filter", psz_filter_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( access_, "AddToAction 'Filter' failed: %s",
                UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
            CONTENT_DIRECTORY_SERVICE_TYPE, "RequestedCount", psz_requested_count_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( access_, "AddToAction 'RequestedCount' failed: %s",
                UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpAddToAction( &p_action, "Browse",
            CONTENT_DIRECTORY_SERVICE_TYPE, "SortCriteria", psz_sort_criteria_ );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Dbg( access_, "AddToAction 'SortCriteria' failed: %s",
                UpnpGetErrorMessage( i_res ) );
        goto browseActionCleanup;
    }

    i_res = UpnpSendAction( access_->p_sys->p_upnp->handle(),
              psz_url,
              CONTENT_DIRECTORY_SERVICE_TYPE,
              NULL, /* ignored in SDK, must be NULL */
              p_action,
              &p_response );

    if ( i_res != UPNP_E_SUCCESS )
    {
        msg_Err( access_, "%s when trying the send() action with URL: %s",
                UpnpGetErrorMessage( i_res ), psz_url );

        ixmlDocument_free( p_response );
        p_response = NULL;
    }

browseActionCleanup:
    ixmlDocument_free( p_action );
    return p_response;
}