Handle XML-RPC request in liblinphone directly instead of using libsoup.

This commit is contained in:
Ghislain MARY 2015-06-02 11:02:23 +02:00
parent a4666bd1dc
commit 16eba02ebf
9 changed files with 592 additions and 118 deletions

View file

@ -92,6 +92,8 @@ set(SOURCE_FILES
xml2lpc.c
xml2lpc.h
xml.c
xmlrpc.c
xmlrpc.h
vtables.c
)
if(ENABLE_TUNNEL)

View file

@ -373,6 +373,7 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy);
#include "content.h"
#include "event.h"
#include "linphonefriend.h"
#include "xmlrpc.h"
#else
#include "linphone/buffer.h"
#include "linphone/call_log.h"
@ -380,6 +381,7 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy);
#include "linphone/content.h"
#include "linphone/event.h"
#include "linphone/linphonefriend.h"
#include "linphone/xmlrpc.h"
#endif
LINPHONE_PUBLIC LinphoneAddress * linphone_address_new(const char *addr);

View file

@ -979,6 +979,38 @@ struct _LinphoneBuffer {
BELLE_SIP_DECLARE_VPTR(LinphoneBuffer);
/*****************************************************************************
* XML-RPC interface *
****************************************************************************/
struct _LinphoneXmlRpcRequest {
belle_sip_object_t base;
void *user_data;
belle_sip_list_t *arg_list;
char *content; /**< The string representation of the XML-RPC request */
char *method;
LinphoneXmlRpcStatus status;
int response;
};
BELLE_SIP_DECLARE_VPTR(LinphoneXmlRpcRequest);
struct _LinphoneXmlRpcSession {
belle_sip_object_t base;
void *user_data;
belle_sip_list_t *arg_list;
LinphoneCore *core;
LinphoneXmlRpcRequest *request;
LinphoneContent *content;
char *url;
ms_cond_t cond;
ms_mutex_t cond_mutex;
ms_mutex_t mutex;
};
BELLE_SIP_DECLARE_VPTR(LinphoneXmlRpcSession);
/*****************************************************************************
* REMOTE PROVISIONING FUNCTIONS *
****************************************************************************/
@ -1083,7 +1115,9 @@ BELLE_SIP_TYPE_ID(LinphoneContent),
BELLE_SIP_TYPE_ID(LinphoneLDAPContactProvider),
BELLE_SIP_TYPE_ID(LinphoneLDAPContactSearch),
BELLE_SIP_TYPE_ID(LinphoneProxyConfig),
BELLE_SIP_TYPE_ID(LinphoneFriend)
BELLE_SIP_TYPE_ID(LinphoneFriend),
BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequest),
BELLE_SIP_TYPE_ID(LinphoneXmlRpcSession)
BELLE_SIP_DECLARE_TYPES_END

View file

@ -1517,7 +1517,7 @@ LinphoneAccountCreator *linphone_account_creator_new(struct _LinphoneCore *core,
return NULL;
}
obj=ms_new0(LinphoneAccountCreator,1);
cfg=linphone_proxy_config_new();
cfg=linphone_core_create_proxy_config(core);
ssctx=sip_setup_context_new(ss,cfg);
obj->lc=core;
obj->ssctx=ssctx;

View file

@ -31,10 +31,13 @@ struct _SipSetup;
struct _BuddyInfo;
struct _LinphoneXmlRpcSession;
struct _SipSetupContext{
struct _SipSetup *funcs;
struct _LinphoneProxyConfig *cfg;
struct _LinphoneXmlRpcSession *xmlrpc_session;
char domain[128];
char username[128];
void *data;

View file

@ -20,18 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "linphonecore.h"
#include "private.h"
#include <ctype.h>
#include <libsoup/soup.h>
typedef struct _BLReq{
int status;
int result;
SoupMessage *msg;
SoupSession *session;
ortp_thread_t th;
}BLReq;
static const int XMLRPC_FAILED = -1;
static const int XMLRPC_OK = 0;
static const char *XMLRPC_URL = "https://www.linphone.org/wizard.php";
static void sip_wizard_init_instance(SipSetupContext *ctx){
@ -40,6 +30,13 @@ static void sip_wizard_init_instance(SipSetupContext *ctx){
linphone_proxy_config_enable_register(cfg,FALSE);
}
static void sip_wizard_uninit_instance(SipSetupContext *ctx) {
if (ctx->xmlrpc_session != NULL) {
linphone_xml_rpc_session_unref(ctx->xmlrpc_session);
ctx->xmlrpc_session = NULL;
}
}
static const char ** sip_wizard_get_domains(SipSetupContext *ctx) {
LinphoneProxyConfig *cfg=sip_setup_context_get_proxy_config(ctx);
const char **domains = (const char**) &cfg->reg_proxy;
@ -47,94 +44,23 @@ static const char ** sip_wizard_get_domains(SipSetupContext *ctx) {
}
static int xml_rpc_parse_response(BLReq *blreq, SoupMessage *sm){
SoupBuffer *sb;
GValue retval;
GError *error=NULL;
sb=soup_message_body_flatten(sm->response_body);
ms_message("This the xml-rpc response:\n%s\n",sb->data);
if (soup_xmlrpc_parse_method_response(sb->data,sb->length,&retval,&error)==FALSE){
if (error!=NULL){
ms_error("xmlrpc fault: %s",error->message);
g_error_free(error);
}else{
ms_error("Could not parse xml-rpc response !");
}
blreq->status=XMLRPC_FAILED;
}else{
ms_message("Extracting values from return type...");
blreq->result = g_value_get_int(&retval);
g_value_unset(&retval);
blreq->status=XMLRPC_OK;
}
soup_buffer_free(sb);
return blreq->status;
}
static int do_simple_xmlrpc_request(SipSetupContext *ctx, LinphoneXmlRpcRequest *request) {
int ret = -1;
static void got_headers(BLReq *blreq, SoupMessage*msg){
ms_message("Got headers !");
blreq->status=XMLRPC_OK;
}
#if SERIALIZE_HTTPS
/*on windows libsoup support for threads with gnutls is not yet functionnal (only in git)
This will come in next release of libsoup, probably.
In the meantime, we are forced to serialize all soup https processing with a big
ugly global mutex...*/
static GStaticMutex big_mutex = G_STATIC_MUTEX_INIT;
#endif
static void * process_xml_rpc_request(void *up){
BLReq *blreq=(BLReq*)up;
SoupMessage *sm=blreq->msg;
int code;
g_signal_connect_swapped(G_OBJECT(sm),"got-headers",(GCallback)got_headers,blreq);
blreq->status=XMLRPC_OK;
#if SERIALIZE_HTTPS
g_static_mutex_lock(&big_mutex);
#endif
code=soup_session_send_message(blreq->session,sm);
if (code==200){
xml_rpc_parse_response(blreq,sm);
}else{
ms_error("request failed, error-code=%i (%s)",code,soup_status_get_phrase(code));
blreq->status=XMLRPC_FAILED;
}
#if SERIALIZE_HTTPS
g_static_mutex_unlock(&big_mutex);
#endif
return NULL;
}
static int do_simple_xmlrpc_request(SoupMessage *msg) {
int ret=-1;
BLReq *req;
if (!msg){
ms_error("Fail to create SoupMessage !");
if (!request) {
ms_error("Fail to create XML-RPC request!");
return -1;
}else{
SoupBuffer *sb=soup_message_body_flatten(msg->request_body);
ms_message("This is the XML-RPC request we are going to send:\n%s\n",sb->data);
soup_buffer_free(sb);
} else {
ms_message("This is the XML-RPC request we are going to send:\n%s\n", linphone_xml_rpc_request_get_content(request));
}
req=ms_new0(BLReq, 1);
req->session=soup_session_sync_new();
req->msg=msg;
process_xml_rpc_request(req);
if (req->status == XMLRPC_OK) {
ret=req->result;
}
// Freeing allocated structures lead to a crash (why?)
//g_free(req->session);
//g_free(msg);
ms_free(req);
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);
}
linphone_xml_rpc_request_unref(request);
return ret;
}
@ -145,30 +71,27 @@ static int do_simple_xmlrpc_request(SoupMessage *msg) {
* -1 if information isn't available
*/
static int sip_wizard_account_exists(SipSetupContext *ctx, const char *identity) {
SoupMessage *msg=soup_xmlrpc_request_new(XMLRPC_URL,
"check_account",
G_TYPE_STRING, identity,
G_TYPE_INVALID);
return do_simple_xmlrpc_request(msg);
LinphoneXmlRpcRequest *request = linphone_xml_rpc_request_new("check_account",
LinphoneXmlRpcArgString, identity,
LinphoneXmlRpcArgNone);
return do_simple_xmlrpc_request(ctx, request);
}
static int sip_wizard_account_validated(SipSetupContext *ctx, const char *identity) {
SoupMessage *msg=soup_xmlrpc_request_new(XMLRPC_URL,
"check_account_validated",
G_TYPE_STRING, identity,
G_TYPE_INVALID);
return do_simple_xmlrpc_request(msg);
LinphoneXmlRpcRequest *request = linphone_xml_rpc_request_new("check_account_validated",
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 suscribe) {
SoupMessage *msg=soup_xmlrpc_request_new(XMLRPC_URL,
"create_account",
G_TYPE_STRING, identity,
G_TYPE_STRING, passwd,
G_TYPE_STRING, email,
G_TYPE_INT, suscribe,
G_TYPE_INVALID);
return do_simple_xmlrpc_request(msg);
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",
LinphoneXmlRpcArgString, identity,
LinphoneXmlRpcArgString, passwd,
LinphoneXmlRpcArgString, email,
LinphoneXmlRpcArgInt, subscribe,
LinphoneXmlRpcArgNone);
return do_simple_xmlrpc_request(ctx, request);
}
static void guess_display_name(LinphoneAddress *from){
@ -232,6 +155,7 @@ SipSetup linphone_sip_wizard={
.name="SipWizard",
.capabilities=SIP_SETUP_CAP_ACCOUNT_MANAGER,
.init_instance=sip_wizard_init_instance,
.uninit_instance=sip_wizard_uninit_instance,
.account_exists=sip_wizard_account_exists,
.create_account=sip_wizard_create_account,
.login_account=sip_wizard_do_login,
@ -247,7 +171,7 @@ SipSetup linphone_sip_wizard={
NULL,
NULL,
sip_wizard_init_instance,
NULL,
sip_wizard_uninit_instance,
sip_wizard_account_exists,
sip_wizard_create_account,
sip_wizard_do_login,
@ -261,6 +185,4 @@ SipSetup linphone_sip_wizard={
sip_wizard_account_validated
};
#endif

346
coreapi/xmlrpc.c Normal file
View file

@ -0,0 +1,346 @@
/*
linphone
Copyright (C) 2010-2015 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "linphonecore.h"
#include "private.h"
#include <string.h>
#include <libxml/tree.h>
#include <libxml/xmlwriter.h>
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;
xmlBufferPtr buf;
xmlTextWriterPtr writer;
int err;
buf = xmlBufferCreate();
if (buf == NULL) {
ms_error("Error creating the XML buffer");
return;
}
writer = xmlNewTextWriterMemory(buf, 0);
if (writer == NULL) {
ms_error("Error creating the XML writer");
return;
}
err = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
if (err >= 0) {
err = xmlTextWriterStartElement(writer, (const xmlChar *)"methodCall");
}
if (err >= 0) {
err = xmlTextWriterWriteElement(writer, (const xmlChar *)"methodName", (const xmlChar *)request->method);
}
if (err >= 0) {
err = xmlTextWriterStartElement(writer, (const xmlChar *)"params");
}
while (arg_ptr != NULL) {
LinphoneXmlRpcArg *arg = (LinphoneXmlRpcArg *)arg_ptr->data;
if (err >= 0) {
err = xmlTextWriterStartElement(writer, (const xmlChar *)"param");
}
if (err >= 0) {
err = xmlTextWriterStartElement(writer, (const xmlChar *)"value");
}
switch (arg->type) {
case LinphoneXmlRpcArgNone:
break;
case LinphoneXmlRpcArgInt:
memset(si, 0, sizeof(si));
snprintf(si, sizeof(si), "%i", arg->data.i);
err = xmlTextWriterWriteElement(writer, (const xmlChar *)"int", (const xmlChar *)si);
break;
case LinphoneXmlRpcArgString:
err = xmlTextWriterWriteElement(writer, (const xmlChar *)"string", (const xmlChar *)arg->data.s);
break;
}
if (err >= 0) {
/* Close the "value" element. */
err = xmlTextWriterEndElement(writer);
}
if (err >= 0) {
/* Close the "param" element. */
err = xmlTextWriterEndElement(writer);
}
arg_ptr = arg_ptr->next;
}
if (err >= 0) {
/* Close the "params" element. */
err = xmlTextWriterEndElement(writer);
}
if (err >= 0) {
/* Close the "methodCall" element. */
err = xmlTextWriterEndElement(writer);
}
if (err >= 0) {
err = xmlTextWriterEndDocument(writer);
}
if (err > 0) {
/* xmlTextWriterEndDocument returns the size of the content. */
request->content = belle_sip_strdup((const char *)buf->content);
}
xmlFreeTextWriter(writer);
xmlBufferFree(buf);
}
static void free_arg(LinphoneXmlRpcArg *arg) {
if ((arg->type == LinphoneXmlRpcArgString) && (arg->data.s != NULL)) {
belle_sip_free(arg->data.s);
}
belle_sip_free(arg);
}
static void process_io_error_from_post_xml_rpc_request(void *data, const belle_sip_io_error_event_t *event) {
LinphoneXmlRpcSession *session = (LinphoneXmlRpcSession *)data;
ms_error("I/O Error during XML-RPC request sending to %s", session->url);
session->request->status = LinphoneXmlRpcStatusFailed;
ms_cond_signal(&session->cond);
}
static void process_auth_requested_from_post_xml_rpc_request(void *data, belle_sip_auth_event_t *event) {
LinphoneXmlRpcSession *session = (LinphoneXmlRpcSession *)data;
ms_error("Error during XML-RPC request sending to connect %s", session->url);
session->request->status = LinphoneXmlRpcStatusFailed;
ms_cond_signal(&session->cond);
}
static void parse_valid_xml_rpc_response(LinphoneXmlRpcSession *session, const char *response_body) {
xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new();
xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error);
session->request->status = LinphoneXmlRpcStatusFailed;
xml_ctx->doc = xmlReadDoc((const unsigned char*)response_body, 0, NULL, 0);
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;
}
linphone_free_xml_text_content(response_str);
} else {
ms_warning("Wrongly formatted XML-RPC response: %s", xml_ctx->errorBuffer);
}
end:
linphone_xmlparsing_context_destroy(xml_ctx);
ms_cond_signal(&session->cond);
}
static void notify_xml_rpc_error(LinphoneXmlRpcSession *session) {
session->request->status = LinphoneXmlRpcStatusOk;
ms_cond_signal(&session->cond);
}
/**
* Callback function called when we have a response from server during the upload of the log collection to the server (rcs5.1 recommandation)
* Note: The first post is empty and the server shall reply a 204 (No content) message, this will trigger a new post request to the server
* to upload the file. The server response to this second post is processed by this same function
*
* @param[in] data The user-defined pointer associated with the request, it contains the LinphoneCore object
* @param[in] event The response from server
*/
static void process_response_from_post_xml_rpc_request(void *data, const belle_http_response_event_t *event) {
LinphoneXmlRpcSession *session = (LinphoneXmlRpcSession *)data;
/* Check the answer code */
if (event->response) {
int code = belle_http_response_get_status_code(event->response);
if (code == 200) { /* Valid response from the server. */
parse_valid_xml_rpc_response(session, belle_sip_message_get_body((belle_sip_message_t *)event->response));
} else {
notify_xml_rpc_error(session);
}
}
}
static void linphone_xml_rpc_request_destroy(LinphoneXmlRpcRequest *request) {
belle_sip_list_free_with_data(request->arg_list, (void (*)(void*))free_arg);
if (request->content) belle_sip_free(request->content);
belle_sip_free(request->method);
}
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);
ms_mutex_destroy(&session->mutex);
}
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,
NULL, // clone
NULL, // marshal
TRUE
);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneXmlRpcSession, belle_sip_object_t,
(belle_sip_object_destroy_t)linphone_xml_rpc_session_destroy,
NULL, // clone
NULL, // marshal
TRUE
);
LinphoneXmlRpcRequest * linphone_xml_rpc_request_new(const char *method, ...) {
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);
while (cont) {
arg_type = va_arg(args, LinphoneXmlRpcArgType);
switch (arg_type) {
case LinphoneXmlRpcArgNone:
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);
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);
break;
}
}
va_end(args);
format_request(request);
return request;
}
LinphoneXmlRpcRequest * linphone_xml_rpc_request_ref(LinphoneXmlRpcRequest *request) {
belle_sip_object_ref(request);
return request;
}
void linphone_xml_rpc_request_unref(LinphoneXmlRpcRequest *request) {
belle_sip_object_unref(request);
}
void *linphone_xml_rpc_request_get_user_data(const LinphoneXmlRpcRequest *request) {
return request->user_data;
}
void linphone_xml_rpc_request_set_user_data(LinphoneXmlRpcRequest *request, void *ud) {
request->user_data = ud;
}
const char * linphone_xml_rpc_request_get_content(const LinphoneXmlRpcRequest *request) {
return request->content;
}
LinphoneXmlRpcStatus linphone_xml_rpc_request_get_status(const LinphoneXmlRpcRequest *request) {
return request->status;
}
int linphone_xml_rpc_request_get_response(const LinphoneXmlRpcRequest *request) {
return request->response;
}
LinphoneXmlRpcSession * linphone_xml_rpc_session_new(LinphoneCore *core, const char *url) {
LinphoneXmlRpcSession *session = belle_sip_object_new(LinphoneXmlRpcSession);
belle_sip_object_ref(session);
session->core = core;
session->url = belle_sip_strdup(url);
ms_cond_init(&session->cond, NULL);
ms_mutex_init(&session->cond_mutex, NULL);
ms_mutex_init(&session->mutex, NULL);
return session;
}
LinphoneXmlRpcSession * linphone_xml_rpc_session_ref(LinphoneXmlRpcSession *session) {
belle_sip_object_ref(session);
return session;
}
void linphone_xml_rpc_session_unref(LinphoneXmlRpcSession *session) {
belle_sip_object_unref(session);
}
void *linphone_xml_rpc_session_get_user_data(const LinphoneXmlRpcSession *session) {
return session->user_data;
}
void linphone_xml_rpc_session_set_user_data(LinphoneXmlRpcSession *session, void *ud) {
session->user_data = ud;
}
LinphoneXmlRpcStatus linphone_xml_rpc_session_send_request(LinphoneXmlRpcSession *session, LinphoneXmlRpcRequest *request) {
belle_http_request_listener_callbacks_t cbs = { 0 };
belle_http_request_listener_t *l;
belle_generic_uri_t *uri;
belle_http_request_t *req;
belle_sip_memory_body_handler_t *bh;
const char *data;
LinphoneXmlRpcStatus status;
ms_mutex_lock(&session->mutex);
session->request = linphone_xml_rpc_request_ref(request);
session->content = linphone_content_new();
linphone_content_set_type(session->content, "text");
linphone_content_set_subtype(session->content,"xml");
linphone_content_set_string_buffer(session->content, linphone_xml_rpc_request_get_content(request));
uri = belle_generic_uri_parse(session->url);
req = belle_http_request_create("POST", uri, belle_sip_header_content_type_create("text", "xml"), NULL);
data = linphone_xml_rpc_request_get_content(request);
bh = belle_sip_memory_body_handler_new_copy_from_buffer(data, strlen(data), NULL, session);
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(bh));
cbs.process_response = process_response_from_post_xml_rpc_request;
cbs.process_io_error = process_io_error_from_post_xml_rpc_request;
cbs.process_auth_requested = process_auth_requested_from_post_xml_rpc_request;
l = belle_http_request_listener_create_from_callbacks(&cbs, session);
belle_http_provider_send_request(session->core->http_provider, req, l);
ms_mutex_lock(&session->cond_mutex);
ms_cond_wait(&session->cond, &session->cond_mutex);
ms_mutex_unlock(&session->cond_mutex);
status = session->request->status;
linphone_xml_rpc_request_unref(session->request);
session->request = NULL;
linphone_content_unref(session->content);
session->content = NULL;
ms_mutex_unlock(&session->mutex);
return status;
}

164
coreapi/xmlrpc.h Normal file
View file

@ -0,0 +1,164 @@
/*
buffer.h
Copyright (C) 2010-2015 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef LINPHONE_XMLRPC_H_
#define LINPHONE_XMLRPC_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup misc
* @{
*/
typedef enum _LinphoneXmlRpcArgType {
LinphoneXmlRpcArgNone,
LinphoneXmlRpcArgInt,
LinphoneXmlRpcArgString
} LinphoneXmlRpcArgType;
typedef enum _LinphoneXmlRpcStatus {
LinphoneXmlRpcStatusPending,
LinphoneXmlRpcStatusOk,
LinphoneXmlRpcStatusFailed
} LinphoneXmlRpcStatus;
/**
* The LinphoneXmlRpcRequest object representing a XML-RPC request to be sent.
**/
typedef struct _LinphoneXmlRpcRequest LinphoneXmlRpcRequest;
/**
* The LinphoneXmlRpcSession object used to send XML-RPC requests and handle their responses.
**/
typedef struct _LinphoneXmlRpcSession LinphoneXmlRpcSession;
/**
* Create a new LinphoneXmlRpcRequest object.
* @param[in] method The XML-RPC method to call.
* @return A new LinphoneXmlRpcRequest object.
*/
LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_new(const char *method, ...);
/**
* Acquire a reference to the XML-RPC request.
* @param[in] request LinphoneXmlRpcRequest object.
* @return The same LinphoneXmlRpcRequest object.
**/
LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_ref(LinphoneXmlRpcRequest *request);
/**
* Release reference to the XML-RPC request.
* @param[in] request LinphoneXmlRpcRequest object.
**/
LINPHONE_PUBLIC void linphone_xml_rpc_request_unref(LinphoneXmlRpcRequest *request);
/**
* Retrieve the user pointer associated with the XML-RPC request.
* @param[in] request LinphoneXmlRpcRequest object.
* @return The user pointer associated with the XML-RPC request.
**/
LINPHONE_PUBLIC void *linphone_xml_rpc_request_get_user_data(const LinphoneXmlRpcRequest *request);
/**
* Assign a user pointer to the XML-RPC request.
* @param[in] request LinphoneXmlRpcRequest object.
* @param[in] ud The user pointer to associate with the XML-RPC request.
**/
LINPHONE_PUBLIC void linphone_xml_rpc_request_set_user_data(LinphoneXmlRpcRequest *request, void *ud);
/**
* Get the content of the XML-RPC request.
* @param[in] request LinphoneXmlRpcRequest object.
* @return The string representation of the content of the XML-RPC request.
*/
LINPHONE_PUBLIC const char * linphone_xml_rpc_request_get_content(const LinphoneXmlRpcRequest *request);
/**
* Get the status of the XML-RPC request.
* @param[in] request LinphoneXmlRpcRequest object.
* @return The status of the XML-RPC request.
**/
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().
* @param[in] request LinphoneXmlRpcRequest object.
* @return The response to the XML-RPC request.
**/
LINPHONE_PUBLIC int linphone_xml_rpc_request_get_response(const LinphoneXmlRpcRequest *request);
/**
* Create a new LinphoneXmlRpcSession object.
* @param[in] core The LinphoneCore object used to send the XML-RPC requests.
* @param[in] url The URL of the XML-RPC server to send the XML-RPC requests to.
* @return A new LinphoneXmlRpcSession object.
*/
LINPHONE_PUBLIC LinphoneXmlRpcSession * linphone_xml_rpc_session_new(LinphoneCore *core, const char *url);
/**
* Acquire a reference to the XML-RPC session.
* @param[in] session LinphoneXmlRpcSession object.
* @return The same LinphoneXmlRpcSession object.
**/
LINPHONE_PUBLIC LinphoneXmlRpcSession * linphone_xml_rpc_session_ref(LinphoneXmlRpcSession *session);
/**
* Release reference to the XML-RPC session.
* @param[in] session LinphoneXmlRpcSession object.
**/
LINPHONE_PUBLIC void linphone_xml_rpc_session_unref(LinphoneXmlRpcSession *session);
/**
* Retrieve the user pointer associated with the XML-RPC session.
* @param[in] session LinphoneXmlRpcSession object.
* @return The user pointer associated with the XML-RPC session.
**/
LINPHONE_PUBLIC void *linphone_xml_rpc_session_get_user_data(const LinphoneXmlRpcSession *session);
/**
* Assign a user pointer to the XML-RPC session.
* @param[in] session LinphoneXmlRpcSession object.
* @param[in] ud The user pointer to associate with the XML-RPC session.
**/
LINPHONE_PUBLIC void linphone_xml_rpc_session_set_user_data(LinphoneXmlRpcSession *session, void *ud);
/**
* Send an XML-RPC request.
* @param[in] session LinphoneXmlRpcSession object.
* @param[in] request The LinphoneXmlRpcRequest to be sent.
* @return The status of the XML-RPC request sending. If it is LinphoneXmlRpcStatusOk, use linphone_xml_rpc_session_get_response() to get the XML-RPC response.
**/
LINPHONE_PUBLIC LinphoneXmlRpcStatus linphone_xml_rpc_session_send_request(LinphoneXmlRpcSession *session, LinphoneXmlRpcRequest *request);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* LINPHONE_XMLRPC_H_ */

View file

@ -292,6 +292,7 @@ static void account_username_changed(GtkEntry *entry, GtkWidget *w) {
LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(assistant);
linphone_account_creator_set_username(creator, gtk_entry_get_text(username));
linphone_account_creator_set_domain(creator, "sip.linphone.org");
if (g_regex_match_simple("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{3,}$", gtk_entry_get_text(username), 0, 0)) {
#if !GLIB_CHECK_VERSION(2, 31, 0)