From a03e42860f5ee777481ce06d3a4f7d5dfa8ca824 Mon Sep 17 00:00:00 2001
From: Mark Spencer <markster@digium.com>
Date: Sat, 19 Apr 2003 18:12:41 +0000
Subject: [PATCH] IAX2 updates, dial fix

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@873 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 apps/app_dial.c        |   2 +-
 channels/chan_iax2.c   | 136 ++++++++++++++---------------------------
 channels/iax2-parser.c |  55 ++++++++++++++++-
 channels/iax2-parser.h |  20 ++++--
 4 files changed, 116 insertions(+), 97 deletions(-)

diff --git a/apps/app_dial.c b/apps/app_dial.c
index e3d59d4d6a..5b4d967c9f 100755
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -241,7 +241,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
 						case AST_CONTROL_RINGING:
 							if (option_verbose > 2)
 								ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
-							if (!sentringing) {
+							if (!sentringing && !moh) {
 								ast_indicate(in, AST_CONTROL_RINGING);
 								sentringing++;
 								ringind++;
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 8b9159781d..0e842c5a39 100755
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -379,8 +379,8 @@ struct chan_iax2_pvt {
 };
 
 static struct ast_iax2_queue {
-	struct ast_iax2_frame *head;
-	struct ast_iax2_frame *tail;
+	struct iax_frame *head;
+	struct iax_frame *tail;
 	int count;
 	pthread_mutex_t lock;
 } iaxq;
@@ -569,65 +569,13 @@ static int get_samples(struct ast_frame *f)
 	return samples;
 }
 
-static int frames = 0;
-static int iframes = 0;
-static int oframes = 0;
-
-static void ast_iax2_frame_wrap(struct ast_iax2_frame *fr, struct ast_frame *f)
-{
-	fr->af.frametype = f->frametype;
-	fr->af.subclass = f->subclass;
-	fr->af.mallocd = 0;				/* Our frame is static relative to the container */
-	fr->af.datalen = f->datalen;
-	fr->af.samples = f->samples;
-	fr->af.offset = AST_FRIENDLY_OFFSET;
-	fr->af.src = f->src;
-	fr->af.data = fr->afdata;
-	if (fr->af.datalen) 
-		memcpy(fr->af.data, f->data, fr->af.datalen);
-}
-
-static struct ast_iax2_frame *ast_iax2_frame_new(int direction, int datalen)
-{
-	struct ast_iax2_frame *fr;
-	fr = malloc(sizeof(struct ast_iax2_frame) + datalen);
-	if (fr) {
-		fr->direction = direction;
-		fr->retrans = -1;
-		frames++;
-		if (fr->direction == DIRECTION_INGRESS)
-			iframes++;
-		else
-			oframes++;
-	}
-	return fr;
-}
-
-static void ast_iax2_frame_free(struct ast_iax2_frame *fr)
-{
-	if (fr->retrans > -1)
-		ast_sched_del(sched, fr->retrans);
-	if (fr->direction == DIRECTION_INGRESS)
-		iframes--;
-	else if (fr->direction == DIRECTION_OUTGRESS)
-		oframes--;
-	else {
-		ast_log(LOG_WARNING, "Attempt to double free frame detected\n");
-		CRASH;
-		return;
-	}
-	fr->direction = 0;
-	free(fr);
-	frames--;
-}
-
-static struct ast_iax2_frame *iaxfrdup2(struct ast_iax2_frame *fr)
+static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
 {
 	/* Malloc() a copy of a frame */
-	struct ast_iax2_frame *new = ast_iax2_frame_new(DIRECTION_INGRESS, fr->af.datalen);
+	struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen);
 	if (new) {
-		memcpy(new, fr, sizeof(struct ast_iax2_frame));	
-		ast_iax2_frame_wrap(new, &fr->af);
+		memcpy(new, fr, sizeof(struct iax_frame));	
+		iax_frame_wrap(new, &fr->af);
 		new->data = NULL;
 		new->datalen = 0;
 		new->direction = DIRECTION_INGRESS;
@@ -802,6 +750,13 @@ static int find_callno(unsigned short callno, unsigned short dcallno, struct soc
 	return res;
 }
 
+static void iax2_frame_free(struct iax_frame *fr)
+{
+	if (fr->retrans > -1)
+		ast_sched_del(sched, fr->retrans);
+	iax_frame_free(fr);
+}
+
 static int iax2_queue_frame(int callno, struct ast_frame *f)
 {
 	int pass =0;
@@ -835,7 +790,7 @@ static int __do_deliver(void *data)
 {
 	/* Just deliver the packet by using queueing.  This is called by
 	  the IAX thread with the iaxsl lock held. */
-	struct ast_iax2_frame *fr = data;
+	struct iax_frame *fr = data;
 	unsigned int ts;
 	fr->retrans = -1;
 	if (iaxs[fr->callno] && !iaxs[fr->callno]->alreadygone) {
@@ -856,7 +811,7 @@ static int __do_deliver(void *data)
 		}
 	}
 	/* Free our iax frame */
-	ast_iax2_frame_free(fr);
+	iax2_frame_free(fr);
 	/* And don't run again */
 	return 0;
 }
@@ -864,7 +819,7 @@ static int __do_deliver(void *data)
 static int do_deliver(void *data)
 {
 	/* Locking version of __do_deliver */
-	struct ast_iax2_frame *fr = data;
+	struct iax_frame *fr = data;
 	int callno = fr->callno;
 	int res;
 	ast_pthread_mutex_lock(&iaxsl[callno]);
@@ -907,7 +862,7 @@ static int handle_error(void)
 	return 0;
 }
 
-static int send_packet(struct ast_iax2_frame *f)
+static int send_packet(struct iax_frame *f)
 {
 	int res;
 	/* Called with iaxsl held */
@@ -998,7 +953,7 @@ static int iax2_predestroy_nolock(int callno)
 static void iax2_destroy(int callno)
 {
 	struct chan_iax2_pvt *pvt;
-	struct ast_iax2_frame *cur;
+	struct iax_frame *cur;
 	struct ast_channel *owner;
 
 retry:
@@ -1070,7 +1025,7 @@ static void iax2_destroy_nolock(int callno)
 	ast_pthread_mutex_lock(&iaxsl[callno]);
 }
 
-static int update_packet(struct ast_iax2_frame *f)
+static int update_packet(struct iax_frame *f)
 {
 	/* Called with iaxsl lock held, and iaxs[callno] non-NULL */
 	struct ast_iax2_full_hdr *fh = f->data;
@@ -1086,7 +1041,7 @@ static int attempt_transmit(void *data)
 {
 	/* Attempt to transmit the frame to the remote peer...
 	   Called without iaxsl held. */
-	struct ast_iax2_frame *f = data;
+	struct iax_frame *f = data;
 	int freeme=0;
 	int callno = f->callno;
 	/* Make sure this call is still active */
@@ -1163,7 +1118,7 @@ static int attempt_transmit(void *data)
 		ast_pthread_mutex_unlock(&iaxq.lock);
 		f->retrans = -1;
 		/* Free the IAX frame */
-		ast_iax2_frame_free(f);
+		iax2_frame_free(f);
 	}
 	return 0;
 }
@@ -1201,7 +1156,7 @@ static char jitter_usage[] =
 
 static int iax2_show_stats(int fd, int argc, char *argv[])
 {
-	struct ast_iax2_frame *cur;
+	struct iax_frame *cur;
 	int cnt = 0, dead=0, final=0;
 	if (argc != 3)
 		return RESULT_SHOWUSAGE;
@@ -1214,7 +1169,7 @@ static int iax2_show_stats(int fd, int argc, char *argv[])
 	}
 	ast_cli(fd, "    IAX Statistics\n");
 	ast_cli(fd, "---------------------\n");
-	ast_cli(fd, "Outstanding frames: %d (%d ingress, %d outgress)\n", frames, iframes, oframes);
+	ast_cli(fd, "Outstanding frames: %d (%d ingress, %d outgress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
 	ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n", dead, final, cnt);
 	return RESULT_SUCCESS;
 }
@@ -1296,7 +1251,7 @@ static unsigned int calc_rxstamp(struct chan_iax2_pvt *p);
 #ifdef BRIDGE_OPTIMIZATION
 static unsigned int calc_fakestamp(struct chan_iax2_pvt *from, struct chan_iax2_pvt *to, unsigned int ts);
 
-static int forward_delivery(struct ast_iax2_frame *fr)
+static int forward_delivery(struct iax_frame *fr)
 {
 	struct chan_iax2_pvt *p1, *p2;
 	p1 = iaxs[fr->callno];
@@ -1313,7 +1268,7 @@ static int forward_delivery(struct ast_iax2_frame *fr)
 }
 #endif
 
-static int schedule_delivery(struct ast_iax2_frame *fr, int reallydeliver, int updatehistory)
+static int schedule_delivery(struct iax_frame *fr, int reallydeliver, int updatehistory)
 {
 	int ms,x;
 	int drops[MEMORY_SIZE];
@@ -1434,7 +1389,7 @@ static int schedule_delivery(struct ast_iax2_frame *fr, int reallydeliver, int u
 			if (option_debug)
 				ast_log(LOG_DEBUG, "Dropping voice packet since %d ms is, too old\n", ms);
 			/* Free our iax frame */
-			ast_iax2_frame_free(fr);
+			iax2_frame_free(fr);
 		}
 	} else {
 		if (option_debug)
@@ -1444,7 +1399,7 @@ static int schedule_delivery(struct ast_iax2_frame *fr, int reallydeliver, int u
 	return 0;
 }
 
-static int iax2_transmit(struct ast_iax2_frame *fr)
+static int iax2_transmit(struct iax_frame *fr)
 {
 	/* Lock the queue and place this packet at the end */
 	fr->next = NULL;
@@ -2136,8 +2091,8 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 	struct ast_iax2_full_hdr *fh;
 	struct ast_iax2_mini_hdr *mh;
 	unsigned char buffer[4096];		/* Buffer -- must preceed fr2 */
-	struct ast_iax2_frame fr2;
-	struct ast_iax2_frame *fr;
+	struct iax_frame fr2;
+	struct iax_frame *fr;
 	int res;
 	int sendmini=0;
 	unsigned int lastsent;
@@ -2166,23 +2121,23 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 			/* Mark that mini-style frame is appropriate */
 			sendmini = 1;
 	}
-	/* Allocate an ast_iax2_frame */
+	/* Allocate an iax_frame */
 	if (now) {
 		fr = &fr2;
 	} else
-		fr = ast_iax2_frame_new(DIRECTION_OUTGRESS, f->datalen);
+		fr = iax_frame_new(DIRECTION_OUTGRESS, f->datalen);
 	if (!fr) {
 		ast_log(LOG_WARNING, "Out of memory\n");
 		return -1;
 	}
 	/* Copy our prospective frame into our immediate or retransmitted wrapper */
-	ast_iax2_frame_wrap(fr, f);
+	iax_frame_wrap(fr, f);
 
 	fr->ts = fts;
 	if (!fr->ts) {
 		ast_log(LOG_WARNING, "timestamp is 0?\n");
 		if (!now)
-			ast_iax2_frame_free(fr);
+			iax2_frame_free(fr);
 		return -1;
 	}
 	fr->callno = pvt->callno;
@@ -2704,7 +2659,6 @@ static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
 		strncpy(md5secret, ies->md5_result, sizeof(md5secret)-1);
 	if (ies->rsa_result)
 		strncpy(rsasecret, ies->rsa_result, sizeof(rsasecret)-1);
-	printf("Auth methods: %d, rsasecret: %s, inkeys: %s\n", p->authmethods, rsasecret, p->inkeys);
 	if ((p->authmethods & IAX_AUTH_RSA) && strlen(rsasecret) && strlen(p->inkeys)) {
 		struct ast_key *key;
 		char *keyn;
@@ -3046,7 +3000,7 @@ static int complete_transfer(int callno, struct iax_ies *ies)
 {
 	int peercallno = 0;
 	struct chan_iax2_pvt *pvt = iaxs[callno];
-	struct ast_iax2_frame *cur;
+	struct iax_frame *cur;
 
 	if (ies->callno)
 		peercallno = ies->callno;
@@ -3378,7 +3332,7 @@ static int iax2_vnak(int callno)
 
 static void vnak_retransmit(int callno, int last)
 {
-	struct ast_iax2_frame *f;
+	struct iax_frame *f;
 	ast_pthread_mutex_lock(&iaxq.lock);
 	f = iaxq.head;
 	while(f) {
@@ -3406,15 +3360,15 @@ static int send_trunk(struct iax2_peer *peer)
 	int calls = 0;
 	int res = 0;
 	int firstcall = 0;
-	unsigned char buf[65536 + sizeof(struct ast_iax2_frame)], *ptr;
+	unsigned char buf[65536 + sizeof(struct iax_frame)], *ptr;
 	int len = 65536;
-	struct ast_iax2_frame *fr;
+	struct iax_frame *fr;
 	struct ast_iax2_meta_hdr *meta;
 	struct ast_iax2_meta_trunk_hdr *mth;
 	struct ast_iax2_meta_trunk_entry *met;
 	
 	/* Point to frame */
-	fr = (struct ast_iax2_frame *)buf;
+	fr = (struct iax_frame *)buf;
 	/* Point to meta data */
 	meta = (struct ast_iax2_meta_hdr *)fr->afdata;
 	mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
@@ -3540,8 +3494,8 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
 	struct ast_iax2_meta_trunk_hdr *mth;
 	struct ast_iax2_meta_trunk_entry *mte;
 	char dblbuf[4096];	/* Declaration of dblbuf must immediately *preceed* fr  on the stack */
-	struct ast_iax2_frame fr;
-	struct ast_iax2_frame *cur;
+	struct iax_frame fr;
+	struct iax_frame *cur;
 	struct ast_frame f;
 	struct ast_channel *c;
 	struct iax2_dpcache *dp;
@@ -3628,7 +3582,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
 								else
 									f.samples = 0;
 								fr.outoforder = 0;
-								ast_iax2_frame_wrap(&fr, &f);
+								iax_frame_wrap(&fr, &f);
 #ifdef BRIDGE_OPTIMIZATION
 								if (iaxs[fr.callno]->bridgecallno) {
 									forward_delivery(&fr);
@@ -4113,7 +4067,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
 					f.mallocd = 0;
 					f.offset = 0;
 					f.samples = 0;
-					ast_iax2_frame_wrap(&fr, &f);
+					iax_frame_wrap(&fr, &f);
 					schedule_delivery(iaxfrdup2(&fr), 1, updatehistory);
 #ifdef BRIDGE_OPTIMIZATION
 				}
@@ -4383,7 +4337,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
 		f.samples = get_samples(&f);
 	else
 		f.samples = 0;
-	ast_iax2_frame_wrap(&fr, &f);
+	iax_frame_wrap(&fr, &f);
 
 	/* If this is our most recent packet, use it as our basis for timestamping */
 	if (iaxs[fr.callno]->last < fr.ts) {
@@ -4560,7 +4514,7 @@ static void *network_thread(void *ignore)
 	/* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
 	   from the network, and queue them for delivery to the channels */
 	int res;
-	struct ast_iax2_frame *f, *freeme;
+	struct iax_frame *f, *freeme;
 	/* Establish I/O callback for socket read */
 	ast_io_add(io, netsocket, socket_read, AST_IO_IN, NULL);
 	if (timingfd > -1)
@@ -4599,7 +4553,7 @@ static void *network_thread(void *ignore)
 			}
 			f = f->next;
 			if (freeme)
-				ast_iax2_frame_free(freeme);
+				iax_frame_free(freeme);
 		}
 		ast_pthread_mutex_unlock(&iaxq.lock);
 		res = ast_sched_wait(sched);
diff --git a/channels/iax2-parser.c b/channels/iax2-parser.c
index 1187a9098e..1e512a0447 100755
--- a/channels/iax2-parser.c
+++ b/channels/iax2-parser.c
@@ -23,6 +23,10 @@
 #include "iax2-parser.h"
 
 
+static int frames = 0;
+static int iframes = 0;
+static int oframes = 0;
+
 static void internaloutput(const char *str)
 {
 	printf(str);
@@ -165,7 +169,7 @@ static void dump_ies(unsigned char *iedata, int len)
 	outputf("\n");
 }
 
-void iax_showframe(struct ast_iax2_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
+void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
 {
 	char *frames[] = {
 		"(0?)",
@@ -504,3 +508,52 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 	return 0;
 }
 
+void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
+{
+	fr->af.frametype = f->frametype;
+	fr->af.subclass = f->subclass;
+	fr->af.mallocd = 0;				/* Our frame is static relative to the container */
+	fr->af.datalen = f->datalen;
+	fr->af.samples = f->samples;
+	fr->af.offset = AST_FRIENDLY_OFFSET;
+	fr->af.src = f->src;
+	fr->af.data = fr->afdata;
+	if (fr->af.datalen) 
+		memcpy(fr->af.data, f->data, fr->af.datalen);
+}
+
+struct iax_frame *iax_frame_new(int direction, int datalen)
+{
+	struct iax_frame *fr;
+	fr = malloc(sizeof(struct iax_frame) + datalen);
+	if (fr) {
+		fr->direction = direction;
+		fr->retrans = -1;
+		frames++;
+		if (fr->direction == DIRECTION_INGRESS)
+			iframes++;
+		else
+			oframes++;
+	}
+	return fr;
+}
+
+void iax_frame_free(struct iax_frame *fr)
+{
+	/* Note: does not remove from scheduler! */
+	if (fr->direction == DIRECTION_INGRESS)
+		iframes--;
+	else if (fr->direction == DIRECTION_OUTGRESS)
+		oframes--;
+	else {
+		errorf("Attempt to double free frame detected\n");
+		return;
+	}
+	fr->direction = 0;
+	free(fr);
+	frames--;
+}
+
+int iax_get_frames(void) { return frames; }
+int iax_get_iframes(void) { return iframes; }
+int iax_get_oframes(void) { return oframes; }
diff --git a/channels/iax2-parser.h b/channels/iax2-parser.h
index f23b70d35b..bdca49686d 100755
--- a/channels/iax2-parser.h
+++ b/channels/iax2-parser.h
@@ -47,7 +47,12 @@ struct iax_ies {
 #define DIRECTION_INGRESS 1
 #define DIRECTION_OUTGRESS 2
 
-struct ast_iax2_frame {
+struct iax_frame {
+#ifdef LIBIAX
+	struct iax_session *session;
+	struct iax_event *event;
+#endif
+
 	/* /Our/ call number */
 	unsigned short callno;
 	/* /Their/ call number */
@@ -79,8 +84,8 @@ struct ast_iax2_frame {
 	/* Retransmission ID */
 	int retrans;
 	/* Easy linking */
-	struct ast_iax2_frame *next;
-	struct ast_iax2_frame *prev;
+	struct iax_frame *next;
+	struct iax_frame *prev;
 	/* Actual, isolated frame header */
 	struct ast_frame af;
 	unsigned char unused[AST_FRIENDLY_OFFSET];
@@ -96,7 +101,7 @@ struct iax_ie_data {
 extern void iax_set_output(void (*output)(const char *data));
 /* Choose a different function for errors */
 extern void iax_set_error(void (*output)(const char *data));
-extern void iax_showframe(struct ast_iax2_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen);
+extern void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen);
 
 extern const char *iax_ie2str(int ie);
 
@@ -109,4 +114,11 @@ extern int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigne
 extern int iax_ie_append(struct iax_ie_data *ied, unsigned char ie);
 extern int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen);
 
+extern int iax_get_frames(void);
+extern int iax_get_iframes(void);
+extern int iax_get_oframes(void);
+
+extern void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f);
+extern struct iax_frame *iax_frame_new(int direction, int datalen);
+extern void iax_frame_free(struct iax_frame *fr);
 #endif
-- 
GitLab