[asterisk-commits] oej: branch oej/bp-res_conf_ldap-1.4 r286269 - in /team/oej/bp-res_conf_ldap-...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Sep 11 12:09:04 CDT 2010
Author: oej
Date: Sat Sep 11 12:08:55 2010
New Revision: 286269
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=286269
Log:
Reset automerge
Added:
team/oej/bp-res_conf_ldap-1.4/BSDmakefile
- copied unchanged from r286267, branches/1.4/BSDmakefile
team/oej/bp-res_conf_ldap-1.4/include/asterisk/select.h
- copied unchanged from r286267, branches/1.4/include/asterisk/select.h
team/oej/bp-res_conf_ldap-1.4/tests/test_poll.c
- copied unchanged from r286267, branches/1.4/tests/test_poll.c
Modified:
team/oej/bp-res_conf_ldap-1.4/ (props changed)
team/oej/bp-res_conf_ldap-1.4/apps/app_chanspy.c
team/oej/bp-res_conf_ldap-1.4/apps/app_voicemail.c
team/oej/bp-res_conf_ldap-1.4/channels/chan_alsa.c
team/oej/bp-res_conf_ldap-1.4/channels/chan_dahdi.c
team/oej/bp-res_conf_ldap-1.4/channels/chan_iax2.c
team/oej/bp-res_conf_ldap-1.4/channels/chan_local.c
team/oej/bp-res_conf_ldap-1.4/channels/chan_misdn.c
team/oej/bp-res_conf_ldap-1.4/channels/chan_oss.c
team/oej/bp-res_conf_ldap-1.4/channels/chan_phone.c
team/oej/bp-res_conf_ldap-1.4/channels/chan_sip.c
team/oej/bp-res_conf_ldap-1.4/codecs/gsm/Makefile
team/oej/bp-res_conf_ldap-1.4/configure
team/oej/bp-res_conf_ldap-1.4/configure.ac
team/oej/bp-res_conf_ldap-1.4/funcs/func_channel.c
team/oej/bp-res_conf_ldap-1.4/include/asterisk/autoconfig.h.in
team/oej/bp-res_conf_ldap-1.4/include/asterisk/channel.h
team/oej/bp-res_conf_ldap-1.4/include/asterisk/frame.h
team/oej/bp-res_conf_ldap-1.4/include/asterisk/pbx.h
team/oej/bp-res_conf_ldap-1.4/include/asterisk/poll-compat.h
team/oej/bp-res_conf_ldap-1.4/main/asterisk.c
team/oej/bp-res_conf_ldap-1.4/main/channel.c
team/oej/bp-res_conf_ldap-1.4/main/file.c
team/oej/bp-res_conf_ldap-1.4/main/manager.c
team/oej/bp-res_conf_ldap-1.4/main/poll.c
team/oej/bp-res_conf_ldap-1.4/main/test.c
team/oej/bp-res_conf_ldap-1.4/makeopts.in
team/oej/bp-res_conf_ldap-1.4/pbx/pbx_config.c
team/oej/bp-res_conf_ldap-1.4/res/res_features.c
team/oej/bp-res_conf_ldap-1.4/res/res_musiconhold.c
Propchange: team/oej/bp-res_conf_ldap-1.4/
------------------------------------------------------------------------------
automerge = http://www.codename-pineapple.org/
Propchange: team/oej/bp-res_conf_ldap-1.4/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Sat Sep 11 12:08:55 2010
@@ -1,1 +1,1 @@
-/branches/1.4:1-284402
+/branches/1.4:1-286267
Modified: team/oej/bp-res_conf_ldap-1.4/apps/app_chanspy.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/bp-res_conf_ldap-1.4/apps/app_chanspy.c?view=diff&rev=286269&r1=286268&r2=286269
==============================================================================
--- team/oej/bp-res_conf_ldap-1.4/apps/app_chanspy.c (original)
+++ team/oej/bp-res_conf_ldap-1.4/apps/app_chanspy.c Sat Sep 11 12:08:55 2010
@@ -633,7 +633,7 @@
ast_channel_unlock(peer);
if (!ast_test_flag(flags, OPTION_QUIET)) {
- if (ast_fileexists(peer_name, NULL, NULL) != -1) {
+ if (ast_fileexists(peer_name, NULL, NULL) > 0) {
res = ast_streamfile(chan, peer_name, chan->language);
if (!res)
res = ast_waitstream(chan, "");
Modified: team/oej/bp-res_conf_ldap-1.4/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/bp-res_conf_ldap-1.4/apps/app_voicemail.c?view=diff&rev=286269&r1=286268&r2=286269
==============================================================================
--- team/oej/bp-res_conf_ldap-1.4/apps/app_voicemail.c (original)
+++ team/oej/bp-res_conf_ldap-1.4/apps/app_voicemail.c Sat Sep 11 12:08:55 2010
@@ -915,11 +915,12 @@
}
value = strstr(tmp,",");
if (!value) {
- ast_log(LOG_WARNING, "variable has bad format.\n");
- break;
+ new = alloca(strlen(newpassword)+1);
+ sprintf(new, "%s", newpassword);
+ } else {
+ new = alloca((strlen(value)+strlen(newpassword)+1));
+ sprintf(new,"%s%s", newpassword, value);
}
- new = alloca((strlen(value)+strlen(newpassword)+1));
- sprintf(new,"%s%s", newpassword, value);
if (!(cat = ast_category_get(cfg, category))) {
ast_log(LOG_WARNING, "Failed to get category structure.\n");
break;
Modified: team/oej/bp-res_conf_ldap-1.4/channels/chan_alsa.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/bp-res_conf_ldap-1.4/channels/chan_alsa.c?view=diff&rev=286269&r1=286268&r2=286269
==============================================================================
--- team/oej/bp-res_conf_ldap-1.4/channels/chan_alsa.c (original)
+++ team/oej/bp-res_conf_ldap-1.4/channels/chan_alsa.c Sat Sep 11 12:08:55 2010
@@ -277,34 +277,25 @@
static void *sound_thread(void *unused)
{
- fd_set rfds;
- fd_set wfds;
- int max, res;
+ struct pollfd pfd[3] = { { .fd = sndcmd[0], .events = POLLIN }, { .fd = writedev }, { .fd = readdev } };
+ int res, x;
for (;;) {
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- max = sndcmd[0];
- FD_SET(sndcmd[0], &rfds);
- if (cursound > -1) {
- FD_SET(writedev, &wfds);
- if (writedev > max)
- max = writedev;
- }
+ for (x = 0; x < 3; x++) {
+ pfd[x].revents = 0;
+ }
+
+ pfd[1].events = cursound > -1 ? POLLOUT : 0;
#ifdef ALSA_MONITOR
- if (!alsa.owner) {
- FD_SET(readdev, &rfds);
- if (readdev > max)
- max = readdev;
- }
-#endif
- res = ast_select(max + 1, &rfds, &wfds, NULL, NULL);
+ pfd[2].events = !alsa.owner ? POLLIN : 0;
+#endif
+ res = ast_poll(pfd, 3, -1);
if (res < 1) {
- ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
+ ast_log(LOG_WARNING, "poll() failed: %s\n", strerror(errno));
continue;
}
#ifdef ALSA_MONITOR
- if (FD_ISSET(readdev, &rfds)) {
+ if (pfd[2].revents & POLLIN) {
/* Keep the pipe going with read audio */
snd_pcm_state_t state;
short buf[FRAME_SIZE];
@@ -329,7 +320,7 @@
alsa_monitor_read((char *) buf, r * 2);
}
#endif
- if (FD_ISSET(sndcmd[0], &rfds)) {
+ if (pfd[0].revents & POLLIN) {
if (read(sndcmd[0], &cursound, sizeof(cursound)) < 0) {
ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
}
@@ -337,9 +328,11 @@
offset = 0;
sampsent = 0;
}
- if (FD_ISSET(writedev, &wfds))
- if (send_sound())
+ if (pfd[1].revents & POLLOUT) {
+ if (send_sound()) {
ast_log(LOG_WARNING, "Failed to write sound\n");
+ }
+ }
}
/* Never reached */
return NULL;
Modified: team/oej/bp-res_conf_ldap-1.4/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/bp-res_conf_ldap-1.4/channels/chan_dahdi.c?view=diff&rev=286269&r1=286268&r2=286269
==============================================================================
--- team/oej/bp-res_conf_ldap-1.4/channels/chan_dahdi.c (original)
+++ team/oej/bp-res_conf_ldap-1.4/channels/chan_dahdi.c Sat Sep 11 12:08:55 2010
@@ -9911,6 +9911,14 @@
pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
break;
default:
+ if (!pri->pvts[chanpos]->outgoing) {
+ /*
+ * The incoming call leg hung up before getting
+ * connected so just hangup the call.
+ */
+ pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+ break;
+ }
switch (e->hangup.cause) {
case PRI_CAUSE_USER_BUSY:
pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
@@ -9986,6 +9994,14 @@
pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
break;
default:
+ if (!pri->pvts[chanpos]->outgoing) {
+ /*
+ * The incoming call leg hung up before getting
+ * connected so just hangup the call.
+ */
+ pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+ break;
+ }
switch (e->hangup.cause) {
case PRI_CAUSE_USER_BUSY:
pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
Modified: team/oej/bp-res_conf_ldap-1.4/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/bp-res_conf_ldap-1.4/channels/chan_iax2.c?view=diff&rev=286269&r1=286268&r2=286269
==============================================================================
--- team/oej/bp-res_conf_ldap-1.4/channels/chan_iax2.c (original)
+++ team/oej/bp-res_conf_ldap-1.4/channels/chan_iax2.c Sat Sep 11 12:08:55 2010
@@ -12713,13 +12713,6 @@
return AST_MODULE_LOAD_FAILURE;
}
- randomcalltokendata = ast_random();
- ast_custom_function_register(&iaxpeer_function);
-
- iax_set_output(iax_debug_output);
- iax_set_error(iax_error_output);
- jb_setoutput(jb_error_output, jb_warning_output, NULL);
-
#ifdef HAVE_DAHDI
#ifdef DAHDI_TIMERACK
timingfd = open(DAHDI_FILE_TIMER, O_RDWR);
@@ -12735,12 +12728,12 @@
for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
ast_mutex_init(&iaxsl[x]);
}
-
+
ast_cond_init(&sched_cond, NULL);
io = io_context_create();
sched = sched_context_create();
-
+
if (!io || !sched) {
ast_log(LOG_ERROR, "Out of memory\n");
return -1;
@@ -12760,33 +12753,44 @@
}
ast_netsock_init(outsock);
+ randomcalltokendata = ast_random();
+
+ iax_set_output(iax_debug_output);
+ iax_set_error(iax_error_output);
+ jb_setoutput(jb_error_output, jb_warning_output, NULL);
+
ast_mutex_init(&waresl.lock);
AST_LIST_HEAD_INIT(&iaxq.queue);
-
+
+ if (set_config(config, 0) == -1) {
+ return AST_MODULE_LOAD_DECLINE;
+ }
+
ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
-
+
+ ast_custom_function_register(&iaxpeer_function);
+
ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
- if(set_config(config, 0) == -1)
- return AST_MODULE_LOAD_DECLINE;
-
- if (ast_channel_register(&iax2_tech)) {
+ if (ast_channel_register(&iax2_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
__unload_module();
return -1;
}
- if (ast_register_switch(&iax2_switch))
+ if (ast_register_switch(&iax2_switch)) {
ast_log(LOG_ERROR, "Unable to register IAX switch\n");
+ }
res = start_network_thread();
if (!res) {
- if (option_verbose > 1)
+ if (option_verbose > 1) {
ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
+ }
} else {
ast_log(LOG_ERROR, "Unable to start network thread\n");
ast_netsock_release(netsock);
Modified: team/oej/bp-res_conf_ldap-1.4/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/bp-res_conf_ldap-1.4/channels/chan_local.c?view=diff&rev=286269&r1=286268&r2=286269
==============================================================================
--- team/oej/bp-res_conf_ldap-1.4/channels/chan_local.c (original)
+++ team/oej/bp-res_conf_ldap-1.4/channels/chan_local.c Sat Sep 11 12:08:55 2010
@@ -79,6 +79,7 @@
static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
static int local_sendtext(struct ast_channel *ast, const char *text);
static int local_devicestate(void *data);
+static int local_setoption(struct ast_channel *chan, int option, void *data, int datalen);
/* PBX interface structure for channel registration */
static const struct ast_channel_tech local_tech = {
@@ -100,6 +101,7 @@
.send_html = local_sendhtml,
.send_text = local_sendtext,
.devicestate = local_devicestate,
+ .setoption = local_setoption,
};
struct local_pvt {
@@ -123,6 +125,71 @@
#define LOCAL_MOH_PASSTHRU (1 << 5) /*!< Pass through music on hold start/stop frames */
static AST_LIST_HEAD_STATIC(locals, local_pvt);
+
+static int local_setoption(struct ast_channel *chan, int option, void * data, int datalen)
+{
+ int res;
+ struct local_pvt *p;
+ struct ast_channel *otherchan;
+ ast_chan_write_info_t *write_info;
+
+ if (option != AST_OPTION_CHANNEL_WRITE) {
+ return -1;
+ }
+
+ write_info = data;
+
+ if (write_info->version != AST_CHAN_WRITE_INFO_T_VERSION) {
+ ast_log(LOG_ERROR, "The chan_write_info_t type has changed, and this channel hasn't been updated!\n");
+ return -1;
+ }
+
+
+startover:
+ ast_channel_lock(chan);
+
+ p = chan->tech_pvt;
+ if (!p) {
+ ast_channel_unlock(chan);
+ ast_log(LOG_WARNING, "Could not update other side of %s, local_pvt went away.\n", chan->name);
+ return -1;
+ }
+
+ while (ast_mutex_trylock(&p->lock)) {
+ ast_channel_unlock(chan);
+ sched_yield();
+ ast_channel_lock(chan);
+ p = chan->tech_pvt;
+ if (!p) {
+ ast_channel_unlock(chan);
+ ast_log(LOG_WARNING, "Could not update other side of %s, local_pvt went away.\n", chan->name);
+ return -1;
+ }
+ }
+
+ otherchan = (write_info->chan == p->owner) ? p->chan : p->owner;
+
+ if (!otherchan || otherchan == write_info->chan) {
+ ast_mutex_unlock(&p->lock);
+ ast_channel_unlock(chan);
+ ast_log(LOG_WARNING, "Could not update other side of %s, other side went away.\n", chan->name);
+ return 0;
+ }
+
+ if (ast_channel_trylock(otherchan)) {
+ ast_mutex_unlock(&p->lock);
+ ast_channel_unlock(chan);
+ goto startover;
+ }
+
+ res = write_info->write_fn(otherchan, write_info->function, write_info->data, write_info->value);
+
+ ast_channel_unlock(otherchan);
+ ast_mutex_unlock(&p->lock);
+ ast_channel_unlock(chan);
+
+ return res;
+}
/*! \brief Adds devicestate to local channels */
static int local_devicestate(void *data)
Modified: team/oej/bp-res_conf_ldap-1.4/channels/chan_misdn.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/bp-res_conf_ldap-1.4/channels/chan_misdn.c?view=diff&rev=286269&r1=286268&r2=286269
==============================================================================
--- team/oej/bp-res_conf_ldap-1.4/channels/chan_misdn.c (original)
+++ team/oej/bp-res_conf_ldap-1.4/channels/chan_misdn.c Sat Sep 11 12:08:55 2010
@@ -2763,9 +2763,8 @@
static struct ast_frame *misdn_read(struct ast_channel *ast)
{
struct chan_list *tmp;
- fd_set rrfs;
- struct timeval tv;
int len, t;
+ struct pollfd pfd = { .fd = -1, .events = POLLIN };
if (!ast) {
chan_misdn_log(1, 0, "misdn_read called without ast\n");
@@ -2781,30 +2780,23 @@
return NULL;
}
- tv.tv_sec=0;
- tv.tv_usec=20000;
-
- FD_ZERO(&rrfs);
- FD_SET(tmp->pipe[0],&rrfs);
-
- t=select(FD_SETSIZE,&rrfs,NULL, NULL,&tv);
+ pfd.fd = tmp->pipe[0];
+ t = ast_poll(&pfd, 1, 20);
+
+ if (t < 0) {
+ chan_misdn_log(-1, tmp->bc->port, "poll() error (err=%s)\n", strerror(errno));
+ return NULL;
+ }
if (!t) {
- chan_misdn_log(3, tmp->bc->port, "read Select Timed out\n");
- len=160;
- }
-
- if (t<0) {
- chan_misdn_log(-1, tmp->bc->port, "Select Error (err=%s)\n",strerror(errno));
- return NULL;
- }
-
- if (FD_ISSET(tmp->pipe[0],&rrfs)) {
- len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf));
-
- if (len<=0) {
+ chan_misdn_log(3, tmp->bc->port, "poll() timed out\n");
+ len = 160;
+ } else if (pfd.revents & POLLIN) {
+ len = read(tmp->pipe[0], tmp->ast_rd_buf, sizeof(tmp->ast_rd_buf));
+
+ if (len <= 0) {
/* we hangup here, since our pipe is closed */
- chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n");
+ chan_misdn_log(2, tmp->bc->port, "misdn_read: Pipe closed, hanging up\n");
return NULL;
}
@@ -4910,26 +4902,22 @@
if (ch->ast)
ast_queue_frame(ch->ast, &frame);
} else {
- fd_set wrfs;
- struct timeval tv = { 0, 0 };
+ struct pollfd pfd = { .fd = ch->pipe[1], .events = POLLOUT };
int t;
- FD_ZERO(&wrfs);
- FD_SET(ch->pipe[1], &wrfs);
-
- t = select(FD_SETSIZE, NULL, &wrfs, NULL, &tv);
+ t = ast_poll(&pfd, 1, 0);
+
+ if (t < 0) {
+ chan_misdn_log(-1, bc->port, "poll() error (err=%s)\n", strerror(errno));
+ break;
+ }
if (!t) {
- chan_misdn_log(9, bc->port, "Select Timed out\n");
+ chan_misdn_log(9, bc->port, "poll() timed out\n");
break;
}
-
- if (t < 0) {
- chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n", strerror(errno));
- break;
- }
-
- if (FD_ISSET(ch->pipe[1], &wrfs)) {
+
+ if (pfd.revents & POLLOUT) {
chan_misdn_log(9, bc->port, "writing %d bytes to asterisk\n", bc->bframe_len);
if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) {
chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno));
Modified: team/oej/bp-res_conf_ldap-1.4/channels/chan_oss.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/bp-res_conf_ldap-1.4/channels/chan_oss.c?view=diff&rev=286269&r1=286268&r2=286269
==============================================================================
--- team/oej/bp-res_conf_ldap-1.4/channels/chan_oss.c (original)
+++ team/oej/bp-res_conf_ldap-1.4/channels/chan_oss.c Sat Sep 11 12:08:55 2010
@@ -604,38 +604,32 @@
if (read(o->sounddev, ign, sizeof(ign)) < 0) {
}
for (;;) {
- fd_set rfds, wfds;
- int maxfd, res;
+ int res;
+ struct pollfd pfd[2] = { { .fd = o->sndcmd[0], .events = POLLIN }, { .fd = o->sounddev, .events = 0 } };
pthread_testcancel();
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_SET(o->sndcmd[0], &rfds);
- maxfd = o->sndcmd[0]; /* pipe from the main process */
- if (o->cursound > -1 && o->sounddev < 0)
+ if (o->cursound > -1 && o->sounddev < 0) {
setformat(o, O_RDWR); /* need the channel, try to reopen */
- else if (o->cursound == -1 && o->owner == NULL)
+ } else if (o->cursound == -1 && o->owner == NULL) {
setformat(o, O_CLOSE); /* can close */
+ }
if (o->sounddev > -1) {
if (!o->owner) { /* no one owns the audio, so we must drain it */
- FD_SET(o->sounddev, &rfds);
- maxfd = MAX(o->sounddev, maxfd);
+ pfd[1].events |= POLLIN;
}
if (o->cursound > -1) {
- FD_SET(o->sounddev, &wfds);
- maxfd = MAX(o->sounddev, maxfd);
+ pfd[1].events |= POLLOUT;
}
}
- /* ast_select emulates linux behaviour in terms of timeout handling */
- res = ast_select(maxfd + 1, &rfds, &wfds, NULL, NULL);
+ res = ast_poll(pfd, 2, -1);
pthread_testcancel();
if (res < 1) {
- ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
+ ast_log(LOG_WARNING, "poll() failed: %s\n", strerror(errno));
sleep(1);
continue;
}
- if (FD_ISSET(o->sndcmd[0], &rfds)) {
+ if (pfd[0].revents & POLLIN) {
/* read which sound to play from the pipe */
int i, what = -1;
@@ -656,11 +650,13 @@
ast_log(LOG_WARNING, "invalid sound index: %d\n", what);
}
if (o->sounddev > -1) {
- if (FD_ISSET(o->sounddev, &rfds)) /* read and ignore errors */
+ if (pfd[1].revents & POLLIN) { /* read and ignore errors */
if (read(o->sounddev, ign, sizeof(ign)) < 0) {
}
- if (FD_ISSET(o->sounddev, &wfds))
+ }
+ if (pfd[1].revents & POLLOUT) {
send_sound(o);
+ }
}
}
return NULL; /* Never reached */
Modified: team/oej/bp-res_conf_ldap-1.4/channels/chan_phone.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/bp-res_conf_ldap-1.4/channels/chan_phone.c?view=diff&rev=286269&r1=286268&r2=286269
==============================================================================
--- team/oej/bp-res_conf_ldap-1.4/channels/chan_phone.c (original)
+++ team/oej/bp-res_conf_ldap-1.4/channels/chan_phone.c Sat Sep 11 12:08:55 2010
@@ -997,12 +997,12 @@
static void *do_monitor(void *data)
{
- fd_set rfds, efds;
- int n, res;
+ struct pollfd *fds = NULL;
+ int nfds = 0, inuse_fds = 0, res;
struct phone_pvt *i;
int tonepos = 0;
/* The tone we're playing this round */
- struct timeval tv = {0,0};
+ struct timeval tv = { 0, 0 };
int dotone;
/* This thread monitors all the frame relay interfaces which are not yet in use
(and thus do not have a separate thread) indefinitely */
@@ -1016,33 +1016,38 @@
}
/* Build the stuff we're going to select on, that is the socket of every
phone_pvt that does not have an associated owner channel */
- n = -1;
- FD_ZERO(&rfds);
- FD_ZERO(&efds);
i = iflist;
dotone = 0;
- while (i) {
- if (FD_ISSET(i->fd, &rfds))
- ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->fd, i->dev);
+ inuse_fds = 0;
+ for (i = iflist; i; i = i->next) {
if (!i->owner) {
/* This needs to be watched, as it lacks an owner */
- FD_SET(i->fd, &rfds);
- FD_SET(i->fd, &efds);
- if (i->fd > n)
- n = i->fd;
+ if (inuse_fds == nfds) {
+ void *tmp = ast_realloc(fds, (nfds + 1) * sizeof(*fds));
+ if (!tmp) {
+ /* Avoid leaking */
+ continue;
+ }
+ fds = tmp;
+ nfds++;
+ }
+ fds[inuse_fds].fd = i->fd;
+ fds[inuse_fds].events = POLLIN | POLLERR;
+ fds[inuse_fds].revents = 0;
+ inuse_fds++;
+
if (i->dialtone && i->mode != MODE_SIGMA) {
/* Remember we're going to have to come back and play
more dialtones */
if (ast_tvzero(tv)) {
/* If we're due for a dialtone, play one */
- if (write(i->fd, DialTone + tonepos, 240) != 240)
+ if (write(i->fd, DialTone + tonepos, 240) != 240) {
ast_log(LOG_WARNING, "Dial tone write error\n");
+ }
}
dotone++;
}
}
-
- i = i->next;
}
/* Okay, now that we know what to do, release the interface lock */
ast_mutex_unlock(&iflock);
@@ -1051,26 +1056,28 @@
if (dotone && i && i->mode != MODE_SIGMA) {
/* If we're ready to recycle the time, set it to 30 ms */
tonepos += 240;
- if (tonepos >= sizeof(DialTone))
- tonepos = 0;
+ if (tonepos >= sizeof(DialTone)) {
+ tonepos = 0;
+ }
if (ast_tvzero(tv)) {
- tv = ast_tv(30000, 0);
- }
- res = ast_select(n + 1, &rfds, NULL, &efds, &tv);
+ tv = ast_tv(0, 30000);
+ }
+ res = ast_poll2(fds, inuse_fds, &tv);
} else {
- res = ast_select(n + 1, &rfds, NULL, &efds, NULL);
- tv = ast_tv(0,0);
+ res = ast_poll(fds, inuse_fds, -1);
+ tv = ast_tv(0, 0);
tonepos = 0;
}
/* Okay, select has finished. Let's see what happened. */
if (res < 0) {
- ast_log(LOG_DEBUG, "select return %d: %s\n", res, strerror(errno));
+ ast_log(LOG_DEBUG, "poll returned %d: %s\n", res, strerror(errno));
continue;
}
/* If there are no fd's changed, just continue, it's probably time
to play some more dialtones */
- if (!res)
+ if (!res) {
continue;
+ }
/* Alright, lock the interface list again, and let's look and see what has
happened */
if (ast_mutex_lock(&iflock)) {
@@ -1078,15 +1085,27 @@
continue;
}
- i = iflist;
- for(; i; i=i->next) {
- if (FD_ISSET(i->fd, &rfds)) {
+ for (i = iflist; i; i = i->next) {
+ int j;
+ /* Find the record */
+ for (j = 0; j < inuse_fds; j++) {
+ if (fds[j].fd == i->fd) {
+ break;
+ }
+ }
+
+ /* Not found? */
+ if (j == inuse_fds) {
+ continue;
+ }
+
+ if (fds[j].revents & POLLIN) {
if (i->owner) {
continue;
}
phone_mini_packet(i);
}
- if (FD_ISSET(i->fd, &efds)) {
+ if (fds[j].revents & POLLERR) {
if (i->owner) {
continue;
}
@@ -1096,7 +1115,6 @@
ast_mutex_unlock(&iflock);
}
return NULL;
-
}
static int restart_monitor()
Modified: team/oej/bp-res_conf_ldap-1.4/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/bp-res_conf_ldap-1.4/channels/chan_sip.c?view=diff&rev=286269&r1=286268&r2=286269
==============================================================================
--- team/oej/bp-res_conf_ldap-1.4/channels/chan_sip.c (original)
+++ team/oej/bp-res_conf_ldap-1.4/channels/chan_sip.c Sat Sep 11 12:08:55 2010
@@ -1258,6 +1258,39 @@
AST_THREADSTORAGE_CUSTOM(ts_video_rtp, ts_video_rtp_init, ts_ast_rtp_destroy);
#endif
+struct sip_extenstate_update {
+ struct sip_pvt *pvt;
+ int state;
+ int marked;
+ AST_LIST_ENTRY(sip_extenstate_update) list; /*!< Pointer to next update in list */
+ char *context;
+ char exten[0];
+};
+
+
+/*!
+ * \brief list of extension state updates for the dialog list.
+ *
+ * \note This list deserves a detailed explanation as to why it was
+ * created and why it is necessary... So here it is.
+ *
+ * When an endpoint SUBSCRIBES to the state of a hint a callback function
+ * is registered with the Asterisk core. That callback is used to notify
+ * chan_sip every time that hint's state changes and what endpoint we need
+ * to update. The problem occurs with the locking order used during that
+ * callback function. When the function is used by the Asterisk core, the
+ * global contexts lock is held. Then within the callback the sip_pvt lock
+ * is held. That completely invalidates the locking order used everywhere
+ * else in chan_sip regarding these two locks. Typically the pvt lock is
+ * held while we ask the Asterisk core about an extension and context which
+ * results in the context being locked. In order to avoid the possible deadlock
+ * that could occur in the callback function due to improper locking, this
+ * list was created to queue those state changes for the sip_pvt to read outside
+ * of that thread. This way the context lock never has to be held before the
+ * pvt lock is held.
+ */
+static AST_LIST_HEAD_STATIC(sip_extenstate_updates, sip_extenstate_update);
+
/*! \todo Move the sip_auth list to AST_LIST */
static struct sip_auth *authl = NULL; /*!< Authentication list for realm authentication */
@@ -1412,7 +1445,8 @@
static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target);
/*--- Device monitoring and Device/extension state handling */
-static int cb_extensionstate(char *context, char* exten, int state, void *data);
+static int notify_extenstate_update(char *context, char* exten, int state, void *data);
+static void clear_extenstate_updates(struct sip_pvt *pvt);
static int sip_devicestate(void *data);
static int sip_poke_noanswer(const void *data);
static int sip_poke_peer(struct sip_peer *peer);
@@ -1976,29 +2010,29 @@
if (pkt->retrans < MAX_RETRANS) {
pkt->retrans++;
- if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */
+ if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */
if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_methods[pkt->method].text, pkt->method);
+ ast_log(LOG_DEBUG, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_methods[pkt->method].text, pkt->method);
} else {
- int siptimer_a;
-
- if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method);
- if (!pkt->timer_a)
- pkt->timer_a = 2 ;
- else
- pkt->timer_a = 2 * pkt->timer_a;
-
- /* For non-invites, a maximum of 4 secs */
- siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */
- if (pkt->method != SIP_INVITE && siptimer_a > 4000)
- siptimer_a = 4000;
-
- /* Reschedule re-transmit */
+ int siptimer_a;
+
+ if (sipdebug && option_debug > 3)
+ ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method);
+ if (!pkt->timer_a)
+ pkt->timer_a = 2 ;
+ else
+ pkt->timer_a = 2 * pkt->timer_a;
+
+ /* For non-invites, a maximum of 4 secs */
+ siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */
+ if (pkt->method != SIP_INVITE && siptimer_a > 4000)
+ siptimer_a = 4000;
+
+ /* Reschedule re-transmit */
reschedule = siptimer_a;
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", pkt->retrans +1, siptimer_a, pkt->timer_t1, pkt->retransid);
- }
+ if (option_debug > 3)
+ ast_log(LOG_DEBUG, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", pkt->retrans +1, siptimer_a, pkt->timer_t1, pkt->retransid);
+ }
if (sip_debug_test_pvt(pkt->owner)) {
const struct sockaddr_in *dst = sip_real_dst(pkt->owner);
@@ -2010,12 +2044,13 @@
append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data);
xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);
- ast_mutex_unlock(&pkt->owner->lock);
- if (xmitres == XMIT_ERROR)
+ if (xmitres == XMIT_ERROR) {
ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid);
- else
+ } else {
+ ast_mutex_unlock(&pkt->owner->lock);
return reschedule;
- }
+ }
+ }
/* Too many retries */
if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) {
if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */
@@ -2028,7 +2063,7 @@
append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
} else
append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
-
+
pkt->retransid = -1;
if (ast_test_flag(pkt, FLAG_FATAL)) {
@@ -2036,9 +2071,9 @@
DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */
}
- if (pkt->owner->owner && !pkt->owner->owner->hangupcause)
+ if (pkt->owner->owner && !pkt->owner->owner->hangupcause)
pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE;
-
+
if (pkt->owner->owner) {
sip_alreadygone(pkt->owner);
ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet (see doc/sip-retransmit.txt).\n", pkt->owner->callid);
@@ -2049,7 +2084,7 @@
/* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
if (pkt->method != SIP_OPTIONS) {
- ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY);
+ ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY);
sip_alreadygone(pkt->owner);
if (option_debug)
append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately");
@@ -2059,7 +2094,7 @@
if (pkt->method == SIP_BYE) {
/* We're not getting answers on SIP BYE's. Tear down the call anyway. */
- if (pkt->owner->owner)
+ if (pkt->owner->owner)
ast_channel_unlock(pkt->owner->owner);
append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway.");
ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY);
@@ -2172,10 +2207,6 @@
}
return 10000;
}
-
- /* If we're destroying a subscription, dereference peer object too */
- if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
- ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer);
/* Reset schedule ID */
p->autokillid = -1;
@@ -3380,6 +3411,11 @@
if (p->stateid > -1)
ast_extension_state_del(p->stateid, NULL);
+
+ /* remove any pending extension notify that could be left in
+ * the extension update queue relating to this dialog. */
+ clear_extenstate_updates(p);
+
AST_SCHED_DEL(sched, p->initid);
AST_SCHED_DEL(sched, p->waitid);
AST_SCHED_DEL(sched, p->autokillid);
@@ -9246,10 +9282,166 @@
return;
}
+static int add_extensionstate_update(char *context, char *exten, int state, void *data)
+{
+ struct sip_extenstate_update *update;
+ size_t exten_len = strlen(exten);
+ size_t context_len = strlen(context);
+
+ if (!(update = ast_calloc(1, sizeof(*update) + exten_len + context_len + 2))) {
+ return -1;
+ }
+
+ strcpy(update->exten, exten);
+
+ update->context = (char *) (update->exten + exten_len + 1);
+ strcpy(update->context, context);
+
+ update->state = state;
+ update->pvt = data;
+
+ AST_LIST_LOCK(&sip_extenstate_updates);
+ AST_LIST_INSERT_TAIL(&sip_extenstate_updates, update, list);
+ AST_LIST_UNLOCK(&sip_extenstate_updates);
+
+ /* Tell the do_monitor thread it has to do stuff! That thread is so lazy :( */
+ if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
+ pthread_kill(monitor_thread, SIGURG);
+ }
+
+ return 0;
+}
+
+/*!
+ * \internal
+ * \brief Check to see if there are any extension state updates
+ * for this pvt. If so send them and remove from queue */
+static void check_extenstate_updates(struct sip_pvt *pvt)
+{
+ struct sip_extenstate_update *update = NULL;
+
+ if (AST_LIST_EMPTY(&sip_extenstate_updates)) {
+ /* avoid holding the lock if possible */
+ return;
+ }
+
+ do {
+ if (update) {
+ /* The notify can not happen while the list lock is held. */
+ notify_extenstate_update(update->context, update->exten, update->state, pvt);
+ ast_free(update);
+ }
+
+ AST_LIST_LOCK(&sip_extenstate_updates);
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) {
+ if (update->pvt == pvt) {
+ AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list);
+ break;
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END
+ AST_LIST_UNLOCK(&sip_extenstate_updates);
+ } while (update);
+}
+
+/*!
+ * \internal
+ * \brief clear all marked extenstate updates left in the queue.
+ */
+static void clearmarked_extenstate_updates(void)
+{
+ struct sip_extenstate_update *update = NULL;
+
+ if (AST_LIST_EMPTY(&sip_extenstate_updates)) {
+ /* avoid holding the lock if possible */
+ return;
+ }
+
+ AST_LIST_LOCK(&sip_extenstate_updates);
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) {
+ if (update->marked) {
+ AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list);
+ ast_free(update);
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END
+ AST_LIST_UNLOCK(&sip_extenstate_updates);
+
+}
+
+/*!
+ * \internal
+ * \brief unmark for destruction all the extension updates for a specific dialog.
+ *
+ * \note this is used to remove updates pertaining to a dialog from destruction because
+ * they need to be sent out at a later time.
+ */
+static void unmark_extenstate_update(struct sip_pvt *pvt)
+{
+ struct sip_extenstate_update *update = NULL;
+
+ if (AST_LIST_EMPTY(&sip_extenstate_updates)) {
+ /* avoid holding the lock if possible */
+ return;
+ }
+
+ AST_LIST_LOCK(&sip_extenstate_updates);
+ AST_LIST_TRAVERSE(&sip_extenstate_updates, update, list) {
+ if (update->pvt == pvt) {
+ update->marked = 0;
+ }
+ }
+ AST_LIST_UNLOCK(&sip_extenstate_updates);
+}
+
+/*!
+ * \internal
+ * \brief mark all the current extenstate updates for removal.
+ */
+static void markall_extenstate_updates(void)
+{
+ struct sip_extenstate_update *update = NULL;
+
+ if (AST_LIST_EMPTY(&sip_extenstate_updates)) {
+ /* avoid holding the lock if possible */
+ return;
+ }
+
+ AST_LIST_LOCK(&sip_extenstate_updates);
+ AST_LIST_TRAVERSE(&sip_extenstate_updates, update, list) {
+ update->marked = 1;
+ }
+ AST_LIST_UNLOCK(&sip_extenstate_updates);
+}
+
+/*!
+ * \internal
+ * \brief clear out all extension state updates for a pvt.
+ */
+static void clear_extenstate_updates(struct sip_pvt *pvt)
+{
+ struct sip_extenstate_update *update = NULL;
+
+ if (AST_LIST_EMPTY(&sip_extenstate_updates)) {
+ /* avoid holding the lock if possible */
+ return;
+ }
+
+ AST_LIST_LOCK(&sip_extenstate_updates);
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) {
+ if (update->pvt == pvt) {
+ AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list);
+ ast_free(update);
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END
+ AST_LIST_UNLOCK(&sip_extenstate_updates);
+}
+
/*! \brief Callback for the devicestate notification (SUBSCRIBE) support subsystem
\note If you add an "hint" priority to the extension in the dial plan,
you will get notifications on device state changes */
-static int cb_extensionstate(char *context, char* exten, int state, void *data)
+static int notify_extenstate_update(char *context, char* exten, int state, void *data)
{
struct sip_pvt *p = data;
@@ -13652,7 +13844,7 @@
if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
/* Ready to send the next state we have on queue */
ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
- cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
+ notify_extenstate_update((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
}
}
} else if (sipmethod == SIP_REGISTER)
@@ -13912,7 +14104,7 @@
if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
/* Ready to send the next state we have on queue */
ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
- cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
+ notify_extenstate_update((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
}
}
} else if (sipmethod == SIP_BYE)
@@ -16407,8 +16599,8 @@
if (p->subscribed != MWI_NOTIFICATION && !resubscribe) {
if (p->stateid > -1)
- ast_extension_state_del(p->stateid, cb_extensionstate);
- p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
+ ast_extension_state_del(p->stateid, add_extensionstate_update);
+ p->stateid = ast_extension_state_add(p->context, p->exten, add_extensionstate_update, p);
}
if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
@@ -17085,8 +17277,15 @@
sipsock_read_id = NULL;
}
}
-restartsearch:
- /* Check for interfaces needing to be killed */
+
+ /* we only want to mark the extenstate updates for destruction
+ * if the dialog list is being traversed */
+ if (!fastrestart) {
+ markall_extenstate_updates();
+ }
+
+restartsearch:
+ /* Check for interfaces needing to be killed and for pending extension state notifications. */
ast_mutex_lock(&iflock);
t = time(NULL);
/* don't scan the interface list if it hasn't been a reasonable period
@@ -17099,8 +17298,16 @@
* sip_hangup otherwise, because sip_hangup is called with the channel
* locked first, and the iface lock is attempted second.
*/
- if (ast_mutex_trylock(&sip->lock))
+ if (ast_mutex_trylock(&sip->lock)) {
+ /* make sure to unmark any extension state updates for this pvt so
+ * they can be sent out when we come back to it. */
+ unmark_extenstate_update(sip);
continue;
+ }
+
+ /* since we are iterating through all the sip_pvts here, this is a good place
+ * to send out extension state updates. */
+ check_extenstate_updates(sip);
/* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
if (sip->rtp && sip->owner &&
@@ -17163,6 +17370,11 @@
ast_mutex_unlock(&sip->lock);
}
ast_mutex_unlock(&iflock);
+
+ /* we only want to clear the extension state updates if the dialog list was traversed */
+ if (!fastrestart) {
+ clearmarked_extenstate_updates();
+ }
/* XXX TODO The scheduler usage in this module does not have sufficient
* synchronization being done between running the scheduler and places
@@ -19736,7 +19948,8 @@
static int unload_module(void)
{
struct sip_pvt *p, *pl;
-
+ struct sip_extenstate_update *update;
+
/* First, take us out of the channel type list */
ast_channel_unregister(&sip_tech);
@@ -19808,6 +20021,14 @@
ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy);
ASTOBJ_CONTAINER_DESTROY(®l);
+ AST_LIST_LOCK(&sip_extenstate_updates);
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) {
+ AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list);
+ ast_free(update);
+ }
+ AST_LIST_TRAVERSE_SAFE_END
+ AST_LIST_UNLOCK(&sip_extenstate_updates);
+
clear_realm_authentication(authl);
clear_sip_domains();
ast_free_ha(global_contact_ha);
Modified: team/oej/bp-res_conf_ldap-1.4/codecs/gsm/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/oej/bp-res_conf_ldap-1.4/codecs/gsm/Makefile?view=diff&rev=286269&r1=286268&r2=286269
==============================================================================
--- team/oej/bp-res_conf_ldap-1.4/codecs/gsm/Makefile (original)
+++ team/oej/bp-res_conf_ldap-1.4/codecs/gsm/Makefile Sat Sep 11 12:08:55 2010
@@ -36,6 +36,14 @@
######### which support MMX instructions. This should be newer pentiums,
[... 1505 lines stripped ...]
More information about the asterisk-commits
mailing list