From bdc788f39ead38b27cb0c0d4a58fd7e1a123fd36 Mon Sep 17 00:00:00 2001
From: Nathan Neulinger <nneul@neulinger.org>
Date: Mon, 17 Feb 2014 13:24:52 -0600
Subject: [PATCH] FS-6231 add support for sending call waiting tone when a
 simultaneous call is received --resolve

---
 src/mod/endpoints/mod_skinny/mod_skinny.c    | 32 ++++++++++++++++++++
 src/mod/endpoints/mod_skinny/mod_skinny.h    |  1 +
 src/mod/endpoints/mod_skinny/skinny_server.c | 16 ++++++++--
 3 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c
index f31be6ae96..37edccafed 100644
--- a/src/mod/endpoints/mod_skinny/mod_skinny.c
+++ b/src/mod/endpoints/mod_skinny/mod_skinny.c
@@ -500,6 +500,38 @@ uint32_t skinny_line_get_state(listener_t *listener, uint32_t line_instance, uin
 	return helper.call_state;
 }
 
+struct skinny_line_count_active_helper {
+	uint32_t count;
+};
+
+int skinny_line_count_active_callback(void *pArg, int argc, char **argv, char **columnNames)
+{
+	struct skinny_line_count_active_helper *helper = pArg;
+	helper->count++;
+	return 0;
+}
+
+uint32_t skinny_line_count_active(listener_t *listener)
+{
+	char *sql;
+	struct skinny_line_count_active_helper helper = {0};
+
+	switch_assert(listener);
+
+	helper.count = 0;
+	if ((sql = switch_mprintf(
+			"SELECT call_state FROM skinny_active_lines "
+			"WHERE device_name='%s' AND device_instance=%d "
+			"AND call_state != 2",
+			listener->device_name, listener->device_instance
+			))) {
+
+		skinny_execute_sql_callback(listener->profile, listener->profile->sql_mutex, sql, skinny_line_count_active_callback, &helper);
+		switch_safe_free(sql);
+	}
+
+	return helper.count;
+}
 
 switch_status_t skinny_tech_set_codec(private_t *tech_pvt, int force)
 {
diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h
index b252dd7e4a..a98be960a9 100644
--- a/src/mod/endpoints/mod_skinny/mod_skinny.h
+++ b/src/mod/endpoints/mod_skinny/mod_skinny.h
@@ -304,6 +304,7 @@ void skinny_line_perform_set_state(const char *file, const char *func, int line,
 #define  skinny_line_set_state(listener, line_instance, call_id, call_state)  skinny_line_perform_set_state(__FILE__, __SWITCH_FUNC__, __LINE__, listener, line_instance, call_id, call_state)
 
 uint32_t skinny_line_get_state(listener_t *listener, uint32_t line_instance, uint32_t call_id);
+uint32_t skinny_line_count_active(listener_t *listener);
 
 switch_status_t skinny_tech_set_codec(private_t *tech_pvt, int force);
 void tech_init(private_t *tech_pvt, skinny_profile_t *profile, switch_core_session_t *session);
diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c
index 13ffaac7fc..4a69786abb 100644
--- a/src/mod/endpoints/mod_skinny/skinny_server.c
+++ b/src/mod/endpoints/mod_skinny/skinny_server.c
@@ -587,6 +587,7 @@ int skinny_ring_lines_callback(void *pArg, int argc, char **argv, char **columnN
 	/* uint32_t call_state = atoi(argv[16]); */
 
 	listener_t *listener = NULL;
+	uint32_t active_calls = 0;
 
 	skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, 
 			device_name, device_instance, &listener);
@@ -596,9 +597,12 @@ int skinny_ring_lines_callback(void *pArg, int argc, char **argv, char **columnN
 		helper->lines_count++;
 		switch_channel_set_variable(channel, "effective_callee_id_number", value);
 		switch_channel_set_variable(channel, "effective_callee_id_name", caller_name);
+	
+		active_calls = skinny_line_count_active(listener);
 
-		skinny_log_l(listener, SWITCH_LOG_DEBUG, "Ring Lines Callback with Callee Number (%s), Caller Name (%s), Dest Number (%s)\n",
-			value, caller_name, helper->tech_pvt->caller_profile->destination_number);
+		skinny_log_l(listener, SWITCH_LOG_DEBUG, 
+			"Ring Lines Callback with Callee Number (%s), Caller Name (%s), Dest Number (%s), Active Calls (%d)\n",
+			value, caller_name, helper->tech_pvt->caller_profile->destination_number, active_calls);
 
 		if (helper->remote_session) {
 			switch_core_session_message_t msg = { 0 };
@@ -630,7 +634,13 @@ int skinny_ring_lines_callback(void *pArg, int argc, char **argv, char **columnN
 		}
 		skinny_session_send_call_info(helper->tech_pvt->session, listener, line_instance);
 		send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_BLINK);
-		send_set_ringer(listener, SKINNY_RING_INSIDE, SKINNY_RING_FOREVER, 0, helper->tech_pvt->call_id);
+
+		if ( active_calls < 1 ) {
+			send_set_ringer(listener, SKINNY_RING_INSIDE, SKINNY_RING_FOREVER, 0, helper->tech_pvt->call_id);
+		} else {
+			send_start_tone(listener, SKINNY_TONE_CALLWAITTONE, 0, line_instance, helper->tech_pvt->call_id);
+			send_stop_tone(listener, line_instance, helper->tech_pvt->call_id);
+		}
 		switch_channel_ring_ready(channel);
 	}
 	return 0;