mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 11:08:06 +00:00
Handle XML-RPC request in liblinphone directly instead of using libsoup.
This commit is contained in:
parent
a4666bd1dc
commit
16eba02ebf
9 changed files with 592 additions and 118 deletions
|
|
@ -92,6 +92,8 @@ set(SOURCE_FILES
|
|||
xml2lpc.c
|
||||
xml2lpc.h
|
||||
xml.c
|
||||
xmlrpc.c
|
||||
xmlrpc.h
|
||||
vtables.c
|
||||
)
|
||||
if(ENABLE_TUNNEL)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
346
coreapi/xmlrpc.c
Normal 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
164
coreapi/xmlrpc.h
Normal 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_ */
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue