diff --git a/console/commands.c b/console/commands.c index d953878..73e1b2b 100644 --- a/console/commands.c +++ b/console/commands.c @@ -542,8 +542,8 @@ lpc_cmd_answer(LinphoneCore *lc, char *args) if (!args) { - //TODO if just one call is present answer the only one ... - if ( -1 == linphone_core_accept_call(lc, linphone_core_get_current_call(lc)) )//TODO is there any current call here=> nope + //if just one call is present answer the only one in passing NULL to the linphone_core_accept_call ... + if ( -1 == linphone_core_accept_call(lc, NULL) ) { linphonec_out("No incoming call.\n"); } diff --git a/console/linphonec.c b/console/linphonec.c index 18a78c1..86187ad 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -113,9 +113,11 @@ static char **linephonec_readline_completion(const char *text, /* These are callback for linphone core */ static void linphonec_call_received(LinphoneCore *lc, LinphoneCall *call); +static void linphonec_paused_received(LinphoneCore *lc, LinphoneCall *call); +static void linphonec_resumed_received(LinphoneCore *lc, LinphoneCall *call); static void linphonec_prompt_for_auth(LinphoneCore *lc, const char *realm, const char *username); -static void linphonec_display_refer (LinphoneCore * lc,const char *refer_to); +static void linphonec_display_refer (LinphoneCore * lc,LinphoneCall *call, const char *refer_to); static void linphonec_display_something (LinphoneCore * lc, const char *something); static void linphonec_display_url (LinphoneCore * lc, const char *something, const char *url); static void linphonec_display_warning (LinphoneCore * lc, const char *something); @@ -131,6 +133,7 @@ static void linphonec_display_status (LinphoneCore * lc, const char *something); static void linphonec_general_state (LinphoneCore * lc, LinphoneGeneralState *gstate); static void linphonec_dtmf_received(LinphoneCore *lc, int dtmf); static void print_prompt(LinphoneCore *opm); +void linphonec_out(const char *fmt,...); /*************************************************************************** * * Global variables @@ -176,6 +179,11 @@ LinphoneCoreVTable linphonec_vtable .show =(ShowInterfaceCb) stub, .inv_recv = linphonec_call_received, .bye_recv = linphonec_bye_received, + .ringing_recv = (RingingReceivedCb) stub, + .connected_recv = (ConnectedReceivedCb) stub, + .failure_recv = (FailureReceivedCb) stub, + .paused_recv = linphonec_paused_received, + .resumed_recv = linphonec_resumed_received, .notify_recv = linphonec_notify_received, .notify_presence_recv = linphonec_notify_presence_received, .new_unknown_subscriber = linphonec_new_unknown_subscriber, @@ -209,7 +217,7 @@ LinphoneCoreVTable linphonec_vtable * Linphone core callback */ static void -linphonec_display_refer (LinphoneCore * lc,const char *refer_to) +linphonec_display_refer (LinphoneCore * lc,LinphoneCall *call, const char *refer_to) { fprintf (stdout, "The distant end point asked to transfer the call to %s,don't forget to terminate the call if not\n%s", refer_to,prompt); fflush(stdout); @@ -268,6 +276,34 @@ linphonec_call_received(LinphoneCore *lc, LinphoneCall *call) answer_call=TRUE; } } +/* + * Linphone core callback + */ +static void +linphonec_paused_received(LinphoneCore *lc, LinphoneCall *call) +{ + char *from=linphone_call_get_remote_address_as_string(call); + if(from) + { + linphonec_out("the call from %s have been paused\n",from); + ms_free(from); + } +} +/* + * Linphone core callback + */ +static void +linphonec_resumed_received(LinphoneCore *lc, LinphoneCall *call) +{ + char *from=linphone_call_get_remote_address_as_string(call); + if(from) + { + linphonec_out("the call from %s have been resumed\n",from); + ms_free(from); + } +} + + /* * Linphone core callback diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 0f1dc41..cb9999a 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -30,6 +30,8 @@ static void linphone_connect_incoming(LinphoneCore *lc, LinphoneCall *call){ lc->vtable.show(lc); if (lc->vtable.display_status) lc->vtable.display_status(lc,_("Connected.")); + if (lc->vtable.connected_recv) + lc->vtable.connected_recv(lc,call); call->state=LinphoneCallAVRunning; if (lc->ringstream!=NULL){ ring_stop(lc->ringstream); @@ -130,6 +132,8 @@ static void call_ringing(SalOp *h){ if (call==NULL) return; if (lc->vtable.display_status) lc->vtable.display_status(lc,_("Remote ringing.")); + if (lc->vtable.ringing_recv) + lc->vtable.ringing_recv(lc,call); md=sal_call_get_final_media_description(h); if (md==NULL){ if (lc->ringstream!=NULL) return; /*already ringing !*/ @@ -233,16 +237,40 @@ static void call_ack(SalOp *op){ static void call_updated(SalOp *op){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); - if(call == linphone_core_get_current_call(lc)) - { - linphone_core_stop_media_streams(lc,call); - linphone_core_init_media_streams(lc,call); - } if (call->resultdesc) sal_media_description_unref(call->resultdesc); call->resultdesc=sal_call_get_final_media_description(op); - if (call->resultdesc && !sal_media_description_empty(call->resultdesc)){ - linphone_connect_incoming(lc,call); + if (call->resultdesc && !sal_media_description_empty(call->resultdesc)) + { + if( (call->state == LinphoneCallPaused) && strcmp(call->resultdesc->addr,"0.0.0.0")) + { + if(lc->vtable.display_status) + lc->vtable.display_status(lc,"we have been resumed..."); + call->state = LinphoneCallAVRunning; + lc->vtable.resumed_recv(lc,call); + linphone_core_start_media_streams(lc,call); + } + else if( (call->state != LinphoneCallPaused) && !strcmp(call->resultdesc->addr,"0.0.0.0")) + { + if(lc->vtable.display_status) + lc->vtable.display_status(lc,"we have been paused..."); + call->state = LinphoneCallPaused; + lc->vtable.paused_recv(lc,call); + if(call == linphone_core_get_current_call(lc)) + { + linphone_core_stop_media_streams(lc,call); + linphone_core_init_media_streams(lc,call); + } + } + else + { + if(call == linphone_core_get_current_call(lc)) + { + linphone_core_stop_media_streams(lc,call); + linphone_core_init_media_streams(lc,call); + } + linphone_connect_incoming(lc,call); + } } } @@ -276,7 +304,7 @@ static void call_terminated(SalOp *op, const char *from){ linphone_call_unref(call); } -static void call_failure(SalOp *op, SalError error, SalReason sr, const char *details){ +static void call_failure(SalOp *op, SalError error, SalReason sr, const char *details, int code){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); char *msg486=_("User is busy."); char *msg480=_("User is temporarily unavailable."); @@ -336,6 +364,8 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de lc->vtable.display_status(lc,_("Call failed.")); } } + if (lc->vtable.failure_recv) + lc->vtable.failure_recv(lc,call,code); if (lc->ringstream!=NULL) { ring_stop(lc->ringstream); lc->ringstream=NULL; @@ -415,8 +445,9 @@ static void dtmf_received(SalOp *op, char dtmf){ static void refer_received(Sal *sal, SalOp *op, const char *referto){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal); + LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); if (lc->vtable.refer_received){ - lc->vtable.refer_received(lc,referto); + lc->vtable.refer_received(lc,call,referto); if (op) sal_refer_accept(op); } } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index f9d3f29..d21b81c 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1574,6 +1574,8 @@ LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url) lc->vtable.display_status(lc,_("Looking for telephone number destination...")); if (enum_lookup(enum_domain,&enumres)<0){ lc->vtable.display_status(lc,_("Could not resolve this number.")); + if(lc->vtable.failure_recv) + lc->vtable.failure_recv(lc,NULL,400); ms_free(enum_domain); return NULL; } @@ -2205,7 +2207,11 @@ int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call) const char *contact=NULL; if (call==NULL){ - return -1; + //if just one call is present answer the only one ... + if(ms_list_size(linphone_core_get_calls(lc)) != 1) + return -1; + else + call = linphone_core_get_calls(lc)->data; } if (call->state==LinphoneCallAVRunning){ diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index fc735fd..5c25073 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -398,6 +398,16 @@ typedef void (*InviteReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call); /** Callback prototype */ typedef void (*ByeReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call); /** Callback prototype */ +typedef void (*RingingReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call); +/** Callback prototype */ +typedef void (*ConnectedReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call); +/** Callback prototype */ +typedef void (*FailureReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call, int error_code); +/** Callback prototype */ +typedef void (*PausedReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call); +/** Callback prototype */ +typedef void (*ResumedReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call); +/** Callback prototype */ typedef void (*DisplayStatusCb)(struct _LinphoneCore *lc, const char *message); /** Callback prototype */ typedef void (*DisplayMessageCb)(struct _LinphoneCore *lc, const char *message); @@ -424,7 +434,7 @@ typedef void (*GeneralStateChange)(struct _LinphoneCore *lc, LinphoneGeneralStat /** Callback prototype */ typedef void (*DtmfReceived)(struct _LinphoneCore* lc, int dtmf); /** Callback prototype */ -typedef void (*ReferReceived)(struct _LinphoneCore *lc, const char *refer_to); +typedef void (*ReferReceived)(struct _LinphoneCore *lc, LinphoneCall *call, const char *refer_to); /** Callback prototype */ typedef void (*BuddyInfoUpdated)(struct _LinphoneCore *lc, LinphoneFriend *lf); @@ -437,6 +447,11 @@ typedef struct _LinphoneVTable ShowInterfaceCb show; /**< Notifies the application that it should show up*/ InviteReceivedCb inv_recv; /**< Notifies incoming calls */ ByeReceivedCb bye_recv; /**< Notify calls terminated by far end*/ + RingingReceivedCb ringing_recv; /**< Notify that the distant phone is ringing*/ + ConnectedReceivedCb connected_recv; /**< Notify that the distant phone answered the call*/ + FailureReceivedCb failure_recv; /**< Notify that the call failed*/ + PausedReceivedCb paused_recv; /**< Notify that the call failed*/ + ResumedReceivedCb resumed_recv; /**< Notify that the call failed*/ NotifyPresenceReceivedCb notify_presence_recv; /**< Notify received presence events*/ NewUnknownSubscriberCb new_unknown_subscriber; /**< Notify about unknown subscriber */ AuthInfoRequested auth_info_requested; /**< Ask the application some authentication information */ diff --git a/coreapi/sal.h b/coreapi/sal.h index 8aedd44..7643ab7 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -177,7 +177,7 @@ typedef void (*SalOnCallAccepted)(SalOp *op); typedef void (*SalOnCallAck)(SalOp *op); typedef void (*SalOnCallUpdated)(SalOp *op); typedef void (*SalOnCallTerminated)(SalOp *op, const char *from); -typedef void (*SalOnCallFailure)(SalOp *op, SalError error, SalReason reason, const char *details); +typedef void (*SalOnCallFailure)(SalOp *op, SalError error, SalReason reason, const char *details, int code); typedef void (*SalOnAuthRequested)(SalOp *op, const char *realm, const char *username); typedef void (*SalOnAuthSuccess)(SalOp *op, const char *realm, const char *username); typedef void (*SalOnRegisterSuccess)(SalOp *op, bool_t registered); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 7c4a24d..94a51fa 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -915,7 +915,7 @@ static void call_released(Sal *sal, eXosip_event_t *ev){ } op->cid=-1; if (op->did==-1) - sal->callbacks.call_failure(op,SalErrorNoResponse,SalReasonUnknown,NULL); + sal->callbacks.call_failure(op,SalErrorNoResponse,SalReasonUnknown,NULL, 487); } static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){ @@ -1066,7 +1066,7 @@ static bool_t call_failure(Sal *sal, eXosip_event_t *ev){ sr=SalReasonUnknown; }else error=SalErrorNoResponse; } - sal->callbacks.call_failure(op,error,sr,reason); + sal->callbacks.call_failure(op,error,sr,reason,code); return TRUE; }