Пример #1
0
/*!
 * \brief Searches for the node specifed by the last name in the 'name' array.
 *
 * \return UPNP_E_SUCCESS if successful, else returns appropriate error.
 */
static int dom_find_deep_node(
	/* [in] array of names. */
	const char *names[],
	/* [in] size of array. */
	int num_names,
	/* [in] Node from where it should should be searched. */
	IXML_Node *start_node,
	/* [out] Node that matches the last name of the array. */
	IXML_Node **matching_node)
{
	int i;
	IXML_Node *node;
	IXML_Node *match_node;

	assert(num_names > 0);

	node = start_node;
	if (dom_cmp_name(names[0], start_node) == 0) {
		if (num_names == 1) {
			*matching_node = start_node;
			return UPNP_E_SUCCESS;
		}
	}
	for (i = 1; i < num_names; i++) {
		if (dom_find_node(names[i], node, &match_node) != UPNP_E_SUCCESS)
			return UPNP_E_NOT_FOUND;
		if (i == num_names - 1) {
			*matching_node = match_node;
			return UPNP_E_SUCCESS;
		}
		/* try again */
		node = match_node;
	}

	/* this line not reached */
	return UPNP_E_NOT_FOUND;
}
Пример #2
0
/****************************************************************************
*	Function :	dom_find_deep_node
*
*	Parameters :
*			IN char* names[] : array of names
*			IN int num_names :	size of array
*			IN IXML_Node *start_node : Node from where it should should be 
*										searched	
*			OUT IXML_Node ** matching_node : Node that matches the last name
*											of the array
*
*	Description :	This function searches for the node specifed by the last 
*		name in the 'name' array.
*
*	Return : int
*		return UPNP_E_SUCCESS if successful else returns appropriate error
*	Note :
****************************************************************************/
static int
dom_find_deep_node( IN char *names[],
                    IN int num_names,
                    IN IXML_Node * start_node,
                    OUT IXML_Node ** matching_node )
{
    int i;
    IXML_Node *node;
    IXML_Node *match_node;

    assert( num_names > 0 );

    node = start_node;
    if( dom_cmp_name( names[0], start_node ) == 0 ) {
        if( num_names == 1 ) {
            *matching_node = start_node;
            return UPNP_E_SUCCESS;
        }
    }

    for( i = 1; i < num_names; i++ ) {
        if( dom_find_node( names[i], node, &match_node ) !=
            UPNP_E_SUCCESS ) {
            return UPNP_E_NOT_FOUND;
        }

        if( i == num_names - 1 ) {
            *matching_node = match_node;
            return UPNP_E_SUCCESS;
        }

        node = match_node;      // try again
    }

    return UPNP_E_NOT_FOUND;    // this line not reached
}
Пример #3
0
/****************************************************************************
*	Function :	get_response_value
*
*	Parameters :
*			IN http_message_t* hmsg :	HTTP response message
*			IN int code :	return code in the HTTP response
*			IN char*name :	name of the action
*			OUT int *upnp_error_code :	UPnP error code
*			OUT IXML_Node ** action_value :	SOAP response node 
*			OUT DOMString * str_value : state varible value ( in the case of 
*							querry state variable request)	
*
*	Description :	This function handles the response coming back from the 
*		device. This function parses the response and gives back the SOAP 
*		response node.
*
*	Return : int
*		return the type of the SOAP message if successful else returns 
*	appropriate error.
*
*	Note :
****************************************************************************/
static int
get_response_value( IN http_message_t * hmsg,
                    IN int code,
                    IN char *name,
                    OUT int *upnp_error_code,
                    OUT IXML_Node ** action_value,
                    OUT DOMString * str_value )
{
    IXML_Node *node = NULL;
    IXML_Node *root_node = NULL;
    IXML_Node *error_node = NULL;
    IXML_Document *doc = NULL;
    char *node_str = NULL;
    const char *temp_str = NULL;
    DOMString error_node_str = NULL;
    int err_code;
    xboolean done = FALSE;
    char *names[5];
    const DOMString nodeValue;

    err_code = UPNP_E_BAD_RESPONSE; // default error

    // only 200 and 500 status codes are relevant
    if( ( hmsg->status_code != HTTP_OK &&
          hmsg->status_code != HTTP_INTERNAL_SERVER_ERROR ) ||
        !has_xml_content_type( hmsg ) ) {

        goto error_handler;
    }

    if( ixmlParseBufferEx( hmsg->entity.buf, &doc ) != IXML_SUCCESS ) {

        goto error_handler;
    }

    root_node = ixmlNode_getFirstChild( ( IXML_Node * ) doc );
    if( root_node == NULL ) {

        goto error_handler;
    }

    if( code == SOAP_ACTION_RESP ) {
        //
        // try reading soap action response
        //
        assert( action_value != NULL );

        *action_value = NULL;

        names[0] = "Envelope";
        names[1] = "Body";
        names[2] = name;
        if( dom_find_deep_node( names, 3, root_node, &node ) ==
            UPNP_E_SUCCESS ) {
            node_str = ixmlPrintNode( node );
            if( node_str == NULL ) {
                err_code = UPNP_E_OUTOF_MEMORY;
                goto error_handler;
            }

            if( ixmlParseBufferEx( node_str,
                                   ( IXML_Document ** ) action_value ) !=
                IXML_SUCCESS ) {
                err_code = UPNP_E_BAD_RESPONSE;
                goto error_handler;
            }

            err_code = SOAP_ACTION_RESP;
            done = TRUE;
        }
    } else if( code == SOAP_VAR_RESP ) {
        // try reading var response
        assert( str_value != NULL );
        *str_value = NULL;

        names[0] = "Envelope";
        names[1] = "Body";
        names[2] = "QueryStateVariableResponse";
        names[3] = "return";
        if( dom_find_deep_node( names, 4, root_node, &node )
            == UPNP_E_SUCCESS ) {
            nodeValue = get_node_value( node );
            if( nodeValue == NULL ) {
                goto error_handler;
            }

            *str_value = ixmlCloneDOMString( nodeValue );
            err_code = SOAP_VAR_RESP;
            done = TRUE;
        }
    }

    if( !done ) {
        // not action or var resp; read error code and description
        *str_value = NULL;

        names[0] = "Envelope";
        names[1] = "Body";
        names[2] = "Fault";
        names[3] = "detail";
        names[4] = "UPnPError";
        if( dom_find_deep_node( names, 5, root_node, &error_node )
            != UPNP_E_SUCCESS ) {
            goto error_handler;
        }

        if( dom_find_node( "errorCode", error_node, &node )
            != UPNP_E_SUCCESS ) {
            goto error_handler;
        }

        temp_str = get_node_value( node );
        if( temp_str == NULL ) {
            goto error_handler;
        }

        *upnp_error_code = atoi( temp_str );
        if( *upnp_error_code > 400 ) {
            err_code = *upnp_error_code;
            goto error_handler; // bad SOAP error code
        }

        if( code == SOAP_VAR_RESP ) {
            if( dom_find_node( "errorDescription", error_node, &node )
                != UPNP_E_SUCCESS ) {
                goto error_handler;
            }

            nodeValue = get_node_value( node );
            if( nodeValue == NULL ) {
                goto error_handler;
            }
            *str_value = ixmlCloneDOMString( nodeValue );
            if( *str_value == NULL ) {
                goto error_handler;
            }
            err_code = SOAP_VAR_RESP_ERROR;
        }

        else if( code == SOAP_ACTION_RESP ) {
            error_node_str = ixmlPrintNode( error_node );
            if( error_node_str == NULL ) {
                err_code = UPNP_E_OUTOF_MEMORY;
                goto error_handler;
            }

            if( ixmlParseBufferEx( error_node_str,
                                   ( IXML_Document ** ) action_value ) !=
                IXML_SUCCESS ) {
                err_code = UPNP_E_BAD_RESPONSE;

                goto error_handler;
            }
            err_code = SOAP_ACTION_RESP_ERROR;
        }
    }

  error_handler:

    ixmlDocument_free( doc );
    ixmlFreeDOMString( node_str );
    ixmlFreeDOMString( error_node_str );
    return err_code;
}