From b07a41cec088cf2a000ecb1e872e92856ea6ba86 Mon Sep 17 00:00:00 2001
From: Moises Silva <moy@sangoma.com>
Date: Fri, 12 Mar 2010 22:47:50 +0000
Subject: [PATCH] added configuration of gains in openzap.conf and display
 through CLI

git-svn-id: http://svn.openzap.org/svn/openzap/trunk@1062 a93c3328-9c30-0410-af19-c9cd2b2d52af
---
 libs/openzap/mod_openzap/mod_openzap.c |  8 ++++++
 libs/openzap/src/include/zap_types.h   |  2 ++
 libs/openzap/src/zap_io.c              | 37 ++++++++++++++++++++++++++
 3 files changed, 47 insertions(+)

diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c
index 5cad5abb79..f03f8309db 100644
--- a/libs/openzap/mod_openzap/mod_openzap.c
+++ b/libs/openzap/mod_openzap/mod_openzap.c
@@ -2810,6 +2810,8 @@ void dump_chan(zap_span_t *span, uint32_t chan_id, switch_stream_handle_t *strea
 						   "type: %s\n"
 						   "state: %s\n"
 						   "last_state: %s\n"
+						   "txgain: %3.2f\n"
+						   "rxgain: %3.2f\n"
 						   "cid_date: %s\n"
 						   "cid_name: %s\n"
 						   "cid_num: %s\n"
@@ -2825,6 +2827,8 @@ void dump_chan(zap_span_t *span, uint32_t chan_id, switch_stream_handle_t *strea
 						   zap_chan_type2str(span->channels[chan_id]->type),
 						   zap_channel_state2str(span->channels[chan_id]->state),
 						   zap_channel_state2str(span->channels[chan_id]->last_state),
+						   span->channels[chan_id]->txgain,
+						   span->channels[chan_id]->rxgain,
 						   span->channels[chan_id]->caller_data.cid_date,
 						   span->channels[chan_id]->caller_data.cid_name,
 						   span->channels[chan_id]->caller_data.cid_num.digits,
@@ -2851,6 +2855,8 @@ void dump_chan_xml(zap_span_t *span, uint32_t chan_id, switch_stream_handle_t *s
 						   "  <type>%s</type>\n"
 						   "  <state>%s</state>\n"
 						   "  <last-state>%s</last-state>\n"
+						   "  <txgain>%3.2f</txgain>\n"
+						   "  <rxgain>%3.2f</rxgain>\n"
 						   "  <cid-date>%s</cid-date>\n"
 						   "  <cid-name>%s</cid-name>\n"
 						   "  <cid-num>%s</cid-num>\n"
@@ -2867,6 +2873,8 @@ void dump_chan_xml(zap_span_t *span, uint32_t chan_id, switch_stream_handle_t *s
 						   zap_chan_type2str(span->channels[chan_id]->type),
 						   zap_channel_state2str(span->channels[chan_id]->state),
 						   zap_channel_state2str(span->channels[chan_id]->last_state),
+						   span->channels[chan_id]->txgain,
+						   span->channels[chan_id]->rxgain,
 						   span->channels[chan_id]->caller_data.cid_date,
 						   span->channels[chan_id]->caller_data.cid_name,
 						   span->channels[chan_id]->caller_data.cid_num.digits,
diff --git a/libs/openzap/src/include/zap_types.h b/libs/openzap/src/include/zap_types.h
index 3bb726148e..effd2c41e1 100644
--- a/libs/openzap/src/include/zap_types.h
+++ b/libs/openzap/src/include/zap_types.h
@@ -317,6 +317,8 @@ typedef enum {
 #define CHAN_TYPE_STRINGS "B", "DQ921", "DQ931", "FXS", "FXO", "EM", "CAS", "INVALID"
 ZAP_STR2ENUM_P(zap_str2zap_chan_type, zap_chan_type2str, zap_chan_type_t)
 
+#define ZAP_IS_VOICE_CHANNEL(zap_chan) ((zap_chan)->type != ZAP_CHAN_TYPE_DQ921 && (zap_chan)->type != ZAP_CHAN_TYPE_DQ931)
+
 typedef enum {
 	ZAP_CHANNEL_FEATURE_DTMF_DETECT = (1 << 0),
 	ZAP_CHANNEL_FEATURE_DTMF_GENERATE = (1 << 1),
diff --git a/libs/openzap/src/zap_io.c b/libs/openzap/src/zap_io.c
index 8ca5e71b56..ea6d987b7a 100644
--- a/libs/openzap/src/zap_io.c
+++ b/libs/openzap/src/zap_io.c
@@ -2523,6 +2523,22 @@ OZ_DECLARE(char *) zap_api_execute(const char *type, const char *cmd)
 	return rval;
 }
 
+static void zap_set_channels_gains(zap_span_t *span, int currindex, float rxgain, float txgain)
+{
+	unsigned chan_index = 0;
+
+	if (!span->chan_count) {
+		return;
+	}
+
+	for (chan_index = currindex+1; chan_index <= span->chan_count; chan_index++) {
+		if (!ZAP_IS_VOICE_CHANNEL(span->channels[chan_index])) {
+			continue;
+		}
+		zap_channel_command(span->channels[chan_index], ZAP_COMMAND_SET_RX_GAIN, &rxgain);
+		zap_channel_command(span->channels[chan_index], ZAP_COMMAND_SET_TX_GAIN, &txgain);
+	}
+}
 
 static zap_status_t load_config(void)
 {
@@ -2536,6 +2552,9 @@ static zap_status_t load_config(void)
 	char number[25] = "";
 	zap_io_interface_t *zio = NULL;
 	zap_analog_start_type_t tmp;
+	float rxgain = 0.0;
+	float txgain = 0.0;
+	int chanindex = 0;
 
 	if (!zap_config_open_file(&cfg, cfg_name)) {
 		return ZAP_FAIL;
@@ -2640,7 +2659,9 @@ static zap_status_t load_config(void)
 							zap_analog_start_type2str(span->start_type));
 				}
 				if (span->trunk_type == ZAP_TRUNK_FXO) {
+					chanindex = span->chan_count;
 					configured += zio->configure_span(span, val, ZAP_CHAN_TYPE_FXO, name, number);
+					zap_set_channels_gains(span, chanindex, rxgain, txgain);
 				} else {
 					zap_log(ZAP_LOG_WARNING, "Cannot add FXO channels to an FXS trunk!\n");
 				}
@@ -2651,7 +2672,9 @@ static zap_status_t load_config(void)
 							zap_analog_start_type2str(span->start_type));
 				}
 				if (span->trunk_type == ZAP_TRUNK_FXS) {
+					chanindex = span->chan_count;
 					configured += zio->configure_span(span, val, ZAP_CHAN_TYPE_FXS, name, number);
+					zap_set_channels_gains(span, chanindex, rxgain, txgain);
 				} else {
 					zap_log(ZAP_LOG_WARNING, "Cannot add FXS channels to an FXO trunk!\n");
 				}
@@ -2662,12 +2685,16 @@ static zap_status_t load_config(void)
 							zap_analog_start_type2str(span->start_type));
 				}
 				if (span->trunk_type == ZAP_TRUNK_EM) {
+					chanindex = span->chan_count;
 					configured += zio->configure_span(span, val, ZAP_CHAN_TYPE_EM, name, number);
+					zap_set_channels_gains(span, chanindex, rxgain, txgain);
 				} else {
 					zap_log(ZAP_LOG_WARNING, "Cannot add EM channels to a non-EM trunk!\n");
 				}
 			} else if (!strcasecmp(var, "b-channel")) {
+				chanindex = span->chan_count;
 				configured += zio->configure_span(span, val, ZAP_CHAN_TYPE_B, name, number);
+				zap_set_channels_gains(span, chanindex, rxgain, txgain);
 			} else if (!strcasecmp(var, "d-channel")) {
 				if (d) {
 					zap_log(ZAP_LOG_WARNING, "ignoring extra d-channel\n");
@@ -2683,10 +2710,20 @@ static zap_status_t load_config(void)
 					d++;
 				}
 			} else if (!strcasecmp(var, "cas-channel")) {
+				chanindex = span->chan_count;
 				configured += zio->configure_span(span, val, ZAP_CHAN_TYPE_CAS, name, number);	
+				zap_set_channels_gains(span, chanindex, rxgain, txgain);
 			} else if (!strcasecmp(var, "dtmf_hangup")) {
 				span->dtmf_hangup = strdup(val);
 				span->dtmf_hangup_len = strlen(val);
+			} else if (!strcasecmp(var, "txgain")) {
+				if (sscanf(val, "%f", &txgain) != 1) {
+					zap_log(ZAP_LOG_ERROR, "invalid txgain: '%s'\n", val);
+				}
+			} else if (!strcasecmp(var, "rxgain")) {
+				if (sscanf(val, "%f", &rxgain) != 1) {
+					zap_log(ZAP_LOG_ERROR, "invalid rxgain: '%s'\n", val);
+				}
 			} else {
 				zap_log(ZAP_LOG_ERROR, "unknown span variable '%s'\n", var);
 			}