Commit bee6752f authored by Simon Morlat's avatar Simon Morlat

add automatic tone user indications

parent 74edc292
...@@ -151,7 +151,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia ...@@ -151,7 +151,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
bool_t send_ringbacktone=FALSE; bool_t send_ringbacktone=FALSE;
if (call->audiostream==NULL){ if (call->audiostream==NULL){
/*this happens after pausing the call locally. The streams is destroyed and then we wait the 200Ok to recreate it*/ /*this happens after pausing the call locally. The streams are destroyed and then we wait the 200Ok to recreate them*/
linphone_call_init_media_streams (call); linphone_call_init_media_streams (call);
} }
if (call->state==LinphoneCallIncomingEarlyMedia && linphone_core_get_remote_ringback_tone (lc)!=NULL){ if (call->state==LinphoneCallIncomingEarlyMedia && linphone_core_get_remote_ringback_tone (lc)!=NULL){
...@@ -163,6 +163,9 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia ...@@ -163,6 +163,9 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
} }
linphone_call_start_media_streams(call,all_muted,send_ringbacktone); linphone_call_start_media_streams(call,all_muted,send_ringbacktone);
} }
if (call->state==LinphoneCallPausing && call->paused_by_app && ms_list_size(lc->calls)==1){
linphone_core_play_named_tone(lc,LinphoneToneCallOnHold);
}
} }
#if 0 #if 0
static bool_t is_duplicate_call(LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to){ static bool_t is_duplicate_call(LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to){
...@@ -654,6 +657,7 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de ...@@ -654,6 +657,7 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
} else if (sr == SalReasonBusy) { } else if (sr == SalReasonBusy) {
call->reason=LinphoneReasonBusy; call->reason=LinphoneReasonBusy;
linphone_call_set_state(call,LinphoneCallError,"User is busy."); linphone_call_set_state(call,LinphoneCallError,"User is busy.");
linphone_core_play_named_tone(lc,LinphoneToneBusy);
} else { } else {
linphone_call_set_state(call,LinphoneCallError,msg); linphone_call_set_state(call,LinphoneCallError,msg);
} }
...@@ -809,7 +813,7 @@ static void refer_received(Sal *sal, SalOp *op, const char *referto){ ...@@ -809,7 +813,7 @@ static void refer_received(Sal *sal, SalOp *op, const char *referto){
} }
if (call->state!=LinphoneCallPaused){ if (call->state!=LinphoneCallPaused){
ms_message("Automatically pausing current call to accept transfer."); ms_message("Automatically pausing current call to accept transfer.");
linphone_core_pause_call(lc,call); _linphone_core_pause_call(lc,call);
call->was_automatically_paused=TRUE; call->was_automatically_paused=TRUE;
/*then we will start the refered when the pause is accepted, in order to serialize transactions within the dialog. /*then we will start the refered when the pause is accepted, in order to serialize transactions within the dialog.
* Indeed we need to avoid to send a NOTIFY to inform about of state of the refered call while the pause isn't completed. * Indeed we need to avoid to send a NOTIFY to inform about of state of the refered call while the pause isn't completed.
......
...@@ -240,7 +240,7 @@ static int remove_from_conference(LinphoneCore *lc, LinphoneCall *call, bool_t a ...@@ -240,7 +240,7 @@ static int remove_from_conference(LinphoneCore *lc, LinphoneCall *call, bool_t a
err=linphone_core_update_call(lc,call,&call->params); err=linphone_core_update_call(lc,call,&call->params);
} else{ } else{
ms_message("Pausing call to actually remove from conference"); ms_message("Pausing call to actually remove from conference");
err=linphone_core_pause_call(lc,call); err=_linphone_core_pause_call(lc,call);
} }
return err; return err;
...@@ -339,7 +339,7 @@ int linphone_core_enter_conference(LinphoneCore *lc){ ...@@ -339,7 +339,7 @@ int linphone_core_enter_conference(LinphoneCore *lc){
return -1; return -1;
} }
if (lc->current_call != NULL) { if (lc->current_call != NULL) {
linphone_core_pause_call(lc, lc->current_call); _linphone_core_pause_call(lc, lc->current_call);
} }
LinphoneConference *conf=&lc->conf_ctx; LinphoneConference *conf=&lc->conf_ctx;
if (conf->local_participant==NULL) add_local_endpoint(conf,lc); if (conf->local_participant==NULL) add_local_endpoint(conf,lc);
......
...@@ -133,6 +133,9 @@ static void on_tone_received(void *data, MSFilter *f, unsigned int event_id, voi ...@@ -133,6 +133,9 @@ static void on_tone_received(void *data, MSFilter *f, unsigned int event_id, voi
static void ecc_play_tones(EcCalibrator *ecc){ static void ecc_play_tones(EcCalibrator *ecc){
MSDtmfGenCustomTone tone; MSDtmfGenCustomTone tone;
MSToneDetectorDef expected_tone; MSToneDetectorDef expected_tone;
memset(&tone,0,sizeof(tone));
memset(&expected_tone,0,sizeof(expected_tone));
ms_filter_set_notify_callback(ecc->det,on_tone_received,ecc); ms_filter_set_notify_callback(ecc->det,on_tone_received,ecc);
...@@ -161,7 +164,7 @@ static void ecc_play_tones(EcCalibrator *ecc){ ...@@ -161,7 +164,7 @@ static void ecc_play_tones(EcCalibrator *ecc){
/*play an initial tone to startup the audio playback/capture*/ /*play an initial tone to startup the audio playback/capture*/
tone.frequency=140; tone.frequencies[0]=140;
tone.duration=1000; tone.duration=1000;
tone.amplitude=0.5; tone.amplitude=0.5;
...@@ -172,17 +175,17 @@ static void ecc_play_tones(EcCalibrator *ecc){ ...@@ -172,17 +175,17 @@ static void ecc_play_tones(EcCalibrator *ecc){
/* play the three tones*/ /* play the three tones*/
tone.frequency=2000; tone.frequencies[0]=2000;
tone.duration=100; tone.duration=100;
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
ms_usleep(300000); ms_usleep(300000);
tone.frequency=2300; tone.frequencies[0]=2300;
tone.duration=100; tone.duration=100;
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
ms_usleep(300000); ms_usleep(300000);
tone.frequency=2500; tone.frequencies[0]=2500;
tone.duration=100; tone.duration=100;
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
ms_sleep(1); ms_sleep(1);
......
...@@ -2114,7 +2114,7 @@ static void linphone_core_disconnected(LinphoneCore *lc, LinphoneCall *call){ ...@@ -2114,7 +2114,7 @@ static void linphone_core_disconnected(LinphoneCore *lc, LinphoneCall *call){
if (from) if (from)
{ {
snprintf(temp,sizeof(temp),"Remote end %s seems to have disconnected, the call is going to be closed.",from); snprintf(temp,sizeof(temp),"Remote end %s seems to have disconnected, the call is going to be closed.",from);
free(from); ms_free(from);
} }
else else
{ {
...@@ -2123,6 +2123,7 @@ static void linphone_core_disconnected(LinphoneCore *lc, LinphoneCall *call){ ...@@ -2123,6 +2123,7 @@ static void linphone_core_disconnected(LinphoneCore *lc, LinphoneCall *call){
if (lc->vtable.display_warning!=NULL) if (lc->vtable.display_warning!=NULL)
lc->vtable.display_warning(lc,temp); lc->vtable.display_warning(lc,temp);
linphone_core_terminate_call(lc,call); linphone_core_terminate_call(lc,call);
linphone_core_play_named_tone(lc,LinphoneToneCallFailed);
} }
static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){
......
...@@ -2118,9 +2118,10 @@ void linphone_core_iterate(LinphoneCore *lc){ ...@@ -2118,9 +2118,10 @@ void linphone_core_iterate(LinphoneCore *lc){
ms_message("incoming call ringing for %i seconds",elapsed); ms_message("incoming call ringing for %i seconds",elapsed);
if (elapsed>lc->sip_conf.inc_timeout){ if (elapsed>lc->sip_conf.inc_timeout){
ms_message("incoming call timeout (%i)",lc->sip_conf.inc_timeout); ms_message("incoming call timeout (%i)",lc->sip_conf.inc_timeout);
LinphoneReason decline_reason=lc->current_call ? LinphoneReasonBusy : LinphoneReasonDeclined;
call->log->status=LinphoneCallMissed; call->log->status=LinphoneCallMissed;
call->reason=LinphoneReasonNotAnswered; call->reason=LinphoneReasonNotAnswered;
linphone_core_terminate_call(lc,call); linphone_core_decline_call(lc,call,decline_reason);
} }
} }
if (lc->sip_conf.in_call_timeout > 0 && elapsed>lc->sip_conf.in_call_timeout) { if (lc->sip_conf.in_call_timeout > 0 && elapsed>lc->sip_conf.in_call_timeout) {
...@@ -2754,7 +2755,7 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){ ...@@ -2754,7 +2755,7 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
}else{ }else{
/* else play a tone within the context of the current call */ /* else play a tone within the context of the current call */
call->ringing_beep=TRUE; call->ringing_beep=TRUE;
linphone_core_play_tone(lc); linphone_core_play_named_tone(lc,LinphoneToneCallWaiting);
} }
linphone_call_set_state(call,LinphoneCallIncomingReceived,"Incoming call"); linphone_call_set_state(call,LinphoneCallIncomingReceived,"Incoming call");
...@@ -3305,8 +3306,7 @@ bool_t linphone_core_in_call(const LinphoneCore *lc){ ...@@ -3305,8 +3306,7 @@ bool_t linphone_core_in_call(const LinphoneCore *lc){
* *
* @ingroup call_control * @ingroup call_control
**/ **/
LinphoneCall *linphone_core_get_current_call(const LinphoneCore *lc) LinphoneCall *linphone_core_get_current_call(const LinphoneCore *lc){
{
return lc->current_call; return lc->current_call;
} }
...@@ -3316,7 +3316,14 @@ LinphoneCall *linphone_core_get_current_call(const LinphoneCore *lc) ...@@ -3316,7 +3316,14 @@ LinphoneCall *linphone_core_get_current_call(const LinphoneCore *lc)
* *
* @ingroup call_control * @ingroup call_control
**/ **/
int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call) int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call){
int err=_linphone_core_pause_call(lc,call);
if (err==0) call->paused_by_app=TRUE;
return err;
}
/* Internal version that does not play tone indication*/
int _linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call)
{ {
const char *subject=NULL; const char *subject=NULL;
...@@ -3354,6 +3361,7 @@ int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call) ...@@ -3354,6 +3361,7 @@ int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call)
lc->vtable.display_status(lc,_("Pausing the current call...")); lc->vtable.display_status(lc,_("Pausing the current call..."));
if (call->audiostream || call->videostream) if (call->audiostream || call->videostream)
linphone_call_stop_media_streams (call); linphone_call_stop_media_streams (call);
call->paused_by_app=FALSE;
return 0; return 0;
} }
...@@ -3367,7 +3375,7 @@ int linphone_core_pause_all_calls(LinphoneCore *lc){ ...@@ -3367,7 +3375,7 @@ int linphone_core_pause_all_calls(LinphoneCore *lc){
LinphoneCall *call=(LinphoneCall *)elem->data; LinphoneCall *call=(LinphoneCall *)elem->data;
LinphoneCallState cs=linphone_call_get_state(call); LinphoneCallState cs=linphone_call_get_state(call);
if (cs==LinphoneCallStreamsRunning || cs==LinphoneCallPausedByRemote){ if (cs==LinphoneCallStreamsRunning || cs==LinphoneCallPausedByRemote){
linphone_core_pause_call(lc,call); _linphone_core_pause_call(lc,call);
} }
} }
return 0; return 0;
...@@ -3382,7 +3390,11 @@ void linphone_core_preempt_sound_resources(LinphoneCore *lc){ ...@@ -3382,7 +3390,11 @@ void linphone_core_preempt_sound_resources(LinphoneCore *lc){
current_call=linphone_core_get_current_call(lc); current_call=linphone_core_get_current_call(lc);
if(current_call != NULL){ if(current_call != NULL){
ms_message("Pausing automatically the current call."); ms_message("Pausing automatically the current call.");
linphone_core_pause_call(lc,current_call); _linphone_core_pause_call(lc,current_call);
}
if (lc->ringstream){
ring_stop(lc->ringstream);
lc->ringstream=NULL;
} }
} }
...@@ -4905,13 +4917,54 @@ void linphone_core_play_tone(LinphoneCore *lc){ ...@@ -4905,13 +4917,54 @@ void linphone_core_play_tone(LinphoneCore *lc){
ms_error("No dtmf generator at this time !"); ms_error("No dtmf generator at this time !");
return; return;
} }
memset(&def,0,sizeof(def));
def.duration=300; def.duration=300;
def.frequency=500; def.frequencies[0]=500;
def.amplitude=1; def.amplitude=1;
def.interval=2000; def.interval=2000;
ms_filter_call_method(f, MS_DTMF_GEN_PLAY_CUSTOM,&def); ms_filter_call_method(f, MS_DTMF_GEN_PLAY_CUSTOM,&def);
} }
void linphone_core_play_named_tone(LinphoneCore *lc, LinphoneToneID toneid){
if (linphone_core_tone_indications_enabled(lc)){
MSFilter *f=get_dtmf_gen(lc);
MSDtmfGenCustomTone def;
if (f==NULL){
ms_error("No dtmf generator at this time !");
return;
}
memset(&def,0,sizeof(def));
def.amplitude=1;
/*these are french tones, excepted the failed one, which is USA congestion tone (does not exist in France)*/
switch(toneid){
case LinphoneToneCallOnHold:
case LinphoneToneCallWaiting:
def.duration=300;
def.frequencies[0]=440;
def.interval=2000;
break;
case LinphoneToneBusy:
def.duration=500;
def.frequencies[0]=440;
def.interval=500;
def.repeat_count=3;
break;
case LinphoneToneCallFailed:
def.duration=250;
def.frequencies[0]=480;
def.frequencies[0]=620;
def.interval=250;
def.repeat_count=3;
break;
default:
ms_warning("Unhandled tone id.");
}
if (def.duration>0)
ms_filter_call_method(f, MS_DTMF_GEN_PLAY_CUSTOM,&def);
}
}
/** /**
* @ingroup media_parameters * @ingroup media_parameters
* *
......
...@@ -190,6 +190,7 @@ void lp_config_parse(LpConfig *lpconfig, FILE *file){ ...@@ -190,6 +190,7 @@ void lp_config_parse(LpConfig *lpconfig, FILE *file){
if (pos2-pos1>=0){ if (pos2-pos1>=0){
/* found a pair key,value */ /* found a pair key,value */
if (cur!=NULL){ if (cur!=NULL){
LpItem *item=lp_section_find_item(cur,key); LpItem *item=lp_section_find_item(cur,key);
if (item==NULL){ if (item==NULL){
...@@ -198,7 +199,7 @@ void lp_config_parse(LpConfig *lpconfig, FILE *file){ ...@@ -198,7 +199,7 @@ void lp_config_parse(LpConfig *lpconfig, FILE *file){
ms_free(item->value); ms_free(item->value);
item->value=strdup(pos1); item->value=strdup(pos1);
} }
/*printf("Found %s %s={%s}\n",cur->name,key,pos1);*/ /*ms_message("Found %s=%s",key,pos1);*/
}else{ }else{
ms_warning("found key,item but no sections"); ms_warning("found key,item but no sections");
} }
...@@ -212,6 +213,7 @@ void lp_config_parse(LpConfig *lpconfig, FILE *file){ ...@@ -212,6 +213,7 @@ void lp_config_parse(LpConfig *lpconfig, FILE *file){
LpConfig * lp_config_new(const char *filename){ LpConfig * lp_config_new(const char *filename){
LpConfig *lpconfig=lp_new0(LpConfig,1); LpConfig *lpconfig=lp_new0(LpConfig,1);
if (filename!=NULL){ if (filename!=NULL){
ms_message("Using (r/w) config information from %s", filename);
lpconfig->filename=ortp_strdup(filename); lpconfig->filename=ortp_strdup(filename);
lpconfig->file=fopen(filename,"rw"); lpconfig->file=fopen(filename,"rw");
if (lpconfig->file!=NULL){ if (lpconfig->file!=NULL){
...@@ -237,6 +239,7 @@ LpConfig * lp_config_new(const char *filename){ ...@@ -237,6 +239,7 @@ LpConfig * lp_config_new(const char *filename){
int lp_config_read_file(LpConfig *lpconfig, const char *filename){ int lp_config_read_file(LpConfig *lpconfig, const char *filename){
FILE* f=fopen(filename,"r"); FILE* f=fopen(filename,"r");
if (f!=NULL){ if (f!=NULL){
ms_message("Reading config information from %s", filename);
lp_config_parse(lpconfig,f); lp_config_parse(lpconfig,f);
fclose(f); fclose(f);
return 0; return 0;
......
...@@ -1005,6 +1005,9 @@ unsigned int linphone_core_get_audio_features(LinphoneCore *lc){ ...@@ -1005,6 +1005,9 @@ unsigned int linphone_core_get_audio_features(LinphoneCore *lc){
return ret; return ret;
} }
bool_t linphone_core_tone_indications_enabled(LinphoneCore*lc){
return lp_config_get_int(lc->config,"sound","tone_indications",1);
}
#ifdef HAVE_GETIFADDRS #ifdef HAVE_GETIFADDRS
......
...@@ -211,6 +211,7 @@ struct _LinphoneCall ...@@ -211,6 +211,7 @@ struct _LinphoneCall
bool_t was_automatically_paused; bool_t was_automatically_paused;
bool_t ping_replied; bool_t ping_replied;
bool_t record_active; bool_t record_active;
bool_t paused_by_app;
}; };
...@@ -678,6 +679,8 @@ void ec_calibrator_destroy(EcCalibrator *ecc); ...@@ -678,6 +679,8 @@ void ec_calibrator_destroy(EcCalibrator *ecc);
void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapsed); void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapsed);
void linphone_core_preempt_sound_resources(LinphoneCore *lc); void linphone_core_preempt_sound_resources(LinphoneCore *lc);
int _linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call);
/*conferencing subsystem*/ /*conferencing subsystem*/
void _post_configure_audio_stream(AudioStream *st, LinphoneCore *lc, bool_t muted); void _post_configure_audio_stream(AudioStream *st, LinphoneCore *lc, bool_t muted);
/* When a conference participant pause the conference he may send a music. /* When a conference participant pause the conference he may send a music.
...@@ -718,6 +721,15 @@ void linphone_chat_message_store_state(LinphoneChatMessage *msg); ...@@ -718,6 +721,15 @@ void linphone_chat_message_store_state(LinphoneChatMessage *msg);
void linphone_core_message_storage_init(LinphoneCore *lc); void linphone_core_message_storage_init(LinphoneCore *lc);
void linphone_core_message_storage_close(LinphoneCore *lc); void linphone_core_message_storage_close(LinphoneCore *lc);
typedef enum _LinphoneToneID{
LinphoneToneBusy,
LinphoneToneCallWaiting,
LinphoneToneCallOnHold,
LinphoneToneCallFailed
}LinphoneToneID;
void linphone_core_play_named_tone(LinphoneCore *lc, LinphoneToneID id);
bool_t linphone_core_tone_indications_enabled(LinphoneCore*lc);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
mediastreamer2 @ d1d3e1af
Subproject commit 28c3383b5e98196ab394f6616f11c195e6759d28 Subproject commit d1d3e1af51ab26ecb9808d6f83629e661c67af5f
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