📄 xsupgui_request.c
字号:
/**
* Licensed under a dual GPL/BSD license. (See LICENSE file for more info.)
*
* \file xsupgui_request.c
*
* \author chris@open1x.org
*
* $Id: xsupgui_request.c,v 1.1.2.41 2007/06/26 18:05:28 chessing Exp $
* $Date: 2007/06/26 18:05:28 $
**/
#include <string.h>
#include <libxml/parser.h>
#ifdef WINDOWS
#include "../../src/stdintwin.h"
#endif
#include "xsupgui.h"
#include "../libxsupconfig/xsupconfig_structs.h"
#include "xsupgui_request.h"
#include "xsupgui_xml_common.h"
// Uncomment this to get printf() debug information.
//#define REQUEST_DEBUG 1
/**
* \brief Search through the node list, and find the node called 'nodename'.
*
* @param[in] head An xmlNodePtr to the head of the list of nodes to search.
* @param[in] nodename The name of the node to locate. (Case sensative!)
*
* \note This function should usually only be called from inside \ref xsupgui_request.c.
**/
xmlNodePtr xsupgui_request_find_node(xmlNodePtr head, char *nodename)
{
xmlNodePtr cur_node = NULL;
if ((head == NULL) || (nodename == NULL)) return NULL;
for (cur_node = head; cur_node; cur_node = cur_node->next)
{
#if 0
if (cur_node->type == XML_ELEMENT_NODE)
printf("Node Name : %s\n", cur_node->name);
#endif
if ((cur_node->type == XML_ELEMENT_NODE) && (strcmp(cur_node->name, nodename) == 0))
{
return cur_node;
}
}
return NULL;
}
/**
* \brief Send a request on a given interface that will result in a byte string.
*
* @param[in] device The OS specific name of the device to query. When the
* request isn't interface specific, this may be NULL.
* @param[in] request A text version of the 'request' node that will be passed
* to the supplicant back end. (See IPC documentation.)
* @param[in] response A text version of XML node that the 'response' will be
* found in. (See IPC documentation.)
* @param[in] response_key A text version of the XML node that will contain the
* response string.
* @param[out] result The string value that the supplicant returned inside of the
* 'response_key' XML node.
*
* \retval REQUEST_SUCCESS on success
* \retval REQUEST_TIMEOUT on timeout
* \retval >299 on other error (See error "#defines" in \ref xsupgui_request.h)
**/
int xsupgui_request_get_byte_string(char *device, char *request, char *response,
char *response_key, char **result)
{
xmlDocPtr doc = NULL;
xmlDocPtr retdoc = NULL;
xmlNodePtr n = NULL, t = NULL;
int done = 0, err;
char *temp = NULL;
if ((device == NULL) || (request == NULL) || (response == NULL))
return REQUEST_FAILURE;
(*result) = NULL;
doc = xsupgui_xml_common_build_msg();
if (doc == NULL) return IPC_ERROR_CANT_CREATE_REQ_HDR;
n = xmlDocGetRootElement(doc);
if (n == NULL)
{
done = IPC_ERROR_CANT_FIND_REQ_ROOT_NODE;
goto get_some_bytestr_done;
}
t = xmlNewChild(n, NULL, request, NULL);
if (t == NULL)
{
done = IPC_ERROR_CANT_CREATE_REQUEST;
goto get_some_bytestr_done;
}
xsupgui_xml_common_convert_amp(device, &temp);
if (xmlNewChild(t, NULL, "Interface", temp) == NULL)
{
done = IPC_ERROR_CANT_CREATE_INT_NODE;
free(temp);
goto get_some_bytestr_done;
}
free(temp);
err = xsupgui_request_send(doc, &retdoc);
if (err != REQUEST_SUCCESS)
{
done = err;
goto get_some_bytestr_done;
}
// Otherwise, parse it and see if we got what we wanted.
err = xsupgui_request_check_exceptions(retdoc);
if (err != 0)
{
done = err;
goto get_some_bytestr_done;
}
n = xmlDocGetRootElement(retdoc);
if (n == NULL)
{
done = IPC_ERROR_CANT_FIND_RESP_ROOT_NODE;
goto get_some_bytestr_done;
}
// If we get here, then we know that the document passed the
// validation tests imposed. So, we need to see if we got the result
// we wanted.
n = n->children;
t = xsupgui_request_find_node(n, response);
if (t == NULL)
{
done = IPC_ERROR_CANT_FIND_RESPONSE;
goto get_some_bytestr_done;
}
// The interface will be included in the response, but it really doesn't matter
// right now, so ignore it.
t = xsupgui_request_find_node(t->children, response_key);
if (t == NULL)
{
done = IPC_ERROR_BAD_RESPONSE;
goto get_some_bytestr_done;
}
// Otherwise, we need to return the value of the state.
(*result) = (char *)xmlNodeGetContent(t);
done = REQUEST_SUCCESS;
get_some_bytestr_done:
if (doc != NULL) xmlFreeDoc(doc);
if (retdoc != NULL) xmlFreeDoc(retdoc);
return done;
}
/**
* \brief Send a request on a given interface that will result in a long int.
*
* @param[in] device The OS specific name of the device to query. When the
* request isn't interface specific, this may be NULL.
* @param[in] request A text version of the 'request' node that will be passed
* to the supplicant back end. (See IPC documentation.)
* @param[in] response A text version of XML node that the 'response' will be
* found in. (See IPC documentation.)
* @param[in] response_key A text version of the XML node that will contain the
* response string.
* @param[out] result A pointer to a long int that contains the value that was
* returned in the tag specified by 'response_key'.
*
* \retval REQUEST_SUCCESS on success
* \retval REQUEST_TIMEOUT on timeout
* \retval >299 on other error (See error "#defines" in \ref xsupgui_request.h)
**/
int xsupgui_request_get_long_int(char *device, char *request, char *response,
char *response_key, long int *result)
{
xmlDocPtr doc = NULL;
xmlDocPtr retdoc = NULL;
xmlNodePtr n = NULL, t = NULL;
xmlChar *content = NULL;
int done = 0, err = 0;
char *temp = NULL;
if ((device == NULL) || (request == NULL) || (response == NULL)
|| (response_key == NULL))
return IPC_ERROR_INVALID_PARAMETERS;
doc = xsupgui_xml_common_build_msg();
if (doc == NULL) return IPC_ERROR_CANT_CREATE_REQUEST;
n = xmlDocGetRootElement(doc);
if (n == NULL)
{
done = IPC_ERROR_CANT_CREATE_REQ_HDR;
goto get_some_longint_done;
}
t = xmlNewChild(n, NULL, request, NULL);
if (t == NULL)
{
done = IPC_ERROR_CANT_CREATE_REQUEST;
goto get_some_longint_done;
}
xsupgui_xml_common_convert_amp(device, &temp);
if (xmlNewChild(t, NULL, "Interface", temp) == NULL)
{
done = IPC_ERROR_CANT_CREATE_INT_NODE;
free(temp);
goto get_some_longint_done;
}
free(temp);
err = xsupgui_request_send(doc, &retdoc);
if (err != REQUEST_SUCCESS)
{
done = err;
goto get_some_longint_done;
}
// Otherwise, parse it and see if we got what we wanted.
err = xsupgui_request_check_exceptions(retdoc);
if (err != 0)
{
done = err;
goto get_some_longint_done;
}
n = xmlDocGetRootElement(retdoc);
if (n == NULL)
{
done = IPC_ERROR_CANT_FIND_RESP_ROOT_NODE;
goto get_some_longint_done;
}
// If we get here, then we know that the document passed the
// validation tests imposed. So, we need to see if we got the result
// we wanted.
n = n->children;
t = xsupgui_request_find_node(n, response);
if (t == NULL)
{
done = IPC_ERROR_BAD_RESPONSE;
goto get_some_longint_done;
}
// The interface will be included in the response, but it really doesn't matter
// right now, so ignore it.
t = xsupgui_request_find_node(t->children, response_key);
if (t == NULL)
{
done = IPC_ERROR_BAD_RESPONSE;
goto get_some_longint_done;
}
// Otherwise, we need to return the value of the state.
content = (char *)xmlNodeGetContent(t);
(*result) = atol((char *)content);
done = REQUEST_SUCCESS;
if (content != NULL) free(content);
get_some_longint_done:
if (doc != NULL) xmlFreeDoc(doc);
if (retdoc != NULL) xmlFreeDoc(retdoc);
return done;
}
/**
* \brief Send a request on a given interface that will result in an integer between 0 and
* 299.
*
* @param[in] device The OS specific name of the device to query. When the
* request isn't interface specific, this may be NULL.
* @param[in] state_request A text version of the 'request' node that will be passed
* to the supplicant back end. (See IPC documentation.)
* @param[in] state_response A text version of XML node that the 'response' will be
* found in. (See IPC documentation.)
* @param[in] response_key A text version of the XML node that will contain the
* response string.
* @param[out] result The result value.
*
* \retval REQUEST_FAILURE on error
* \retval REQUEST_SUCCESS on success
* \retval REQUEST_TIMEOUT on timeout
* \retval >299 on other error (See error "#defines" in \ref xsupgui_request.h)
**/
int xsupgui_request_get_some_value(char *device, char *state_request, char *state_response,
char *response_key, int *result)
{
xmlDocPtr doc = NULL;
xmlDocPtr retdoc = NULL;
xmlNodePtr n = NULL, t = NULL;
xmlChar *content = NULL;
int done = REQUEST_SUCCESS, err;
char *temp = NULL;
if ((device == NULL) || (state_request == NULL) || (state_response == NULL) ||
(response_key == NULL))
return IPC_ERROR_INVALID_PARAMETERS;
doc = xsupgui_xml_common_build_msg();
if (doc == NULL) return IPC_ERROR_CANT_CREATE_REQ_HDR;
n = xmlDocGetRootElement(doc);
if (n == NULL)
{
done = IPC_ERROR_CANT_FIND_REQ_ROOT_NODE;
goto get_some_value_done;
}
t = xmlNewChild(n, NULL, state_request, NULL);
if (t == NULL)
{
done = IPC_ERROR_CANT_CREATE_REQUEST;
goto get_some_value_done;
}
xsupgui_xml_common_convert_amp(device, &temp);
if (xmlNewChild(t, NULL, "Interface", temp) == NULL)
{
done = IPC_ERROR_CANT_CREATE_INT_NODE;
free(temp);
goto get_some_value_done;
}
free(temp);
err = xsupgui_request_send(doc, &retdoc);
if (err != REQUEST_SUCCESS)
{
done = err;
goto get_some_value_done;
}
// Otherwise, parse it and see if we got what we wanted.
err = xsupgui_request_check_exceptions(retdoc);
if (err != 0)
{
done = err;
goto get_some_value_done;
}
n = xmlDocGetRootElement(retdoc);
if (n == NULL)
{
done = IPC_ERROR_CANT_FIND_RESP_ROOT_NODE;
goto get_some_value_done;
}
// If we get here, then we know that the document passed the
// validation tests imposed. So, we need to see if we got the result
// we wanted.
n = n->children;
t = xsupgui_request_find_node(n, state_response);
if (t == NULL)
{
done = IPC_ERROR_BAD_RESPONSE;
goto get_some_value_done;
}
// The interface will be included in the response, but it really doesn't matter
// right now, so ignore it.
t = xsupgui_request_find_node(t->children, response_key);
if (t == NULL)
{
done = IPC_ERROR_BAD_RESPONSE;
goto get_some_value_done;
}
// Otherwise, we need to return the value of the state.
content = xmlNodeGetContent(t);
(*result) = atoi((char *)content);
if (content != NULL) free(content);
get_some_value_done:
if (doc != NULL) xmlFreeDoc(doc);
if (retdoc != NULL) xmlFreeDoc(retdoc);
return done;
}
/**
* \brief Verify the XML document returned isn't an error/deprecated message.
*
* @param[in] indoc An XML document that has been returned from the IPC call, and
* parsed by the XML parser to create a document tree.
*
* \retval REQUEST_SUCCESS if it isn't an error/deprecated message.
* \retval >299 on other error (See error "#defines" in \ref xsupgui_request.h)
*
* \note The error messages contain an interface name. However, in the current
* Xsupplicant implementation the caller will already know the interface
* name that was quired, since the calls are synchronous. So, for now,
* the interface name is ignored.
**/
int xsupgui_request_check_exceptions(xmlDocPtr indoc)
{
xmlNodePtr n = NULL, t = NULL, err = NULL;
int done = REQUEST_SUCCESS;
char *resval = NULL;
if (indoc == NULL) return IPC_ERROR_NULL_DOCUMENT;
// Find the root node.
n = xmlDocGetRootElement(indoc);
if (n == NULL) return IPC_ERROR_CANT_FIND_REQ_ROOT_NODE;
// If we get here, then we know that the document passed the
// validation tests imposed. So, we need to see if we got the result
// we wanted.
n = n->children;
// See if we have an error block
t = xsupgui_request_find_node(n, "Error");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -