[svn-commits] branch oej/sipregister r8982 - in /team/oej/sipregister: ./ apps/ channels/ c...

svn-commits at lists.digium.com svn-commits at lists.digium.com
Tue Jan 31 08:15:30 MST 2006


Author: oej
Date: Tue Jan 31 09:15:21 2006
New Revision: 8982

URL: http://svn.digium.com/view/asterisk?rev=8982&view=rev
Log:
Merged revisions 8850-8852,8877,8883,8896,8906,8919,8925-8926,8932,8938,8948-8949,8961,8976 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
r8850 | kpfleming | 2006-01-29 06:07:04 +0100 (Sun, 29 Jan 2006) | 5 lines

make ast_read() able to handle channel read()/exception() methods that return a chain of frames
cleanup code in ast_read()
add AST_FRAME_DTMF_BEGIN and AST_FRAME_DTMF_END so that variable-length DTMF events can be supported
teach chan_zap to send DTMF_BEGIN and DTMF_END when appropriate

................
r8851 | kpfleming | 2006-01-29 06:15:24 +0100 (Sun, 29 Jan 2006) | 3 lines

add channel-driver callbacks for variable length DTMF
teach ast_write() to call those new callbacks

................
r8852 | kpfleming | 2006-01-29 06:29:29 +0100 (Sun, 29 Jan 2006) | 2 lines

don't use tone generation for DTMF if the channel driver only supports begin/end (will need more work to translate non-variable events into begin/end events)

................
r8877 | markster | 2006-01-30 04:13:33 +0100 (Mon, 30 Jan 2006) | 2 lines

Merge Rizzo's waitfor update (bug #4584)

................
r8883 | tilghman | 2006-01-30 07:07:05 +0100 (Mon, 30 Jan 2006) | 2 lines

Bug 6378 - deprecate CHECK_MD5 function

................
r8896 | oej | 2006-01-30 15:12:39 +0100 (Mon, 30 Jan 2006) | 2 lines

Document installation changes for BSD users.

................
r8906 | kpfleming | 2006-01-30 18:09:55 +0100 (Mon, 30 Jan 2006) | 10 lines

Merged revisions 8905 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r8905 | kpfleming | 2006-01-30 11:08:28 -0600 (Mon, 30 Jan 2006) | 2 lines

disable buggy PRI user-user code until it can be fixed

........

................
r8919 | oej | 2006-01-30 19:51:02 +0100 (Mon, 30 Jan 2006) | 6 lines

Issue #5793 
- simplification of check_auth
- constifications
- whitespace changes
Rizzo's patch with some changes

................
r8925 | oej | 2006-01-30 20:09:08 +0100 (Mon, 30 Jan 2006) | 3 lines

Issue #6035 - Don't send 403 on bad auth (correcting one of my old mistakes...) Reported by maik.
Patch inspired by, but not the patch in the bug tracker.

................
r8926 | oej | 2006-01-30 20:50:39 +0100 (Mon, 30 Jan 2006) | 2 lines

Issue 5892: Set a minimum T1 timer for calls. Reporter: twisted

................
r8932 | oej | 2006-01-30 21:36:38 +0100 (Mon, 30 Jan 2006) | 8 lines

- Doxygen and comments updates
- Moving structure declarations to top of file with the rest
- Adding some forward declarations for RTP interface functions

(All these changes to position in file are in preparation for splitting chan_sip up
into several files at some point in the future)


................
r8938 | mogorman | 2006-01-30 22:16:43 +0100 (Mon, 30 Jan 2006) | 3 lines

reverting  blocks 9 and 10 from revision 7547
fixes bug 6080

................
r8948 | kpfleming | 2006-01-31 01:17:43 +0100 (Tue, 31 Jan 2006) | 2 lines

increment for recent ast_channel change

................
r8949 | russell | 2006-01-31 01:24:34 +0100 (Tue, 31 Jan 2006) | 3 lines

add a note to hopefully decrease the chance that someone forgets to increment
.cleancount after changing the ast_channel structure

................
r8961 | kpfleming | 2006-01-31 04:45:09 +0100 (Tue, 31 Jan 2006) | 2 lines

Yes Virginia, Zaptel does support native ALAW

................
r8976 | oej | 2006-01-31 15:30:09 +0100 (Tue, 31 Jan 2006) | 3 lines

- Change "prefs" to "default_prefs" and move declaration to "default" group
- Add doxygen comments

................

Modified:
    team/oej/sipregister/   (props changed)
    team/oej/sipregister/.cleancount
    team/oej/sipregister/UPGRADE.txt
    team/oej/sipregister/apps/app_meetme.c
    team/oej/sipregister/channel.c
    team/oej/sipregister/channels/chan_agent.c
    team/oej/sipregister/channels/chan_features.c
    team/oej/sipregister/channels/chan_sip.c
    team/oej/sipregister/channels/chan_zap.c
    team/oej/sipregister/configs/sip.conf.sample
    team/oej/sipregister/funcs/func_md5.c
    team/oej/sipregister/include/asterisk/channel.h
    team/oej/sipregister/include/asterisk/frame.h

Propchange: team/oej/sipregister/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Jan 31 09:15:21 2006
@@ -1,1 +1,1 @@
-/trunk:1-8836
+/trunk:1-8980

Modified: team/oej/sipregister/.cleancount
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/.cleancount?rev=8982&r1=8981&r2=8982&view=diff
==============================================================================
--- team/oej/sipregister/.cleancount (original)
+++ team/oej/sipregister/.cleancount Tue Jan 31 09:15:21 2006
@@ -1,1 +1,1 @@
-8
+9

Modified: team/oej/sipregister/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/UPGRADE.txt?rev=8982&r1=8981&r2=8982&view=diff
==============================================================================
--- team/oej/sipregister/UPGRADE.txt (original)
+++ team/oej/sipregister/UPGRADE.txt Tue Jan 31 09:15:21 2006
@@ -21,6 +21,7 @@
 * app_read has been updated to use the newer options codes, using "skip" or
   "noanswer" will not work.  Use s or n.  Also there is a new feature i, for
   using indication tones, so typing in skip would give you unexpected results.
+
 Variables:
 
 * The builtin variables ${CALLERID}, ${CALLERIDNAME}, ${CALLERIDNUM},
@@ -29,6 +30,21 @@
   functions.  You are encouraged to move towards the associated dialplan
   function, as these variables will be removed in a future release.
 
+Functions:
+
+* The function ${CHECK_MD5()} has been deprecated in favor of using an
+  expression: $[${MD5(<string>)} = ${saved_md5}].
+
 The SIP channel:
 
 * The "incominglimit" setting is replaced by the "call-limit" setting in sip.conf.
+
+Installation:
+
+* On BSD systems, the installation directories have changed to more "FreeBSDish" directories. On startup, Asterisk will look for the main configuration in /usr7local/etc/asterisk/asterisk.conf
+If you have an old installation, you might want to remove the binaries and move the configuration files to the new locations. The following directories are now default:
+	ASTLIBDIR	/usr/local/lib/asterisk
+	ASTVARLIBDIR	/usr/local/share/asterisk
+	ASTETCDIR	/usr/local/etc/asterisk
+	ASTBINDIR	/usr/local/bin/asterisk
+	ASTSBINDIR	/usr/local/sbin/asterisk

Modified: team/oej/sipregister/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/apps/app_meetme.c?rev=8982&r1=8981&r2=8982&view=diff
==============================================================================
--- team/oej/sipregister/apps/app_meetme.c (original)
+++ team/oej/sipregister/apps/app_meetme.c Tue Jan 31 09:15:21 2006
@@ -426,8 +426,6 @@
 	unsigned char *data;
 	int len;
 	int res = -1;
-	short *data2;
-	int x;
 
 	if (!chan->_softhangup)
 		res = ast_autoservice_start(chan);
@@ -448,10 +446,7 @@
 		len = 0;
 	}
 	if (data) {
-		data2 = alloca(len * 2);
-		for (x=0;x<len;x++)
-			data2[x] = AST_MULAW(data[x]);
-		careful_write(conf->fd, (unsigned char *)data2, len << 1, 1);
+		careful_write(conf->fd, data, len, 1);
 	}
 
 	AST_LIST_UNLOCK(&confs);

Modified: team/oej/sipregister/channel.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/channel.c?rev=8982&r1=8981&r2=8982&view=diff
==============================================================================
--- team/oej/sipregister/channel.c (original)
+++ team/oej/sipregister/channel.c Tue Jan 31 09:15:21 2006
@@ -604,7 +604,10 @@
 		return NULL;
 	}
 	
-	for (x=0; x<AST_MAX_FDS - 1; x++)
+	/* Don't bother initializing the last two FD here, because they
+	   will *always* be set just a few lines down (AST_TIMING_FD,
+	   AST_ALERT_FD). */
+	for (x=0; x<AST_MAX_FDS - 2; x++)
 		tmp->fds[x] = -1;
 
 #ifdef ZAPTEL_OPTIMIZATIONS
@@ -636,9 +639,9 @@
 		tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
 
 	/* Always watch the alertpipe */
-	tmp->fds[AST_MAX_FDS-1] = tmp->alertpipe[0];
+	tmp->fds[AST_ALERT_FD] = tmp->alertpipe[0];
 	/* And timing pipe */
-	tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
+	tmp->fds[AST_TIMING_FD] = tmp->timingfd;
 	strcpy(tmp->name, "**Unknown**");
 	/* Initial state */
 	tmp->_state = AST_STATE_DOWN;
@@ -1414,6 +1417,7 @@
 			chan->generator->release(chan, chan->generatordata);
 		chan->generatordata = NULL;
 		chan->generator = NULL;
+		chan->fds[AST_GENERATOR_FD] = -1;
 		ast_clear_flag(chan, AST_FLAG_WRITE_INT);
 		ast_settimeout(chan, 0, NULL, NULL);
 	}
@@ -1470,56 +1474,8 @@
 /*! \brief Wait for x amount of time on a file descriptor to have input.  */
 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
 {
-	struct timeval start = { 0 , 0 };
-	int res;
-	int x, y;
 	int winner = -1;
-	int spoint;
-	struct pollfd *pfds;
-	
-	pfds = alloca(sizeof(struct pollfd) * n);
-	if (!pfds) {
-		ast_log(LOG_ERROR, "Out of memory\n");
-		return -1;
-	}
-	if (*ms > 0)
-		start = ast_tvnow();
-	y = 0;
-	for (x=0; x < n; x++) {
-		if (fds[x] > -1) {
-			pfds[y].fd = fds[x];
-			pfds[y].events = POLLIN | POLLPRI;
-			y++;
-		}
-	}
-	res = poll(pfds, y, *ms);
-	if (res < 0) {
-		/* Simulate a timeout if we were interrupted */
-		if (errno != EINTR)
-			*ms = -1;
-		else
-			*ms = 0;
-		return -1;
-	}
-	spoint = 0;
-	for (x=0; x < n; x++) {
-		if (fds[x] > -1) {
-			if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) {
-				winner = fds[x];
-				if (exception) {
-					if (res & POLLPRI)
-						*exception = -1;
-					else
-						*exception = 0;
-				}
-			}
-		}
-	}
-	if (*ms > 0) {
-		*ms -= ast_tvdiff_ms(ast_tvnow(), start);
-		if (*ms < 0)
-			*ms = 0;
-	}
+	ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
 	return winner;
 }
 
@@ -1532,13 +1488,19 @@
 	int res;
 	long rms;
 	int x, y, max;
-	int spoint;
+	int sz;
 	time_t now = 0;
-	long whentohangup = 0, havewhen = 0, diff;
+	long whentohangup = 0, diff;
 	struct ast_channel *winner = NULL;
-
-	pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds));
-	if (!pfds) {
+	struct fdmap {
+		int chan;
+		int fdno;
+	} *fdmap;
+
+	sz = n * AST_MAX_FDS + nfds;
+	pfds = alloca(sizeof(struct pollfd) * sz);
+	fdmap = alloca(sizeof(struct fdmap) * sz);
+	if (!pfds || !fdmap) {
 		ast_log(LOG_ERROR, "Out of memory\n");
 		*outfd = -1;
 		return NULL;
@@ -1552,15 +1514,6 @@
 	/* Perform any pending masquerades */
 	for (x=0; x < n; x++) {
 		ast_mutex_lock(&c[x]->lock);
-		if (c[x]->whentohangup) {
-			if (!havewhen)
-				time(&now);
-			diff = c[x]->whentohangup - now;
-			if (!havewhen || (diff < whentohangup)) {
-				havewhen++;
-				whentohangup = diff;
-			}
-		}
 		if (c[x]->masq) {
 			if (ast_do_masquerade(c[x])) {
 				ast_log(LOG_WARNING, "Masquerade failed\n");
@@ -1569,40 +1522,52 @@
 				return NULL;
 			}
 		}
+		if (c[x]->whentohangup) {
+			if (!whentohangup)
+				time(&now);
+			diff = c[x]->whentohangup - now;
+			if (diff < 1) {
+				/* Should already be hungup */
+				c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
+				ast_mutex_unlock(&c[x]->lock);
+				return c[x];
+			}
+			if (!whentohangup || (diff < whentohangup))
+				whentohangup = diff;
+		}
 		ast_mutex_unlock(&c[x]->lock);
 	}
-
+	/* Wait full interval */
 	rms = *ms;
-	
-	if (havewhen) {
-		if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
-			rms =  whentohangup * 1000;
-		}
-	}
+	if (whentohangup) {
+		rms = (whentohangup - now) * 1000;	/* timeout in milliseconds */
+		if (*ms >= 0 && *ms < rms)		/* original *ms still smaller */
+			rms =  *ms;
+	}
+	/*
+	 * Build the pollfd array, putting the channels' fds first,
+	 * followed by individual fds. Order is important because
+	 * individual fd's must have priority over channel fds.
+	 */
 	max = 0;
-	for (x=0; x < n; x++) {
-		for (y=0; y< AST_MAX_FDS; y++) {
-			if (c[x]->fds[y] > -1) {
-				pfds[max].fd = c[x]->fds[y];
-				pfds[max].events = POLLIN | POLLPRI;
-				pfds[max].revents = 0;
-				max++;
-			}
+	for (x=0; x<n; x++) {
+		for (y=0; y<AST_MAX_FDS; y++) {
+			fdmap[max].fdno = y;  /* fd y is linked to this pfds */
+			fdmap[max].chan = x;  /* channel x is linked to this pfds */
+			max += ast_add_fd(&pfds[max], c[x]->fds[y]);
 		}
 		CHECK_BLOCKING(c[x]);
 	}
-	for (x=0; x < nfds; x++) {
-		if (fds[x] > -1) {
-			pfds[max].fd = fds[x];
-			pfds[max].events = POLLIN | POLLPRI;
-			pfds[max].revents = 0;
-			max++;
-		}
-	}
+	/* Add the individual fds */
+	for (x=0; x<nfds; x++) {
+		fdmap[max].chan = -1;
+		max += ast_add_fd(&pfds[max], fds[x]);
+	}
+
 	if (*ms > 0) 
 		start = ast_tvnow();
 	
-	if (sizeof(int) == 4) {
+	if (sizeof(int) == 4) {	/* XXX fix timeout > 600000 on linux x86-32 */
 		do {
 			int kbrms = rms;
 			if (kbrms > 600000)
@@ -1614,65 +1579,49 @@
 	} else {
 		res = poll(pfds, max, rms);
 	}
-	
-	if (res < 0) {
-		for (x=0; x < n; x++) 
-			ast_clear_flag(c[x], AST_FLAG_BLOCKING);
-		/* Simulate a timeout if we were interrupted */
-		if (errno != EINTR)
-			*ms = -1;
-		else {
-			/* Just an interrupt */
-#if 0
-			*ms = 0;
-#endif			
-		}
+	for (x=0; x<n; x++)
+		ast_clear_flag(c[x], AST_FLAG_BLOCKING);
+	if (res < 0) { /* Simulate a timeout if we were interrupted */
+		*ms = (errno != EINTR) ? -1 : 0;
 		return NULL;
-        } else {
-        	/* If no fds signalled, then timeout. So set ms = 0
-		   since we may not have an exact timeout.
-		*/
+	}
+	if (whentohangup) {   /* if we have a timeout, check who expired */
+		time(&now);
+		for (x=0; x<n; x++) {
+			if (c[x]->whentohangup && now >= c[x]->whentohangup) {
+				c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
+				if (winner == NULL)
+					winner = c[x];
+			}
+		}
+	}
+	if (res == 0) { /* no fd ready, reset timeout and done */
+		*ms = 0;	/* XXX use 0 since we may not have an exact timeout. */
+		return winner;
+	}
+	/*
+	 * Then check if any channel or fd has a pending event.
+	 * Remember to check channels first and fds last, as they
+	 * must have priority on setting 'winner'
+	 */
+	for (x = 0; x < max; x++) {
+		res = pfds[x].revents;
 		if (res == 0)
-			*ms = 0;
-	}
-
-	if (havewhen)
-		time(&now);
-	spoint = 0;
-	for (x=0; x < n; x++) {
-		ast_clear_flag(c[x], AST_FLAG_BLOCKING);
-		if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) {
-			c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
-			if (!winner)
-				winner = c[x];
-		}
-		for (y=0; y < AST_MAX_FDS; y++) {
-			if (c[x]->fds[y] > -1) {
-				if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) {
-					if (res & POLLPRI)
-						ast_set_flag(c[x], AST_FLAG_EXCEPTION);
-					else
-						ast_clear_flag(c[x], AST_FLAG_EXCEPTION);
-					c[x]->fdno = y;
-					winner = c[x];
-				}
-			}
-		}
-	}
-	for (x=0; x < nfds; x++) {
-		if (fds[x] > -1) {
-			if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) {
-				if (outfd)
-					*outfd = fds[x];
-				if (exception) {	
-					if (res & POLLPRI) 
-						*exception = -1;
-					else
-						*exception = 0;
-				}
-				winner = NULL;
-			}
-		}	
+			continue;
+		if (fdmap[x].chan >= 0) {	/* this is a channel */
+			winner = c[fdmap[x].chan];	/* override previous winners */
+			if (res & POLLPRI)
+				ast_set_flag(winner, AST_FLAG_EXCEPTION);
+			else
+				ast_clear_flag(winner, AST_FLAG_EXCEPTION);
+			winner->fdno = fdmap[x].fdno;
+		} else {			/* this is an fd */
+			if (outfd)
+				*outfd = pfds[x].fd;
+			if (exception)
+				*exception = (res & POLLPRI) ? -1 : 0;
+			winner = NULL;
+		}
 	}
 	if (*ms > 0) {
 		*ms -= ast_tvdiff_ms(ast_tvnow(), start);
@@ -1689,16 +1638,11 @@
 
 int ast_waitfor(struct ast_channel *c, int ms)
 {
-	struct ast_channel *chan;
 	int oldms = ms;
 
-	chan = ast_waitfor_n(&c, 1, &ms);
-	if (ms < 0) {
-		if (oldms < 0)
-			return 0;
-		else
-			return -1;
-	}
+	ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
+	if ((ms < 0) && (oldms < 0))
+		ms = 0;
 	return ms;
 }
 
@@ -1856,7 +1800,7 @@
 		read(chan->alertpipe[0], &blah, sizeof(blah));
 	}
 #ifdef ZAPTEL_OPTIMIZATIONS
-	if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
+	if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
 		ast_clear_flag(chan, AST_FLAG_EXCEPTION);
 		blah = -1;
 		/* IF we can't get event, assume it's an expired as-per the old interface */
@@ -1898,12 +1842,24 @@
 			return f;
 		} else
 			ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
-	}
+	} else
 #endif
+	/* Check for AST_GENERATOR_FD if not null.  If so, call generator with -1
+	   arguments now so it can do whatever it needs to. */
+	if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
+		void *tmp = chan->generatordata;
+		chan->generatordata = NULL;     /* reset to let ast_write get through */
+		chan->generator->generate(chan, tmp, -1, -1);
+		chan->generatordata = tmp;
+		f = &null_frame;
+		return f;
+	}
+
 	/* Check for pending read queue */
 	if (chan->readq) {
 		f = chan->readq;
 		chan->readq = f->next;
+		f->next = NULL;
 		/* Interpret hangup and return NULL */
 		if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
 			ast_frfree(f);
@@ -1928,103 +1884,126 @@
 		}
 	}
 
-
-	if (f && (f->frametype == AST_FRAME_VOICE)) {
-		if (dropaudio) {
-			ast_frfree(f);
-			f = &null_frame;
-		} else if (!(f->subclass & chan->nativeformats)) {
-			/* This frame can't be from the current native formats -- drop it on the
-			   floor */
-			ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n", chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
-			ast_frfree(f);
-			f = &null_frame;
-		} else {
-			if (chan->spies)
-				queue_frame_to_spies(chan, f, SPY_READ);
-
-			if (chan->monitor && chan->monitor->read_stream ) {
+	if (f) {
+		/* if the channel driver returned more than one frame, stuff the excess
+		   into the readq for the next ast_read call
+		*/
+		if (f->next) {
+			chan->readq = f->next;
+			f->next = NULL;
+		}
+
+		switch (f->frametype) {
+		case AST_FRAME_CONTROL:
+			if (f->subclass == AST_CONTROL_ANSWER) {
+				if (prestate == AST_STATE_UP) {
+					ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
+					f = &null_frame;
+				}
+				/* Answer the CDR */
+				ast_setstate(chan, AST_STATE_UP);
+				ast_cdr_answer(chan->cdr);
+			}
+			break;
+		case AST_FRAME_DTMF:
+			ast_log(LOG_DTMF, "DTMF '%c' received on %s\n", f->subclass, chan->name);
+			if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF)) {
+				if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
+					chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
+				else
+					ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
+				f = &null_frame;
+			}
+			break;
+		case AST_FRAME_DTMF_BEGIN:
+			ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
+			break;
+		case AST_FRAME_DTMF_END:
+			ast_log(LOG_DTMF, "DTMF end '%c' received on %s\n", f->subclass, chan->name);
+			break;
+		case AST_FRAME_VOICE:
+			if (dropaudio) {
+				ast_frfree(f);
+				f = &null_frame;
+			} else if (!(f->subclass & chan->nativeformats)) {
+				/* This frame can't be from the current native formats -- drop it on the
+				   floor */
+				ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
+					chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
+				ast_frfree(f);
+				f = &null_frame;
+			} else {
+				if (chan->spies)
+					queue_frame_to_spies(chan, f, SPY_READ);
+				
+				if (chan->monitor && chan->monitor->read_stream ) {
 #ifndef MONITOR_CONSTANT_DELAY
-				int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
-				if (jump >= 0) {
-					if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1)
-						ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
-					chan->insmpl += jump + 4 * f->samples;
-				} else
-					chan->insmpl+= f->samples;
+					int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
+					if (jump >= 0) {
+						if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1)
+							ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
+						chan->insmpl += jump + 4 * f->samples;
+					} else
+						chan->insmpl+= f->samples;
 #else
-				int jump = chan->outsmpl - chan->insmpl;
-				if (jump - MONITOR_DELAY >= 0) {
-					if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
-						ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
-					chan->insmpl += jump;
-				} else
-					chan->insmpl += f->samples;
+					int jump = chan->outsmpl - chan->insmpl;
+					if (jump - MONITOR_DELAY >= 0) {
+						if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
+							ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
+						chan->insmpl += jump;
+					} else
+						chan->insmpl += f->samples;
 #endif
-				if (chan->monitor->state == AST_MONITOR_RUNNING) {
-					if (ast_writestream(chan->monitor->read_stream, f) < 0)
-						ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
+					if (chan->monitor->state == AST_MONITOR_RUNNING) {
+						if (ast_writestream(chan->monitor->read_stream, f) < 0)
+							ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
+					}
+				}
+
+				if (chan->readtrans) {
+					if (!(f = ast_translate(chan->readtrans, f, 1)))
+						f = &null_frame;
+				}
+
+				/* Run any generator sitting on the channel */
+				if (chan->generatordata) {
+					/* Mask generator data temporarily and apply.  If there is a timing function, it
+					   will be calling the generator instead */
+					void *tmp;
+					int res;
+					int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
+					
+					if (chan->timingfunc) {
+						ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
+						ast_settimeout(chan, 0, NULL, NULL);
+					}
+					tmp = chan->generatordata;
+					chan->generatordata = NULL;
+					generate = chan->generator->generate;
+					res = generate(chan, tmp, f->datalen, f->samples);
+					chan->generatordata = tmp;
+					if (res) {
+						ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
+						ast_deactivate_generator(chan);
+					}
+				} else if (f->frametype == AST_FRAME_CNG) {
+					if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
+						ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n");
+						ast_settimeout(chan, 160, generator_force, chan);
+					}
 				}
 			}
-			if (chan->readtrans) {
-				f = ast_translate(chan->readtrans, f, 1);
-				if (!f)
-					f = &null_frame;
-			}
-		}
-	}
-
-	/* Make sure we always return NULL in the future */
-	if (!f) {
+		}
+	} else {
+		/* Make sure we always return NULL in the future */
 		chan->_softhangup |= AST_SOFTHANGUP_DEV;
 		if (chan->generator)
 			ast_deactivate_generator(chan);
 		/* End the CDR if appropriate */
 		if (chan->cdr)
 			ast_cdr_end(chan->cdr);
-	} else if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && f->frametype == AST_FRAME_DTMF) {
-		if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
-			chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
-		else
-			ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
-		f = &null_frame;
-	} else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
-		if (prestate == AST_STATE_UP) {
-			ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
-			f = &null_frame;
-		}
-		/* Answer the CDR */
-		ast_setstate(chan, AST_STATE_UP);
-		ast_cdr_answer(chan->cdr);
-	} 
-
-	/* Run any generator sitting on the line */
-	if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
-		/* Mask generator data temporarily and apply.  If there is a timing function, it
-		   will be calling the generator instead */
-		void *tmp;
-		int res;
-		int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
-
-		if (chan->timingfunc) {
-			ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
-			ast_settimeout(chan, 0, NULL, NULL);
-		}
-		tmp = chan->generatordata;
-		chan->generatordata = NULL;
-		generate = chan->generator->generate;
-		res = generate(chan, tmp, f->datalen, f->samples);
-		chan->generatordata = tmp;
-		if (res) {
-			ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
-			ast_deactivate_generator(chan);
-		}
-	} else if (f && (f->frametype == AST_FRAME_CNG)) {
-		if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
-			ast_log(LOG_DEBUG, "Generator got CNG, switching to zap timed mode\n");
-			ast_settimeout(chan, 160, generator_force, chan);
-		}
-	}
+	}
+
 	/* High bit prints debugging */
 	if (chan->fin & 0x80000000)
 		ast_frame_dump(chan->name, f, "<<");
@@ -2033,6 +2012,7 @@
 	else
 		chan->fin++;
 	ast_mutex_unlock(&chan->lock);
+
 	return f;
 }
 
@@ -2159,7 +2139,8 @@
 
 	if (chan->tech->send_digit)
 		res = chan->tech->send_digit(chan, digit);
-	if (!chan->tech->send_digit || res) {
+	if (!(chan->tech->send_digit && chan->tech->send_digit_begin) ||
+	    res) {
 		/*
 		 * Device does not support DTMF tones, lets fake
 		 * it by doing our own generation. (PM2002)
@@ -2269,6 +2250,18 @@
 		/* XXX Interpret control frames XXX */
 		ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
 		break;
+	case AST_FRAME_DTMF_BEGIN:
+		if (chan->tech->send_digit_begin)
+			res = chan->tech->send_digit_begin(chan, fr->subclass);
+		else
+			res = 0;
+		break;
+	case AST_FRAME_DTMF_END:
+		if (chan->tech->send_digit_end)
+			res = chan->tech->send_digit_end(chan);
+		else
+			res = 0;
+		break;
 	case AST_FRAME_DTMF:
 		ast_clear_flag(chan, AST_FLAG_BLOCKING);
 		ast_mutex_unlock(&chan->lock);
@@ -2295,7 +2288,7 @@
 		else
 			res = 0;
 		break;
-	default:
+	case AST_FRAME_VOICE:
 		if (chan->tech->write) {
 			/* Bypass translator if we're writing format in the raw write format.  This
 			   allows mixing of native / non-native formats */
@@ -2304,11 +2297,10 @@
 			else
 				f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
 			if (f) {
-				if (f->frametype == AST_FRAME_VOICE && chan->spies)
+				if (chan->spies)
 					queue_frame_to_spies(chan, f, SPY_WRITE);
 
-				if( chan->monitor && chan->monitor->write_stream &&
-						f && ( f->frametype == AST_FRAME_VOICE ) ) {
+				if (chan->monitor && chan->monitor->write_stream) {
 #ifndef MONITOR_CONSTANT_DELAY
 					int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
 					if (jump >= 0) {
@@ -2336,13 +2328,6 @@
 			} else
 				res = 0;
 		}
-	}
-
-	/* It's possible this is a translated frame */
-	if (f && f->frametype == AST_FRAME_DTMF) {
-		ast_log(LOG_DTMF, "%s : %c\n", chan->name, f->subclass);
-	} else if (fr->frametype == AST_FRAME_DTMF) {
-		ast_log(LOG_DTMF, "%s : %c\n", chan->name, fr->subclass);
 	}
 
 	if (f && (f != fr))
@@ -3058,9 +3043,10 @@
 	
 	/* Keep the same language.  */
 	ast_copy_string(original->language, clone->language, sizeof(original->language));
-	/* Copy the FD's */
+	/* Copy the FD's other than the generator fd */
 	for (x = 0; x < AST_MAX_FDS; x++) {
-		original->fds[x] = clone->fds[x];
+		if (x != AST_GENERATOR_FD)
+			original->fds[x] = clone->fds[x];
 	}
 	clone_variables(original, clone);
 	AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead);
@@ -3084,7 +3070,7 @@
 	clone->cid = tmpcid;
 	
 	/* Restore original timing file descriptor */
-	original->fds[AST_MAX_FDS - 2] = original->timingfd;
+	original->fds[AST_TIMING_FD] = original->timingfd;
 	
 	/* Our native formats are different now */
 	original->nativeformats = clone->nativeformats;

Modified: team/oej/sipregister/channels/chan_agent.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/channels/chan_agent.c?rev=8982&r1=8981&r2=8982&view=diff
==============================================================================
--- team/oej/sipregister/channels/chan_agent.c (original)
+++ team/oej/sipregister/channels/chan_agent.c Tue Jan 31 09:15:21 2006
@@ -233,10 +233,10 @@
 	int x; \
 	if (p->chan) { \
 		for (x=0;x<AST_MAX_FDS;x++) {\
-			if (x != AST_MAX_FDS - 2) \
+			if (x != AST_TIMING_FD) \
 				ast->fds[x] = p->chan->fds[x]; \
 		} \
-		ast->fds[AST_MAX_FDS - 3] = p->chan->fds[AST_MAX_FDS - 2]; \
+		ast->fds[AST_AGENT_FD] = p->chan->fds[AST_TIMING_FD]; \
 	} \
 } while(0)
 
@@ -445,10 +445,7 @@
 	CHECK_FORMATS(ast, p);
 	if (p->chan) {
 		ast_copy_flags(p->chan, ast, AST_FLAG_EXCEPTION);
-		if (ast->fdno == AST_MAX_FDS - 3)
-			p->chan->fdno = AST_MAX_FDS - 2;
-		else
-			p->chan->fdno = ast->fdno;
+		p->chan->fdno = (ast->fdno == AST_AGENT_FD) ? AST_TIMING_FD : ast->fdno;
 		f = ast_read(p->chan);
 	} else
 		f = &null_frame;

Modified: team/oej/sipregister/channels/chan_features.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/channels/chan_features.c?rev=8982&r1=8981&r2=8982&view=diff
==============================================================================
--- team/oej/sipregister/channels/chan_features.c (original)
+++ team/oej/sipregister/channels/chan_features.c Tue Jan 31 09:15:21 2006
@@ -170,8 +170,8 @@
 	p->subs[index].owner->timingfd = p->subs[index].timingfdbackup;
 	p->subs[index].owner->alertpipe[0] = p->subs[index].alertpipebackup[0];
 	p->subs[index].owner->alertpipe[1] = p->subs[index].alertpipebackup[1];
-	p->subs[index].owner->fds[AST_MAX_FDS-1] = p->subs[index].alertpipebackup[0];
-	p->subs[index].owner->fds[AST_MAX_FDS-2] = p->subs[index].timingfdbackup;
+	p->subs[index].owner->fds[AST_ALERT_FD] = p->subs[index].alertpipebackup[0];
+	p->subs[index].owner->fds[AST_TIMING_FD] = p->subs[index].timingfdbackup;
 }
 
 static void update_features(struct feature_pvt *p, int index)

Modified: team/oej/sipregister/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/channels/chan_sip.c?rev=8982&r1=8981&r2=8982&view=diff
==============================================================================
--- team/oej/sipregister/channels/chan_sip.c (original)
+++ team/oej/sipregister/channels/chan_sip.c Tue Jan 31 09:15:21 2006
@@ -365,6 +365,7 @@
 #define DEFAULT_PEDANTIC	FALSE
 #define DEFAULT_AUTOCREATEPEER	FALSE
 #define DEFAULT_QUALIFY		FALSE
+#define DEFAULT_T1MIN		100		/*!< 100 MS for minimal roundtrip time */
 #ifndef DEFAULT_USERAGENT
 #define DEFAULT_USERAGENT "Asterisk PBX"	/*!< Default Useragent: header unless re-defined in sip.conf */
 #endif
@@ -380,6 +381,7 @@
 static int default_qualify;		/*!< Default Qualify= setting */
 static char default_vmexten[AST_MAX_EXTENSION];
 static char default_musicclass[MAX_MUSICCLASS];		/*!< Global music on hold class */
+static struct ast_codec_pref default_prefs;		/*!< Default codec prefs */
 
 /* Global settings only apply to the channel */
 static int global_rtautoclear = 120;
@@ -405,6 +407,7 @@
 static char global_useragent[AST_MAX_EXTENSION];	/*!< Useragent for the SIP channel */
 static int allow_external_domains;	/*!< Accept calls to external SIP domains? */
 static int global_callevents;		/*!< Whether we send manager events or not */
+static int global_t1min;		/*!< T1 roundtrip time minimum */
 
 /*! \brief Codecs that we support by default: */
 static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
@@ -443,13 +446,12 @@
 static int sip_reloading = FALSE;			/*!< Flag for avoiding multiple reloads at the same time */
 static enum channelreloadreason sip_reloadreason;	/*!< Reason for last reload/load of configuration */
 
-static struct sched_context *sched;
-static struct io_context *io;
+static struct sched_context *sched;	/*!< The scheduling context */
+static struct io_context *io;		/*!< The IO context */
 
 #define DEC_CALL_LIMIT	0
 #define INC_CALL_LIMIT	1
 
-static struct ast_codec_pref prefs;
 
 /*! \brief sip_request: The data grabbed from the UDP socket */
 struct sip_request {
@@ -464,6 +466,13 @@
 	char data[SIP_MAX_PACKET];
 	int debug;		/*!< Debug flag for this packet */
 	unsigned int flags;	/*!< SIP_PKT Flags for this packet */
+};
+
+/*! \brief structure used in transfers */
+struct sip_dual {
+	struct ast_channel *chan1;
+	struct ast_channel *chan2;
+	struct sip_request req;
 };
 
 struct sip_pkt;
@@ -904,7 +913,7 @@
 static int transmit_response(struct sip_pvt *p, char *msg, struct sip_request *req);
 static int transmit_response_with_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
 static int transmit_response_with_unsupported(struct sip_pvt *p, char *msg, struct sip_request *req, char *unsupported);
-static int transmit_response_with_auth(struct sip_pvt *p, char *msg, struct sip_request *req, const char *rand, int reliable, char *header, int stale);
+static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, struct sip_request *req, const char *rand, int reliable, const char *header, int stale);
 static int transmit_request(struct sip_pvt *p, int sipmethod, int inc, int reliable, int newbranch);
 static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int inc, int reliable, int newbranch);
 static int transmit_invite(struct sip_pvt *p, int sipmethod, int sendsdp, int init);
@@ -923,7 +932,6 @@
 static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime);
 static int sip_do_reload(enum channelreloadreason reason);
 static int expire_register(void *data);
-
 static struct ast_channel *sip_request_call(const char *type, int format, void *data, int *cause);
 static int sip_devicestate(void *data);
 static int sip_sendtext(struct ast_channel *ast, const char *text);
@@ -939,6 +947,9 @@
 static int clear_realm_authentication(struct sip_auth *authlist);                            /* Clear realm authentication list (at reload) */
 static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, char *configuration, int lineno);   /* Add realm authentication in list */
 static struct sip_auth *find_realm_authentication(struct sip_auth *authlist, const char *realm);         /* Find authentication for a specific realm */
+static int check_auth(struct sip_pvt *p, struct sip_request *req, const char *username,
+		      const char *secret, const char *md5secret, int sipmethod,
+		      char *uri, int reliable, int ignore);
 static int check_sip_domain(const char *domain, char *context, size_t len); /* Check if domain is one of our local domains */
 static void append_date(struct sip_request *req);	/* Append date to SIP packet */
 static int determine_firstline_parts(struct sip_request *req);
@@ -950,7 +961,7 @@
 static unsigned int parse_sip_options(struct sip_pvt *pvt, char *supported);
 static void sip_destroy(struct sip_pvt *p);
 static void parse_request(struct sip_request *req);
-static char *get_header(struct sip_request *req, char *name);
+static char *get_header(struct sip_request *req, const char *name);
 static void copy_request(struct sip_request *dst,struct sip_request *src);
 static int transmit_response_reliable(struct sip_pvt *p, char *msg, struct sip_request *req, int fatal);
 static int transmit_register(struct sip_registry *r, int sipmethod, char *auth, char *authheader);
@@ -958,6 +969,12 @@
 static int __sip_do_register(struct sip_registry *r);
 static int restart_monitor(void);
 static char *generate_random_string(char *buf, size_t size);
+
+/*----- RTP interface functions */
+static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active);
+static struct ast_rtp *sip_get_rtp_peer(struct ast_channel *chan);
+static struct ast_rtp *sip_get_vrtp_peer(struct ast_channel *chan);
+static int sip_get_codec(struct ast_channel *chan);
 
 /*! \brief Definition of this channel for PBX channel registration */
 static const struct ast_channel_tech sip_tech = {
@@ -980,6 +997,16 @@
 	.bridge = ast_rtp_bridge,
 	.send_text = sip_sendtext,
 };
+
+/*! \brief Interface structure with callbacks used to connect to RTP module */
+static struct ast_rtp_protocol sip_rtp = {
+	type: channeltype,
+	get_rtp_info: sip_get_rtp_peer,
+	get_vrtp_info: sip_get_vrtp_peer,
+	set_rtp_peer: sip_set_rtp_peer,
+	get_codec: sip_get_codec,
+};
+
 
 /*!
   \brief Thread-safe random number generator
@@ -1926,8 +1953,9 @@
 	r->callgroup = peer->callgroup;
 	r->pickupgroup = peer->pickupgroup;
 	/* Set timer T1 to RTT for this peer (if known by qualify=) */
+	/* Minimum is settable or default to 100 ms */
 	if (peer->maxms && peer->lastms)
-		r->timer_t1 = peer->lastms;
+		r->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
 	if ((ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_AUTO))
 		r->noncodeccapability |= AST_RTP_DTMF;
 	else
@@ -2983,7 +3011,7 @@
 	return _default;
 }
 
-static char *__get_header(struct sip_request *req, char *name, int *start)
+static char *__get_header(struct sip_request *req, const char *name, int *start)
 {
 	int pass;
 
@@ -3019,7 +3047,7 @@
 }
 
 /*! \brief Get header from SIP request */
-static char *get_header(struct sip_request *req, char *name)
+static char *get_header(struct sip_request *req, const char *name)
 {
 	int start = 0;
 	return __get_header(req, name, &start);
@@ -3154,7 +3182,8 @@
 	p->autokillid = -1;
 	p->subscribed = NONE;
 	p->stateid = -1;
-	p->prefs = prefs;
+	p->prefs = default_prefs;		/* Set default codecs for this call */
+
 	if (intended_method != SIP_OPTIONS)	/* Peerpoke has it's own system */
 		p->timer_t1 = 500;	/* Default SIP retransmission timer T1 (RFC 3261) */
 #ifdef OSP_SUPPORT
@@ -4077,7 +4106,7 @@
 }
 
 /*! \brief Initialize SIP response, based on SIP request */
-static int init_resp(struct sip_request *req, char *resp, struct sip_request *orig)
+static int init_resp(struct sip_request *req, const char *resp, struct sip_request *orig)
 {
 	/* Initialize a response */
 	if (req->headers || req->len) {
@@ -4110,7 +4139,7 @@
 
 
 /*! \brief Prepare SIP response packet */
-static int respprep(struct sip_request *resp, struct sip_pvt *p, char *msg, struct sip_request *req)
+static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, struct sip_request *req)
 {
 	char newto[256], *ot;
 
@@ -4341,7 +4370,7 @@
 }
 
 /*! \brief Respond with authorization request */
-static int transmit_response_with_auth(struct sip_pvt *p, char *msg, struct sip_request *req, const char *randdata, int reliable, char *header, int stale)
+static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, struct sip_request *req, const char *randdata, int reliable, const char *header, int stale)
 {
 	struct sip_request resp;
 	char tmp[256];
@@ -6217,19 +6246,19 @@
 
 /*! \brief  Check user authorization from peer definition 
 	Some actions, like REGISTER and INVITEs from peers require
-	authentication (if peer have secret set) */
+	authentication (if peer have secret set) 
+	\return -1 on Error, 0 on success, 1 on challenge sent
+	
+*/
 static int check_auth(struct sip_pvt *p, struct sip_request *req, const char *username,
 		      const char *secret, const char *md5secret, int sipmethod,
 		      char *uri, int reliable, int ignore)
 {
-	int res = -1;
-	char *response = "407 Proxy Authentication Required";
-	char *reqheader = "Proxy-Authorization";
-	char *respheader = "Proxy-Authenticate";
-	char *authtoken;
-#ifdef OSP_SUPPORT
-	char *osptoken;
-#endif
+	const char *response = "407 Proxy Authentication Required";
+	const char *reqheader = "Proxy-Authorization";

[... 1201 lines stripped ...]


More information about the svn-commits mailing list