Commit 86ade217 authored by Simon Morlat's avatar Simon Morlat

add two new methods to access pointers to transferer call and transfer target call.

parent b3c08e5d
......@@ -743,6 +743,15 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
sal_op_release(call->op);
call->op=NULL;
}
/*it is necessary to reset pointers to other call to prevent circular references that would result in memory never freed.*/
if (call->transferer){
linphone_call_unref(call->transferer);
call->transferer=NULL;
}
if (call->transfer_target){
linphone_call_unref(call->transfer_target);
call->transfer_target=NULL;
}
linphone_call_unref(call);
}
}
......@@ -773,6 +782,12 @@ static void linphone_call_destroy(LinphoneCall *obj)
if (obj->refer_to){
ms_free(obj->refer_to);
}
if (obj->transferer){
linphone_call_unref(obj->transferer);
}
if (obj->transfer_target){
linphone_call_unref(obj->transfer_target);
}
if (obj->owns_call_log)
linphone_call_log_destroy(obj->log);
if (obj->auth_token) {
......@@ -940,6 +955,21 @@ const char *linphone_call_get_refer_to(const LinphoneCall *call){
return call->refer_to;
}
/**
* Returns the transferer if this call was started automatically as a result of an incoming transfer request.
* The call in which the transfer request was received is returned in this case.
**/
LinphoneCall *linphone_call_get_transferer_call(const LinphoneCall *call){
return call->transferer;
}
/**
* When this call has received a transfer request, returns the new call that was automatically created as a result of the transfer.
**/
LinphoneCall *linphone_call_get_transfer_target_call(const LinphoneCall *call){
return call->transfer_target;
}
/**
* Returns direction of the call (incoming or outgoing).
**/
......@@ -2468,6 +2498,10 @@ void linphone_call_log_completed(LinphoneCall *call){
call_logs_write_to_config_file(lc);
}
/**
* Returns the current transfer state, if a transfer has been initiated from this call.
* @see linphone_core_transfer_call() , linphone_core_transfer_call_to_another()
**/
LinphoneCallState linphone_call_get_transfer_state(LinphoneCall *call) {
return call->transfer_state;
}
......
......@@ -2333,7 +2333,10 @@ void linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call){
call->refer_pending=FALSE;
newcall=linphone_core_invite_with_params(lc,call->refer_to,cp);
linphone_call_params_destroy(cp);
if (newcall) linphone_core_notify_refer_state(lc,call,newcall);
if (newcall) {
call->transfer_target=linphone_call_ref(newcall);
linphone_core_notify_refer_state(lc,call,newcall);
}
}
}
......@@ -2670,6 +2673,10 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
linphone_call_unref(call);
return NULL;
}
if (params && params->referer){
call->transferer=linphone_call_ref(params->referer);
}
/* this call becomes now the current one*/
lc->current_call=call;
linphone_call_set_state (call,LinphoneCallOutgoingInit,"Starting outgoing call");
......@@ -2728,6 +2735,10 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
* @ingroup call_control
* The remote endpoint is expected to issue a new call to the specified destination.
* The current call remains active and thus can be later paused or terminated.
*
* It is possible to follow the progress of the transfer provided that transferee sends notification about it.
* In this case, the transfer_state_changed callback of the #LinphoneCoreVTable is invoked to notify of the state of the new call at the other party.
* The notified states are #LinphoneCallOutgoingInit , #LinphoneCallOutgoingProgress, #LinphoneCallOutgoingRinging and #LinphoneCallOutgoingConnected.
**/
int linphone_core_transfer_call(LinphoneCore *lc, LinphoneCall *call, const char *url)
{
......@@ -2764,6 +2775,10 @@ int linphone_core_transfer_call(LinphoneCore *lc, LinphoneCall *call, const char
* This method will send a transfer request to the transfered person. The phone of the transfered is then
* expected to automatically call to the destination of the transfer. The receiver of the transfer will then automatically
* close the call with us (the 'dest' call).
*
* It is possible to follow the progress of the transfer provided that transferee sends notification about it.
* In this case, the transfer_state_changed callback of the #LinphoneCoreVTable is invoked to notify of the state of the new call at the other party.
* The notified states are #LinphoneCallOutgoingInit , #LinphoneCallOutgoingProgress, #LinphoneCallOutgoingRinging and #LinphoneCallOutgoingConnected.
**/
int linphone_core_transfer_call_to_another(LinphoneCore *lc, LinphoneCall *call, LinphoneCall *dest){
int result = sal_call_refer_with_replaces (call->op,dest->op);
......@@ -3312,25 +3327,23 @@ int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *the_call)
call = the_call;
}
switch (call->state) {
case LinphoneCallReleased:
case LinphoneCallEnd:
ms_warning("No need to terminate a call [%p] in state [%s]",call,linphone_call_state_to_string(call->state));
return -1;
case LinphoneCallIncomingReceived:
case LinphoneCallIncomingEarlyMedia:
return linphone_core_decline_call(lc,call,LinphoneReasonDeclined);
case LinphoneCallOutgoingInit: {
/* In state OutgoingInit, op has to be destroyed */
sal_op_release(call->op);
call->op = NULL;
case LinphoneCallReleased:
case LinphoneCallEnd:
ms_warning("No need to terminate a call [%p] in state [%s]",call,linphone_call_state_to_string(call->state));
return -1;
case LinphoneCallIncomingReceived:
case LinphoneCallIncomingEarlyMedia:
return linphone_core_decline_call(lc,call,LinphoneReasonDeclined);
case LinphoneCallOutgoingInit: {
/* In state OutgoingInit, op has to be destroyed */
sal_op_release(call->op);
call->op = NULL;
break;
}
default:
sal_call_terminate(call->op);
break;
}
default:
sal_call_terminate(call->op);
break;
}
terminate_call(lc,call);
return 0;
}
......
......@@ -121,7 +121,9 @@ struct _LinphoneCall;
typedef struct _LinphoneCall LinphoneCall;
/**
* Enum describing failure reasons.
* Enum describing various failure reasons or contextual information for some events.
* @see linphone_call_get_reason()
* @see linphone_proxy_config_get_error()
* @ingroup misc
**/
enum _LinphoneReason{
......@@ -134,8 +136,7 @@ enum _LinphoneReason{
LinphoneReasonBusy, /**<Phone line was busy */
LinphoneReasonMedia, /**<Incompatible media */
LinphoneReasonIOError, /**<Transport error: connection failures, disconnections etc...*/
LinphoneReasonDoNotDisturb /*Do not disturb reason*/
LinphoneReasonDoNotDisturb /**<Do not disturb reason*/
};
/**
......@@ -533,7 +534,7 @@ typedef enum _LinphoneCallState{
LINPHONE_PUBLIC const char *linphone_call_state_to_string(LinphoneCallState cs);
LinphoneCore *linphone_call_get_core(const LinphoneCall *call);
LINPHONE_PUBLIC LinphoneCore *linphone_call_get_core(const LinphoneCall *call);
LINPHONE_PUBLIC LinphoneCallState linphone_call_get_state(const LinphoneCall *call);
bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call);
LINPHONE_PUBLIC const LinphoneAddress * linphone_core_get_current_call_remote_address(struct _LinphoneCore *lc);
......@@ -543,15 +544,17 @@ LINPHONE_PUBLIC LinphoneCallDir linphone_call_get_dir(const LinphoneCall *call);
LINPHONE_PUBLIC LinphoneCall * linphone_call_ref(LinphoneCall *call);
LINPHONE_PUBLIC void linphone_call_unref(LinphoneCall *call);
LINPHONE_PUBLIC LinphoneCallLog *linphone_call_get_call_log(const LinphoneCall *call);
const char *linphone_call_get_refer_to(const LinphoneCall *call);
bool_t linphone_call_has_transfer_pending(const LinphoneCall *call);
LINPHONE_PUBLIC const char *linphone_call_get_refer_to(const LinphoneCall *call);
LINPHONE_PUBLIC bool_t linphone_call_has_transfer_pending(const LinphoneCall *call);
LINPHONE_PUBLIC LinphoneCall *linphone_call_get_transferer_call(const LinphoneCall *call);
LINPHONE_PUBLIC LinphoneCall *linphone_call_get_transfer_target_call(const LinphoneCall *call);
LINPHONE_PUBLIC LinphoneCall *linphone_call_get_replaced_call(LinphoneCall *call);
LINPHONE_PUBLIC int linphone_call_get_duration(const LinphoneCall *call);
LINPHONE_PUBLIC const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call);
LINPHONE_PUBLIC const LinphoneCallParams * linphone_call_get_remote_params(LinphoneCall *call);
LINPHONE_PUBLIC void linphone_call_enable_camera(LinphoneCall *lc, bool_t enabled);
LINPHONE_PUBLIC bool_t linphone_call_camera_enabled(const LinphoneCall *lc);
int linphone_call_take_video_snapshot(LinphoneCall *call, const char *file);
LINPHONE_PUBLIC int linphone_call_take_video_snapshot(LinphoneCall *call, const char *file);
LINPHONE_PUBLIC LinphoneReason linphone_call_get_reason(const LinphoneCall *call);
LINPHONE_PUBLIC const char *linphone_call_get_remote_user_agent(LinphoneCall *call);
LINPHONE_PUBLIC const char *linphone_call_get_remote_contact(LinphoneCall *call);
......@@ -566,8 +569,8 @@ LINPHONE_PUBLIC void linphone_call_send_vfu_request(LinphoneCall *call);
LINPHONE_PUBLIC void *linphone_call_get_user_pointer(LinphoneCall *call);
LINPHONE_PUBLIC void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer);
LINPHONE_PUBLIC void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, LinphoneCallCbFunc cb, void* user_data);
LinphoneCallState linphone_call_get_transfer_state(LinphoneCall *call);
void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx, float* cy);
LINPHONE_PUBLIC LinphoneCallState linphone_call_get_transfer_state(LinphoneCall *call);
LINPHONE_PUBLIC void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx, float* cy);
LINPHONE_PUBLIC void linphone_call_start_recording(LinphoneCall *call);
LINPHONE_PUBLIC void linphone_call_stop_recording(LinphoneCall *call);
/**
......@@ -1152,7 +1155,7 @@ LINPHONE_PUBLIC int linphone_core_accept_call_with_params(LinphoneCore *lc, Linp
LINPHONE_PUBLIC int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *call);
int linphone_core_redirect_call(LinphoneCore *lc, LinphoneCall *call, const char *redirect_uri);
LINPHONE_PUBLIC int linphone_core_redirect_call(LinphoneCore *lc, LinphoneCall *call, const char *redirect_uri);
LINPHONE_PUBLIC int linphone_core_decline_call(LinphoneCore *lc, LinphoneCall * call, LinphoneReason reason);
......
......@@ -198,6 +198,8 @@ struct _LinphoneCall
int ping_time;
unsigned int remote_session_id;
unsigned int remote_session_ver;
LinphoneCall *transferer; /*if this call is the result of a transfer, transferer points to the call from which the transfer request was received.*/
LinphoneCall *transfer_target;/*if this call received a transfer request, then transfer_target points to the new call created to the refer target */
bool_t refer_pending;
bool_t media_pending;
bool_t audio_muted;
......
......@@ -938,6 +938,8 @@ static void simple_call_transfer(void) {
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc");
LinphoneCall* pauline_called_by_marie;
LinphoneCall *marie_calling_pauline;
LinphoneCall *marie_calling_laure;
char* laure_identity=linphone_address_as_string(laure->identity);
MSList* lcs=ms_list_append(NULL,marie->lc);
......@@ -946,6 +948,7 @@ static void simple_call_transfer(void) {
CU_ASSERT_TRUE(call(marie,pauline));
marie_calling_pauline=linphone_core_get_current_call(marie->lc);
pauline_called_by_marie=linphone_core_get_current_call(pauline->lc);
reset_counters(&marie->stat);
......@@ -961,6 +964,9 @@ static void simple_call_transfer(void) {
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallPaused,1,2000));
/*marie calling laure*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingProgress,1,2000));
CU_ASSERT_PTR_NOT_NULL(linphone_call_get_transfer_target_call(marie_calling_pauline));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,2000));
......@@ -970,6 +976,11 @@ static void simple_call_transfer(void) {
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000));
marie_calling_laure=linphone_core_get_current_call(marie->lc);
CU_ASSERT_PTR_NOT_NULL_FATAL(marie_calling_laure);
CU_ASSERT_TRUE(linphone_call_get_transferer_call(marie_calling_laure)==marie_calling_pauline);
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallConnected,1,2000));
/*terminate marie to pauline call*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment