aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-12-12 22:58:49 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-12-12 22:58:49 +0000
commit41df2e668668137091861464cabe91cf110f4302 (patch)
tree921cb941ba1a59df6cc1650b935d249fa0b73f84
parent476ed07a1111e6172eb4f860ad239d3ef7bb5f49 (diff)
manual update, since automerge is not running at this time
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2-netsec@48421 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--Makefile9
-rw-r--r--apps/app_cut.c4
-rw-r--r--apps/app_db.c2
-rw-r--r--apps/app_dial.c3
-rw-r--r--apps/app_directory.c2
-rw-r--r--apps/app_externalivr.c14
-rw-r--r--apps/app_festival.c11
-rw-r--r--apps/app_ices.c18
-rw-r--r--apps/app_mp3.c16
-rw-r--r--apps/app_nbscat.c16
-rw-r--r--apps/app_sms.c2
-rw-r--r--apps/app_voicemail.c123
-rw-r--r--apps/app_zapras.c18
-rw-r--r--cdr.c12
-rw-r--r--cdr/Makefile2
-rw-r--r--cdr/cdr_pgsql.c4
-rw-r--r--channel.c78
-rw-r--r--channels/chan_iax2.c23
-rw-r--r--channels/chan_local.c25
-rw-r--r--channels/chan_misdn.c99
-rw-r--r--channels/chan_phone.c3
-rw-r--r--channels/chan_sip.c162
-rw-r--r--channels/chan_zap.c15
-rw-r--r--channels/misdn/chan_misdn_config.h2
-rw-r--r--channels/misdn/isdn_lib.c34
-rw-r--r--channels/misdn/isdn_msg_parser.c4
-rw-r--r--channels/misdn_config.c8
-rw-r--r--config.c14
-rw-r--r--configs/extensions.conf.sample2
-rw-r--r--configs/iax.conf.sample2
-rw-r--r--configs/sip.conf.sample2
-rw-r--r--doc/README.cdr21
-rw-r--r--doc/README.misdn9
-rw-r--r--frame.c4
-rw-r--r--include/asterisk/channel.h1
-rw-r--r--include/asterisk/config.h1
-rw-r--r--pbx/pbx_spool.c2
-rw-r--r--res/res_agi.c20
-rw-r--r--res/res_features.c16
-rw-r--r--res/res_musiconhold.c45
-rw-r--r--res/res_odbc.c1
-rw-r--r--rtp.c2
-rw-r--r--sounds.txt22
-rw-r--r--sounds/silence/1.gsmbin0 -> 165 bytes
-rw-r--r--sounds/silence/10.gsmbin0 -> 165 bytes
-rw-r--r--sounds/silence/2.gsmbin0 -> 165 bytes
-rw-r--r--sounds/silence/3.gsmbin0 -> 165 bytes
-rw-r--r--sounds/silence/4.gsmbin0 -> 165 bytes
-rw-r--r--sounds/silence/5.gsmbin0 -> 165 bytes
-rw-r--r--sounds/silence/6.gsmbin0 -> 165 bytes
-rw-r--r--sounds/silence/7.gsmbin0 -> 165 bytes
-rw-r--r--sounds/silence/8.gsmbin0 -> 165 bytes
-rw-r--r--sounds/silence/9.gsmbin0 -> 165 bytes
53 files changed, 561 insertions, 312 deletions
diff --git a/Makefile b/Makefile
index e0921fdf8..f8eaff3d2 100644
--- a/Makefile
+++ b/Makefile
@@ -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 \
diff --git a/apps/app_cut.c b/apps/app_cut.c
index 46f934b89..a97405775 100644
--- a/apps/app_cut.c
+++ b/apps/app_cut.c
@@ -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;
diff --git a/apps/app_db.c b/apps/app_db.c
index 245c8d3ca..0a66959bf 100644
--- a/apps/app_db.c
+++ b/apps/app_db.c
@@ -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 =
diff --git a/apps/app_dial.c b/apps/app_dial.c
index b214017bb..662a2142a 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -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);
diff --git a/apps/app_directory.c b/apps/app_directory.c
index b403cae4a..9caefc030 100644
--- a/apps/app_directory.c
+++ b/apps/app_directory.c
@@ -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"
diff --git a/apps/app_externalivr.c b/apps/app_externalivr.c
index fc5f34082..1d4a6f3fd 100644
--- a/apps/app_externalivr.c
+++ b/apps/app_externalivr.c
@@ -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]);
diff --git a/apps/app_festival.c b/apps/app_festival.c
index 7c69dc8b9..33f54aaf3 100644
--- a/apps/app_festival.c
+++ b/apps/app_festival.c
@@ -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)
diff --git a/apps/app_ices.c b/apps/app_ices.c
index b6b5ad3f7..5a9b9412d 100644
--- a/apps/app_ices.c
+++ b/apps/app_ices.c
@@ -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)
diff --git a/apps/app_mp3.c b/apps/app_mp3.c
index 31fc32096..1cba886bb 100644
--- a/apps/app_mp3.c
+++ b/apps/app_mp3.c
@@ -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)
diff --git a/apps/app_nbscat.c b/apps/app_nbscat.c
index adc232373..004bde77b 100644
--- a/apps/app_nbscat.c
+++ b/apps/app_nbscat.c
@@ -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)
diff --git a/apps/app_sms.c b/apps/app_sms.c
index 78ff4d143..3a7677601 100644
--- a/apps/app_sms.c
+++ b/apps/app_sms.c
@@ -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;
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index a2773dd7a..a8477724c 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -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;
diff --git a/apps/app_zapras.c b/apps/app_zapras.c
index cf770f2b7..91336f5e4 100644
--- a/apps/app_zapras.c
+++ b/apps/app_zapras.c
@@ -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));
diff --git a/cdr.c b/cdr.c
index 64a9e5690..f09d1e131 100644
--- a/cdr.c
+++ b/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;
diff --git a/cdr/Makefile b/cdr/Makefile
index 6be6d9b95..84ea0fe4b 100644
--- a/cdr/Makefile
+++ b/cdr/Makefile
@@ -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
diff --git a/cdr/cdr_pgsql.c b/cdr/cdr_pgsql.c
index 776bf6a54..17ed573c3 100644
--- a/cdr/cdr_pgsql.c
+++ b/cdr/cdr_pgsql.c
@@ -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)
{
diff --git a/channel.c b/channel.c
index ae5d5f79c..539b3d9c1 100644
--- a/channel.c
+++ b/channel.c
@@ -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;
}
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 5e4648f37..e896abeb3 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -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)
diff --git a/channels/chan_local.c b/channels/chan_local.c
index 84fd9d220..b3bf3b24c 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -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) {
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index 4f2fac442..9049ba753 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -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;
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index 65257d507..ad7b87013 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -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"
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 892ec86fc..67005f690 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -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);
diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index 69177a981..277a152c1 100644
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -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);
diff --git a/channels/misdn/chan_misdn_config.h b/channels/misdn/chan_misdn_config.h
index db007f57d..d36686cc0 100644
--- a/channels/misdn/chan_misdn_config.h
+++ b/channels/misdn/chan_misdn_config.h
@@ -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);
diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c
index f07951c57..72b7d8243 100644
--- a/channels/misdn/isdn_lib.c
+++ b/channels/misdn/isdn_lib.c
@@ -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);
}
diff --git a/channels/misdn/isdn_msg_parser.c b/channels/misdn/isdn_msg_parser.c
index 136c9a62d..3d841d893 100644
--- a/channels/misdn/isdn_msg_parser.c
+++ b/channels/misdn/isdn_msg_parser.c
@@ -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");
diff --git a/channels/misdn_config.c b/channels/misdn_config.c
index 689c8c7c7..1d33ac15d 100644
--- a/channels/misdn_config.c
+++ b/channels/misdn_config.c
@@ -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;
}
diff --git a/config.c b/config.c
index b35045427..989cd0b15 100644
--- a/config.c
+++ b/config.c
@@ -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);
diff --git a/configs/extensions.conf.sample b/configs/extensions.conf.sample
index 649e53c0d..7188cb951 100644
--- a/configs/extensions.conf.sample
+++ b/configs/extensions.conf.sample
@@ -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]
diff --git a/configs/iax.conf.sample b/configs/iax.conf.sample
index ff787bd66..85f1bf06e 100644
--- a/configs/iax.conf.sample
+++ b/configs/iax.conf.sample
@@ -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)
diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample
index f080e149b..b16eed5e7 100644
--- a/configs/sip.conf.sample
+++ b/configs/sip.conf.sample
@@ -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
diff --git a/doc/README.cdr b/doc/README.cdr
index cb9813845..2f6891ed6 100644
--- a/doc/README.cdr
+++ b/doc/README.cdr
@@ -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.
diff --git a/doc/README.misdn b/doc/README.misdn
index ab029e4d1..96368e7a2 100644
--- a/doc/README.misdn
+++ b/doc/README.misdn
@@ -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
---------------------------------
diff --git a/frame.c b/frame.c
index 27d82d665..ddb61d6fb 100644
--- a/frame.c
+++ b/frame.c
@@ -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;
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 38b33ed2d..dd78844c9 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -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)
diff --git a/include/asterisk/config.h b/include/asterisk/config.h
index aa639aaae..142055509 100644
--- a/include/asterisk/config.h
+++ b/include/asterisk/config.h
@@ -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);
diff --git a/pbx/pbx_spool.c b/pbx/pbx_spool.c
index a91a7e255..187beda1c 100644
--- a/pbx/pbx_spool.c
+++ b/pbx/pbx_spool.c
@@ -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++;
diff --git a/res/res_agi.c b/res/res_agi.c
index 022cee46e..1d39c6936 100644
--- a/res/res_agi.c
+++ b/res/res_agi.c
@@ -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];
diff --git a/res/res_features.c b/res/res_features.c
index a33844b1e..b1eb6f16c 100644
--- a/res/res_features.c
+++ b/res/res_features.c
@@ -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;
}
diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c
index 6c0c380bd..746fa2d06 100644
--- a/res/res_musiconhold.c
+++ b/res/res_musiconhold.c
@@ -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];
diff --git a/res/res_odbc.c b/res/res_odbc.c
index cc4b61f2d..92cd1ccfb 100644
--- a/res/res_odbc.c
+++ b/res/res_odbc.c
@@ -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;
diff --git a/rtp.c b/rtp.c
index d7730830c..6d2f5049c 100644
--- a/rtp.c
+++ b/rtp.c
@@ -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;
diff --git a/sounds.txt b/sounds.txt
index c323ffbe6..f95688c26 100644
--- a/sounds.txt
+++ b/sounds.txt
@@ -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
+
diff --git a/sounds/silence/1.gsm b/sounds/silence/1.gsm
new file mode 100644
index 000000000..aae90ed02
--- /dev/null
+++ b/sounds/silence/1.gsm
Binary files differ
diff --git a/sounds/silence/10.gsm b/sounds/silence/10.gsm
new file mode 100644
index 000000000..aae90ed02
--- /dev/null
+++ b/sounds/silence/10.gsm
Binary files differ
diff --git a/sounds/silence/2.gsm b/sounds/silence/2.gsm
new file mode 100644
index 000000000..aae90ed02
--- /dev/null
+++ b/sounds/silence/2.gsm
Binary files differ
diff --git a/sounds/silence/3.gsm b/sounds/silence/3.gsm
new file mode 100644
index 000000000..aae90ed02
--- /dev/null
+++ b/sounds/silence/3.gsm
Binary files differ
diff --git a/sounds/silence/4.gsm b/sounds/silence/4.gsm
new file mode 100644
index 000000000..aae90ed02
--- /dev/null
+++ b/sounds/silence/4.gsm
Binary files differ
diff --git a/sounds/silence/5.gsm b/sounds/silence/5.gsm
new file mode 100644
index 000000000..aae90ed02
--- /dev/null
+++ b/sounds/silence/5.gsm
Binary files differ
diff --git a/sounds/silence/6.gsm b/sounds/silence/6.gsm
new file mode 100644
index 000000000..aae90ed02
--- /dev/null
+++ b/sounds/silence/6.gsm
Binary files differ
diff --git a/sounds/silence/7.gsm b/sounds/silence/7.gsm
new file mode 100644
index 000000000..aae90ed02
--- /dev/null
+++ b/sounds/silence/7.gsm
Binary files differ
diff --git a/sounds/silence/8.gsm b/sounds/silence/8.gsm
new file mode 100644
index 000000000..aae90ed02
--- /dev/null
+++ b/sounds/silence/8.gsm
Binary files differ
diff --git a/sounds/silence/9.gsm b/sounds/silence/9.gsm
new file mode 100644
index 000000000..aae90ed02
--- /dev/null
+++ b/sounds/silence/9.gsm
Binary files differ