manual update, since automerge is not running at this time

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.2-netsec@48421 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.2-netsec
Kevin P. Fleming 19 years ago
parent 3bb733a7c7
commit 05f6188c69

@ -557,6 +557,7 @@ clean:
datafiles: all
if [ x`$(ID) -un` = xroot ]; then sh mkpkgconfig $(DESTDIR)/usr/lib/pkgconfig; fi
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/digits
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/silence
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/priv-callerintros
for x in sounds/digits/*.gsm; do \
if $(GREP) -q "^%`basename $$x`%" sounds.txt; then \
@ -566,6 +567,14 @@ datafiles: all
exit 1; \
fi; \
done
for x in sounds/silence/*.gsm; do \
if $(GREP) -q "^%`basename $$x`%" sounds.txt; then \
$(INSTALL) -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/silence ; \
else \
echo "No description for $$x"; \
exit 1; \
fi; \
done
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/dictate
for x in sounds/dictate/*.gsm; do \
if $(GREP) -q "^%`basename $$x`%" sounds.txt; then \

@ -48,7 +48,7 @@ static char *app_cut = "Cut";
static char *cut_synopsis = "Splits a variable's contents using the specified delimiter";
static char *cut_descrip =
" Cut(newvar=varname,delimiter,fieldspec): This applicaiton will split the\n"
" Cut(newvar=varname,delimiter,fieldspec): This application will split the\n"
"contents of a variable based on the given delimeter and store the result in\n"
"a new variable.\n"
"Parameters:\n"
@ -66,7 +66,7 @@ static char *app_sort_descrip =
" Sort(newvar=key1:val1[,key2:val2[[...],keyN:valN]]): This application will\n"
"sort the list provided in ascending order. The result will be stored in the\n"
"specified variable name.\n"
" This applicaiton has been deprecated in favor of the SORT function.\n";
" This application has been deprecated in favor of the SORT function.\n";
STANDARD_LOCAL_USER;

@ -63,7 +63,7 @@ static char *p_descrip =
" This application has been deprecated in favor of the DB function.\n";
static char *d_descrip =
" DBdel(family/key): This applicaiton will delete a key from the Asterisk\n"
" DBdel(family/key): This application will delete a key from the Asterisk\n"
"database.\n";
static char *dt_descrip =

@ -65,7 +65,7 @@ static char *synopsis = "Place a call and connect to the current channel";
static char *descrip =
" Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
"This applicaiton will place calls to one or more specified channels. As soon\n"
"This application will place calls to one or more specified channels. As soon\n"
"as one of the requested channels answers, the originating channel will be\n"
"answered, if it has not already been answered. These two channels will then\n"
"be active in a bridged call. All other channels that were requested will then\n"
@ -1197,6 +1197,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
strcpy(status, "NOANSWER");
if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
moh=1;
ast_indicate(chan, AST_CONTROL_PROGRESS);
ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK]);
} else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
ast_indicate(chan, AST_CONTROL_RINGING);

@ -61,7 +61,7 @@ static char *descrip =
"the calling channel with a directory of extensions from which they can search\n"
"by name. The list of names and corresponding extensions is retrieved from the\n"
"voicemail configuration file, voicemail.conf.\n"
" This applicaiton will immediate exit if one of the following DTMF digits are\n"
" This application will immediately exit if one of the following DTMF digits are\n"
"received and the extension to jump to exists:\n"
" 0 - Jump to the 'o' extension, if it exists.\n"
" * - Jump to the 'a' extension, if it exists.\n\n"

@ -31,6 +31,7 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include "asterisk.h"
@ -152,7 +153,7 @@ static int gen_nextfile(struct gen_state *state)
if (state->current) {
file_to_stream = state->current->filename;
} else {
file_to_stream = "silence-10";
file_to_stream = "silence/10";
u->playing_silence = 1;
}
@ -258,9 +259,13 @@ static int app_exec(struct ast_channel *chan, void *data)
FILE *child_commands = NULL;
FILE *child_errors = NULL;
FILE *child_events = NULL;
sigset_t fullset, oldset;
LOCAL_USER_ADD(u);
sigfillset(&fullset);
pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
AST_LIST_HEAD_INIT(&u->playlist);
AST_LIST_HEAD_INIT(&u->finishlist);
u->abort_current_sound = 0;
@ -314,6 +319,9 @@ static int app_exec(struct ast_channel *chan, void *data)
/* child process */
int i;
signal(SIGPIPE, SIG_DFL);
pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
if (option_highpriority)
ast_set_priority(0);
@ -337,6 +345,8 @@ static int app_exec(struct ast_channel *chan, void *data)
int waitfds[2] = { child_errors_fd, child_commands_fd };
struct ast_channel *rchan;
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
close(child_stdin[0]);
child_stdin[0] = 0;
close(child_stdout[1]);

@ -127,19 +127,26 @@ static int send_waveform_to_fd(char *waveform, int length, int fd) {
#ifdef __PPC__
char c;
#endif
sigset_t fullset, oldset;
sigfillset(&fullset);
pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
res = fork();
if (res < 0)
ast_log(LOG_WARNING, "Fork failed\n");
if (res)
if (res) {
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
return res;
}
for (x=0;x<256;x++) {
if (x != fd)
close(x);
}
if (option_highpriority)
ast_set_priority(0);
signal(SIGPIPE, SIG_DFL);
pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
/*IAS */
#ifdef __PPC__
for( x=0; x<length; x+=2)

@ -68,15 +68,27 @@ static int icesencode(char *filename, int fd)
{
int res;
int x;
sigset_t fullset, oldset;
sigfillset(&fullset);
pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
res = fork();
if (res < 0)
ast_log(LOG_WARNING, "Fork failed\n");
if (res)
if (res) {
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
return res;
}
/* Stop ignoring PIPE */
signal(SIGPIPE, SIG_DFL);
pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
if (option_highpriority)
ast_set_priority(0);
dup2(fd, STDIN_FILENO);
for (x=STDERR_FILENO + 1;x<256;x++) {
for (x=STDERR_FILENO + 1;x<1024;x++) {
if ((x != STDIN_FILENO) && (x != STDOUT_FILENO))
close(x);
}
@ -87,7 +99,7 @@ static int icesencode(char *filename, int fd)
/* As a last-ditch effort, try to use PATH */
execlp("ices", "ices", filename, (char *)NULL);
ast_log(LOG_WARNING, "Execute of ices failed\n");
return -1;
_exit(0);
}
static int ices_exec(struct ast_channel *chan, void *data)

@ -67,15 +67,25 @@ static int mp3play(char *filename, int fd)
{
int res;
int x;
sigset_t fullset, oldset;
sigfillset(&fullset);
pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
res = fork();
if (res < 0)
ast_log(LOG_WARNING, "Fork failed\n");
if (res)
if (res) {
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
return res;
}
if (option_highpriority)
ast_set_priority(0);
signal(SIGPIPE, SIG_DFL);
pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
dup2(fd, STDOUT_FILENO);
for (x=0;x<256;x++) {
for (x=STDERR_FILENO + 1;x<256;x++) {
if (x != STDOUT_FILENO)
close(x);
}
@ -97,7 +107,7 @@ static int mp3play(char *filename, int fd)
execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
}
ast_log(LOG_WARNING, "Execute of mpg123 failed\n");
return -1;
_exit(0);
}
static int timed_read(int fd, void *data, int datalen, int timeout)

@ -71,16 +71,26 @@ static int NBScatplay(int fd)
{
int res;
int x;
sigset_t fullset, oldset;
sigfillset(&fullset);
pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
res = fork();
if (res < 0)
ast_log(LOG_WARNING, "Fork failed\n");
if (res)
if (res) {
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
return res;
}
signal(SIGPIPE, SIG_DFL);
pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
if (option_highpriority)
ast_set_priority(0);
dup2(fd, STDOUT_FILENO);
for (x=0;x<256;x++) {
for (x = STDERR_FILENO + 1; x < 1024; x++) {
if (x != STDOUT_FILENO)
close(x);
}
@ -88,7 +98,7 @@ static int NBScatplay(int fd)
execl(NBSCAT, "nbscat8k", "-d", (char *)NULL);
execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL);
ast_log(LOG_WARNING, "Execute of nbscat8k failed\n");
return -1;
_exit(0);
}
static int timed_read(int fd, void *data, int datalen)

@ -1050,7 +1050,7 @@ static void sms_nextoutgoing (sms_t * h)
unsigned char p = 2;
h->omsg[0] = 0x91; /* SMS_DATA */
if (h->smsc) { /* deliver */
h->omsg[p++] = (more ? 4 : 0);
h->omsg[p++] = (more ? 4 : 0) + ((h->udhl > 0) ? 0x40 : 0);
p += packaddress (h->omsg + p, h->oa);
h->omsg[p++] = h->pid;
h->omsg[p++] = h->dcs;

@ -77,6 +77,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define COMMAND_TIMEOUT 5000
#define VOICEMAIL_DIR_MODE 0700
#define VOICEMAIL_FILE_MODE 0600
#define CHUNKSIZE 65536
#define VOICEMAIL_CONFIG "voicemail.conf"
#define ASTERISK_USERNAME "asterisk"
@ -925,6 +926,7 @@ static int retrieve_file(char *dir, int msgnum)
goto yuck;
}
if (!strcasecmp(coltitle, "recording")) {
off_t offset;
res = SQLGetData(stmt, x + 1, SQL_BINARY, NULL, 0, &colsize);
fdlen = colsize;
if (fd > -1) {
@ -935,17 +937,25 @@ static int retrieve_file(char *dir, int msgnum)
fd = -1;
continue;
}
if (fd > -1)
fdm = mmap(NULL, fdlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
}
if (fdm) {
memset(fdm, 0, fdlen);
res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, fdlen, &colsize);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
goto yuck;
/* Read out in small chunks */
for (offset = 0; offset < colsize; offset += CHUNKSIZE) {
/* +1 because SQLGetData likes null-terminating binary data */
if ((fdm = mmap(NULL, CHUNKSIZE + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset)) == -1) {
ast_log(LOG_WARNING, "Could not mmap the output file: %s (%d)\n", strerror(errno), errno);
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
goto yuck;
} else {
res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, CHUNKSIZE + 1, NULL);
munmap(fdm, 0);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
unlink(full_fn);
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
goto yuck;
}
}
}
truncate(full_fn, fdlen);
}
} else {
res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
@ -964,8 +974,6 @@ static int retrieve_file(char *dir, int msgnum)
yuck:
if (f)
fclose(f);
if (fdm)
munmap(fdm, fdlen);
if (fd > -1)
close(fd);
return x - 1;
@ -2749,7 +2757,7 @@ static int adsi_logo(unsigned char *buf)
{
int bytes = 0;
bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002 LSS, Inc.", "");
bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
return bytes;
}
@ -3277,12 +3285,11 @@ static int get_folder2(struct ast_channel *chan, char *fn, int start)
return res;
}
static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vmfts,
char *context, signed char record_gain)
static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vmfmts,
char *context, signed char record_gain, long *duration)
{
int cmd = 0;
int retries = 0;
int duration = 0;
signed char zero_gain = 0;
while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
@ -3290,15 +3297,66 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
retries = 0;
switch (cmd) {
case '1':
/* prepend a message to the current message and return */
/* prepend a message to the current message, update the metadata and return */
{
char file[200];
snprintf(file, sizeof(file), "%s/msg%04d", curdir, curmsg);
char msgfile[PATH_MAX];
char textfile[PATH_MAX];
int prepend_duration = 0;
struct ast_config *msg_cfg;
char *duration_str;
make_file(msgfile, sizeof(msgfile), curdir, curmsg);
strcpy(textfile, msgfile);
strncat(textfile, ".txt", sizeof(textfile) - 1);
*duration = 0;
/* if we can't read the message metadata, stop now */
if (!(msg_cfg = ast_config_load(textfile))) {
cmd = 0;
break;
}
if (record_gain)
ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
cmd = ast_play_and_prepend(chan, NULL, file, 0, vmfmts, &duration, 1, silencethreshold, maxsilence);
cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
if (record_gain)
ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
*duration = atoi(duration_str);
if (prepend_duration) {
struct ast_variable *var, *prev = NULL, *varlist;
struct ast_category *msg_cat;
*duration += prepend_duration;
msg_cat = ast_category_get(msg_cfg, "message");
varlist = ast_category_detach_variables(msg_cat);
for (var = varlist; var; prev = var, var = var->next) {
if (!strcmp(var->name, "duration")) {
if (!prev)
varlist = var->next;
else
prev->next = var->next;
free(var);
break;
}
}
/* need enough space for a maximum-length message duration */
duration_str = alloca(12);
snprintf(duration_str, 11, "%ld", *duration);
if ((var = ast_variable_new("duration", duration_str))) {
ast_variable_append(msg_cat, varlist);
ast_variable_append(msg_cat, var);
config_text_file_save(textfile, msg_cfg, "app_voicemail");
STORE(curdir, vmu->mailbox, context, curmsg);
}
}
ast_config_destroy(msg_cfg);
break;
}
case '2':
@ -3509,11 +3567,13 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
cmd = leave_voicemail(chan, mailbox, &leave_options);
} else {
/* Forward VoiceMail */
long duration = 0;
RETRIEVE(dir, curmsg);
cmd = vm_forwardoptions(chan, sender, dir, curmsg, vmfmts, context, record_gain);
cmd = vm_forwardoptions(chan, sender, dir, curmsg, vmfmts, context, record_gain, &duration);
if (!cmd) {
while (!res && vmtmp) {
copy_message(chan, sender, 0, curmsg, 0, vmtmp, fmt);
copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt);
saved_messages++;
vmfree = vmtmp;
@ -5711,22 +5771,13 @@ static int handle_show_voicemail_users(int fd, int argc, char *argv[])
}
}
while (vmu) {
char dirname[256];
DIR *vmdir;
struct dirent *vment;
int vmcount = 0;
char count[12];
int newmsgs = 0, oldmsgs = 0;
char count[12], tmp[256] = "";
if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
make_dir(dirname, 255, vmu->context, vmu->mailbox, "INBOX");
if ((vmdir = opendir(dirname))) {
/* No matter what the format of VM, there will always be a .txt file for each message. */
while ((vment = readdir(vmdir)))
if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7,".txt",4))
vmcount++;
closedir(vmdir);
}
snprintf(count,sizeof(count),"%d",vmcount);
snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
messagecount(tmp, &newmsgs, &oldmsgs);
snprintf(count,sizeof(count),"%d",newmsgs);
ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
}
vmu = vmu->next;

@ -87,11 +87,23 @@ static pid_t spawn_ras(struct ast_channel *chan, char *args)
char *argv[PPP_MAX_ARGS];
int argc = 0;
char *stringp=NULL;
sigset_t fullset, oldset;
sigfillset(&fullset);
pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
/* Start by forking */
pid = fork();
if (pid)
if (pid) {
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
return pid;
}
/* Restore original signal handlers */
for (x=0;x<NSIG;x++)
signal(x, SIG_DFL);
pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
/* Execute RAS on File handles */
dup2(chan->fds[0], STDIN_FILENO);
@ -104,10 +116,6 @@ static pid_t spawn_ras(struct ast_channel *chan, char *args)
for (x=STDERR_FILENO + 1;x<1024;x++)
close(x);
/* Restore original signal handlers */
for (x=0;x<NSIG;x++)
signal(x, SIG_DFL);
/* Reset all arguments */
memset(argv, 0, sizeof(argv));

12
cdr.c

@ -440,11 +440,11 @@ void ast_cdr_free(struct ast_cdr *cdr)
next = cdr->next;
chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
if (!ast_test_flag(cdr, AST_CDR_FLAG_POSTED) && !ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED))
ast_log(LOG_WARNING, "CDR on channel '%s' not posted\n", chan);
ast_log(LOG_NOTICE, "CDR on channel '%s' not posted\n", chan);
if (ast_tvzero(cdr->end))
ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", chan);
ast_log(LOG_NOTICE, "CDR on channel '%s' lacks end\n", chan);
if (ast_tvzero(cdr->start))
ast_log(LOG_WARNING, "CDR on channel '%s' lacks start\n", chan);
ast_log(LOG_NOTICE, "CDR on channel '%s' lacks start\n", chan);
ast_cdr_free_vars(cdr, 0);
free(cdr);
@ -806,11 +806,11 @@ static void post_cdr(struct ast_cdr *cdr)
while (cdr) {
chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
ast_log(LOG_NOTICE, "CDR on channel '%s' already posted\n", chan);
if (ast_tvzero(cdr->end))
ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", chan);
ast_log(LOG_NOTICE, "CDR on channel '%s' lacks end\n", chan);
if (ast_tvzero(cdr->start)) {
ast_log(LOG_WARNING, "CDR on channel '%s' lacks start\n", chan);
ast_log(LOG_NOTICE, "CDR on channel '%s' lacks start\n", chan);
cdr->disposition = AST_CDR_FAILED;
} else
cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec;

@ -65,7 +65,7 @@ endif
#
# PGSQL stuff... Autoconf anyone??
#
ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/postgresql)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/pgsql/include)$(wildcard $(CROSS_COMPILE_TARGET)/usr/include/pgsql)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/include/pgsql)$(wildcard $(CROSS_COMPILE_TARGET)/opt/pgsql/include)$(wildcard $(CROSS_COMPILE_TARGET)/usr/include/libpq-fe.h),)
ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/postgresql/libpq-fe.h)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/pgsql/include/libpq-fe.h)$(wildcard $(CROSS_COMPILE_TARGET)/usr/include/pgsql/libpq-fe.h)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/include/pgsql/libpq-fe.h)$(wildcard $(CROSS_COMPILE_TARGET)/opt/pgsql/include/libpq-fe.h)$(wildcard $(CROSS_COMPILE_TARGET)/usr/include/libpq-fe.h),)
MODS+=cdr_pgsql.so
endif

@ -64,8 +64,8 @@ static int connected = 0;
AST_MUTEX_DEFINE_STATIC(pgsql_lock);
PGconn *conn;
PGresult *result;
PGconn *conn = NULL;
PGresult *result = NULL;
static int pgsql_log(struct ast_cdr *cdr)
{

@ -355,8 +355,11 @@ void ast_channel_unregister(const struct ast_channel_tech *tech)
{
struct chanlist *chan, *last=NULL;
if (option_debug)
if (option_debug && tech && tech->type )
ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
else if (option_debug)
ast_log(LOG_DEBUG, "Unregistering channel, tech is NULL!!!\n");
ast_mutex_lock(&chlock);
@ -732,43 +735,34 @@ static struct ast_channel *channel_find_locked(const struct ast_channel *prev,
const char *context, const char *exten)
{
const char *msg = prev ? "deadlock" : "initial deadlock";
int retries, done;
int retries;
struct ast_channel *c;
for (retries = 0; retries < 10; retries++) {
int done;
ast_mutex_lock(&chlock);
for (c = channels; c; c = c->next) {
if (!prev) {
/* want head of list */
if (!name && !exten)
break;
if (name) {
/* want match by full name */
if (!namelen) {
if (!strcasecmp(c->name, name))
break;
else
continue;
}
/* want match by name prefix */
if (!strncasecmp(c->name, name, namelen))
break;
} else if (exten) {
/* want match by context and exten */
if (context && (strcasecmp(c->context, context) &&
strcasecmp(c->macrocontext, context)))
continue;
/* match by exten */
if (strcasecmp(c->exten, exten) &&
strcasecmp(c->macroexten, exten))
continue;
else
break;
}
} else if (c == prev) { /* found, return c->next */
if (prev) { /* look for next item */
if (c != prev) /* not this one */
continue;
/* found, prepare to return c->next */
c = c->next;
break;
}
if (name) { /* want match by name */
if ((!namelen && strcasecmp(c->name, name)) ||
(namelen && strncasecmp(c->name, name, namelen)))
continue; /* name match failed */
} else if (exten) {
if (context && strcasecmp(c->context, context) &&
strcasecmp(c->macrocontext, context))
continue; /* context match failed */
if (strcasecmp(c->exten, exten) &&
strcasecmp(c->macroexten, exten))
continue; /* exten match failed */
}
/* if we get here, c points to the desired record */
break;
}
/* exit if chan not found or mutex acquired successfully */
done = (c == NULL) || (ast_mutex_trylock(&c->lock) == 0);
@ -2302,6 +2296,11 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
else
res = 0;
break;
case AST_FRAME_NULL:
case AST_FRAME_IAX:
/* Ignore these */
res = 0;
break;
default:
if (chan->tech->write) {
f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
@ -2590,6 +2589,7 @@ struct ast_channel *ast_request(const char *type, int format, void *data, int *c
c->cid.cid_num ? c->cid.cid_num : "<unknown>",
c->cid.cid_name ? c->cid.cid_name : "<unknown>",
c->uniqueid);
ast_set_flag(c, AST_FLAG_NOTNEW);
}
return c;
}
@ -3253,7 +3253,7 @@ int ast_setstate(struct ast_channel *chan, int state)
chan->_state = state;
ast_device_state_changed_literal(chan->name);
manager_event(EVENT_FLAG_CALL,
(oldstate == AST_STATE_DOWN) ? "Newchannel" : "Newstate",
(oldstate == AST_STATE_DOWN && !ast_test_flag(chan, AST_FLAG_NOTNEW)) ? "Newchannel" : "Newstate",
"Channel: %s\r\n"
"State: %s\r\n"
"CallerID: %s\r\n"
@ -3510,10 +3510,11 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
if (!ast_tvzero(nexteventts)) {
now = ast_tvnow();
to = ast_tvdiff_ms(nexteventts, now);
if (to <= 0) {
if (to <= 0 && !config->timelimit) {
res = AST_BRIDGE_COMPLETE;
break;
}
}
}
if (config->timelimit) {
@ -3533,7 +3534,7 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
break;
}
if (!to) {
if (to <= 0) {
if (time_left_ms >= 5000) {
/* force the time left to round up if appropriate */
if (caller_warning && config->warning_sound && config->play_warning)
@ -3545,8 +3546,11 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
}
if (config->warning_freq) {
nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
} else
}
if ( (!config->warning_freq) || ( config->timelimit - ast_tvdiff_ms(nexteventts, config->start_time) < 0)) {
nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
}
}
}
@ -3644,7 +3648,7 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
o1nativeformats = c1->nativeformats;
}
res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
if (res != AST_BRIDGE_RETRY)
if (res != AST_BRIDGE_RETRY && fo)
break;
}

@ -410,6 +410,7 @@ struct iax2_registry {
};
static struct iax2_registry *registrations;
AST_MUTEX_DEFINE_STATIC(reg_lock);
/* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
#define MIN_RETRY_TIME 100
@ -4399,8 +4400,8 @@ static int iax2_show_registry(int fd, int argc, char *argv[])
char iabuf[INET_ADDRSTRLEN];
if (argc != 3)
return RESULT_SHOWUSAGE;
ast_mutex_lock(&peerl.lock);
ast_cli(fd, FORMAT2, "Host", "Username", "Perceived", "Refresh", "State");
ast_mutex_lock(&reg_lock);
for (reg = registrations;reg;reg = reg->next) {
snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->addr.sin_addr), ntohs(reg->addr.sin_port));
if (reg->us.sin_addr.s_addr)
@ -4410,7 +4411,7 @@ static int iax2_show_registry(int fd, int argc, char *argv[])
ast_cli(fd, FORMAT, host,
reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
}
ast_mutex_unlock(&peerl.lock);
ast_mutex_unlock(&reg_lock);
return RESULT_SUCCESS;
#undef FORMAT
#undef FORMAT2
@ -5624,9 +5625,11 @@ static int iax2_register(char *value, int lineno)
reg->addr.sin_family = AF_INET;
memcpy(&reg->addr.sin_addr, hp->h_addr, sizeof(&reg->addr.sin_addr));
reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
ast_mutex_lock(&reg_lock);
reg->next = registrations;
reg->callno = 0;
registrations = reg;
ast_mutex_unlock(&reg_lock);
} else {
ast_log(LOG_ERROR, "Out of memory\n");
return -1;
@ -7110,7 +7113,7 @@ retryowner:
if (!strcmp(ies.called_number, ast_parking_ext())) {
if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) {
ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
} else
} else if (ast_bridged_channel(iaxs[fr->callno]->owner))
ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
} else {
if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1))
@ -8582,6 +8585,7 @@ static void delete_users(void)
user = user->next;
}
ast_mutex_unlock(&userl.lock);
ast_mutex_lock(&reg_lock);
for (reg = registrations;reg;) {
regl = reg;
reg = reg->next;
@ -8600,6 +8604,7 @@ static void delete_users(void)
free(regl);
}
registrations = NULL;
ast_mutex_unlock(&reg_lock);
ast_mutex_lock(&peerl.lock);
for (peer=peerl.peers;peer;) {
/* Assume all will be deleted, and we'll find out for sure later */
@ -8976,8 +8981,10 @@ static int reload_config(void)
set_config(config,1);
prune_peers();
prune_users();
ast_mutex_lock(&reg_lock);
for (reg = registrations; reg; reg = reg->next)
iax2_do_register(reg);
ast_mutex_unlock(&reg_lock);
/* Qualify hosts, too */
ast_mutex_lock(&peerl.lock);
for (peer = peerl.peers; peer; peer = peer->next)
@ -9347,9 +9354,6 @@ static char *function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, c
buf[0] = '\0';
if (chan->tech != &iax2_tech)
return buf;
if (!(peername = ast_strdupa(data))) {
ast_log(LOG_ERROR, "Memory Error!\n");
return ret;
@ -9357,7 +9361,10 @@ static char *function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, c
/* if our channel, return the IP address of the endpoint of current channel */
if (!strcmp(peername,"CURRENTCHANNEL")) {
unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
unsigned short callno;
if (chan->tech != &iax2_tech)
return buf;
callno = PTR_TO_CALLNO(chan->tech_pvt);
ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len);
return buf;
}
@ -9742,8 +9749,10 @@ int load_module(void)
ast_netsock_release(netsock);
}
ast_mutex_lock(&reg_lock);
for (reg = registrations; reg; reg = reg->next)
iax2_do_register(reg);
ast_mutex_unlock(&reg_lock);
ast_mutex_lock(&peerl.lock);
for (peer = peerl.peers; peer; peer = peer->next) {
if (peer->sockfd < 0)

@ -168,6 +168,9 @@ static int local_answer(struct ast_channel *ast)
int isoutbound;
int res = -1;
if (!p)
return -1;
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
if (isoutbound) {
@ -245,6 +248,9 @@ static int local_write(struct ast_channel *ast, struct ast_frame *f)
int res = -1;
int isoutbound;
if (!p)
return -1;
/* Just queue for delivery to the other side */
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
@ -263,6 +269,10 @@ static int local_write(struct ast_channel *ast, struct ast_frame *f)
static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
{
struct local_pvt *p = newchan->tech_pvt;
if (!p)
return -1;
ast_mutex_lock(&p->lock);
if ((p->owner != oldchan) && (p->chan != oldchan)) {
@ -285,6 +295,9 @@ static int local_indicate(struct ast_channel *ast, int condition)
struct ast_frame f = { AST_FRAME_CONTROL, };
int isoutbound;
if (!p)
return -1;
/* Queue up a frame representing the indication as a control frame */
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
@ -301,6 +314,9 @@ static int local_digit(struct ast_channel *ast, char digit)
struct ast_frame f = { AST_FRAME_DTMF, };
int isoutbound;
if (!p)
return -1;
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
f.subclass = digit;
@ -316,6 +332,9 @@ static int local_sendhtml(struct ast_channel *ast, int subclass, const char *dat
struct ast_frame f = { AST_FRAME_HTML, };
int isoutbound;
if (!p)
return -1;
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
f.subclass = subclass;
@ -334,6 +353,9 @@ static int local_call(struct ast_channel *ast, char *dest, int timeout)
int res;
struct ast_var_t *varptr = NULL, *new;
size_t len, namelen;
if (!p)
return -1;
ast_mutex_lock(&p->lock);
@ -410,6 +432,9 @@ static int local_hangup(struct ast_channel *ast)
struct ast_channel *ochan = NULL;
int glaredetect;
if (!p)
return -1;
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
if (isoutbound) {

@ -796,8 +796,8 @@ static int misdn_show_cls (int fd, int argc, char *argv[])
print_bc_info(fd, help, bc);
} else {
if (help->state == MISDN_HOLDED) {
chan_misdn_log(0, 0, "ITS A HOLDED BC:\n");
chan_misdn_log(0,0," --> l3_id: %x\n"
chan_misdn_log(2, 0, "ITS A HOLDED BC:\n");
chan_misdn_log(2,0," --> l3_id: %x\n"
" --> dad:%s oad:%s\n"
,help->l3id
@ -1220,8 +1220,7 @@ static int update_config (struct chan_list *ch, int orig)
int port=bc->port;
chan_misdn_log(1,port,"update_config: Getting Config\n");
chan_misdn_log(7,port,"update_config: Getting Config\n");
int hdlc=0;
misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
@ -1635,7 +1634,7 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
chan_misdn_log(1, port, "* CALL: %s\n",dest);
chan_misdn_log(1, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);
chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);
chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten);
if (ast->exten) {
@ -1691,7 +1690,7 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
return -1;
}
chan_misdn_log(1, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);
chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);
ast_setstate(ast, AST_STATE_DIALING);
ast->hangupcause=16;
@ -1855,12 +1854,11 @@ static int misdn_indication(struct ast_channel *ast, int cond)
return -1;
}
chan_misdn_log(1, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten);
chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten);
switch (cond) {
case AST_CONTROL_BUSY:
chan_misdn_log(1, p->bc->port, "* IND :\tbusy\n");
chan_misdn_log(1, p->bc->port, " --> * SEND: State Busy pid:%d\n",p->bc?p->bc->pid:-1);
chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n",p->bc?p->bc->pid:-1);
ast_setstate(ast,AST_STATE_BUSY);
p->bc->out_cause=17;
@ -1873,41 +1871,42 @@ static int misdn_indication(struct ast_channel *ast, int cond)
return -1;
break;
case AST_CONTROL_RING:
chan_misdn_log(1, p->bc->port, " --> * IND :\tring pid:%d\n",p->bc?p->bc->pid:-1);
chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n",p->bc?p->bc->pid:-1);
return -1;
break;
case AST_CONTROL_RINGING:
chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
switch (p->state) {
case MISDN_ALERTING:
chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoreing it\n",p->bc?p->bc->pid:-1);
chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoreing it\n",p->bc?p->bc->pid:-1);
break;
case MISDN_CONNECTED:
chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n",p->bc?p->bc->pid:-1);
chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n",p->bc?p->bc->pid:-1);
return -1;
break;
default:
p->state=MISDN_ALERTING;
chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
misdn_lib_send_event( p->bc, EVENT_ALERTING);
if (p->other_ch && p->other_ch->bc) {
if (misdn_inband_avail(p->other_ch->bc)) {
chan_misdn_log(1,p->bc->port, " --> other End is mISDN and has inband info available\n");
chan_misdn_log(2,p->bc->port, " --> other End is mISDN and has inband info available\n");
break;
}
if (!p->other_ch->bc->nt) {
chan_misdn_log(1,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");
chan_misdn_log(2,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");
break;
}
}
chan_misdn_log(1, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1);
chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1);
ast_setstate(ast,AST_STATE_RINGING);
if ( !p->bc->nt && (p->orginator==ORG_MISDN) && !p->incoming_early_audio )
chan_misdn_log(1,p->bc->port, " --> incoming_early_audio off\n");
chan_misdn_log(2,p->bc->port, " --> incoming_early_audio off\n");
else
return -1;
}
@ -1967,7 +1966,7 @@ static int misdn_indication(struct ast_channel *ast, int cond)
chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n",p->bc?p->bc->pid:-1);
break;
default:
ast_log(LOG_NOTICE, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1);
chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1);
}
return 0;
@ -2044,10 +2043,10 @@ static int misdn_hangup(struct ast_channel *ast)
}
chan_misdn_log(1, bc->port, "* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s State:%s\n",p->bc?p->bc->pid:-1, ast->context, ast->exten, AST_CID_P(ast), misdn_get_ch_state(p));
chan_misdn_log(2, bc->port, " --> l3id:%x\n",p->l3id);
chan_misdn_log(1, bc->port, " --> cause:%d\n",bc->cause);
chan_misdn_log(1, bc->port, " --> out_cause:%d\n",bc->out_cause);
chan_misdn_log(1, bc->port, " --> state:%s\n", misdn_get_ch_state(p));
chan_misdn_log(3, bc->port, " --> l3id:%x\n",p->l3id);
chan_misdn_log(3, bc->port, " --> cause:%d\n",bc->cause);
chan_misdn_log(2, bc->port, " --> out_cause:%d\n",bc->out_cause);
chan_misdn_log(2, bc->port, " --> state:%s\n", misdn_get_ch_state(p));
switch (p->state) {
case MISDN_CALLING:
@ -2132,7 +2131,7 @@ static int misdn_hangup(struct ast_channel *ast)
}
chan_misdn_log(1, bc->port, "Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p));
chan_misdn_log(3, bc->port, " --> Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p));
return 0;
}
@ -2348,9 +2347,9 @@ enum ast_bridge_result misdn_bridge (struct ast_channel *c0,
/* got hangup .. */
if (!f)
chan_misdn_log(1,ch1->bc->port,"Read Null Frame\n");
chan_misdn_log(4,ch1->bc->port,"Read Null Frame\n");
else
chan_misdn_log(1,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass);
chan_misdn_log(4,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass);
*fo=f;
*rc=who;
@ -2955,11 +2954,11 @@ static void hangup_chan(struct chan_list *ch)
return;
}
cb_log(1,port,"hangup_chan\n");
cb_log(5,port,"hangup_chan called\n");
if (ch->need_hangup)
{
cb_log(1,port,"-> hangup\n");
cb_log(2,port," --> hangup\n");
send_cause2ast(ch->ast,ch->bc,ch);
ch->need_hangup=0;
ch->need_queue_hangup=0;
@ -2969,7 +2968,7 @@ static void hangup_chan(struct chan_list *ch)
}
if (!ch->need_queue_hangup) {
cb_log(1,port,"No need to queue hangup\n");
cb_log(2,port," --> No need to queue hangup\n");
}
ch->need_queue_hangup=0;
@ -2978,7 +2977,7 @@ static void hangup_chan(struct chan_list *ch)
if (ch->ast)
ast_queue_hangup(ch->ast);
cb_log(1,port,"-> queue_hangup\n");
cb_log(2,port," --> queue_hangup\n");
} else {
cb_log(1,port,"Cannot hangup chan, no ast\n");
}
@ -2998,7 +2997,7 @@ static void release_chan(struct misdn_bchannel *bc) {
ast=ch->ast;
}
chan_misdn_log(1, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id);
chan_misdn_log(5, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id);
/*releaseing jitterbuffer*/
if (ch->jb ) {
@ -3177,22 +3176,32 @@ void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_
tmp=pbx_builtin_getvar_helper(chan,"MISDN_PID");
if (tmp) {
ch->other_pid=atoi(tmp);
chan_misdn_log(1,bc->port,"IMPORT_PID: importing pid:%s\n",tmp);
chan_misdn_log(3,bc->port," --> IMPORT_PID: importing pid:%s\n",tmp);
if (ch->other_pid >0) {
ch->other_ch=find_chan_by_pid(cl_te,ch->other_pid);
if (ch->other_ch) ch->other_ch->other_ch=ch;
}
}
tmp=pbx_builtin_getvar_helper(chan,"MISDN_ADDRESS_COMPLETE");
if (tmp && (atoi(tmp) == 1)) {
bc->sending_complete=1;
}
}
void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
{
char tmp[32];
chan_misdn_log(1,bc->port,"EXPORT_PID: pid:%d\n",bc->pid);
chan_misdn_log(3,bc->port," --> EXPORT_PID: pid:%d\n",bc->pid);
sprintf(tmp,"%d",bc->pid);
pbx_builtin_setvar_helper(chan,"_MISDN_PID",tmp);
if (bc->sending_complete) {
sprintf(tmp,"%d",bc->sending_complete);
pbx_builtin_setvar_helper(chan,"MISDN_ADDRESS_COMPLETE",tmp);
}
}
@ -3730,15 +3739,15 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ast_queue_control(ch->ast, AST_CONTROL_RINGING);
ast_setstate(ch->ast, AST_STATE_RINGING);
cb_log(1,bc->port,"Set State Ringing\n");
cb_log(7,bc->port," --> Set State Ringing\n");
if ( misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) {
cb_log(1,bc->port,"Starting Tones, we have inband Data\n");
start_bc_tones(ch);
} else {
cb_log(1,bc->port,"We have no inband Data, the other end must create ringing\n");
cb_log(3,bc->port," --> We have no inband Data, the other end must create ringing\n");
if (ch->far_alerting) {
cb_log(1,bc->port,"The other end can not do ringing eh ?.. we must do all ourself..");
cb_log(1,bc->port," --> The other end can not do ringing eh ?.. we must do all ourself..");
start_bc_tones(ch);
/*tone_indicate(ch, TONE_FAR_ALERTING);*/
}
@ -3937,7 +3946,11 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len);
if (ret<=0) {
chan_misdn_log(-1, bc->port, "Write returned <=0 (err=%s)\n",strerror(errno));
chan_misdn_log(-1, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n",strerror(errno));
stop_bc_tones(ch);
hangup_chan(ch);
release_chan(bc);
}
} else {
chan_misdn_log(1, bc->port, "Wripe Pipe full!\n");
@ -4009,6 +4022,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ch->bc=bc;
ch->state = MISDN_CONNECTED;
ch->hold_info.port=0;
ch->hold_info.channel=0;
struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast);
if (hold_ast) {
@ -4090,7 +4106,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break;
default:
ast_log(LOG_NOTICE, "Got Unknown Event\n");
chan_misdn_log(1,0, "Got Unknown Event\n");
break;
}
@ -4121,8 +4137,11 @@ int load_module(void)
return 0;
}
misdn_cfg_init(max_ports);
if (misdn_cfg_init(max_ports)<0) {
ast_log(LOG_ERROR, "Unable to initialize mISDN Config System\n");
return 0;
}
g_config_initialized=1;
misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1));
@ -4345,7 +4364,7 @@ static int misdn_facility_exec(struct ast_channel *chan, void *data)
misdn_lib_send_facility(ch->bc, FACILITY_CALLDEFLECT, tok);
} else {
ast_log(LOG_WARNING, "Unknown Facility: %s\n",tok);
chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n",tok);
}
return 0;

@ -37,9 +37,6 @@
#include <linux/telephony.h>
/* Still use some IXJ specific stuff */
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
# include <linux/compiler.h>
#endif
#include <linux/ixjuser.h>
#include "asterisk.h"

@ -1273,7 +1273,9 @@ static int retrans_pkt(void *data)
ast_mutex_unlock(&pkt->owner->owner->lock);
} else {
/* If no channel owner, destroy now */
ast_set_flag(pkt->owner, SIP_NEEDDESTROY);
/* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
if (pkt->method != SIP_OPTIONS)
ast_set_flag(pkt->owner, SIP_NEEDDESTROY);
}
}
/* In any case, go ahead and remove the packet */
@ -1426,6 +1428,7 @@ static int __sip_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod)
if (sipdebug && option_debug > 3)
ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
ast_sched_del(sched, cur->retransid);
cur->retransid = -1;
}
free(cur);
res = 0;
@ -1481,8 +1484,8 @@ static int __sip_semi_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod)
if (option_debug > 3 && sipdebug)
ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, msg);
ast_sched_del(sched, cur->retransid);
cur->retransid = -1;
}
cur->retransid = -1;
res = 0;
break;
}
@ -1681,6 +1684,7 @@ static void sip_destroy_peer(struct sip_peer *peer)
}
if (peer->expire > -1)
ast_sched_del(sched, peer->expire);
if (peer->pokeexpire > -1)
ast_sched_del(sched, peer->pokeexpire);
register_peer_exten(peer, 0);
@ -2289,7 +2293,7 @@ static int update_call_counter(struct sip_pvt *fup, int event)
case INC_CALL_LIMIT:
if (*call_limit > 0 ) {
if (*inuse >= *call_limit) {
ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
ast_log(LOG_NOTICE, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
if (u)
ASTOBJ_UNREF(u,sip_destroy_user);
else
@ -2518,7 +2522,7 @@ static int sip_hangup(struct ast_channel *ast)
/* Do we need a timer here if we don't hear from them at all? */
} else {
/* Send a new request: CANCEL */
transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
transmit_request(p, SIP_CANCEL, p->ocseq, 1, 0);
/* Actually don't destroy us yet, wait for the 487 on our original
INVITE, but do set an autodestruct just in case we never get it. */
}
@ -2592,7 +2596,7 @@ static int sip_answer(struct ast_channel *ast)
ast_setstate(ast, AST_STATE_UP);
if (option_debug)
ast_log(LOG_DEBUG, "sip_answer(%s)\n", ast->name);
res = transmit_response_with_sdp(p, "200 OK", &p->initreq, 1);
res = transmit_response_with_sdp(p, "200 OK", &p->initreq, 2);
}
ast_mutex_unlock(&p->lock);
return res;
@ -2655,6 +2659,11 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
{
struct sip_pvt *p = newchan->tech_pvt;
if (!p) {
ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n");
return -1;
}
ast_mutex_lock(&p->lock);
if (p->owner != oldchan) {
ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
@ -3278,9 +3287,10 @@ static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *si
ast_mutex_unlock(&iflock);
/* If this is a response and we have ignoring of out of dialog responses turned on, then drop it */
/* ...and never respond to a SIP ACK message */
if (!sip_methods[intended_method].can_create) {
/* Can't create dialog */
if (intended_method != SIP_RESPONSE)
if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK)
transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
} else if (sip_methods[intended_method].can_create == 2) {
char *response = "481 Call leg/transaction does not exist";
@ -3298,6 +3308,19 @@ static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *si
p = sip_alloc(callid, sin, 1, intended_method);
if (p)
ast_mutex_lock(&p->lock);
else {
/* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
getting a dialog from sip_alloc.
Without a dialog we can't retransmit and handle ACKs and all that, but at least
send an error message.
Sorry, we apologize for the inconvienience
*/
transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
if (option_debug > 3)
ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
}
}
return p;
@ -3541,7 +3564,9 @@ static int find_sdp(struct sip_request *req)
for (x = 0; x < (req->lines - 2); x++) {
if (!strncasecmp(req->line[x], boundary, strlen(boundary)) &&
!strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) {
req->sdp_start = x + 2;
x += 2;
req->sdp_start = x;
/* search for the end of the body part */
for ( ; x < req->lines; x++) {
if (!strncasecmp(req->line[x], boundary, strlen(boundary)))
@ -4272,7 +4297,8 @@ static int reqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, in
add_header(req, "From", ot);
add_header(req, "To", of);
}
add_header(req, "Contact", p->our_contact);
if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
add_header(req, "Contact", p->our_contact);
copy_header(req, orig, "Call-ID");
add_header(req, "CSeq", tmp);
@ -4310,6 +4336,7 @@ static int __transmit_response(struct sip_pvt *p, char *msg, struct sip_request
static int transmit_response_using_temp(char *callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, struct sip_request *req, char *msg)
{
struct sip_pvt *p = alloca(sizeof(*p));
struct sip_history *hist = NULL;
memset(p, 0, sizeof(*p));
@ -4335,6 +4362,11 @@ static int transmit_response_using_temp(char *callid, struct sockaddr_in *sin, i
__transmit_response(p, msg, req, 0);
while ((hist = p->history)) {
p->history = p->history->next;
free(hist);
}
return 0;
}
@ -5717,7 +5749,8 @@ static int transmit_register(struct sip_registry *r, int sipmethod, char *auth,
ast_copy_string(p->domain, r->domain, sizeof(p->domain));
ast_copy_string(p->opaque, r->opaque, sizeof(p->opaque));
ast_copy_string(p->qop, r->qop, sizeof(p->qop));
p->noncecount = r->noncecount++;
r->noncecount++;
p->noncecount = r->noncecount;
memset(digest,0,sizeof(digest));
if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
@ -6165,8 +6198,10 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
else
p->username[0] = '\0';
if (p->expire > -1)
if (p->expire > -1) {
ast_sched_del(sched, p->expire);
p->expire = -1;
}
if ((expiry < 1) || (expiry > max_expiry))
expiry = max_expiry;
if (!ast_test_flag(p, SIP_REALTIME))
@ -8217,7 +8252,7 @@ static int _sip_show_peer(int type, int fd, struct mansession *s, struct message
print_group(fd, peer->pickupgroup, 0);
ast_cli(fd, " Mailbox : %s\n", peer->mailbox);
ast_cli(fd, " VM Extension : %s\n", peer->vmexten);
ast_cli(fd, " LastMsgsSent : %d\n", peer->lastmsgssent);
ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
ast_cli(fd, " Call limit : %d\n", peer->call_limit);
ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Yes":"No"));
ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
@ -9718,7 +9753,7 @@ static void check_pendings(struct sip_pvt *p)
if (ast_test_flag(p, SIP_PENDINGBYE)) {
/* if we can't BYE, then this is really a pending CANCEL */
if (!ast_test_flag(p, SIP_CAN_BYE))
transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
transmit_request(p, SIP_CANCEL, p->ocseq, 1, 0);
/* Actually don't destroy us yet, wait for the 487 on our original
INVITE, but do set an autodestruct just in case we never get it. */
else
@ -9889,12 +9924,23 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru
ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
transmit_request(p, SIP_ACK, seqno, 0, 0);
break;
case 487: /* Cancelled transaction */
/* We have sent CANCEL on an outbound INVITE
This transaction is already scheduled to be killed by sip_hangup().
*/
transmit_request(p, SIP_ACK, seqno, 0, 0);
if (p->owner && !ignore)
ast_queue_hangup(p->owner);
else if (!ignore)
update_call_counter(p, DEC_CALL_LIMIT);
break;
case 491: /* Pending */
/* we have to wait a while, then retransmit */
/* Transmission is rescheduled, so everything should be taken care of.
We should support the retry-after at some point */
break;
case 501: /* Not implemented */
transmit_request(p, SIP_ACK, seqno, 0, 0);
if (p->owner)
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
break;
@ -9920,6 +9966,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, char *rest, str
if (global_regattempts_max)
p->registry->regattempts = global_regattempts_max+1;
ast_sched_del(sched, r->timeout);
r->timeout = -1;
ast_set_flag(p, SIP_NEEDDESTROY);
break;
case 404: /* Not found */
@ -9929,6 +9976,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, char *rest, str
ast_set_flag(p, SIP_NEEDDESTROY);
r->call = NULL;
ast_sched_del(sched, r->timeout);
r->timeout = -1;
break;
case 407: /* Proxy auth */
if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
@ -9943,6 +9991,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, char *rest, str
ast_set_flag(p, SIP_NEEDDESTROY);
r->call = NULL;
ast_sched_del(sched, r->timeout);
r->timeout = -1;
break;
case 200: /* 200 OK */
if (!r) {
@ -10062,7 +10111,7 @@ static int handle_response_peerpoke(struct sip_pvt *p, int resp, char *rest, str
ast_sched_del(sched, peer->pokeexpire);
if (sipmethod == SIP_INVITE) /* Does this really happen? */
transmit_request(p, SIP_ACK, seqno, 0, 0);
ast_set_flag(p, SIP_NEEDDESTROY);
ast_set_flag(p, SIP_NEEDDESTROY);
/* Try again eventually */
if ((peer->lastms < 0) || (peer->lastms > peer->maxms))
@ -10199,6 +10248,10 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
ast_set_flag(p, SIP_NEEDDESTROY);
break;
case 487:
if (sipmethod == SIP_INVITE)
handle_response_invite(p, resp, rest, req, ignore, seqno);
break;
case 491: /* Pending */
if (sipmethod == SIP_INVITE) {
handle_response_invite(p, resp, rest, req, ignore, seqno);
@ -10213,7 +10266,6 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
if ((resp >= 300) && (resp < 700)) {
if ((option_verbose > 2) && (resp != 487))
ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
ast_set_flag(p, SIP_ALREADYGONE);
if (p->rtp) {
/* Immediately stop RTP */
ast_rtp_stop(p->rtp);
@ -10236,12 +10288,6 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
if (p->owner)
ast_queue_control(p->owner, AST_CONTROL_BUSY);
break;
case 487:
/* channel now destroyed - dec the inUse counter */
if (owner)
ast_queue_hangup(p->owner);
update_call_counter(p, DEC_CALL_LIMIT);
break;
case 482: /* SIP is incapable of performing a hairpin call, which
is yet another failure of not having a layer 2 (again, YAY
IETF for thinking ahead). So we treat this as a call
@ -10612,8 +10658,9 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
/* This is a call to ourself. Send ourselves an error code and stop
processing immediately, as SIP really has no good mechanism for
being able to call yourself */
transmit_response(p, "482 Loop Detected", req);
/* We do NOT destroy p here, so that our response will be accepted */
transmit_response_reliable(p, "482 Loop Detected", req, 1);
if (!p->lastinvite)
ast_set_flag(p, SIP_NEEDDESTROY);
return 0;
}
if (!ignore) {
@ -10655,10 +10702,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1);
} else {
ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
if (ignore)
transmit_response(p, "403 Forbidden", req);
else
transmit_response_reliable(p, "403 Forbidden", req, 1);
transmit_response_reliable(p, "403 Forbidden", req, 1);
}
ast_set_flag(p, SIP_NEEDDESTROY);
p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */
@ -10700,10 +10744,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
if (res) {
if (res < 0) {
ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
if (ignore)
transmit_response(p, "480 Temporarily Unavailable (Call limit)", req);
else
transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1);
transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1);
ast_set_flag(p, SIP_NEEDDESTROY);
}
return 0;
@ -10716,20 +10757,13 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
build_contact(p);
if (gotdest) {
if (gotdest < 0) {
if (ignore)
transmit_response(p, "404 Not Found", req);
else
transmit_response_reliable(p, "404 Not Found", req, 1);
update_call_counter(p, DEC_CALL_LIMIT);
} else {
if (ignore)
transmit_response(p, "484 Address Incomplete", req);
else
transmit_response_reliable(p, "484 Address Incomplete", req, 1);
update_call_counter(p, DEC_CALL_LIMIT);
}
if (gotdest < 0)
transmit_response_reliable(p, "404 Not Found", req, 1);
else
transmit_response_reliable(p, "484 Address Incomplete", req, 1);
update_call_counter(p, DEC_CALL_LIMIT);
ast_set_flag(p, SIP_NEEDDESTROY);
return 0;
} else {
/* If no extension was specified, use the s one */
if (ast_strlen_zero(p->exten))
@ -10835,19 +10869,12 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
} else {
if (p && !ast_test_flag(p, SIP_NEEDDESTROY) && !ignore) {
if (!p->jointcapability) {
if (ignore)
transmit_response(p, "488 Not Acceptable Here (codec error)", req);
else
transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1);
ast_set_flag(p, SIP_NEEDDESTROY);
transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1);
} else {
ast_log(LOG_NOTICE, "Unable to create/find channel\n");
if (ignore)
transmit_response(p, "503 Unavailable", req);
else
transmit_response_reliable(p, "503 Unavailable", req, 1);
ast_set_flag(p, SIP_NEEDDESTROY);
transmit_response_reliable(p, "503 Unavailable", req, 1);
}
ast_set_flag(p, SIP_NEEDDESTROY);
}
}
return res;
@ -10961,7 +10988,8 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req, int de
struct ast_channel *bridged_to;
char iabuf[INET_ADDRSTRLEN];
if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore)
/* If we have an INCOMING invite that we haven't answered, terminate that transaction */
if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore && !p->owner)
transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1);
copy_request(&p->initreq, req);
@ -11202,7 +11230,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
char iabuf[INET_ADDRSTRLEN];
ast_log(LOG_ERROR, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension\n", p->exten, p->context, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension\n", p->exten, p->context, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
transmit_response(p, "404 Not found", req);
ast_set_flag(p, SIP_NEEDDESTROY);
return 0;
@ -11272,7 +11300,6 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
{
/* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
relatively static */
struct sip_request resp;
char *cmd;
char *cseq;
char *useragent;
@ -11286,9 +11313,6 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
char *e;
int error = 0;
/* Clear out potential response */
memset(&resp, 0, sizeof(resp));
/* Get Method and Cseq */
cseq = get_header(req, "Cseq");
cmd = req->header[0];
@ -11303,7 +11327,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
error = 1;
}
if (error) {
if (!p->initreq.header) /* New call */
if (!p->initreq.headers) /* New call */
ast_set_flag(p, SIP_NEEDDESTROY); /* Make sure we destroy this dialog */
return -1;
}
@ -11534,7 +11558,7 @@ retrylock:
goto retrylock;
}
if (!lockretry) {
ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", p->owner->name);
ast_log(LOG_ERROR, "We could NOT get the channel lock for %s - Call ID %s! \n", p->owner->name, p->callid);
ast_log(LOG_ERROR, "SIP MESSAGE JUST IGNORED: %s \n", req.data);
ast_log(LOG_ERROR, "BAD! BAD! BAD!\n");
return 1;
@ -11576,7 +11600,7 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer)
time(&peer->lastmsgcheck);
/* Return now if it's the same thing we told them last time */
if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) {
if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) {
return 0;
}
@ -11585,7 +11609,7 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer)
ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n");
return -1;
}
peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs));
peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs));
if (create_addr_from_peer(p, peer)) {
/* Maybe they're not registered, etc. */
sip_destroy(p);
@ -11816,7 +11840,7 @@ static int sip_poke_peer(struct sip_peer *peer)
peer->call = NULL;
return 0;
}
if (peer->call > 0) {
if (peer->call) {
if (sipdebug)
ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
sip_destroy(peer->call);
@ -13520,8 +13544,10 @@ static int sip_do_reload(void)
sip_destroy(iterator->call);
}
ASTOBJ_UNLOCK(iterator);
} while(0));
ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
ASTOBJ_CONTAINER_MARKALL(&peerl);
@ -13713,13 +13739,7 @@ int unload_module()
while (p) {
pl = p;
p = p->next;
/* Free associated memory */
ast_mutex_destroy(&pl->lock);
if (pl->chanvars) {
ast_variables_destroy(pl->chanvars);
pl->chanvars = NULL;
}
free(pl);
__sip_destroy(pl, 1);
}
iflist = NULL;
ast_mutex_unlock(&iflock);

@ -3339,7 +3339,7 @@ static int attempt_transfer(struct zt_pvt *p)
stop if now if appropriate */
if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
ast_moh_stop(ast_bridged_channel(p->subs[SUB_THREEWAY].owner));
if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
}
if (p->subs[SUB_REAL].owner->cdr) {
@ -3363,7 +3363,7 @@ static int attempt_transfer(struct zt_pvt *p)
ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
unalloc_sub(p, SUB_THREEWAY);
} else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
}
ast_moh_stop(ast_bridged_channel(p->subs[SUB_THREEWAY].owner));
@ -4853,11 +4853,10 @@ static int zt_indicate(struct ast_channel *chan, int condition)
}
#endif
res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
if (chan->_state != AST_STATE_UP) {
if ((chan->_state != AST_STATE_RING) ||
((p->sig != SIG_FXSKS) &&
if (chan->_state != AST_STATE_UP && chan->_state != AST_STATE_RING) {
if ((p->sig != SIG_FXSKS) &&
(p->sig != SIG_FXSLS) &&
(p->sig != SIG_FXSGS)))
(p->sig != SIG_FXSGS))
ast_setstate(chan, AST_STATE_RINGING);
}
break;
@ -6268,7 +6267,9 @@ static int handle_init_event(struct zt_pvt *i, int event)
case SIG_FXOLS:
case SIG_FXOGS:
case SIG_FXOKS:
zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
if (res && (errno == EBUSY))
break;
if (i->cidspill) {
/* Cancel VMWI spill */
free(i->cidspill);

@ -85,7 +85,7 @@ enum misdn_cfg_method {
};
/* you must call misdn_cfg_init before any other function of this header file */
void misdn_cfg_init(int max_ports);
int misdn_cfg_init(int max_ports);
void misdn_cfg_reload(void);
void misdn_cfg_destroy(void);

@ -420,10 +420,10 @@ static int find_free_chan_in_stack(struct misdn_stack *stack, int channel)
{
int i;
cb_log(1,stack->port,"find_free_chan: req_chan:%d\n",channel);
cb_log(5,stack->port,"find_free_chan: req_chan:%d\n",channel);
if (channel < 0 || channel > MAX_BCHANS) {
cb_log(4, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
cb_log(0, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
return 0;
}
@ -432,14 +432,14 @@ static int find_free_chan_in_stack(struct misdn_stack *stack, int channel)
for (i = 0; i < stack->b_num; i++) {
if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 Dchannel ;) and work with chan preselection */
if (!stack->channels[i]) {
cb_log (1, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1);
cb_log (3, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1);
stack->channels[i] = 1;
return i+1;
}
}
}
cb_log (4, stack->port, " !! NO FREE CHAN IN STACK\n");
cb_log (1, stack->port, " !! NO FREE CHAN IN STACK\n");
dump_chan_list(stack);
return 0;
@ -1671,8 +1671,6 @@ int misdn_lib_port_up(int port, int check)
stack;
stack=stack->next) {
if ( !stack->ptp && !check) return 1;
if (stack->port == port) {
if (stack->blocked) {
@ -1690,7 +1688,7 @@ int misdn_lib_port_up(int port, int check)
return 0;
}
} else {
if ( stack->l1link)
if ( !check || stack->l1link )
return 1;
else {
cb_log(0,port, "Port down PMP\n");
@ -2030,7 +2028,7 @@ handle_event_nt(void *dat, void *arg)
if (stack->ptp)
set_chan_in_stack(stack, bc->channel);
else
cb_log(0,stack->port," --> PTMP but channel requested\n");
cb_log(3,stack->port," --> PTMP but channel requested\n");
} else {
@ -3173,7 +3171,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
}
cb_log(1, stack->port, "I SEND:%s oad:%s dad:%s pid:%d\n", isdn_get_info(msgs_g, event, 0), bc->oad, bc->dad, bc->pid);
cb_log(1, stack->port, " --> bc_state:%s\n",bc_state2str(bc->bc_state));
cb_log(4, stack->port, " --> bc_state:%s\n",bc_state2str(bc->bc_state));
misdn_lib_log_ies(bc);
switch (event) {
@ -4182,7 +4180,7 @@ void manager_ec_enable(struct misdn_bchannel *bc)
struct misdn_stack *stack=get_stack_by_bc(bc);
cb_log(1, stack?stack->port:0,"ec_enable\n");
cb_log(4, stack?stack->port:0,"ec_enable\n");
if (!misdn_cap_is_speech(bc->capability)) {
cb_log(1, stack?stack->port:0, " --> no speech? cannot enable EC\n");
@ -4190,7 +4188,7 @@ void manager_ec_enable(struct misdn_bchannel *bc)
}
if (bc->ec_enable) {
cb_log(1, stack?stack->port:0,"Sending Control ECHOCAN_ON taps:%d training:%d\n",bc->ec_deftaps, bc->ec_training);
cb_log(3, stack?stack->port:0,"Sending Control ECHOCAN_ON taps:%d training:%d\n",bc->ec_deftaps, bc->ec_training);
switch (bc->ec_deftaps) {
case 4:
@ -4222,7 +4220,7 @@ void manager_ec_disable(struct misdn_bchannel *bc)
{
struct misdn_stack *stack=get_stack_by_bc(bc);
cb_log(1, stack?stack->port:0,"ec_disable\n");
cb_log(4, stack?stack->port:0," --> ec_disable\n");
if (!misdn_cap_is_speech(bc->capability)) {
cb_log(1, stack?stack->port:0, " --> no speech? cannot disable EC\n");
@ -4230,7 +4228,7 @@ void manager_ec_disable(struct misdn_bchannel *bc)
}
if ( ! bc->ec_enable) {
cb_log(1, stack?stack->port:0, "Sending Control ECHOCAN_OFF\n");
cb_log(3, stack?stack->port:0, "Sending Control ECHOCAN_OFF\n");
manager_ph_control(bc, ECHOCAN_OFF, 0);
}
}
@ -4247,7 +4245,7 @@ void misdn_join_conf(struct misdn_bchannel *bc, int conf_id)
manager_ph_control(bc, CMX_RECEIVE_OFF, 0);
manager_ph_control(bc, CMX_CONF_JOIN, conf_id);
cb_log(1,bc->port, "Joining bc:%x in conf:%d\n",bc->addr,conf_id);
cb_log(3,bc->port, "Joining bc:%x in conf:%d\n",bc->addr,conf_id);
char data[16];
int len=15;
@ -4265,13 +4263,13 @@ void misdn_split_conf(struct misdn_bchannel *bc, int conf_id)
manager_ph_control(bc, CMX_RECEIVE_ON, 0);
manager_ph_control(bc, CMX_CONF_SPLIT, conf_id);
cb_log(1,bc->port, "Splitting bc:%x in conf:%d\n",bc->addr,conf_id);
cb_log(4,bc->port, "Splitting bc:%x in conf:%d\n",bc->addr,conf_id);
}
void misdn_lib_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2) {
int conf_id=bc1->pid +1;
cb_log(1, bc1->port, "I Send: BRIDGE from:%d to:%d\n",bc1->port,bc2->port);
cb_log(4, bc1->port, "I Send: BRIDGE from:%d to:%d\n",bc1->port,bc2->port);
struct misdn_bchannel *bc_list[]={
bc1,bc2,NULL
@ -4280,7 +4278,7 @@ void misdn_lib_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2)
for (bc=bc_list; *bc; *bc++) {
(*bc)->conf_id=conf_id;
cb_log(1, (*bc)->port, " --> bc_addr:%x\n",(*bc)->addr);
cb_log(4, (*bc)->port, " --> bc_addr:%x\n",(*bc)->addr);
switch((*bc)->bc_state) {
case BCHAN_ACTIVATED:
@ -4315,7 +4313,7 @@ void misdn_lib_split_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel
void misdn_lib_echo(struct misdn_bchannel *bc, int onoff)
{
cb_log(1,bc->port, " --> ECHO %s\n", onoff?"ON":"OFF");
cb_log(3,bc->port, " --> ECHO %s\n", onoff?"ON":"OFF");
manager_ph_control(bc, onoff?CMX_ECHO_ON:CMX_ECHO_OFF, 0);
}

@ -323,6 +323,10 @@ msg_t *build_setup (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
enc_ie_bearer(&setup->BEARER, msg, coding, capability, mode, rate, -1, user, nt,bc);
}
if (bc->sending_complete) {
enc_ie_complete(&setup->BEARER,msg, bc->sending_complete, nt, bc);
}
#if DEBUG
printf("Building SETUP Msg\n");

@ -91,7 +91,7 @@ static const struct misdn_cfg_spec port_spec[] = {
{ "far_alerting", MISDN_CFG_FAR_ALERTING, MISDN_CTYPE_BOOL, "no", NONE },
{ "pmp_l1_check", MISDN_CFG_PMP_L1_CHECK, MISDN_CTYPE_BOOL, "yes", NONE },
{ "reject_cause", MISDN_CFG_REJECT_CAUSE, MISDN_CTYPE_INT, "21", NONE },
{ "block_on_alarm", MISDN_CFG_ALARM_BLOCK, MISDN_CTYPE_BOOL, "yes", NONE },
{ "block_on_alarm", MISDN_CFG_ALARM_BLOCK, MISDN_CTYPE_BOOL, "no", NONE },
{ "hdlc", MISDN_CFG_HDLC, MISDN_CTYPE_BOOL, "no", NONE },
{ "context", MISDN_CFG_CONTEXT, MISDN_CTYPE_STR, "default", NONE },
{ "language", MISDN_CFG_LANGUAGE, MISDN_CTYPE_STR, "en", NONE },
@ -727,7 +727,7 @@ void misdn_cfg_destroy (void)
ast_mutex_destroy(&config_mutex);
}
void misdn_cfg_init (int this_max_ports)
int misdn_cfg_init (int this_max_ports)
{
char config[] = "misdn.conf";
char *cat, *p;
@ -737,7 +737,7 @@ void misdn_cfg_init (int this_max_ports)
if (!(cfg = AST_LOAD_CFG(config))) {
ast_log(LOG_WARNING,"no misdn.conf ?\n");
return;
return -1;
}
misdn_cfg_lock();
@ -783,4 +783,6 @@ void misdn_cfg_init (int this_max_ports)
misdn_cfg_unlock();
AST_DESTROY_CFG(cfg);
return 0;
}

@ -120,6 +120,8 @@ void ast_variable_append(struct ast_category *category, struct ast_variable *var
else
category->root = variable;
category->last = variable;
while (category->last->next)
category->last = category->last->next;
}
void ast_variables_destroy(struct ast_variable *v)
@ -301,6 +303,7 @@ struct ast_variable *ast_category_detach_variables(struct ast_category *cat)
v = cat->root;
cat->root = NULL;
cat->last = NULL;
return v;
}
@ -698,10 +701,13 @@ int config_text_file_save(const char *configfile, const struct ast_config *cfg,
if ((f = fopen(fn, "w"))) {
#endif
if (option_verbose > 1)
ast_verbose( VERBOSE_PREFIX_2 "Saving '%s': ", fn);
ast_verbose(VERBOSE_PREFIX_2 "Saving '%s': ", fn);
fprintf(f, ";!\n");
fprintf(f, ";! Automatically generated configuration file\n");
fprintf(f, ";! Filename: %s (%s)\n", configfile, fn);
if (strcmp(configfile, fn))
fprintf(f, ";! Filename: %s (%s)\n", configfile, fn);
else
fprintf(f, ";! Filename: %s\n", configfile);
fprintf(f, ";! Generator: %s\n", generator);
fprintf(f, ";! Creation Date: %s", date);
fprintf(f, ";!\n");
@ -731,9 +737,9 @@ int config_text_file_save(const char *configfile, const struct ast_config *cfg,
}
} else {
if (option_debug)
printf("Unable to open for writing: %s\n", fn);
ast_log(LOG_DEBUG, "Unable to open for writing: %s\n", fn);
if (option_verbose > 1)
printf( "Unable to write (%s)", strerror(errno));
ast_verbose(VERBOSE_PREFIX_2 "Unable to write (%s)", strerror(errno));
return -1;
}
fclose(f);

@ -154,7 +154,7 @@ TRUNKMSD=1 ; MSD digits to strip (usually 1 or 0)
;
; List canonical entries here
;
;exten => 12564286000,1,Macro(std-exten,6000,IAX2/foo)
;exten => 12564286000,1,Macro(stdexten,6000,IAX2/foo)
;exten => _125642860XX,1,Dial(IAX2/otherbox/${EXTEN:7})
[dundi-e164-customers]

@ -272,7 +272,7 @@ autokill=yes
; friends expire within this number of seconds instead of the
; registration interval.
;rtignoreexpire=yes ; When reading a peer from Realtime, if the peer's registration
;rtignoreregexpire=yes ; When reading a peer from Realtime, if the peer's registration
; has expired based on its registration interval, used the stored
; address information regardless. (yes|no)

@ -32,6 +32,7 @@ context=default ; Default context for incoming calls
; Realms MUST be globally unique according to RFC 3261
; Set this to your host name or domain name
bindport=5060 ; UDP Port to bind to (SIP standard port is 5060)
; bindport is the local UDP port that Asterisk will listen on
bindaddr=0.0.0.0 ; IP address to bind to (0.0.0.0 binds to all)
srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; Note: Asterisk only uses the first host
@ -327,6 +328,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
;usereqphone=yes ; This provider requires ";user=phone" on URI
;call-limit=5 ; permit only 5 simultaneous outgoing calls to this peer
;outboundproxy=proxy.provider.domain ; send outbound signaling to this proxy, not directly to the peer
;port=80 ; The port number we want to connect to on the remote side
;------------------------------------------------------------------------------
; Definitions of locally connected SIP phones

@ -102,21 +102,6 @@ ${CDR(uniqueid)} The channel's unique id.
${CDR(userfield)} The channels uses specified field.
In addition, you can set your own extra variables by using Set(CDR(name)=value).
______________________________
cdr_csv2
------------------------------
This module is an experimental new cdr module to demonstrate the cdr vars.
usage(
*) Create a file called cdr.conf and place it in your /etc/asterisk (or wherever your config files are) in the [cdr_csv2] section.
*) Add an entry called format to indicate any format you want for the output.
The following format string will emulate the regular cdr file format:
[cdr_csv2]
format => "${CDR(clid)}","${CDR(src)}","${CDR(dst)}","${CDR(dcontext)}","${CDR(channel)}","${CDR(dstchannel)}","${CDR(lastapp)}","${CDR(lastdata)}","${CDR(start)}","${CDR(answer)}","${CDR(end)}","${CDR(duration)}","${CDR(billsec)}","${CDR(disposition)}","${CDR(amaflags)}","${CDR(accountcode)}","${CDR(uniqueid)}","${CDR(userfield)}"
You can put anything you want as the value of format incuding new cdr vars you make up or any global variables.
These variables can be output into a text-format CDR by using the cdr_custom
CDR driver; see the cdr_custom.conf.sample file in the configs directory for
an example of how to do this.

@ -40,6 +40,7 @@ Overview
- Configuration
- Dial and Options String
- misdn cli commands
- mISDN Variables
- Debugging and sending Bugreports
- Examples
- Known working Configurations
@ -235,6 +236,14 @@ where 1 is the Port of the Card where the phone is plugged in, and 101 is the
msn (callerid) of the Phone to send the text to.
mISDN Variables
---------------
mISDN Exports/Imports a few Variables:
- MISDN_ADDRESS_COMPLETE : Is either set to 1 from the Provider, or you
can set it to 1 to force a sending complete.
Debugging and sending bug reports
---------------------------------

@ -157,6 +157,8 @@ int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap)
/* Optimize by sending the frame we just got
on the next read, thus eliminating the douple
copy */
if (swap)
ast_swapcopy_samples(f->data, f->data, f->samples);
s->opt = f;
return 0;
} else {
@ -167,6 +169,8 @@ int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap)
we were unable to optimize because there was still
some cruft left over. Lets just drop the cruft so
we can move to a fully optimized path */
if (swap)
ast_swapcopy_samples(f->data, f->data, f->samples);
s->len = 0;
s->opt = f;
return 0;

@ -435,6 +435,7 @@ struct ast_channel {
so when ->priority is set, it will get incremented before
finding the next priority to run
*/
#define AST_FLAG_NOTNEW (1 << 10) /*!< see bug:7855 incorrect Newchannel event generation */
/* @} */
#define AST_FEATURE_PLAY_WARNING (1 << 0)

@ -181,7 +181,6 @@ void ast_category_rename(struct ast_category *cat, const char *name);
struct ast_variable *ast_variable_new(const char *name, const char *value);
void ast_variable_append(struct ast_category *category, struct ast_variable *variable);
int ast_variable_delete(struct ast_config *cfg, char *category, char *variable, char *value);
int config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator);

@ -315,8 +315,8 @@ static int scan_service(char *fn, time_t now, time_t atime)
now += o->retrytime;
if (o->callingpid && (o->callingpid == ast_mainpid)) {
safe_append(o, time(NULL), "DelayedRetry");
free_outgoing(o);
ast_log(LOG_DEBUG, "Delaying retry since we're currently running '%s'\n", o->fn);
free_outgoing(o);
} else {
/* Increment retries */
o->retries++;

@ -234,7 +234,7 @@ static int launch_script(char *script, char *argv[], int *fds, int *efd, int *op
int audio[2];
int x;
int res;
sigset_t signal_set;
sigset_t signal_set, old_set;
if (!strncasecmp(script, "agi://", 6))
return launch_netscript(script, argv, fds, efd, opid);
@ -276,6 +276,10 @@ static int launch_script(char *script, char *argv[], int *fds, int *efd, int *op
return -1;
}
}
/* Block SIGHUP during the fork - prevents a race */
sigfillset(&signal_set);
pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
pid = fork();
if (pid < 0) {
ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
@ -293,9 +297,18 @@ static int launch_script(char *script, char *argv[], int *fds, int *efd, int *op
} else {
close(STDERR_FILENO + 1);
}
/* Before we unblock our signals, return our trapped signals back to the defaults */
signal(SIGHUP, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGURG, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
signal(SIGXFSZ, SIG_DFL);
/* unblock important signal handlers */
if (sigfillset(&signal_set) || pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
if (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno));
_exit(1);
}
@ -310,6 +323,7 @@ static int launch_script(char *script, char *argv[], int *fds, int *efd, int *op
fprintf(stderr, "Failed to execute '%s': %s\n", script, strerror(errno));
_exit(1);
}
pthread_sigmask(SIG_SETMASK, &old_set, NULL);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script);
fds[0] = toast[0];

@ -1774,12 +1774,6 @@ static int park_exec(struct ast_channel *chan, void *data)
ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park);
memset(&config, 0, sizeof(struct ast_bridge_config));
ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
config.timelimit = 0;
config.play_warning = 0;
config.warning_freq = 0;
config.warning_sound=NULL;
res = ast_bridge_call(chan, peer, &config);
/* Simulate the PBX hanging up */
@ -2058,7 +2052,8 @@ static int load_config(void)
ast_unregister_features();
var = ast_variable_browse(cfg, "applicationmap");
while(var) {
char *tmp_val=strdup(var->value);
char *tmp_val_orig=strdup(var->value);
char *tmp_val = tmp_val_orig;
char *exten, *party=NULL, *app=NULL, *app_args=NULL;
if (!tmp_val) {
@ -2075,7 +2070,7 @@ static int load_config(void)
if (!(app && strlen(app)) || !(exten && strlen(exten)) || !(party && strlen(party)) || !(var->name && strlen(var->name))) {
ast_log(LOG_NOTICE, "Please check the feature Mapping Syntax, either extension, name, or app aren't provided %s %s %s %s\n",app,exten,party,var->name);
free(tmp_val);
free(tmp_val_orig);
var = var->next;
continue;
}
@ -2090,7 +2085,7 @@ static int load_config(void)
}
if (!feature) {
ast_log(LOG_NOTICE, "Malloc failed at feature mapping\n");
free(tmp_val);
free(tmp_val_orig);
var = var->next;
continue;
}
@ -2099,7 +2094,6 @@ static int load_config(void)
ast_copy_string(feature->sname,var->name,FEATURE_SNAME_LEN);
ast_copy_string(feature->app,app,FEATURE_APP_LEN);
ast_copy_string(feature->exten, exten,FEATURE_EXTEN_LEN);
free(tmp_val);
if (app_args)
ast_copy_string(feature->app_args,app_args,FEATURE_APP_ARGS_LEN);
@ -2114,6 +2108,7 @@ static int load_config(void)
ast_set_flag(feature,AST_FEATURE_FLAG_CALLEE);
else {
ast_log(LOG_NOTICE, "Invalid party specification for feature '%s', must be caller, or callee\n", var->name);
free(tmp_val_orig);
var = var->next;
continue;
}
@ -2121,6 +2116,7 @@ static int load_config(void)
ast_register_feature(feature);
if (option_verbose >=1) ast_verbose(VERBOSE_PREFIX_2 "Mapping Feature '%s' to app '%s' with code '%s'\n", var->name, app, exten);
free(tmp_val_orig);
}
var = var->next;
}

@ -190,7 +190,7 @@ static void moh_files_release(struct ast_channel *chan, void *data)
if (state->origwfmt && ast_set_write_format(chan, state->origwfmt)) {
ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%d'\n", chan->name, state->origwfmt);
}
state->save_pos = state->pos + 1;
state->save_pos = state->pos;
}
}
@ -201,35 +201,33 @@ static int ast_moh_files_next(struct ast_channel *chan)
int tries;
if (state->save_pos) {
state->pos = state->save_pos - 1;
state->pos = state->save_pos;
state->save_pos = 0;
} else {
/* Try 20 times to find something good */
for (tries=0;tries < 20;tries++) {
state->samples = 0;
if (chan->stream) {
ast_closestream(chan->stream);
chan->stream = NULL;
state->pos++;
}
}
if (ast_test_flag(state->class, MOH_RANDOMIZE))
state->pos = rand();
state->samples = 0;
if (chan->stream) {
ast_closestream(chan->stream);
chan->stream = NULL;
state->pos++;
state->pos %= state->class->total_files;
}
state->pos %= state->class->total_files;
if (ast_test_flag(state->class, MOH_RANDOMIZE)) {
/* Try 20 times to find something good */
for (tries = 0; tries < 20; tries++) {
state->pos = rand() % state->class->total_files;
/* check to see if this file's format can be opened */
if (ast_fileexists(state->class->filearray[state->pos], NULL, NULL) > 0)
break;
}
}
state->pos = state->pos % state->class->total_files;
if (!ast_openstream_full(chan, state->class->filearray[state->pos], chan->language, 1)) {
ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", state->class->filearray[state->pos], strerror(errno));
state->pos++;
state->pos %= state->class->total_files;
return -1;
}
@ -297,6 +295,8 @@ static void *moh_files_alloc(struct ast_channel *chan, void *params)
/* initialize */
memset(state, 0, sizeof(struct moh_files_state));
state->class = class;
if (ast_test_flag(state->class, MOH_RANDOMIZE))
state->pos = rand() % class->total_files;
}
state->origwfmt = chan->writeformat;
@ -326,6 +326,7 @@ static int spawn_mp3(struct mohclass *class)
int argc = 0;
DIR *dir = NULL;
struct dirent *de;
sigset_t signal_set, old_set;
if (!strcasecmp(class->dir, "nodir")) {
@ -426,6 +427,11 @@ static int spawn_mp3(struct mohclass *class)
if (time(NULL) - class->start < respawn_time) {
sleep(respawn_time - (time(NULL) - class->start));
}
/* Block signals during the fork() */
sigfillset(&signal_set);
pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
time(&class->start);
class->pid = fork();
if (class->pid < 0) {
@ -440,6 +446,10 @@ static int spawn_mp3(struct mohclass *class)
if (option_highpriority)
ast_set_priority(0);
/* Reset ignored signals back to default */
signal(SIGPIPE, SIG_DFL);
pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL);
close(fds[0]);
/* Stdout goes to pipe */
dup2(fds[1], STDOUT_FILENO);
@ -466,6 +476,7 @@ static int spawn_mp3(struct mohclass *class)
_exit(1);
} else {
/* Parent */
pthread_sigmask(SIG_SETMASK, &old_set, NULL);
close(fds[1]);
}
return fds[0];

@ -140,6 +140,7 @@ SQLHSTMT odbc_prepare_and_execute(odbc_obj *obj, SQLHSTMT (*prepare_cb)(odbc_obj
ast_log(LOG_WARNING, "SQL Execute error %d! Attempting a reconnect...\n", res);
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
stmt = NULL;
ast_mutex_lock(&obj->lock);
obj->up = 0;

@ -1481,6 +1481,8 @@ int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
f = _f;
}
ast_rtp_raw_write(rtp, f, codec);
if (f != _f)
ast_frfree(f);
}
return 0;

@ -728,3 +728,25 @@
%spy-zap.gsm%Zap
; Silence directory
%1.gsm%1 second of silence
%2.gsm%2 seconds of silence
%3.gsm%3 seconds of silence
%4.gsm%4 seconds of silence
%5.gsm%5 seconds of silence
%6.gsm%6 seconds of silence
%7.gsm%7 seconds of silence
%8.gsm%8 seconds of silence
%9.gsm%9 seconds of silence
%10.gsm%10 seconds of silence

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.
Loading…
Cancel
Save