mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 11:08:06 +00:00
Improve XML-RPC API.
- Handle XML-RPC request returning a string response - Allow creating a request adding the arguments one at a time (useful for automatically generated wrappers where variable args functions can be an issue)
This commit is contained in:
parent
7b3d7861e2
commit
fb8d223f54
4 changed files with 138 additions and 47 deletions
|
|
@ -983,6 +983,14 @@ BELLE_SIP_DECLARE_VPTR(LinphoneBuffer);
|
|||
* XML-RPC interface *
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct _LinphoneXmlRpcArg {
|
||||
LinphoneXmlRpcArgType type;
|
||||
union {
|
||||
int i;
|
||||
char *s;
|
||||
} data;
|
||||
} LinphoneXmlRpcArg;
|
||||
|
||||
struct _LinphoneXmlRpcRequest {
|
||||
belle_sip_object_t base;
|
||||
void *user_data;
|
||||
|
|
@ -990,7 +998,7 @@ struct _LinphoneXmlRpcRequest {
|
|||
char *content; /**< The string representation of the XML-RPC request */
|
||||
char *method;
|
||||
LinphoneXmlRpcStatus status;
|
||||
int response;
|
||||
LinphoneXmlRpcArg response;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneXmlRpcRequest);
|
||||
|
|
|
|||
|
|
@ -50,19 +50,17 @@ static int do_simple_xmlrpc_request(SipSetupContext *ctx, LinphoneXmlRpcRequest
|
|||
if (!request) {
|
||||
ms_error("Fail to create XML-RPC request!");
|
||||
return -1;
|
||||
} else {
|
||||
ms_message("This is the XML-RPC request we are going to send:\n%s\n", linphone_xml_rpc_request_get_content(request));
|
||||
}
|
||||
|
||||
if (ctx->xmlrpc_session == NULL) {
|
||||
ctx->xmlrpc_session = linphone_xml_rpc_session_new(ctx->cfg->lc, XMLRPC_URL);
|
||||
}
|
||||
if (linphone_xml_rpc_session_send_request(ctx->xmlrpc_session, request) == LinphoneXmlRpcStatusOk) {
|
||||
ret = linphone_xml_rpc_request_get_response(request);
|
||||
ret = linphone_xml_rpc_request_get_int_response(request);
|
||||
}
|
||||
linphone_xml_rpc_request_unref(request);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -71,21 +69,24 @@ static int do_simple_xmlrpc_request(SipSetupContext *ctx, LinphoneXmlRpcRequest
|
|||
* -1 if information isn't available
|
||||
*/
|
||||
static int sip_wizard_account_exists(SipSetupContext *ctx, const char *identity) {
|
||||
LinphoneXmlRpcRequest *request = linphone_xml_rpc_request_new("check_account",
|
||||
LinphoneXmlRpcRequest *request = linphone_xml_rpc_request_new_with_args("check_account",
|
||||
LinphoneXmlRpcArgInt,
|
||||
LinphoneXmlRpcArgString, identity,
|
||||
LinphoneXmlRpcArgNone);
|
||||
return do_simple_xmlrpc_request(ctx, request);
|
||||
}
|
||||
|
||||
static int sip_wizard_account_validated(SipSetupContext *ctx, const char *identity) {
|
||||
LinphoneXmlRpcRequest *request = linphone_xml_rpc_request_new("check_account_validated",
|
||||
LinphoneXmlRpcRequest *request = linphone_xml_rpc_request_new_with_args("check_account_validated",
|
||||
LinphoneXmlRpcArgInt,
|
||||
LinphoneXmlRpcArgString, identity,
|
||||
LinphoneXmlRpcArgNone);
|
||||
return do_simple_xmlrpc_request(ctx, request);
|
||||
}
|
||||
|
||||
static int sip_wizard_create_account(SipSetupContext *ctx, const char *identity, const char *passwd, const char *email, int subscribe) {
|
||||
LinphoneXmlRpcRequest *request = linphone_xml_rpc_request_new("create_account",
|
||||
LinphoneXmlRpcRequest *request = linphone_xml_rpc_request_new_with_args("create_account",
|
||||
LinphoneXmlRpcArgInt,
|
||||
LinphoneXmlRpcArgString, identity,
|
||||
LinphoneXmlRpcArgString, passwd,
|
||||
LinphoneXmlRpcArgString, email,
|
||||
|
|
|
|||
112
coreapi/xmlrpc.c
112
coreapi/xmlrpc.c
|
|
@ -26,14 +26,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
|
||||
|
||||
typedef struct _LinphoneXmlRpcArg {
|
||||
LinphoneXmlRpcArgType type;
|
||||
union {
|
||||
int i;
|
||||
char *s;
|
||||
} data;
|
||||
} LinphoneXmlRpcArg;
|
||||
|
||||
static void format_request(LinphoneXmlRpcRequest *request) {
|
||||
char si[64];
|
||||
belle_sip_list_t *arg_ptr = request->arg_list;
|
||||
|
|
@ -41,6 +33,11 @@ static void format_request(LinphoneXmlRpcRequest *request) {
|
|||
xmlTextWriterPtr writer;
|
||||
int err;
|
||||
|
||||
if (request->content != NULL) {
|
||||
belle_sip_free(request->content);
|
||||
request->content = NULL;
|
||||
}
|
||||
|
||||
buf = xmlBufferCreate();
|
||||
if (buf == NULL) {
|
||||
ms_error("Error creating the XML buffer");
|
||||
|
|
@ -140,10 +137,23 @@ static void parse_valid_xml_rpc_response(LinphoneXmlRpcSession *session, const c
|
|||
if (xml_ctx->doc != NULL) {
|
||||
const char *response_str;
|
||||
if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end;
|
||||
response_str = linphone_get_xml_text_content(xml_ctx, "/methodResponse/params/param/value/int");
|
||||
if (response_str != NULL) {
|
||||
session->request->response = atoi(response_str);
|
||||
session->request->status = LinphoneXmlRpcStatusOk;
|
||||
switch (session->request->response.type) {
|
||||
case LinphoneXmlRpcArgInt:
|
||||
response_str = linphone_get_xml_text_content(xml_ctx, "/methodResponse/params/param/value/int");
|
||||
if (response_str != NULL) {
|
||||
session->request->response.data.i = atoi(response_str);
|
||||
session->request->status = LinphoneXmlRpcStatusOk;
|
||||
}
|
||||
break;
|
||||
case LinphoneXmlRpcArgString:
|
||||
response_str = linphone_get_xml_text_content(xml_ctx, "/methodResponse/params/param/value/string");
|
||||
if (response_str != NULL) {
|
||||
session->request->response.data.s = belle_sip_strdup(response_str);
|
||||
session->request->status = LinphoneXmlRpcStatusOk;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
linphone_free_xml_text_content(response_str);
|
||||
} else {
|
||||
|
|
@ -182,13 +192,39 @@ static void process_response_from_post_xml_rpc_request(void *data, const belle_h
|
|||
}
|
||||
|
||||
|
||||
static void linphone_xml_rpc_request_destroy(LinphoneXmlRpcRequest *request) {
|
||||
static LinphoneXmlRpcRequest * _linphone_xml_rpc_request_new(const char *method, LinphoneXmlRpcArgType return_type) {
|
||||
LinphoneXmlRpcRequest *request = belle_sip_object_new(LinphoneXmlRpcRequest);
|
||||
belle_sip_object_ref(request);
|
||||
request->status = LinphoneXmlRpcStatusPending;
|
||||
request->response.type = return_type;
|
||||
request->method = belle_sip_strdup(method);
|
||||
return request;
|
||||
}
|
||||
|
||||
static void _linphone_xml_rpc_request_add_int_arg(LinphoneXmlRpcRequest *request, int value) {
|
||||
LinphoneXmlRpcArg *arg = belle_sip_malloc0(sizeof(LinphoneXmlRpcArg));
|
||||
arg->type = LinphoneXmlRpcArgInt;
|
||||
arg->data.i = value;
|
||||
request->arg_list = belle_sip_list_append(request->arg_list, arg);
|
||||
}
|
||||
|
||||
static void _linphone_xml_rpc_request_add_string_arg(LinphoneXmlRpcRequest *request, const char *value) {
|
||||
LinphoneXmlRpcArg *arg = belle_sip_malloc0(sizeof(LinphoneXmlRpcArg));
|
||||
arg->type = LinphoneXmlRpcArgString;
|
||||
arg->data.s = belle_sip_strdup(value);
|
||||
request->arg_list = belle_sip_list_append(request->arg_list, arg);
|
||||
}
|
||||
|
||||
static void _linphone_xml_rpc_request_destroy(LinphoneXmlRpcRequest *request) {
|
||||
belle_sip_list_free_with_data(request->arg_list, (void (*)(void*))free_arg);
|
||||
if ((request->response.type == LinphoneXmlRpcArgString) && (request->response.data.s != NULL)) {
|
||||
belle_sip_free(request->response.data.s);
|
||||
}
|
||||
if (request->content) belle_sip_free(request->content);
|
||||
belle_sip_free(request->method);
|
||||
}
|
||||
|
||||
static void linphone_xml_rpc_session_destroy(LinphoneXmlRpcSession *session) {
|
||||
static void _linphone_xml_rpc_session_destroy(LinphoneXmlRpcSession *session) {
|
||||
belle_sip_free(session->url);
|
||||
ms_cond_destroy(&session->cond);
|
||||
ms_mutex_destroy(&session->cond_mutex);
|
||||
|
|
@ -199,31 +235,33 @@ BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneXmlRpcRequest);
|
|||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneXmlRpcSession);
|
||||
|
||||
BELLE_SIP_INSTANCIATE_VPTR(LinphoneXmlRpcRequest, belle_sip_object_t,
|
||||
(belle_sip_object_destroy_t)linphone_xml_rpc_request_destroy,
|
||||
(belle_sip_object_destroy_t)_linphone_xml_rpc_request_destroy,
|
||||
NULL, // clone
|
||||
NULL, // marshal
|
||||
TRUE
|
||||
);
|
||||
|
||||
BELLE_SIP_INSTANCIATE_VPTR(LinphoneXmlRpcSession, belle_sip_object_t,
|
||||
(belle_sip_object_destroy_t)linphone_xml_rpc_session_destroy,
|
||||
(belle_sip_object_destroy_t)_linphone_xml_rpc_session_destroy,
|
||||
NULL, // clone
|
||||
NULL, // marshal
|
||||
TRUE
|
||||
);
|
||||
|
||||
|
||||
LinphoneXmlRpcRequest * linphone_xml_rpc_request_new(const char *method, ...) {
|
||||
LinphoneXmlRpcRequest * linphone_xml_rpc_request_new(const char *method, LinphoneXmlRpcArgType return_type) {
|
||||
LinphoneXmlRpcRequest *request = _linphone_xml_rpc_request_new(method, return_type);
|
||||
format_request(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
LinphoneXmlRpcRequest * linphone_xml_rpc_request_new_with_args(const char *method, LinphoneXmlRpcArgType return_type, ...) {
|
||||
bool_t cont = TRUE;
|
||||
va_list args;
|
||||
LinphoneXmlRpcArgType arg_type;
|
||||
LinphoneXmlRpcArg *arg = NULL;
|
||||
LinphoneXmlRpcRequest *request = belle_sip_object_new(LinphoneXmlRpcRequest);
|
||||
belle_sip_object_ref(request);
|
||||
request->status = LinphoneXmlRpcStatusPending;
|
||||
request->response = -1;
|
||||
request->method = belle_sip_strdup(method);
|
||||
va_start(args, method);
|
||||
LinphoneXmlRpcRequest *request = _linphone_xml_rpc_request_new(method, return_type);
|
||||
va_start(args, return_type);
|
||||
while (cont) {
|
||||
arg_type = va_arg(args, LinphoneXmlRpcArgType);
|
||||
switch (arg_type) {
|
||||
|
|
@ -231,16 +269,10 @@ LinphoneXmlRpcRequest * linphone_xml_rpc_request_new(const char *method, ...) {
|
|||
cont = FALSE;
|
||||
break;
|
||||
case LinphoneXmlRpcArgInt:
|
||||
arg = belle_sip_malloc0(sizeof(LinphoneXmlRpcArg));
|
||||
arg->type = LinphoneXmlRpcArgInt;
|
||||
arg->data.i = va_arg(args, int);
|
||||
request->arg_list = belle_sip_list_append(request->arg_list, arg);
|
||||
_linphone_xml_rpc_request_add_int_arg(request, va_arg(args, int));
|
||||
break;
|
||||
case LinphoneXmlRpcArgString:
|
||||
arg = belle_sip_malloc0(sizeof(LinphoneXmlRpcArg));
|
||||
arg->type = LinphoneXmlRpcArgString;
|
||||
arg->data.s = belle_sip_strdup(va_arg(args, char *));
|
||||
request->arg_list = belle_sip_list_append(request->arg_list, arg);
|
||||
_linphone_xml_rpc_request_add_string_arg(request, va_arg(args, char *));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -266,6 +298,16 @@ void linphone_xml_rpc_request_set_user_data(LinphoneXmlRpcRequest *request, void
|
|||
request->user_data = ud;
|
||||
}
|
||||
|
||||
void linphone_xml_rpc_request_add_int_arg(LinphoneXmlRpcRequest *request, int value) {
|
||||
_linphone_xml_rpc_request_add_int_arg(request, value);
|
||||
format_request(request);
|
||||
}
|
||||
|
||||
void linphone_xml_rpc_request_add_string_arg(LinphoneXmlRpcRequest *request, const char *value) {
|
||||
_linphone_xml_rpc_request_add_string_arg(request, value);
|
||||
format_request(request);
|
||||
}
|
||||
|
||||
const char * linphone_xml_rpc_request_get_content(const LinphoneXmlRpcRequest *request) {
|
||||
return request->content;
|
||||
}
|
||||
|
|
@ -274,8 +316,12 @@ LinphoneXmlRpcStatus linphone_xml_rpc_request_get_status(const LinphoneXmlRpcReq
|
|||
return request->status;
|
||||
}
|
||||
|
||||
int linphone_xml_rpc_request_get_response(const LinphoneXmlRpcRequest *request) {
|
||||
return request->response;
|
||||
int linphone_xml_rpc_request_get_int_response(const LinphoneXmlRpcRequest *request) {
|
||||
return request->response.data.i;
|
||||
}
|
||||
|
||||
const char * linphone_xml_rpc_request_get_string_response(const LinphoneXmlRpcRequest *request) {
|
||||
return request->response.data.s;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,12 +31,18 @@ extern "C" {
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enum describing the types of argument for LinphoneXmlRpcRequest.
|
||||
**/
|
||||
typedef enum _LinphoneXmlRpcArgType {
|
||||
LinphoneXmlRpcArgNone,
|
||||
LinphoneXmlRpcArgInt,
|
||||
LinphoneXmlRpcArgString
|
||||
} LinphoneXmlRpcArgType;
|
||||
|
||||
/**
|
||||
* Enum describing the status of a LinphoneXmlRpcRequest.
|
||||
**/
|
||||
typedef enum _LinphoneXmlRpcStatus {
|
||||
LinphoneXmlRpcStatusPending,
|
||||
LinphoneXmlRpcStatusOk,
|
||||
|
|
@ -55,11 +61,20 @@ typedef struct _LinphoneXmlRpcSession LinphoneXmlRpcSession;
|
|||
|
||||
|
||||
/**
|
||||
* Create a new LinphoneXmlRpcRequest object.
|
||||
* Create a new LinphoneXmlRpcRequest object.
|
||||
* @param[in] method The XML-RPC method to call.
|
||||
* @param[in] return_type The expected XML-RPC response type.
|
||||
* @return A new LinphoneXmlRpcRequest object.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_new(const char *method, LinphoneXmlRpcArgType return_type);
|
||||
|
||||
/**
|
||||
* Create a new LinphoneXmlRpcRequest object giving the arguments to the method call.
|
||||
* @param[in] method The XML-RPC method to call.
|
||||
* @param[in] return_type The expected XML-RPC response type.
|
||||
* @return A new LinphoneXmlRpcRequest object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_new(const char *method, ...);
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_new_with_args(const char *method, LinphoneXmlRpcArgType return_type, ...);
|
||||
|
||||
/**
|
||||
* Acquire a reference to the XML-RPC request.
|
||||
|
|
@ -88,6 +103,20 @@ LINPHONE_PUBLIC void *linphone_xml_rpc_request_get_user_data(const LinphoneXmlRp
|
|||
**/
|
||||
LINPHONE_PUBLIC void linphone_xml_rpc_request_set_user_data(LinphoneXmlRpcRequest *request, void *ud);
|
||||
|
||||
/**
|
||||
* Add an integer argument to an XML-RPC request.
|
||||
* @param[in] request LinphoneXmlRpcRequest object.
|
||||
* @param[in] value The integer value of the added argument.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_xml_rpc_request_add_int_arg(LinphoneXmlRpcRequest *request, int value);
|
||||
|
||||
/**
|
||||
* Add a string argument to an XML-RPC request.
|
||||
* @param[in] request LinphoneXmlRpcRequest object.
|
||||
* @param[in] value The string value of the added argument.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_xml_rpc_request_add_string_arg(LinphoneXmlRpcRequest *request, const char *value);
|
||||
|
||||
/**
|
||||
* Get the content of the XML-RPC request.
|
||||
* @param[in] request LinphoneXmlRpcRequest object.
|
||||
|
|
@ -103,11 +132,18 @@ LINPHONE_PUBLIC const char * linphone_xml_rpc_request_get_content(const Linphone
|
|||
LINPHONE_PUBLIC LinphoneXmlRpcStatus linphone_xml_rpc_request_get_status(const LinphoneXmlRpcRequest *request);
|
||||
|
||||
/**
|
||||
* Get the response to an XML-RPC request sent with linphone_xml_rpc_session_send_request().
|
||||
* Get the response to an XML-RPC request sent with linphone_xml_rpc_session_send_request() and returning an integer response.
|
||||
* @param[in] request LinphoneXmlRpcRequest object.
|
||||
* @return The response to the XML-RPC request.
|
||||
* @return The integer response to the XML-RPC request.
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_xml_rpc_request_get_response(const LinphoneXmlRpcRequest *request);
|
||||
LINPHONE_PUBLIC int linphone_xml_rpc_request_get_int_response(const LinphoneXmlRpcRequest *request);
|
||||
|
||||
/**
|
||||
* Get the response to an XML-RPC request sent with linphone_xml_rpc_session_send_request() and returning a string response.
|
||||
* @param[in] request LinphoneXmlRpcRequest object.
|
||||
* @return The string response to the XML-RPC request.
|
||||
**/
|
||||
LINPHONE_PUBLIC const char * linphone_xml_rpc_request_get_string_response(const LinphoneXmlRpcRequest *request);
|
||||
|
||||
/**
|
||||
* Create a new LinphoneXmlRpcSession object.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue