From ca908e767c0df160555a7ead77957196429cf4b7 Mon Sep 17 00:00:00 2001
From: Matteo Brancaleoni <mbrancaleoni@espia.it>
Date: Mon, 17 Mar 2003 18:11:33 +0000
Subject: [PATCH] lun mar 17 19:11:15 CET 2003

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@649 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 channels/chan_iax2.c  | 91 +++++++++++++++++++++++++++++++------------
 channels/chan_zap.c   | 18 +++++++++
 res/res_musiconhold.c | 12 ++----
 3 files changed, 88 insertions(+), 33 deletions(-)

diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index d0691ef399..c58e24e3d4 100755
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -137,6 +137,8 @@ static int use_jitterbuffer = 1;
 
 static int iaxdebug = 0;
 
+static int iaxtrunkdebug = 0;
+
 static char accountcode[20];
 static int amaflags = 0;
 
@@ -2098,9 +2100,37 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 	   or delayed, with retransmission */
 	struct ast_iax2_full_hdr *fh;
 	struct ast_iax2_mini_hdr *mh;
-	struct ast_iax2_frame *fr, fr2;
+	unsigned char buffer[4096];		/* Buffer -- must preceed fr2 */
+	struct ast_iax2_frame fr2;
+	struct ast_iax2_frame *fr;
 	int res;
+	int sendmini=0;
 	unsigned int lastsent;
+	unsigned int fts;
+	
+	/* Shut up GCC */
+	buffer[0] = 0;
+	
+	if (!pvt) {
+		ast_log(LOG_WARNING, "No private structure for packet?\n");
+		return -1;
+	}
+	
+	/* Calculate actual timestamp */
+	fts = calc_timestamp(pvt, ts);
+	lastsent = pvt->lastsent;
+
+	if ((pvt->trunk || ((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)))
+		/* High two bits are the same on timestamp, or sending on a trunk */ &&
+	    (f->frametype == AST_FRAME_VOICE) 
+		/* is a voice frame */ &&
+		(f->subclass == pvt->svoiceformat) 
+		/* is the same type */ ) {
+			/* Force immediate rather than delayed transmission */
+			now = 1;
+			/* Mark that mini-style frame is appropriate */
+			sendmini = 1;
+	}
 	/* Allocate an ast_iax2_frame */
 	if (now) {
 		fr = &fr2;
@@ -2110,17 +2140,10 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 		ast_log(LOG_WARNING, "Out of memory\n");
 		return -1;
 	}
-	if (!pvt) {
-		ast_log(LOG_WARNING, "No private structure for packet (%d)?\n", fr->callno);
-		if (!now)
-			ast_iax2_frame_free(fr);
-		return -1;
-	}
 	/* Copy our prospective frame into our immediate or retransmitted wrapper */
 	ast_iax2_frame_wrap(fr, f);
 
-	lastsent = pvt->lastsent;
-	fr->ts = calc_timestamp(pvt, ts);
+	fr->ts = fts;
 	if (!fr->ts) {
 		ast_log(LOG_WARNING, "timestamp is 0?\n");
 		if (!now)
@@ -2130,12 +2153,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 	fr->callno = pvt->callno;
 	fr->transfer = transfer;
 	fr->final = final;
-	if (((fr->ts & 0xFFFF0000L) != (lastsent & 0xFFFF0000L))
-		/* High two bits of timestamp differ */ ||
-	    (fr->af.frametype != AST_FRAME_VOICE) 
-		/* or not a voice frame */ || 
-		(fr->af.subclass != pvt->svoiceformat) 
-		/* or new voice format */ ) {
+	if (!sendmini) {
 		/* We need a full frame */
 		if (seqno > -1)
 			fr->oseqno = seqno;
@@ -2199,10 +2217,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 			fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
 			fr->data = mh;
 			fr->retries = -1;
-			if (now) {
-				res = send_packet(fr);
-			} else
-				res = iax2_transmit(fr);
+			res = send_packet(fr);
 		}
 	}
 	return res;
@@ -2358,6 +2373,15 @@ static int iax2_show_channels(int fd, int argc, char *argv[])
 #undef FORMAT2
 }
 
+static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
+{
+	if (argc != 3)
+		return RESULT_SHOWUSAGE;
+	iaxtrunkdebug = 1;
+	ast_cli(fd, "IAX2 Trunk Debug Requested\n");
+	return RESULT_SUCCESS;
+}
+
 static int iax2_do_debug(int fd, int argc, char *argv[])
 {
 	if (argc != 2)
@@ -2394,8 +2418,6 @@ static char show_reg_usage[] =
 "Usage: iax2 show registry\n"
 "       Lists all registration requests and status.\n";
 
-#ifdef DEBUG_SUPPORT
-
 static char debug_usage[] = 
 "Usage: iax2 debug\n"
 "       Enables dumping of IAX packets for debugging purposes\n";
@@ -2404,7 +2426,9 @@ static char no_debug_usage[] =
 "Usage: iax2 no debug\n"
 "       Disables dumping of IAX packets for debugging purposes\n";
 
-#endif
+static char debug_trunk_usage[] =
+"Usage: iax2 trunk debug\n"
+"       Requests current status of IAX trunking\n";
 
 static struct ast_cli_entry  cli_show_users = 
 	{ { "iax2", "show", "users", NULL }, iax2_show_users, "Show defined IAX users", show_users_usage };
@@ -2416,6 +2440,8 @@ static struct ast_cli_entry  cli_show_registry =
 	{ { "iax2", "show", "registry", NULL }, iax2_show_registry, "Show IAX registration status", show_reg_usage };
 static struct ast_cli_entry  cli_debug =
 	{ { "iax2", "debug", NULL }, iax2_do_debug, "Enable IAX debugging", debug_usage };
+static struct ast_cli_entry  cli_trunk_debug =
+	{ { "iax2", "trunk", "debug", NULL }, iax2_do_trunk_debug, "Request IAX trunk debug", debug_trunk_usage };
 static struct ast_cli_entry  cli_no_debug =
 	{ { "iax2", "no", "debug", NULL }, iax2_no_debug, "Disable IAX debugging", no_debug_usage };
 
@@ -3495,6 +3521,8 @@ static int send_trunk(struct iax2_peer *peer)
 	for (x=TRUNK_CALL_START;x<maxtrunkcall; x++) {
 		ast_pthread_mutex_lock(&iaxsl[x]);
 		if (iaxs[x] && iaxs[x]->trunk && iaxs[x]->trunkdatalen && !memcmp(&iaxs[x]->addr, &peer->addr, sizeof(iaxs[x]->addr))) {
+			if (iaxtrunkdebug)
+				ast_verbose(" -- Sending call %d via trunk to %s:%d\n", x, inet_ntoa(iaxs[x]->addr.sin_addr), ntohs(iaxs[x]->addr.sin_port));
 			if (len >= iaxs[x]->trunkdatalen + sizeof(struct ast_iax2_meta_trunk_entry)) {
 				met = (struct ast_iax2_meta_trunk_entry *)ptr;
 				/* Store call number and length in meta header */
@@ -3536,7 +3564,9 @@ static int send_trunk(struct iax2_peer *peer)
 #endif		
 		res = send_packet(fr);
 	}
-	return res;
+	if (res < 0)
+		return res;
+	return calls;
 }
 
 static int timing_read(int *id, int fd, short events, void *cbdata)
@@ -3544,6 +3574,10 @@ static int timing_read(int *id, int fd, short events, void *cbdata)
 	char buf[1024];
 	int res;
 	struct iax2_peer *peer;
+	int processed = 0;
+	int totalcalls = 0;
+	if (iaxtrunkdebug)
+		ast_verbose("Beginning trunk processing\n");
 	/* Read and ignore from the pseudo channel for timing */
 	res = read(fd, buf, sizeof(buf));
 	if (res > 0) {
@@ -3552,12 +3586,20 @@ static int timing_read(int *id, int fd, short events, void *cbdata)
 		peer = peerl.peers;
 		while(peer) {
 			if (peer->trunk) {
-				send_trunk(peer);
+				processed++;
+				res = send_trunk(peer);
+				if (iaxtrunkdebug)
+					ast_verbose("Processed trunk peer '%s' with %d call(s)\n", peer->name, res);
+				totalcalls += res;	
+				res = 0;
 			}
 			peer = peer->next;
 		}
 		ast_pthread_mutex_unlock(&peerl.lock);
 	}
+	if (iaxtrunkdebug)
+		ast_verbose("Ending trunk processing with %d peers and %d calls processed\n", processed, totalcalls);
+	iaxtrunkdebug =0;
 	return 1;
 }
 
@@ -5507,6 +5549,7 @@ int load_module(void)
 	ast_cli_register(&cli_show_peers);
 	ast_cli_register(&cli_show_registry);
 	ast_cli_register(&cli_debug);
+	ast_cli_register(&cli_trunk_debug);
 	ast_cli_register(&cli_no_debug);
 	ast_cli_register(&cli_set_jitter);
 	ast_cli_register(&cli_show_stats);
diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index c76791f4f5..21219065fc 100755
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -113,6 +113,7 @@ static char *config = "zapata.conf";
 #define SIG_FXOKS	ZT_SIG_FXOKS
 #define SIG_PRI		ZT_SIG_CLEAR
 #define SIG_R2		ZT_SIG_CAS
+#define	SIG_SF		ZT_SIG_SF
 
 #define NUM_SPANS 	32
 #define RESET_INTERVAL	3600	/* How often (in seconds) to reset unused channels */
@@ -776,6 +777,8 @@ static char *sig2str(int sig)
 		return "PRI Signalling";
 	case SIG_R2:
 		return "R2 Signalling";
+	case SIG_SF:
+		return "SF (Tone) Signalling";
 	case 0:
 		return "Pseudo Signalling";
 	default:
@@ -6207,6 +6210,21 @@ int load_module()
 			} else if (!strcasecmp(v->value, "em_txrx")) {
 				cur_signalling = SIG_EM;
 				cur_radio = 2;
+			} else if (!strcasecmp(v->value, "sf")) {
+				cur_signalling = SIG_SF;
+				cur_radio = 0;
+			} else if (!strcasecmp(v->value, "sf_rx")) {
+				cur_signalling = SIG_SF;
+				cur_radio = 1;
+			} else if (!strcasecmp(v->value, "sf_tx")) {
+				cur_signalling = SIG_SF;
+				cur_radio = 1;
+			} else if (!strcasecmp(v->value, "sf_rxtx")) {
+				cur_signalling = SIG_SF;
+				cur_radio = 2;
+			} else if (!strcasecmp(v->value, "sf_txrx")) {
+				cur_signalling = SIG_SF;
+				cur_radio = 2;
 			} else if (!strcasecmp(v->value, "featd")) {
 				cur_signalling = SIG_FEATD;
 				cur_radio = 0;
diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c
index 5c59e2e198..ab347f9d45 100755
--- a/res/res_musiconhold.c
+++ b/res/res_musiconhold.c
@@ -84,7 +84,6 @@ struct mohclass {
 
 struct mohdata {
 	int pipe[2];
-	int origrfmt;
 	int origwfmt;
 	struct mohclass *parent;
 	struct mohdata *next;
@@ -348,12 +347,10 @@ static void moh_release(struct ast_channel *chan, void *data)
 	ast_pthread_mutex_unlock(&moh_lock);
 	close(moh->pipe[0]);
 	close(moh->pipe[1]);
-	oldrfmt = moh->origrfmt;
 	oldwfmt = moh->origwfmt;
 	free(moh);
 	if (chan) {
-		if (ast_set_write_format(chan, oldwfmt) ||
-		    ast_set_read_format(chan, oldrfmt)) 
+		if (ast_set_write_format(chan, oldwfmt)) 
 			ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %d/%d\n", chan->name, oldwfmt, oldrfmt);
 		if (option_verbose > 2)
 			ast_verbose(VERBOSE_PREFIX_3 "Stopped music on hold on %s\n", chan->name);
@@ -375,16 +372,11 @@ static void *moh_alloc(struct ast_channel *chan, void *params)
 	}
 	ast_pthread_mutex_unlock(&moh_lock);
 	if (res) {
-		res->origrfmt = chan->readformat;
 		res->origwfmt = chan->writeformat;
 		if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
 			ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format\n", chan->name);
 			moh_release(NULL, res);
 			res = NULL;
-		} else if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
-			ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format\n", chan->name);
-			moh_release(NULL, res);
-			res = NULL;
 		}
 #if 0
 		/* Allow writes to interrupt */
@@ -402,6 +394,8 @@ static int moh_generate(struct ast_channel *chan, void *data, int len, int sampl
 	struct mohdata *moh = data;
 	short buf[640 + AST_FRIENDLY_OFFSET / 2];
 	int res;
+
+	len = samples * 2;
 	if (len > sizeof(buf)) {
 		ast_log(LOG_WARNING, "Only doing %d of %d requested bytes on %s\n", sizeof(buf), len, chan->name);
 		len = sizeof(buf);
-- 
GitLab