[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