Commit 86b626d3 authored by François Grisez's avatar François Grisez

Migration of Sal and SalOp into C++ classes

parent 70219e4c
......@@ -28,7 +28,6 @@
#include <sys/types.h>
#include <errno.h>
#include <signal.h>
#include "private.h" /*coreapi/private.h, needed for LINPHONE_VERSION */
#endif /*_WIN32_WCE*/
#include <limits.h>
#include <ctype.h>
......@@ -790,7 +789,7 @@ linphonec_prompt_for_auth_final(LinphoneCore *lc)
pending_auth=auth_stack.elem[auth_stack.nitems-1];
snprintf(auth_prompt, 256, "Password for %s on %s: ",
pending_auth->username, pending_auth->realm);
linphone_auth_info_get_username(pending_auth), linphone_auth_info_get_realm(pending_auth));
printf("\n");
#ifdef HAVE_READLINE
......
......@@ -56,15 +56,7 @@ set(LINPHONE_SOURCE_FILES_C
authentication.c
bellesip_sal/sal_address_impl.c
bellesip_sal/sal_impl.c
bellesip_sal/sal_op_call.c
bellesip_sal/sal_op_call_transfer.c
bellesip_sal/sal_op_events.c
bellesip_sal/sal_op_impl.c
bellesip_sal/sal_op_info.c
bellesip_sal/sal_op_message.c
bellesip_sal/sal_op_presence.c
bellesip_sal/sal_op_publish.c
bellesip_sal/sal_op_registration.c
bellesip_sal/sal_sdp.c
buffer.c
callbacks.c
......@@ -119,6 +111,14 @@ set(LINPHONE_SOURCE_FILES_C
)
set(LINPHONE_SOURCE_FILES_CXX
conference.cc
sal/call_op.cpp
sal/event_op.cpp
sal/message_op.cpp
sal/presence_op.cpp
sal/register_op.cpp
sal/sal.cpp
sal/sal_op.cpp
tester_utils.cpp
)
set(LINPHONE_INCLUDE_DIRS ${LINPHONE_INCLUDE_DIRS})
if(ANDROID)
......
/*
account_creator.h
Copyright (C) 2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _ACCOUNT_CREATOR_PRIVATE_H_
#define _ACCOUNT_CREATOR_PRIVATE_H_
#include "linphone/defs.h"
#include <belle-sip/object.h>
#include "linphone/account_creator_service.h"
#include "linphone/account_creator.h"
struct _LinphoneAccountCreatorService {
belle_sip_object_t base;
void *user_data;
LinphoneAccountCreatorRequestFunc account_creator_service_constructor_cb; /**< Constructor */
LinphoneAccountCreatorRequestFunc account_creator_service_destructor_cb; /**< Destructor */
LinphoneAccountCreatorRequestFunc create_account_request_cb; /**< Request to create account */
LinphoneAccountCreatorRequestFunc is_account_exist_request_cb; /**< Request to know if account exist */
LinphoneAccountCreatorRequestFunc activate_account_request_cb; /**< Request to activate account */
LinphoneAccountCreatorRequestFunc is_account_activated_request_cb; /**< Request to know if account is activated */
LinphoneAccountCreatorRequestFunc link_account_request_cb; /**< Request to link account with an alias */
LinphoneAccountCreatorRequestFunc activate_alias_request_cb; /**< Request to activate the link of alias */
LinphoneAccountCreatorRequestFunc is_alias_used_request_cb; /**< Request to know if alias is used */
LinphoneAccountCreatorRequestFunc is_account_linked_request_cb; /**< Request to know if account is linked with an alias */
LinphoneAccountCreatorRequestFunc recover_account_request_cb; /**< Request to recover account */
LinphoneAccountCreatorRequestFunc update_account_request_cb; /**< Request to update account */
};
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneAccountCreatorService);
struct _LinphoneAccountCreatorCbs {
belle_sip_object_t base;
void *user_data;
LinphoneAccountCreatorCbsStatusCb create_account_response_cb; /**< Response of create_account request */
LinphoneAccountCreatorCbsStatusCb is_account_exist_response_cb; /**< Response of is_account_exist request */
LinphoneAccountCreatorCbsStatusCb activate_account_response_cb; /**< Response of activate_account request */
LinphoneAccountCreatorCbsStatusCb is_account_activated_response_cb; /**< Response of is_account_activated request */
LinphoneAccountCreatorCbsStatusCb link_account_response_cb; /**< Response of link_account request */
LinphoneAccountCreatorCbsStatusCb activate_alias_response_cb; /**< Response of activation alias */
LinphoneAccountCreatorCbsStatusCb is_alias_used_response_cb; /**< Response of is_alias_used request */
LinphoneAccountCreatorCbsStatusCb is_account_linked_response_cb; /**< Response of is_account_linked request */
LinphoneAccountCreatorCbsStatusCb recover_account_response_cb; /**< Response of recover_account request */
LinphoneAccountCreatorCbsStatusCb update_account_response_cb; /**< Response of update_account request */
};
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneAccountCreatorCbs);
struct _LinphoneAccountCreator {
belle_sip_object_t base;
void *user_data;
LinphoneCore *core;
/* AccountCreator */
LinphoneAccountCreatorService *service; /**< Account creator service */
LinphoneAccountCreatorCbs *cbs; /**< Account creator cbs */
LinphoneXmlRpcSession *xmlrpc_session; /**< XML-RPC session */
LinphoneProxyConfig *proxy_cfg; /**< Default proxy config */
/* User */
char *username; /**< Username */
char *display_name; /**< Display name */
/* Password */
char *password; /**< Plain text password */
char *ha1; /**< Hash password */
/* Phone Number(Alias) */
char *phone_number; /**< User phone number*/
char *phone_country_code; /**< User phone number country code */
/* Email(Alias) */
char *email; /**< User email */
/* Misc */
char *language; /**< User language */
char *activation_code; /**< Account validation code */
char *domain; /**< Domain */
LinphoneTransportType transport; /**< Transport used */
/* Deprecated */
char *route;
};
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneAccountCreator);
#ifdef __cplusplus
extern "C" {
#endif
/**
* Account creator custom to set Linphone default values
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_constructor_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to test the existence of a Linphone account.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_account_exist_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to create a Linphone account.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_create_account_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to activate a Linphone account with phone number.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_activate_account_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to activate a Linphone account with email.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_activate_email_account_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to test the validation of a Linphone account.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_account_activated_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to test the existence a phone number with a Linphone account.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_phone_number_used_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to link a phone number with a Linphone account.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_link_phone_number_with_account_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to activate the link of a phone number with a Linphone account.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_activate_phone_number_link_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to a Linphone account with the phone number.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_recover_phone_account_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to ask if an account is linked with a phone number
* @param[in] creator LinphoneAccountCreator object
* @return if this account is linked with a phone number
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_account_linked_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to ask if an account is linked with a phone number
* @param[in] creator LinphoneAccountCreator object
* @param[in] new_pwd const char * : new password for the account creator
* @return LinphoneAccountCreatorStatusRequestOk if everything is OK, or a specific error otherwise.
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_update_password_linphone(LinphoneAccountCreator *creator);
#ifdef __cplusplus
}
#endif
#endif // _ACCOUNT_CREATOR_PRIVATE_H_
......@@ -24,9 +24,12 @@
#include "linphone/core.h"
#include "linphone/lpconfig.h"
#include "sal/sal.hpp"
#include "c-wrapper/c-wrapper.h"
using namespace LINPHONE_NAMESPACE;
static void _linphone_auth_info_uninit(LinphoneAuthInfo *obj);
static void _linphone_auth_info_copy(LinphoneAuthInfo *dst, const LinphoneAuthInfo *src);
......@@ -434,10 +437,10 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info)
lc->auth_info=bctbx_list_append(lc->auth_info,linphone_auth_info_clone(info));
/* retry pending authentication operations */
for(l=elem=sal_get_pending_auths(lc->sal);elem!=NULL;elem=elem->next){
for(l=elem=lc->sal->get_pending_auths();elem!=NULL;elem=elem->next){
SalOp *op=(SalOp*)elem->data;
LinphoneAuthInfo *ai;
const SalAuthInfo *req_sai=sal_op_get_auth_requested(op);
const SalAuthInfo *req_sai=op->get_auth_requested();
ai=(LinphoneAuthInfo*)_linphone_core_find_auth_info(lc,req_sai->realm,req_sai->username,req_sai->domain, FALSE);
if (ai){
SalAuthInfo sai;
......@@ -456,12 +459,12 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info)
}
/*proxy case*/
for (proxy=(bctbx_list_t*)linphone_core_get_proxy_config_list(lc);proxy!=NULL;proxy=proxy->next) {
if (proxy->data == sal_op_get_user_pointer(op)) {
if (proxy->data == op->get_user_pointer()) {
linphone_proxy_config_set_state((LinphoneProxyConfig*)(proxy->data),LinphoneRegistrationProgress,"Authentication...");
break;
}
}
sal_op_authenticate(op,&sai);
op->authenticate(&sai);
restarted_op_count++;
}
}
......
This diff is collapsed.
......@@ -24,161 +24,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "belle-sip/belle-sip.h"
#include "belle-sip/belle-sdp.h"
struct Sal{
MSFactory *factory;
SalCallbacks callbacks;
MSList *pending_auths;/*MSList of SalOp */
belle_sip_stack_t* stack;
belle_sip_provider_t *prov;
belle_sip_header_user_agent_t* user_agent;
belle_sip_listener_t *listener;
void *tunnel_client;
void *up; /*user pointer*/
int session_expires;
unsigned int keep_alive;
char *root_ca;
char *root_ca_data;
char *uuid;
int refresher_retry_after; /*retry after value for refresher*/
MSList *supported_tags;/*list of char * */
belle_sip_header_t *supported;
bool_t one_matching_codec;
bool_t use_tcp_tls_keep_alive;
bool_t nat_helper_enabled;
bool_t tls_verify;
bool_t tls_verify_cn;
bool_t use_dates;
bool_t auto_contacts;
bool_t enable_test_features;
bool_t no_initial_route;
bool_t enable_sip_update; /*true by default*/
SalOpSDPHandling default_sdp_handling;
bool_t pending_trans_checking; /*testing purpose*/
void *ssl_config;
bctbx_list_t *supported_content_types; /* list of char* */
};
typedef enum SalOpState {
SalOpStateEarly=0
,SalOpStateActive
,SalOpStateTerminating /*this state is used to wait until a proceeding state, so we can send the cancel*/
,SalOpStateTerminated
}SalOpState;
const char* sal_op_state_to_string(SalOpState value);
typedef enum SalOpDir {
SalOpDirIncoming=0
,SalOpDirOutgoing
}SalOpDir;
typedef enum SalOpType {
SalOpUnknown,
SalOpRegister,
SalOpCall,
SalOpMessage,
SalOpPresence,
SalOpPublish,
SalOpSubscribe
}SalOpType;
const char* sal_op_type_to_string(SalOpType type);
struct SalOp{
SalOpBase base;
const belle_sip_listener_callbacks_t *callbacks;
SalErrorInfo error_info;
SalErrorInfo reason_error_info;
belle_sip_client_transaction_t *pending_auth_transaction;
belle_sip_server_transaction_t* pending_server_trans;
belle_sip_server_transaction_t* pending_update_server_trans;
belle_sip_client_transaction_t* pending_client_trans;
SalAuthInfo* auth_info;
belle_sip_dialog_t* dialog;
belle_sip_header_replaces_t *replaces;
belle_sip_header_referred_by_t *referred_by;
SalMediaDescription *result;
belle_sdp_session_description_t *sdp_answer;
SalOpState state;
SalOpDir dir;
belle_sip_refresher_t* refresher;
int ref;
SalOpType type;
SalPrivacyMask privacy;
belle_sip_header_event_t *event; /*used by SalOpSubscribe kinds*/
SalOpSDPHandling sdp_handling;
int auth_requests; /*number of auth requested for this op*/
bool_t cnx_ip_to_0000_if_sendonly_enabled;
bool_t auto_answer_asked;
bool_t sdp_offering;
bool_t call_released;
bool_t manual_refresher;
bool_t has_auth_pending;
bool_t supports_session_timers;
bool_t op_released;
};
belle_sdp_session_description_t * media_description_to_sdp(const SalMediaDescription *sal);
belle_sdp_session_description_t * media_description_to_sdp(const SalMediaDescription *desc);
int sdp_to_media_description(belle_sdp_session_description_t *sdp, SalMediaDescription *desc);
belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method);
void sal_op_call_fill_cbs(SalOp*op);
void set_or_update_dialog(SalOp* op, belle_sip_dialog_t* dialog);
/*return reffed op*/
SalOp* sal_op_ref(SalOp* op);
/*return null, destroy op if ref count =0*/
void* sal_op_unref(SalOp* op);
void sal_op_release_impl(SalOp *op);
void sal_op_set_replaces(SalOp* op,belle_sip_header_replaces_t* replaces);
void sal_op_set_remote_ua(SalOp*op,belle_sip_message_t* message);
int sal_op_send_request(SalOp* op, belle_sip_request_t* request);
int sal_op_send_request_with_expires(SalOp* op, belle_sip_request_t* request,int expires);
void sal_op_resend_request(SalOp* op, belle_sip_request_t* request);
int sal_op_send_and_create_refresher(SalOp* op,belle_sip_request_t* req, int expires,belle_sip_refresher_listener_t listener );
belle_sip_response_t *sal_op_create_response_from_request(SalOp *op, belle_sip_request_t *req, int code);
/*
* return true if both from and to uri are sips
* */
bool_t sal_op_is_secure(const SalOp* op);
void sal_process_authentication(SalOp *op);
belle_sip_header_contact_t* sal_op_create_contact(SalOp *op) ;
bool_t _sal_compute_sal_errors(belle_sip_response_t* response, SalReason* sal_reason, char* reason, size_t reason_size);
SalReason _sal_reason_from_sip_code(int code);
void sal_op_set_reason_error_info(SalOp *op, belle_sip_message_t *msg);
void sal_op_set_error_info_from_response(SalOp *op, belle_sip_response_t *response);
/*presence*/
void sal_op_presence_fill_cbs(SalOp*op);
/*messaging*/
void sal_op_message_fill_cbs(SalOp*op);
void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *event);
void sal_op_subscribe_fill_cbs(SalOp*op);
/*call transfer*/
void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t *tr);
void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t *tr);
/*create SalAuthInfo by copying username and realm from suth event*/
SalAuthInfo* sal_auth_info_create(belle_sip_auth_event_t* event) ;
void sal_add_pending_auth(Sal *sal, SalOp *op);
void sal_remove_pending_auth(Sal *sal, SalOp *op);
void sal_add_presence_info(SalOp *op, belle_sip_message_t *notify, SalPresenceModel *presence);
belle_sip_response_t *sal_create_response_from_request(Sal *sal, belle_sip_request_t *req, int code);
void sal_op_assign_recv_headers(SalOp *op, belle_sip_message_t *incoming);
SalBodyHandler * sal_op_get_body_handler(SalOp *op, belle_sip_message_t *msg);
int sal_reason_to_sip_code(SalReason r);
void _sal_op_add_custom_headers(SalOp *op, belle_sip_message_t *msg);
SalSubscribeStatus belle_sip_message_get_subscription_state(const belle_sip_message_t *msg);
#endif /* SAL_IMPL_H_ */
This diff is collapsed.
This diff is collapsed.
/*
linphone
Copyright (C) 2012 Belledonne Communications, Grenoble, France
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "sal_impl.h"
#include "linphone/core.h"
#include "private.h"
#include <libxml/xmlwriter.h>
static void process_error( SalOp* op) {
if (op->dir == SalOpDirOutgoing) {
op->base.root->callbacks.message_delivery_update(op, SalMessageDeliveryFailed);
} else {
ms_warning("unexpected io error for incoming message on op [%p]",op);
}
op->state=SalOpStateTerminated;
}
static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
SalOp* op = (SalOp*)user_ctx;
sal_error_info_set(&op->error_info,SalReasonIOError, "SIP", 503,"IO Error",NULL);
process_error(op);
}
static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
SalOp* op=(SalOp*)user_ctx;
sal_error_info_set(&op->error_info,SalReasonRequestTimeout, "SIP", 408,"Request timeout",NULL);
process_error(op);
}
static void process_response_event(void *op_base, const belle_sip_response_event_t *event){
SalOp* op = (SalOp*)op_base;
int code = belle_sip_response_get_status_code(belle_sip_response_event_get_response(event));
SalMessageDeliveryStatus status;
sal_op_set_error_info_from_response(op,belle_sip_response_event_get_response(event));
if (code>=100 && code <200)
status=SalMessageDeliveryInProgress;
else if (code>=200 && code <300)
status=SalMessageDeliveryDone;
else
status=SalMessageDeliveryFailed;
op->base.root->callbacks.message_delivery_update(op,status);
}
static bool_t is_external_body(belle_sip_header_content_type_t* content_type) {
return strcmp("message",belle_sip_header_content_type_get_type(content_type))==0
&& strcmp("external-body",belle_sip_header_content_type_get_subtype(content_type))==0;
}
static void add_message_accept(SalOp *op, belle_sip_message_t *msg) {
bctbx_list_t *item;
const char *str;
char *old;
char *header = ms_strdup("xml/cipher, application/cipher.vnd.gsma.rcs-ft-http+xml");
for (item = op->base.root->supported_content_types; item != NULL; item = bctbx_list_next(item)) {
str = (const char *)bctbx_list_get_data(item);
old = header;
header = ms_strdup_printf("%s, %s", old, str);
ms_free(old);
}
belle_sip_message_add_header(msg, belle_sip_header_create("Accept", header));
ms_free(header);
}
void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *event){
belle_sip_request_t* req = belle_sip_request_event_get_request(event);
belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,req);
belle_sip_header_address_t* address;
belle_sip_header_from_t* from_header;
belle_sip_header_content_type_t* content_type;
belle_sip_response_t* resp;
int errcode = 500;
belle_sip_header_call_id_t* call_id = belle_sip_message_get_header_by_type(req,belle_sip_header_call_id_t);
belle_sip_header_cseq_t* cseq = belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
belle_sip_header_date_t *date=belle_sip_message_get_header_by_type(req,belle_sip_header_date_t);
char* from;
bool_t external_body=FALSE;
from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t);
content_type=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_content_type_t);
if (content_type) {
SalMessage salmsg;
char message_id[256]={0};
if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
op->pending_server_trans=server_transaction;
belle_sip_object_ref(op->pending_server_trans);
external_body=is_external_body(content_type);
address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address));
snprintf(message_id,sizeof(message_id)-1,"%s%i"
,belle_sip_header_call_id_get_call_id(call_id)
,belle_sip_header_cseq_get_seq_number(cseq));
salmsg.from=from;
/* if we just deciphered a message, use the deciphered part(which can be a rcs xml body pointing to the file to retreive from server)*/
salmsg.text=(!external_body)?belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)):NULL;
salmsg.url=NULL;
salmsg.content_type = ms_strdup_printf("%s/%s", belle_sip_header_content_type_get_type(content_type), belle_sip_header_content_type_get_subtype(content_type));
if (external_body && belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")) {
size_t url_length=strlen(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL"));
salmsg.url = ms_strdup(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")+1); /* skip first "*/
((char*)salmsg.url)[url_length-2]='\0'; /*remove trailing "*/
}
salmsg.message_id=message_id;
salmsg.time=date ? belle_sip_header_date_get_time(date) : time(NULL);
op->base.root->callbacks.message_received(op,&salmsg);
belle_sip_object_unref(address);
belle_sip_free(from);
if (salmsg.url) ms_free((char*)salmsg.url);
ms_free((char *)salmsg.content_type);
} else {
ms_error("Unsupported MESSAGE (no Content-Type)");
resp = belle_sip_response_create_from_request(req, errcode);
add_message_accept(op, (belle_sip_message_t*)resp);
belle_sip_server_transaction_send_response(server_transaction,resp);
sal_op_release(op);
}
}
static void process_request_event(void *op_base, const belle_sip_request_event_t *event) {
SalOp* op = (SalOp*)op_base;
sal_process_incoming_message(op,event);
}
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg, const char *peer_uri){
belle_sip_request_t* req;
char content_type_raw[256];
size_t content_length = msg?strlen(msg):0;
time_t curtime = ms_time(NULL);
const char *body;
int retval;
if (op->dialog){
/*for SIP MESSAGE that are sent in call's dialog*/
req=belle_sip_dialog_create_queued_request(op->dialog,"MESSAGE");
}else{
sal_op_message_fill_cbs(op);
if (from)
sal_op_set_from(op,from);
if (to)
sal_op_set_to(op,to);
op->dir=SalOpDirOutgoing;
req=sal_op_build_request(op,"MESSAGE");
if (req == NULL ){
return -1;
}
if (sal_op_get_contact_address(op)){
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op)));
}
}
snprintf(content_type_raw,sizeof(content_type_raw),BELLE_SIP_CONTENT_TYPE ": %s",content_type);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_type_parse(content_type_raw)));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_length)));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime)));
body = msg;
if (body){
/*don't call set_body() with null argument because it resets content type and content length*/
belle_sip_message_set_body(BELLE_SIP_MESSAGE(req), body, content_length);
}
retval = sal_op_send_request(op,req);
return retval;
}
int sal_message_reply(SalOp *op, SalReason reason){
if (op->pending_server_trans){
int code=sal_reason_to_sip_code(reason);
belle_sip_response_t *resp = belle_sip_response_create_from_request(
belle_sip_transaction_get_request((belle_sip_transaction_t*)op->pending_server_trans),code);
belle_sip_server_transaction_send_response(op->pending_server_trans,resp);
return 0;
}else ms_error("sal_message_reply(): no server transaction");
return -1;
}
int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg) {
return sal_message_send(op,from,to,"text/plain",msg, NULL);
}
static belle_sip_listener_callbacks_t op_message_callbacks={0};
void sal_op_message_fill_cbs(SalOp*op) {
if (op_message_callbacks.process_io_error==NULL){
op_message_callbacks.process_io_error=process_io_error;
op_message_callbacks.process_response_event=process_response_event;
op_message_callbacks.process_timeout=process_timeout;
op_message_callbacks.process_request_event=process_request_event;
}
op->callbacks=&op_message_callbacks;
op->type=SalOpMessage;
}
/*
linphone
Copyright (C) 2012 Belledonne Communications, Grenoble, France
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.