From 1033e14618f4cc2334ede93f7042c4be73e1deb4 Mon Sep 17 00:00:00 2001 From: Andrea Gianarda <andrea.gianarda@belledonne-communications.com> Date: Tue, 7 Mar 2023 10:15:17 +0100 Subject: [PATCH] Rework tone manager: - Remove reason field from LinphoneToneDescription - Store tones by ID - choose tone based on the reason when a call ends --- coreapi/misc.c | 18 ++--- coreapi/private_functions.h | 2 +- coreapi/private_structs.h | 3 +- coreapi/tester_utils.cpp | 4 +- coreapi/tester_utils.h | 1 - include/linphone/core.h | 10 --- include/linphone/types.h | 13 ++-- src/conference/session/tone-manager.cpp | 95 ++++++++++++------------- src/conference/session/tone-manager.h | 5 +- tester/call_single_tester.c | 26 +++---- tester/tester.c | 4 +- 11 files changed, 79 insertions(+), 102 deletions(-) diff --git a/coreapi/misc.c b/coreapi/misc.c index 4173fdcebc..8dfc242f52 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -624,12 +624,10 @@ LinphoneStatus linphone_core_migrate_to_multi_transport(LinphoneCore *lc) { return 0; } -LinphoneToneDescription * -linphone_tone_description_new(LinphoneReason reason, LinphoneToneID id, const char *audiofile) { - LinphoneToneDescription *obj = ms_new0(LinphoneToneDescription, 1); - obj->reason = reason; - obj->toneid = id; - obj->audiofile = audiofile ? ms_strdup(audiofile) : NULL; +LinphoneToneDescription * linphone_tone_description_new(LinphoneToneID id, const char *audiofile){ + LinphoneToneDescription *obj=ms_new0(LinphoneToneDescription,1); + obj->toneid=id; + obj->audiofile=audiofile ? ms_strdup(audiofile) : NULL; return obj; } @@ -638,12 +636,8 @@ void linphone_tone_description_destroy(LinphoneToneDescription *obj) { ms_free(obj); } -void linphone_core_set_call_error_tone(LinphoneCore *lc, LinphoneReason reason, const char *audiofile) { - L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().setTone(reason, LinphoneToneUndefined, audiofile); -} - -void linphone_core_set_tone(LinphoneCore *lc, LinphoneToneID id, const char *audiofile) { - L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().setTone(LinphoneReasonNone, id, audiofile); +void linphone_core_set_tone(LinphoneCore *lc, LinphoneToneID id, const char *audiofile){ + L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().setTone(id, audiofile); } const MSCryptoSuite *linphone_core_generate_srtp_crypto_suites_array_from_string(LinphoneCore *lc, const char *config) { diff --git a/coreapi/private_functions.h b/coreapi/private_functions.h index ef963d7b28..f6bb34c755 100644 --- a/coreapi/private_functions.h +++ b/coreapi/private_functions.h @@ -539,7 +539,7 @@ void _linphone_magic_search_notify_ldap_have_more_results(LinphoneMagicSearch *m const LinphoneParticipantImdnState * _linphone_participant_imdn_state_from_cpp_obj(const LinphonePrivate::ParticipantImdnState &state); -LinphoneToneDescription *linphone_tone_description_new(LinphoneReason reason, LinphoneToneID id, const char *audiofile); +LinphoneToneDescription * linphone_tone_description_new(LinphoneToneID id, const char *audiofile); void linphone_tone_description_destroy(LinphoneToneDescription *obj); void linphone_task_list_init(LinphoneTaskList *t); diff --git a/coreapi/private_structs.h b/coreapi/private_structs.h index c3be9c7206..be80264153 100644 --- a/coreapi/private_structs.h +++ b/coreapi/private_structs.h @@ -298,8 +298,7 @@ struct autoreplier_config { const char *message; /* the path of the file to be played */ }; -struct _LinphoneToneDescription { - LinphoneReason reason; /*the call error code*/ +struct _LinphoneToneDescription{ LinphoneToneID toneid; /*A tone type to play when this error arrives. This is played using tone generator*/ char *audiofile; /*An override audio file to play instead, when this error arrives*/ /*Note that some tones are not affected to any error, in which case it is affected LinphoneReasonNone*/ diff --git a/coreapi/tester_utils.cpp b/coreapi/tester_utils.cpp index 5e41807dfa..a12ef932f6 100644 --- a/coreapi/tester_utils.cpp +++ b/coreapi/tester_utils.cpp @@ -236,8 +236,8 @@ void linphone_core_reset_tone_manager_stats(LinphoneCore *lc) { L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().resetStats(); } -const char *linphone_core_get_tone_file(LinphoneCore *lc, LinphoneToneID id) { - LinphoneToneDescription *tone = L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().getToneFromId(id); +const char *linphone_core_get_tone_file(LinphoneCore *lc, LinphoneToneID id){ + LinphoneToneDescription *tone = L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().getTone(id); return tone ? tone->audiofile : NULL; } diff --git a/coreapi/tester_utils.h b/coreapi/tester_utils.h index 0c8b23fc7b..e9ea6c6401 100644 --- a/coreapi/tester_utils.h +++ b/coreapi/tester_utils.h @@ -66,7 +66,6 @@ typedef enum _LinphoneProxyConfigAddressComparisonResult { typedef struct _LinphoneCoreToneManagerStats { int number_of_startRingbackTone; int number_of_startRingtone; - int number_of_startErrorTone; int number_of_startNamedTone; int number_of_stopRingbackTone; int number_of_stopRingtone; diff --git a/include/linphone/core.h b/include/linphone/core.h index cd7879fe60..bf36edfba1 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -5180,16 +5180,6 @@ LINPHONE_PUBLIC void linphone_core_enable_sdp_200_ack(LinphoneCore *core, bool_t **/ LINPHONE_PUBLIC bool_t linphone_core_sdp_200_ack_enabled(const LinphoneCore *core); -/** - * Assign an audio file to be played locally upon call failure, for a given reason. - * @param core the core @notnil - * @param reason the #LinphoneReason representing the failure error code. - * @param audiofile a wav file to be played when such call failure happensd or NULL to disable it. @maybenil - * @ingroup misc - **/ -LINPHONE_PUBLIC void -linphone_core_set_call_error_tone(LinphoneCore *core, LinphoneReason reason, const char *audiofile); - /** * Assign an audio file to be played as a specific tone id. * This function typically allows to customize telephony tones per country. diff --git a/include/linphone/types.h b/include/linphone/types.h index f96f5a17ee..e2b3243429 100644 --- a/include/linphone/types.h +++ b/include/linphone/types.h @@ -1215,12 +1215,13 @@ typedef enum _LinphoneSubscriptionState { * @ingroup misc **/ typedef enum _LinphoneToneID { - LinphoneToneUndefined = 0, /**< Not a tone */ - LinphoneToneBusy = 1, /**< Busy tone */ - LinphoneToneCallWaiting = 2, /**< Call waiting tone */ - LinphoneToneCallOnHold = 3, /**< Call on hold tone */ - LinphoneToneCallLost = 4, /**< Tone played when call is abruptly disconnected (media lost)*/ - LinphoneToneCallEnd = 5 /**< When the call end for any reason but lost */ + LinphoneToneUndefined = 0, /**< Not a tone */ + LinphoneToneBusy = 1, /**< Busy tone */ + LinphoneToneCallWaiting = 2, /**< Call waiting tone */ + LinphoneToneCallOnHold = 3, /**< Call on hold tone */ + LinphoneToneCallLost = 4, /**< Tone played when call is abruptly disconnected (media lost)*/ + LinphoneToneCallEnd = 5, /**< When the call end for any reason but lost */ + LinphoneToneCallNotAnswered = 6 /**< When the call is not answered */ } LinphoneToneID; /** diff --git a/src/conference/session/tone-manager.cpp b/src/conference/session/tone-manager.cpp index 68575636f7..fb64cbf843 100644 --- a/src/conference/session/tone-manager.cpp +++ b/src/conference/session/tone-manager.cpp @@ -37,19 +37,14 @@ LINPHONE_BEGIN_NAMESPACE ToneManager::ToneManager(Core &core) : mCore(core) { lInfo() << "[ToneManager] create ToneManager()"; - mStats = {0, 0, 0, 0, 0, 0, 0}; + mStats = {0, 0, 0, 0, 0, 0}; /* Assign default tones */ - setTone(LinphoneReasonBusy, LinphoneToneBusy, NULL); - setTone(LinphoneReasonGone, LinphoneToneCallEnd, NULL); - setTone(LinphoneReasonNoResponse, LinphoneToneCallEnd, NULL); - setTone(LinphoneReasonDeclined, LinphoneToneCallEnd, NULL); - setTone(LinphoneReasonNone, LinphoneToneCallEnd, NULL); - setTone(LinphoneReasonTransferred, LinphoneToneCallEnd, NULL); - setTone(LinphoneReasonIOError, LinphoneToneCallLost, NULL); - setTone(LinphoneReasonNotAnswered, LinphoneToneCallLost, NULL); - setTone(LinphoneReasonServerTimeout, LinphoneToneCallLost, NULL); - setTone(LinphoneReasonUnknown, LinphoneToneCallLost, NULL); + setTone(LinphoneToneBusy, NULL); + setTone(LinphoneToneCallEnd, NULL); + setTone(LinphoneToneCallLost, NULL); + setTone(LinphoneToneCallNotAnswered, NULL); + setTone(LinphoneToneCallLost, NULL); } ToneManager::~ToneManager() { @@ -144,26 +139,10 @@ void ToneManager::stopRingtone() { } } -void ToneManager::startErrorTone(LinphoneReason reason) { - lInfo() << "[ToneManager] " << __func__; - mStats.number_of_startErrorTone++; - LinphoneToneDescription *tone = getToneFromReason(reason); - - if (tone) { - if (tone->audiofile) { - playFile(tone->audiofile); - } else if (tone->toneid != LinphoneToneUndefined) { - MSDtmfGenCustomTone dtmfTone = generateToneFromId(tone->toneid); - playTone(dtmfTone); - } - } -} - void ToneManager::startNamedTone(LinphoneToneID toneId) { lInfo() << "[ToneManager] " << __func__; mStats.number_of_startNamedTone++; - LinphoneToneDescription *tone = getToneFromId(toneId); - + LinphoneToneDescription *tone = getTone(toneId); if (tone && tone->audiofile) { playFile(tone->audiofile); } else { @@ -402,16 +381,7 @@ void ToneManager::freeAudioResources() { // setup tones // --------------------------------------------------- -LinphoneToneDescription *ToneManager::getToneFromReason(LinphoneReason reason) { - const bctbx_list_t *elem; - for (elem = getCore().getCCore()->tones; elem != NULL; elem = elem->next) { - LinphoneToneDescription *tone = (LinphoneToneDescription *)elem->data; - if (tone->reason == reason) return tone; - } - return NULL; -} - -LinphoneToneDescription *ToneManager::getToneFromId(LinphoneToneID id) { +LinphoneToneDescription *ToneManager::getTone(LinphoneToneID id) { const bctbx_list_t *elem; for (elem = getCore().getCCore()->tones; elem != NULL; elem = elem->next) { LinphoneToneDescription *tone = (LinphoneToneDescription *)elem->data; @@ -420,15 +390,14 @@ LinphoneToneDescription *ToneManager::getToneFromId(LinphoneToneID id) { return NULL; } -void ToneManager::setTone(LinphoneReason reason, LinphoneToneID id, const char *audiofile) { +void ToneManager::setTone(LinphoneToneID id, const char *audiofile) { LinphoneCore *lc = getCore().getCCore(); - LinphoneToneDescription *tone = getToneFromReason(reason); - + LinphoneToneDescription *tone = getTone(id); if (tone) { lc->tones = bctbx_list_remove(lc->tones, tone); linphone_tone_description_destroy(tone); } - tone = linphone_tone_description_new(reason, id, audiofile); + tone = linphone_tone_description_new(id, audiofile); lc->tones = bctbx_list_append(lc->tones, tone); } @@ -437,7 +406,7 @@ const LinphoneCoreToneManagerStats *ToneManager::getStats() const { } void ToneManager::resetStats() { - mStats = {0, 0, 0, 0, 0, 0, 0}; + mStats = {0, 0, 0, 0, 0, 0}; } MSDtmfGenCustomTone ToneManager::generateToneFromId(LinphoneToneID toneId) { @@ -458,11 +427,17 @@ MSDtmfGenCustomTone ToneManager::generateToneFromId(LinphoneToneID toneId) { def.interval = 2000; break; case LinphoneToneBusy: - def.duration = 500; - def.frequencies[0] = 440; - def.interval = 500; - def.repeat_count = 3; - break; + def.duration=500; + def.frequencies[0]=440; + def.interval=500; + def.repeat_count=3; + break; + case LinphoneToneCallNotAnswered: + def.duration=250; + def.frequencies[0]=440; + def.interval=250; + def.repeat_count=3; + break; case LinphoneToneCallLost: def.duration = 250; // def.frequencies[0]=480; // Second frequency that is hide @@ -566,7 +541,29 @@ void ToneManager::notifyOutgoingCallRinging(const std::shared_ptr<CallSession> & void ToneManager::notifyToneIndication(LinphoneReason reason) { if (!linphone_core_tone_indications_enabled(getCore().getCCore())) return; - startErrorTone(reason); + + lInfo() << "[ToneManager] " << __func__ << " reason " << std::string(linphone_reason_to_string(reason)); + + switch (reason) { + case LinphoneReasonUnknown: + case LinphoneReasonNone: + startNamedTone(LinphoneToneCallEnd); + break; + case LinphoneReasonNotAnswered: + startNamedTone(LinphoneToneCallNotAnswered); + break; + case LinphoneReasonBusy: + startNamedTone(LinphoneToneBusy); + break; + case LinphoneReasonTransferred: + case LinphoneReasonIOError: + case LinphoneReasonServerTimeout: + startNamedTone(LinphoneToneCallLost); + break; + default: + startNamedTone(LinphoneToneUndefined); + break; + } } bool ToneManager::inCallOrConference() const { diff --git a/src/conference/session/tone-manager.h b/src/conference/session/tone-manager.h index 79a7242793..aeb0361414 100644 --- a/src/conference/session/tone-manager.h +++ b/src/conference/session/tone-manager.h @@ -70,9 +70,8 @@ public: void resetStats(); // Tone configuration. - LinphoneToneDescription *getToneFromReason(LinphoneReason reason); - LinphoneToneDescription *getToneFromId(LinphoneToneID id); - void setTone(LinphoneReason reason, LinphoneToneID id, const char *audiofile); + LinphoneToneDescription *getTone(LinphoneToneID id); + void setTone(LinphoneToneID id, const char *audiofile); private: using AudioResourceType = enum { ToneGenerator = 0, LocalPlayer = 1 }; diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 093e30ab40..8ea5dba951 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -1290,8 +1290,9 @@ static void terminate_call_with_error(void) { LinphoneCoreManager *callee_mgr = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + const LinphoneCoreToneManagerStats *caller_tone_mgr_stats = linphone_core_get_tone_manager_stats(caller_mgr->lc); - LinphoneCall *out_call = linphone_core_invite_address(caller_mgr->lc, callee_mgr->identity); + LinphoneCall* out_call = linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity); linphone_call_ref(out_call); ei = linphone_error_info_new(); @@ -1318,9 +1319,10 @@ static void terminate_call_with_error(void) { BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(ei), "Call refused for security reason"); BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(ei), "SIP"); } - linphone_call_terminate_with_error_info(out_call, ei); - BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallEnd, 1)); - BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallReleased, 1)); + linphone_call_terminate_with_error_info(out_call,ei); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallEnd,1)); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallReleased,1)); + BC_ASSERT_EQUAL(caller_tone_mgr_stats->number_of_startNamedTone, caller_mgr->stat.number_of_LinphoneCallEnd, int, "%d"); rei = linphone_call_get_error_info(call_callee); BC_ASSERT_PTR_NOT_NULL(rei); @@ -1495,8 +1497,8 @@ static void cancel_other_device_after_decline(void) { BC_ASSERT_EQUAL(linphone_call_decline(call_callee, LinphoneReasonDeclined), 0, int, "%d"); BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_EQUAL(linphone_core_get_tone_manager_stats(caller_mgr->lc)->number_of_stopRingbackTone, 1, int, "%d"); - BC_ASSERT_EQUAL(linphone_core_get_tone_manager_stats(caller_mgr->lc)->number_of_startErrorTone, 1, int, "%d"); - BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallReleased, 1)); + BC_ASSERT_EQUAL(linphone_core_get_tone_manager_stats(caller_mgr->lc)->number_of_startNamedTone, 1, int, "%d"); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallReleased, 1)); BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_EQUAL(linphone_core_get_tone_manager_stats(callee_mgr->lc)->number_of_stopRingtone, 1, int, "%d"); @@ -1973,15 +1975,13 @@ static void call_declined_base(bool_t use_timeout, bool_t use_earlymedia, bool_t BC_ASSERT_EQUAL(marieToneManagerStats->number_of_stopRingtone, 1, int, "%d"); if (request_timeout || use_timeout) - BC_ASSERT_EQUAL(marieToneManagerStats->number_of_startErrorTone, 0, int, "%d"); + BC_ASSERT_EQUAL(marieToneManagerStats->number_of_startNamedTone, 0, int, "%d"); BC_ASSERT_EQUAL(paulineToneManagerStats->number_of_stopRingbackTone, 1, int, "%d"); - BC_ASSERT_EQUAL(paulineToneManagerStats->number_of_startErrorTone, 1, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallEnd, 1, int, "%d"); - BC_ASSERT_EQUAL((use_timeout || request_timeout) ? pauline->stat.number_of_LinphoneCallError - : pauline->stat.number_of_LinphoneCallEnd, - 1, int, "%d"); - BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, (int *)&paulineToneManagerStats->number_of_stopTone, 1)); + BC_ASSERT_EQUAL(paulineToneManagerStats->number_of_startNamedTone, 1, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallEnd,1, int, "%d"); + BC_ASSERT_EQUAL((use_timeout || request_timeout) ? pauline->stat.number_of_LinphoneCallError : pauline->stat.number_of_LinphoneCallEnd,1, int, "%d"); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc, (int*)&paulineToneManagerStats->number_of_stopTone, 1)); BC_ASSERT_EQUAL(linphone_call_get_reason(in_call), reason, int, "%d"); BC_ASSERT_EQUAL(linphone_call_log_get_status(linphone_call_get_call_log(in_call)), (use_timeout || request_timeout) ? LinphoneCallMissed : LinphoneCallDeclined, int, "%d"); diff --git a/tester/tester.c b/tester/tester.c index ee97e6ea88..f0e0c83661 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -4336,9 +4336,7 @@ bool_t call_with_params2(LinphoneCoreManager *caller_mgr, wait_for_until(callee_mgr->lc, caller_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallStreamsRunning, initial_callee.number_of_LinphoneCallStreamsRunning + 1, 2000); - BC_ASSERT_EQUAL(callee_stats->number_of_startErrorTone, - callee_mgr->stat.number_of_LinphoneCallEnd + callee_mgr->stat.number_of_LinphoneCallError, int, - "%d"); + BC_ASSERT_GREATER(callee_stats->number_of_startNamedTone, callee_mgr->stat.number_of_LinphoneCallEnd + callee_mgr->stat.number_of_LinphoneCallError, int, "%d"); /* The ringtone, if it has started, must have stopped. */ BC_ASSERT_EQUAL(callee_stats->number_of_startRingtone - initial_callee_stats.number_of_startRingtone, -- GitLab