From c6bd038a6d2dcb179f643eaae6bcb8daf34a0976 Mon Sep 17 00:00:00 2001
From: Simon Morlat <simon.morlat@linphone.org>
Date: Tue, 27 Nov 2012 14:44:07 +0100
Subject: [PATCH] implement manual low banwdwidth mode. It is also possible to
 check whether peer is under low bandwidth by looking into the
 linphone_call_get_remote_params()

---
 coreapi/linphonecall.c | 31 ++++++++++++++++++++++++++++---
 coreapi/linphonecore.h |  9 ++-------
 coreapi/misc.c         | 24 +++++++++++++++++-------
 coreapi/private.h      |  3 ++-
 4 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c
index aa5075ddf3..089e7b809f 100644
--- a/coreapi/linphonecall.c
+++ b/coreapi/linphonecall.c
@@ -219,9 +219,7 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
 	SalMediaDescription *md=sal_media_description_new();
 	bool_t keep_srtp_keys=lp_config_get_int(lc->config,"sip","keep_srtp_keys",0);
 	
-	if (call->ping_time>0) {
-		linphone_core_adapt_to_network(lc,call->ping_time,&call->params);
-	}
+	linphone_core_adapt_to_network(lc,call->ping_time,&call->params);
 
 	md->session_id=(old_md ? old_md->session_id : (rand() & 0xfff));
 	md->session_ver=(old_md ? (old_md->session_ver+1) : (rand() & 0xfff));
@@ -746,6 +744,11 @@ const LinphoneCallParams * linphone_call_get_remote_params(LinphoneCall *call){
 			}else if (vsd){
 				cp->has_video=is_video_active(vsd);
 			}
+			if (!cp->has_video){
+				if (md->bandwidth>0 && md->bandwidth<=linphone_core_get_edge_bw(call->core)){
+					cp->low_bandwidth=TRUE;
+				}
+			}
 			return cp;
 		}
 	}
@@ -925,9 +928,31 @@ const PayloadType* linphone_call_params_get_used_video_codec(const LinphoneCallP
 	return cp->video_codec;
 }
 
+/**
+ * @ingroup call_control
+ * Use to know if this call has been configured in low bandwidth mode.
+ * This mode can be automatically discovered thanks to a stun server when activate_edge_workarounds=1 in section [net] of configuration file.
+ * An application that would have reliable way to know network capacity may not use activate_edge_workarounds=1 but instead manually configure
+ * low bandwidth mode with linphone_call_params_enable_low_bandwidth().
+ * <br> When enabled, this param may transform a call request with video in audio only mode.
+ * @return TRUE if low bandwidth has been configured/detected
+ */
 bool_t linphone_call_params_low_bandwidth_enabled(const LinphoneCallParams *cp) {
 	return cp->low_bandwidth;
 }
+
+/**
+ * @ingroup call_control
+ * Indicate low bandwith mode. 
+ * Configuring a call to low bandwidth mode will result in the core to activate several settings for the call in order to ensure that bitrate usage
+ * is lowered to the minimum possible. Typically, ptime (packetization time) will be increased, audio codec's output bitrate will be targetted to 20kbit/s provided
+ * that it is achievable by the codec selected after SDP handshake. Video is automatically disabled.
+ * 
+**/
+void linphone_call_params_enable_low_bandwidth(LinphoneCallParams *cp, bool_t enabled){
+	cp->low_bandwidth=TRUE;
+}
+
 /**
  * Returns whether video is enabled.
 **/
diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h
index f0cf695321..771ddff64e 100644
--- a/coreapi/linphonecore.h
+++ b/coreapi/linphonecore.h
@@ -204,14 +204,9 @@ bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams
 bool_t linphone_call_params_local_conference_mode(const LinphoneCallParams *cp);
 void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int bw);
 void linphone_call_params_destroy(LinphoneCallParams *cp);
-/**
- * @ingroup call_control
- * Use to know if this call has been configured in low bandwidth mode.
- * This mode can be automatically discovered thanks to a stun server when activate_edge_workarounds=1 in section [net] of configuration file
- * <br> When enabled, this param may transform a call request with video in audio only mode.
- * @return TRUE if low bandwidth has been configured/detected
- */
 bool_t linphone_call_params_low_bandwidth_enabled(const LinphoneCallParams *cp);
+void linphone_call_params_enable_low_bandwidth(LinphoneCallParams *cp, bool_t enabled);
+
 /**
  * Enum describing failure reasons.
  * @ingroup initializing
diff --git a/coreapi/misc.c b/coreapi/misc.c
index b9176ebd4a..d757221382 100644
--- a/coreapi/misc.c
+++ b/coreapi/misc.c
@@ -574,21 +574,31 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
 	return -1;
 }
 
+int linphone_core_get_edge_bw(LinphoneCore *lc){
+	int edge_bw=lp_config_get_int(lc->config,"net","edge_bw",20);
+	return edge_bw;
+}
+
+int linphone_core_get_edge_ptime(LinphoneCore *lc){
+	int edge_ptime=lp_config_get_int(lc->config,"net","edge_ptime",100);
+	return edge_ptime;
+}
+
 void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params){
-	if (lp_config_get_int(lc->config,"net","activate_edge_workarounds",0)==1){
+	if (ping_time_ms>0 && lp_config_get_int(lc->config,"net","activate_edge_workarounds",0)==1){
 		ms_message("Stun server ping time is %i ms",ping_time_ms);
 		int threshold=lp_config_get_int(lc->config,"net","edge_ping_time",500);
 		
 		if (ping_time_ms>threshold){
-			int edge_ptime=lp_config_get_int(lc->config,"net","edge_ptime",100);
-			int edge_bw=lp_config_get_int(lc->config,"net","edge_bw",20);
-			/* we are in a 2G network*/
-			params->up_bw=params->down_bw=edge_bw;
-			params->up_ptime=params->down_ptime=edge_ptime;
-			params->has_video=FALSE;
+			/* we might be in a 2G network*/
 			params->low_bandwidth=TRUE;
 		}/*else use default settings */
 	}
+	if (params->low_bandwidth){
+		params->up_bw=params->down_bw=linphone_core_get_edge_bw(lc);
+		params->up_ptime=params->down_ptime=linphone_core_get_edge_ptime(lc);
+		params->has_video=FALSE;
+	}
 }
 
 
diff --git a/coreapi/private.h b/coreapi/private.h
index 5ebe8b5b76..925a303605 100644
--- a/coreapi/private.h
+++ b/coreapi/private.h
@@ -639,7 +639,8 @@ void _linphone_core_codec_config_write(LinphoneCore *lc);
 #endif
 void call_logs_write_to_config_file(LinphoneCore *lc);
 
-
+int linphone_core_get_edge_bw(LinphoneCore *lc);
+int linphone_core_get_edge_ptime(LinphoneCore *lc);
 
 #ifdef __cplusplus
 }
-- 
GitLab