From 598bafd4a8ec6541f67fb276c6e64d21193695fa Mon Sep 17 00:00:00 2001
From: Guillaume Beraudo <guillaume.beraudo@belledonne-communications.com>
Date: Thu, 27 Oct 2011 10:38:05 +0200
Subject: [PATCH] Function to check if a call locks sound resources.

Use to prevent a situation where several calls
try to use the sound resources.
- outgoing states (ring)
- incoming states (ring)
- ..
---
 coreapi/conference.c                          |  3 ++
 coreapi/linphonecore.c                        | 29 +++++++++++++++++++
 coreapi/linphonecore.h                        |  1 +
 coreapi/linphonecore_jni.cc                   |  4 +++
 .../org/linphone/core/LinphoneCore.java       |  9 ++++++
 5 files changed, 46 insertions(+)

diff --git a/coreapi/conference.c b/coreapi/conference.c
index 767eaf07da..94bf17bc17 100644
--- a/coreapi/conference.c
+++ b/coreapi/conference.c
@@ -189,6 +189,9 @@ int linphone_core_leave_conference(LinphoneCore *lc){
 
 
 int linphone_core_enter_conference(LinphoneCore *lc){
+	if (linphone_core_sound_resources_locked) {
+		return -1;
+	}
 	LinphoneConference *conf=&lc->conf_ctx;
 	if (conf->local_participant==NULL) add_local_endpoint(conf,lc);
 	return 0;
diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c
index 7e3a1f2620..66334ea0f4 100644
--- a/coreapi/linphonecore.c
+++ b/coreapi/linphonecore.c
@@ -4381,3 +4381,32 @@ const LinphoneCall* linphone_core_find_call_from_uri(LinphoneCore *lc, const cha
 	}
 	return NULL;
 }
+
+
+/**
+ * Check if a call will need the sound resources.
+ *
+ * @ingroup call_control
+ * @param lc The LinphoneCore
+**/
+bool_t linphone_core_sound_resources_locked(LinphoneCore *lc){
+	MSList *calls=lc->calls;
+	while(calls) {
+		LinphoneCall *c=(LinphoneCall*)calls->data;
+		calls=calls->next;
+		switch (c->state) {
+			case LinphoneCallOutgoingInit:
+			case LinphoneCallOutgoingProgress:
+			case LinphoneCallOutgoingRinging:
+			case LinphoneCallOutgoingEarlyMedia:
+			case LinphoneCallConnected:
+			case LinphoneCallRefered:
+			case LinphoneCallIncomingEarlyMedia:
+			case LinphoneCallUpdated:
+				return TRUE;
+			default:
+				break;
+		}
+	}
+	return FALSE;
+}
diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h
index a85855def0..0f49a4593e 100644
--- a/coreapi/linphonecore.h
+++ b/coreapi/linphonecore.h
@@ -1031,6 +1031,7 @@ int linphone_core_terminate_conference(LinphoneCore *lc);
 int linphone_core_get_conference_size(LinphoneCore *lc);
 
 int linphone_core_get_max_calls(LinphoneCore *lc);
+bool_t linphone_core_sound_resources_locked(LinphoneCore *lc);
 
 #ifdef __cplusplus
 }
diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc
index f12a95d90d..6da09ef6b9 100644
--- a/coreapi/linphonecore_jni.cc
+++ b/coreapi/linphonecore_jni.cc
@@ -1506,6 +1506,10 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_areStreamsEncrypted(
 	return linphone_call_are_all_streams_encrypted((LinphoneCall *) ptr);
 }
 
+extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_soundResourcesLocked(JNIEnv* env,jobject thiz,jlong ptr){
+	return linphone_core_sound_resources_locked((LinphoneCore *) ptr);
+}
+
 // Needed by Galaxy S (can't switch to/from speaker while playing and still keep mic working)
 // Implemented directly in msandroid.cpp (sound filters for Android).
 extern "C" void msandroid_hack_speaker_state(bool speakerOn);
diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java
index 0d560f4e26..fcd041dc8a 100644
--- a/java/common/org/linphone/core/LinphoneCore.java
+++ b/java/common/org/linphone/core/LinphoneCore.java
@@ -625,4 +625,13 @@ public interface LinphoneCore {
 	int getMaxCalls();
 	boolean isMyself(String uri);
 
+	/**
+	 * Use this method to check the calls state and forbid proposing actions
+	 * which could result in an active call.
+	 * Eg: don't start a new call if one is in outgoing ringing.
+	 * Eg: don't merge to conference either as it could result
+	 *     in two active calls (conference and accepted call). 
+	 * @return
+	 */
+	boolean soundResourcesLocked();
 }
-- 
GitLab