aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2008-08-13 22:45:58 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2008-08-13 22:45:58 +0000
commit6d2b1074edb99af1facd6b179e9f2e8c10b13059 (patch)
treed1883e89718401ca751a3572e47c43fec7ebea28
parented3775f2e450adafd9e366b00f109ffe57e75aaa (diff)
parent1e8b08cb2538177a939b40dfb2bf90cf5a1c702b (diff)
Creating tag for the release of asterisk-1.6.0-rc1
git-svn-id: http://svn.digium.com/svn/asterisk/tags/1.6.0-rc1@137637 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--Makefile20
-rw-r--r--UPGRADE.txt26
-rw-r--r--Zaptel-to-DAHDI.txt52
-rw-r--r--apps/app_fax.c25
-rw-r--r--apps/app_voicemail.c57
-rw-r--r--cdr/cdr_tds.c166
-rw-r--r--channels/chan_sip.c5
-rw-r--r--doc/tex/asterisk.tex13
-rw-r--r--doc/tex/cdrdriver.tex3
-rw-r--r--include/asterisk/astobj2.h2
-rw-r--r--include/asterisk/compat.h1
-rw-r--r--res/res_agi.c39
-rw-r--r--res/res_odbc.c17
13 files changed, 273 insertions, 153 deletions
diff --git a/Makefile b/Makefile
index 569e8daf2..b916547bd 100644
--- a/Makefile
+++ b/Makefile
@@ -312,7 +312,7 @@ endif
SILENTMAKE:=$(MAKE) --quiet --no-print-directory
ifneq ($(PRINT_DIR)$(NOISY_BUILD),)
-SUBMAKE:=$(MAKE) --quiet
+SUBMAKE:=$(MAKE)
else
SUBMAKE:=$(MAKE) --quiet --no-print-directory
endif
@@ -369,9 +369,9 @@ $(MOD_SUBDIRS_MENUSELECT_TREE):
makeopts.embed_rules: menuselect.makeopts
@echo "Generating embedded module rules ..."
@rm -f $@
- @$(MAKE) $(PRINT_DIR) $(MOD_SUBDIRS_EMBED_LDSCRIPT)
- @$(MAKE) $(PRINT_DIR) $(MOD_SUBDIRS_EMBED_LDFLAGS)
- @$(MAKE) $(PRINT_DIR) $(MOD_SUBDIRS_EMBED_LIBS)
+ @$(SUBMAKE) $(MOD_SUBDIRS_EMBED_LDSCRIPT)
+ @$(SUBMAKE) $(MOD_SUBDIRS_EMBED_LDFLAGS)
+ @$(SUBMAKE) $(MOD_SUBDIRS_EMBED_LIBS)
$(SUBDIRS): main/version.c include/asterisk/version.h include/asterisk/build.h include/asterisk/buildopts.h defaults.h makeopts.embed_rules
@@ -394,10 +394,10 @@ res: main
endif
$(MOD_SUBDIRS):
- @ASTCFLAGS="$(MOD_SUBDIR_CFLAGS) $(ASTCFLAGS)" ASTLDFLAGS="$(ASTLDFLAGS)" $(MAKE) $(PRINT_DIR) --no-builtin-rules -C $@ SUBDIR=$@ all
+ @ASTCFLAGS="$(MOD_SUBDIR_CFLAGS) $(ASTCFLAGS)" ASTLDFLAGS="$(ASTLDFLAGS)" $(SUBMAKE) --no-builtin-rules -C $@ SUBDIR=$@ all
$(OTHER_SUBDIRS):
- @ASTCFLAGS="$(OTHER_SUBDIR_CFLAGS) $(ASTCFLAGS)" ASTLDFLAGS="$(ASTLDFLAGS)" $(MAKE) $(PRINT_DIR) --no-builtin-rules -C $@ SUBDIR=$@ all
+ @ASTCFLAGS="$(OTHER_SUBDIR_CFLAGS) $(ASTCFLAGS)" ASTLDFLAGS="$(ASTLDFLAGS)" $(SUBMAKE) --no-builtin-rules -C $@ SUBDIR=$@ all
defaults.h: makeopts
@build_tools/make_defaults_h > $@.tmp
@@ -425,10 +425,10 @@ include/asterisk/build.h:
@rm -f $@.tmp
$(SUBDIRS_CLEAN):
- @$(MAKE) $(PRINT_DIR) -C $(@:-clean=) clean
+ @$(SUBMAKE) -C $(@:-clean=) clean
$(SUBDIRS_DIST_CLEAN):
- @$(MAKE) $(PRINT_DIR) -C $(@:-dist-clean=) dist-clean
+ @$(SUBMAKE) -C $(@:-dist-clean=) dist-clean
clean: $(SUBDIRS_CLEAN)
rm -f defaults.h
@@ -539,7 +539,7 @@ bininstall: _all installdirs $(SUBDIRS_INSTALL)
fi
$(SUBDIRS_INSTALL):
- @DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" $(MAKE) --quiet $(PRINT_DIR) -C $(@:-install=) install
+ @DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" $(SUBMAKE) -C $(@:-install=) install
NEWMODS:=$(foreach d,$(MOD_SUBDIRS),$(notdir $(wildcard $(d)/*.so)))
OLDMODS=$(filter-out $(NEWMODS),$(notdir $(wildcard $(DESTDIR)$(MODULES_DIR)/*.so)))
@@ -803,7 +803,7 @@ cleantest:
@cmp -s .cleancount .lastclean || $(MAKE) clean
$(SUBDIRS_UNINSTALL):
- @$(MAKE) $(PRINT_DIR) -C $(@:-uninstall=) uninstall
+ @$(SUBMAKE) -C $(@:-uninstall=) uninstall
_uninstall: $(SUBDIRS_UNINSTALL)
rm -f $(DESTDIR)$(MODULES_DIR)/*
diff --git a/UPGRADE.txt b/UPGRADE.txt
index a3a1bbc67..8fb0a0f71 100644
--- a/UPGRADE.txt
+++ b/UPGRADE.txt
@@ -70,6 +70,7 @@ Voicemail:
to make them more distinguishable from 'maxmsgs', which sets folder
size. The old variables will continue to work in this version, albeit
with a deprecation warning.
+
* If you use any interface for modifying voicemail aside from the built in
dialplan applications, then the option "pollmailboxes" *must* be set in
voicemail.conf for message waiting indication (MWI) to work properly. This
@@ -81,17 +82,22 @@ Voicemail:
Applications:
+
* ChanIsAvail() now has a 't' option, which allows the specified device
to be queried for state without consulting the channel drivers. This
performs mostly a 'ChanExists' sort of function.
+
* ChannelRedirect() will not terminate the channel that fails to do a
channelredirect as it has done previously. Instead CHANNELREDIRECT_STATUS
will reflect if the attempt was successful of not.
+
* SetCallerPres() has been replaced with the CALLERPRES() dialplan function
and is now deprecated.
+
* DISA()'s fifth argument is now an options argument. If you have previously
used 'NOANSWER' in this argument, you'll need to convert that to the new
option 'n'.
+
* Macro() is now deprecated. If you need subroutines, you should use the
Gosub()/Return() applications. To replace MacroExclusive(), we have
introduced dialplan functions LOCK(), TRYLOCK(), and UNLOCK(). You may use
@@ -102,18 +108,25 @@ Applications:
sake of backwards compatibility it will not be removed . It is also worth
noting that using both Macro() and GoSub() at the same time is _heavily_
discouraged.
+
* Read() now sets a READSTATUS variable on exit. It does NOT automatically
return -1 (and hangup) anymore on error. If you want to hangup on error,
you need to do so explicitly in your dialplan.
+
* Privacy() no longer uses privacy.conf, so any options must be specified
directly in the application arguments.
+
* MusicOnHold application now has duration parameter which allows specifying
timeout in seconds.
+
* WaitMusicOnHold application is now deprecated in favor of extended MusicOnHold.
+
* SetMusicOnHold is now deprecated. You should use Set(CHANNEL(musicclass)=...)
instead.
+
* The arguments in ExecIf changed a bit, to be more like other applications.
The syntax is now ExecIf(<cond>?appiftrue(args):appiffalse(args)).
+
* The behavior of the Set application now depends upon a compatibility option,
set in asterisk.conf. To use the old 1.4 behavior, which allowed Set to take
multiple key/value pairs, set app_set=1.4 in [compat] in asterisk.conf. To
@@ -143,7 +156,8 @@ CDR:
systemname was too long, the uniqueid would have been truncated.
* The cdr_tds module now supports all versions of FreeTDS that contain
- the db-lib frontend.
+ the db-lib frontend. It will also now log the userfield variable if
+ the target database table contains a column for it.
Formats:
@@ -162,10 +176,12 @@ Channel Drivers:
file names and formats are all controlled via the normal mechanisms. If the
user has not configured the automon feature, the normal "415 Unsupported media type"
is returned, and nothing is done.
+
* SIP: The "call-limit" option is marked as deprecated. It still works in this version of
Asterisk, but will be removed in the following version. Please use the groupcount functions
in the dialplan to enforce call limits. The "limitonpeer" configuration option is
now renamed to "counteronpeer".
+
* SIP: The "username" option is now renamed to "defaultuser" to match "defaultip".
These are used only before registration to call a peer with the uri
sip:defaultuser@defaultip
@@ -175,6 +191,7 @@ Channel Drivers:
* chan_local.c: the comma delimiter inside the channel name has been changed to a
semicolon, in order to make the Local channel driver compatible with the comma
delimiter change in applications.
+
* H323: The "tos" setting has changed name to "tos_audio" and "cos" to "cos_audio"
to be compatible with settings in sip.conf. The "tos" and "cos" configuration
is deprecated and will stop working in the next release of Asterisk.
@@ -186,7 +203,12 @@ Channel Drivers:
to modify modules.conf to add another "noload" line to ensure that only one of
these three modules gets loaded.
-* Zap: The "msdstrip" option has been deprecated, as it provides no value over
+* DAHDI: The chan_zap module that supported PSTN interfaces using
+ Zaptel has been renamed to chan_dahdi, and only supports the DAHDI
+ telephony driver package for PSTN interfaces. See the
+ Zaptel-to-DAHDI.txt file for more details on this transition.
+
+* DAHDI: The "msdstrip" option has been deprecated, as it provides no value over
the method of stripping digits in the dialplan using variable substring syntax.
Configuration:
diff --git a/Zaptel-to-DAHDI.txt b/Zaptel-to-DAHDI.txt
new file mode 100644
index 000000000..f0cf2f676
--- /dev/null
+++ b/Zaptel-to-DAHDI.txt
@@ -0,0 +1,52 @@
+=========================================================
+=== Information for upgrading from Zaptel to DAHDI ===
+=========================================================
+
+As announced in early 2008, Digium is renaming the Zaptel telephony
+interface project to DAHDI (Digium Asterisk Hardware Device Interface)
+to accommodate the desires of the owner of the Zaptel trademark for
+telephony purposes.
+
+This version of Asterisk can only be built using DAHDI, and as a
+result there are number of changes that will be visible to previous
+users of Asterisk with Zaptel.
+
+First, the modules that directly use services from DAHDI have been
+renamed; the new names are:
+
+ chan_zap.so -> chan_dahdi.so
+ app_zapbarge.so -> app_dahdibarge.so
+ app_zapras.so -> app_dahdiras.so
+ app_zapscan.so -> app_dahdiscan.so
+
+Second, the behavior of many modules has changed due to the switch to
+DAHDI; the changes are listed below.
+
+chan_dahdi.so:
+
+ Incoming and outgoing channels managed by this module will be
+ 'DAHDI' channels instead of 'Zap' channels.
+
+ All CLI commands that began with 'zap' have been renamed to 'dahdi'
+ commands.
+
+ All Asterisk Manager Interface (AMI) actions that began with 'Zap'
+ have changed to 'DAHDI' prefixes.
+
+ The ZapSendKeypadFacility dialplan application has been renamed to
+ DAHDISendKeypadFacility.
+
+ The configuration for the channel driver will be read from
+ /etc/asterisk/chan_dahdi.conf instead of /etc/asterisk/zapata.conf.
+
+app_dahdibarge.so:
+
+ The ZapBarge application has been renamed to DAHDIBarge.
+
+app_dahdiras.so:
+
+ The ZapRAS application has been renamed to DAHDIRAS.
+
+app_dahdiscan.so:
+
+ The ZapScan application has been renamed to DAHDIScan.
diff --git a/apps/app_fax.c b/apps/app_fax.c
index 6d98755cc..6cb47dd1e 100644
--- a/apps/app_fax.c
+++ b/apps/app_fax.c
@@ -46,8 +46,8 @@ static char *app_sndfax_desc =
" SendFAX(filename[|options]):\n"
"Send a given TIFF file to the channel as a FAX.\n"
"The option string may contain zero or more of the following characters:\n"
-" 'a' -- makes the application behave as an answering machine\n"
-" The default behaviour is to behave as a calling machine.\n"
+" 'a' - makes the application behave as an answering machine\n"
+" The default behaviour is to behave as a calling machine.\n"
"\n"
"This application uses following variables:\n"
" LOCALSTATIONID to identify itself to the remote end.\n"
@@ -55,10 +55,12 @@ static char *app_sndfax_desc =
"\n"
"This application sets the following channel variables upon completion:\n"
" FAXSTATUS - status of operation:\n"
-" SUCCESS | FAILED\n"
-" FAXERROR - Error when FAILED\n"
+" SUCCESS | FAILED\n"
+" FAXERROR - Error when FAILED\n"
+" FAXMODE - Mode used:\n"
+" audio | T38\n"
" REMOTESTATIONID - CSID of the remote side.\n"
-" FAXPAGES - number of pages sent.\n"
+" FAXPAGES - number of pages sent.\n"
" FAXBITRATE - transmition rate.\n"
" FAXRESOLUTION - resolution.\n"
"\n"
@@ -73,7 +75,7 @@ static char *app_rcvfax_desc =
"the file if it already exists. File created will have TIFF format.\n"
"The option string may contain zero or more of the following characters:\n"
" 'c' -- makes the application behave as a calling machine\n"
-" The default behaviour is to behave as an answering machine.\n"
+" The default behaviour is to behave as an answering machine.\n"
"\n"
"This application uses following variables:\n"
" LOCALSTATIONID to identify itself to the remote end.\n"
@@ -81,10 +83,12 @@ static char *app_rcvfax_desc =
"\n"
"This application sets the following channel variables upon completion:\n"
" FAXSTATUS - status of operation:\n"
-" SUCCESS | FAILED\n"
-" FAXERROR - Error when FAILED\n"
+" SUCCESS | FAILED\n"
+" FAXERROR - Error when FAILED\n"
+" FAXMODE - Mode used:\n"
+" audio | T38\n"
" REMOTESTATIONID - CSID of the remote side.\n"
-" FAXPAGES - number of pages sent.\n"
+" FAXPAGES - number of pages sent.\n"
" FAXBITRATE - transmition rate.\n"
" FAXRESOLUTION - resolution.\n"
"\n"
@@ -575,6 +579,7 @@ static int transmit(fax_session *s)
pbx_builtin_setvar_helper(s->chan, "FAXSTATUS", "FAILED");
pbx_builtin_setvar_helper(s->chan, "FAXERROR", "Channel problems");
+ pbx_builtin_setvar_helper(s->chan, "FAXMODE", NULL);
pbx_builtin_setvar_helper(s->chan, "REMOTESTATIONID", NULL);
pbx_builtin_setvar_helper(s->chan, "FAXPAGES", NULL);
pbx_builtin_setvar_helper(s->chan, "FAXRESOLUTION", NULL);
@@ -593,6 +598,7 @@ static int transmit(fax_session *s)
s->t38state = ast_channel_get_t38_state(s->chan);
if (s->t38state != T38_STATE_NEGOTIATED) {
/* T38 is not negotiated on the channel yet. First start regular transmission. If it switches to T38, follow */
+ pbx_builtin_setvar_helper(s->chan, "FAXMODE", "audio");
res = transmit_audio(s);
if (res > 0) {
/* transmit_audio reports switchover to T38. Update t38state */
@@ -604,6 +610,7 @@ static int transmit(fax_session *s)
}
if (s->t38state == T38_STATE_NEGOTIATED) {
+ pbx_builtin_setvar_helper(s->chan, "FAXMODE", "T38");
res = transmit_t38(s);
}
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 0af7119ce..5bef5b385 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -2893,6 +2893,33 @@ static void rename_file(char *sdir, int smsg, char *mailboxuser, char *mailboxco
return;
}
+/*!
+ * \brief Removes a voicemail message file.
+ * \param dir the path to the message file.
+ * \param msgnum the unique number for the message within the mailbox.
+ *
+ * Removes the message content file and the information file.
+ * This method is used by the DISPOSE macro when mailboxes are stored in an ODBC back end.
+ * Typical use is to clean up after a RETRIEVE operation.
+ * Note that this does not remove the message from the mailbox folders, to do that we would use delete_file().
+ * \return zero on success, -1 on error.
+ */
+static int remove_file(char *dir, int msgnum)
+{
+ char fn[PATH_MAX];
+ char full_fn[PATH_MAX];
+ char msgnums[80];
+
+ if (msgnum > -1) {
+ snprintf(msgnums, sizeof(msgnums), "%d", msgnum);
+ make_file(fn, sizeof(fn), dir, msgnum);
+ } else
+ ast_copy_string(fn, dir, sizeof(fn));
+ ast_filedelete(fn, NULL);
+ snprintf(full_fn, sizeof(full_fn), "%s.txt", fn);
+ unlink(full_fn);
+ return 0;
+}
#else
#ifndef IMAP_STORAGE
static int count_messages(struct ast_vm_user *vmu, char *dir)
@@ -2963,35 +2990,6 @@ static int last_message_index(struct ast_vm_user *vmu, char *dir)
return x - 1;
}
-#if (defined(IMAP_STORAGE) || defined(ODBC_STORAGE))
-/*!
-* \brief Removes a voicemail message file.
-* \param dir the path to the message file.
-* \param msgnum the unique number for the message within the mailbox.
-*
-* Removes the message content file and the information file.
-* This method is used by the DISPOSE macro when mailboxes are stored in an ODBC back end.
-* Typical use is to clean up after a RETRIEVE operation.
-* Note that this does not remove the message from the mailbox folders, to do that we would use delete_file().
-* \return zero on success, -1 on error.
-*/
-static int remove_file(char *dir, int msgnum)
-{
- char fn[PATH_MAX];
- char full_fn[PATH_MAX];
- char msgnums[80];
-
- if (msgnum > -1) {
- snprintf(msgnums, sizeof(msgnums), "%d", msgnum);
- make_file(fn, sizeof(fn), dir, msgnum);
- } else
- ast_copy_string(fn, dir, sizeof(fn));
- ast_filedelete(fn, NULL);
- snprintf(full_fn, sizeof(full_fn), "%s.txt", fn);
- unlink(full_fn);
- return 0;
-}
-#endif
#endif /* #ifndef IMAP_STORAGE */
#endif /* #else of #ifdef ODBC_STORAGE */
@@ -3088,6 +3086,7 @@ static void copy_plain_file(char *frompath, char *topath)
ast_variables_destroy(var);
}
+
#if (!defined(ODBC_STORAGE) && !defined(IMAP_STORAGE))
/*!
* \brief Removes the voicemail sound and information file.
diff --git a/cdr/cdr_tds.c b/cdr/cdr_tds.c
index 8654c80d5..ff63a676c 100644
--- a/cdr/cdr_tds.c
+++ b/cdr/cdr_tds.c
@@ -48,7 +48,8 @@ CREATE TABLE [dbo].[cdr] (
[billsec] [int] NULL ,
[disposition] [varchar] (20) NULL ,
[amaflags] [varchar] (16) NULL ,
- [uniqueid] [varchar] (32) NULL
+ [uniqueid] [varchar] (32) NULL ,
+ [userfield] [varchar] (256) NULL
) ON [PRIMARY]
\endverbatim
@@ -91,6 +92,7 @@ struct cdr_tds_config {
);
DBPROCESS *dbproc;
unsigned int connected:1;
+ unsigned int has_userfield:1;
};
AST_MUTEX_DEFINE_STATIC(tds_lock);
@@ -100,13 +102,16 @@ static struct cdr_tds_config *settings;
static char *anti_injection(const char *, int);
static void get_date(char *, size_t len, struct timeval);
+static int execute_and_consume(DBPROCESS *dbproc, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+
static int mssql_connect(void);
static int mssql_disconnect(void);
static int tds_log(struct ast_cdr *cdr)
{
char start[80], answer[80], end[80];
- char *accountcode, *src, *dst, *dcontext, *clid, *channel, *dstchannel, *lastapp, *lastdata, *uniqueid;
+ char *accountcode, *src, *dst, *dcontext, *clid, *channel, *dstchannel, *lastapp, *lastdata, *uniqueid, *userfield = NULL;
RETCODE erc;
int res = -1;
@@ -127,6 +132,10 @@ static int tds_log(struct ast_cdr *cdr)
ast_mutex_lock(&tds_lock);
+ if (settings->has_userfield) {
+ userfield = anti_injection(cdr->userfield, AST_MAX_USER_FIELD);
+ }
+
/* Ensure that we are connected */
if (!settings->connected) {
if (mssql_connect()) {
@@ -135,66 +144,46 @@ static int tds_log(struct ast_cdr *cdr)
}
}
- erc = dbfcmd(settings->dbproc,
- "INSERT INTO %s "
- "("
- "accountcode, "
- "src, "
- "dst, "
- "dcontext, "
- "clid, "
- "channel, "
- "dstchannel, "
- "lastapp, "
- "lastdata, "
- "start, "
- "answer, "
- "[end], "
- "duration, "
- "billsec, "
- "disposition, "
- "amaflags, "
- "uniqueid"
- ") "
- "VALUES "
- "("
- "'%s', " /* accountcode */
- "'%s', " /* src */
- "'%s', " /* dst */
- "'%s', " /* dcontext */
- "'%s', " /* clid */
- "'%s', " /* channel */
- "'%s', " /* dstchannel */
- "'%s', " /* lastapp */
- "'%s', " /* lastdata */
- "%s, " /* start */
- "%s, " /* answer */
- "%s, " /* end */
- "%ld, " /* duration */
- "%ld, " /* billsec */
- "'%s', " /* disposition */
- "'%s', " /* amaflags */
- "'%s'" /* uniqueid */
- ")",
- settings->table,
- accountcode,
- src,
- dst,
- dcontext,
- clid,
- channel,
- dstchannel,
- lastapp,
- lastdata,
- start,
- answer,
- end,
- cdr->duration,
- cdr->billsec,
- ast_cdr_disp2str(cdr->disposition),
- ast_cdr_flags2str(cdr->amaflags),
- uniqueid
- );
+ if (settings->has_userfield) {
+ erc = dbfcmd(settings->dbproc,
+ "INSERT INTO %s "
+ "("
+ "accountcode, src, dst, dcontext, clid, channel, "
+ "dstchannel, lastapp, lastdata, start, answer, [end], duration, "
+ "billsec, disposition, amaflags, uniqueid, userfield"
+ ") "
+ "VALUES "
+ "("
+ "'%s', '%s', '%s', '%s', '%s', '%s', "
+ "'%s', '%s', '%s', %s, %s, %s, %ld, "
+ "%ld, '%s', '%s', '%s', '%s'"
+ ")",
+ settings->table,
+ accountcode, src, dst, dcontext, clid, channel,
+ dstchannel, lastapp, lastdata, start, answer, end, cdr->duration,
+ cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), uniqueid,
+ userfield
+ );
+ } else {
+ erc = dbfcmd(settings->dbproc,
+ "INSERT INTO %s "
+ "("
+ "accountcode, src, dst, dcontext, clid, channel, "
+ "dstchannel, lastapp, lastdata, start, answer, [end], duration, "
+ "billsec, disposition, amaflags, uniqueid"
+ ") "
+ "VALUES "
+ "("
+ "'%s', '%s', '%s', '%s', '%s', '%s', "
+ "'%s', '%s', '%s', %s, %s, %s, %ld, "
+ "%ld, '%s', '%s', '%s'"
+ ")",
+ settings->table,
+ accountcode, src, dst, dcontext, clid, channel,
+ dstchannel, lastapp, lastdata, start, answer, end, cdr->duration,
+ cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), uniqueid
+ );
+ }
if (erc == FAIL) {
ast_log(LOG_ERROR, "Failed to build INSERT statement, no CDR was logged.\n");
@@ -228,6 +217,10 @@ done:
ast_free(lastdata);
ast_free(uniqueid);
+ if (userfield) {
+ ast_free(userfield);
+ }
+
return res;
}
@@ -277,6 +270,37 @@ static void get_date(char *dateField, size_t len, struct timeval tv)
}
}
+static int execute_and_consume(DBPROCESS *dbproc, const char *fmt, ...)
+{
+ va_list ap;
+ char *buffer;
+
+ va_start(ap, fmt);
+ if (ast_vasprintf(&buffer, fmt, ap) < 0) {
+ va_end(ap);
+ return 1;
+ }
+ va_end(ap);
+
+ if (dbfcmd(dbproc, buffer) == FAIL) {
+ free(buffer);
+ return 1;
+ }
+
+ free(buffer);
+
+ if (dbsqlexec(dbproc) == FAIL) {
+ return 1;
+ }
+
+ /* Consume the result set (we don't really care about the result, though) */
+ while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ while (dbnextrow(dbproc) != NO_MORE_ROWS);
+ }
+
+ return 0;
+}
+
static int mssql_disconnect(void)
{
if (settings->dbproc) {
@@ -317,19 +341,17 @@ static int mssql_connect(void)
goto failed;
}
- if (dbfcmd(settings->dbproc, "SELECT 1 FROM [%s]", settings->table) == FAIL) {
- ast_log(LOG_ERROR, "Unable to build query while verifying the existence of table '%s'\n", settings->table);
+ if (execute_and_consume(settings->dbproc, "SELECT 1 FROM [%s]", settings->table)) {
+ ast_log(LOG_ERROR, "Unable to find table '%s'\n", settings->table);
goto failed;
}
- if (dbsqlexec(settings->dbproc) == FAIL) {
- ast_log(LOG_ERROR, "Unable to verify existence of table '%s'\n", settings->table);
- goto failed;
- }
-
- /* Consume the result set (we don't really care about the result, though) */
- while (dbresults(settings->dbproc) != NO_MORE_RESULTS) {
- while (dbnextrow(settings->dbproc) != NO_MORE_ROWS);
+ /* Check to see if we have a userfield column in the table */
+ if (execute_and_consume(settings->dbproc, "SELECT userfield FROM [%s] WHERE 1 = 0", settings->table)) {
+ ast_log(LOG_NOTICE, "Unable to find 'userfield' column in table '%s'\n", settings->table);
+ settings->has_userfield = 0;
+ } else {
+ settings->has_userfield = 1;
}
settings->connected = 1;
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index d8fe725a3..66a5fdf3e 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -14705,7 +14705,10 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru
/* Final response, not 200 ? */
if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
p->invitestate = INV_COMPLETED;
-
+
+ /* Final response, clear out pending invite */
+ if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite)
+ p->pendinginvite = 0;
switch (resp) {
case 100: /* Trying */
diff --git a/doc/tex/asterisk.tex b/doc/tex/asterisk.tex
index 111719fd3..7bb217265 100644
--- a/doc/tex/asterisk.tex
+++ b/doc/tex/asterisk.tex
@@ -148,15 +148,8 @@ reference purposes.
%asterisk-mib.txt SNMP mib for Asterisk (net-snmp)
%digium-mib.txt SNMP mib for Asterisk (net-snmp)
%
-%For developers
-%--------------
-%See http://www.asterisk.org/developers for more information
-%
-%callfiles.txt Asterisk callfiles using instruction
-%CODING-GUIDELINES Guidelines for developers
-%externalivr.txt Documentation of the protocol used in externalivr()
-%modules.txt How Asterisk modules work
-%datastores.txt About channel data stores
-%speechrec.txt The Generic Speech Recognition API
+% Note that there is some developer documentation in the doc directory, but
+% the goal is to have developer documentation all integrated into the doxygen
+% documentation.
\end{document}
diff --git a/doc/tex/cdrdriver.tex b/doc/tex/cdrdriver.tex
index 174df5b68..7865958c1 100644
--- a/doc/tex/cdrdriver.tex
+++ b/doc/tex/cdrdriver.tex
@@ -185,7 +185,8 @@ Call data records can be stored in many different databases or even CSV text.
[billsec] [int] NULL ,
[disposition] [varchar] (20) NULL ,
[amaflags] [varchar] (16) NULL ,
- [uniqueid] [varchar] (32) NULL
+ [uniqueid] [varchar] (32) NULL ,
+ [userfield] [varchar] (256) NULL
)
\end{verbatim}
\end{astlisting}
diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h
index b02b6cba8..5899885df 100644
--- a/include/asterisk/astobj2.h
+++ b/include/asterisk/astobj2.h
@@ -17,6 +17,8 @@
#ifndef _ASTERISK_ASTOBJ2_H
#define _ASTERISK_ASTOBJ2_H
+#include "asterisk/compat.h"
+
/*! \file
* \ref AstObj2
*
diff --git a/include/asterisk/compat.h b/include/asterisk/compat.h
index 950712060..e481fbec4 100644
--- a/include/asterisk/compat.h
+++ b/include/asterisk/compat.h
@@ -163,6 +163,7 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
typedef unsigned char u_int8_t;
typedef unsigned short u_int16_t;
typedef unsigned int u_int32_t;
+typedef unsigned int uint;
#endif
#endif /* SOLARIS */
diff --git a/res/res_agi.c b/res/res_agi.c
index d3d07912a..e970f1715 100644
--- a/res/res_agi.c
+++ b/res/res_agi.c
@@ -73,19 +73,20 @@ static char *deadsynopsis = "Executes AGI on a hungup channel";
static char *descrip =
" [E|Dead]AGI(command,args): Executes an Asterisk Gateway Interface compliant\n"
-"program on a channel. AGI allows Asterisk to launch external programs\n"
-"written in any language to control a telephony channel, play audio,\n"
-"read DTMF digits, etc. by communicating with the AGI protocol on stdin\n"
-"and stdout.\n"
-" This channel will stop dialplan execution on hangup inside of this\n"
-"application, except when using DeadAGI. Otherwise, dialplan execution\n"
-"will continue normally.\n"
+"program on a channel. AGI allows Asterisk to launch external programs written\n"
+"in any language to control a telephony channel, play audio, read DTMF digits,\n"
+"etc. by communicating with the AGI protocol on stdin and stdout.\n"
+" As of 1.6.0, this channel will not stop dialplan execution on hangup inside\n"
+"of this application. Dialplan execution will continue normally, even upon\n"
+"hangup until the AGI application signals a desire to stop (either by exiting\n"
+"or, in the case of a net script, by closing the connection).\n"
" A locally executed AGI script will receive SIGHUP on hangup from the channel\n"
-"except when using DeadAGI. This can be disabled by setting the AGISIGHUP channel\n"
-"variable to \"no\" before executing the AGI application.\n"
+"except when using DeadAGI. A fast AGI server will correspondingly receive a\n"
+"HANGUP in OOB data. Both of these signals may be disabled by setting the\n"
+"AGISIGHUP channel variable to \"no\" before executing the AGI application.\n"
" Using 'EAGI' provides enhanced AGI, with incoming audio available out of band\n"
-"on file descriptor 3\n\n"
-" Use the CLI command 'agi show' to list available agi commands\n"
+"on file descriptor 3.\n\n"
+" Use the CLI command 'agi show' to list available agi commands.\n"
" This application sets the following channel variable upon completion:\n"
" AGISTATUS The status of the attempt to the run the AGI script\n"
" text string, one of SUCCESS | FAILURE | NOTFOUND | HANGUP\n";
@@ -2619,6 +2620,7 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi
/* how many times we'll retry if ast_waitfor_nandfs will return without either
channel or file descriptor in case select is interrupted by a system call (EINTR) */
int retry = AGI_NANDFS_RETRY;
+ const char *sighup;
if (!(readf = fdopen(agi->ctrl, "r"))) {
ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n");
@@ -2633,8 +2635,11 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi
if (needhup) {
needhup = 0;
dead = 1;
- if (pid > -1)
+ if (pid > -1) {
kill(pid, SIGHUP);
+ } else if (agi->fast) {
+ send(agi->ctrl, "HANGUP\n", 7, MSG_OOB);
+ }
}
ms = -1;
c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms);
@@ -2716,16 +2721,18 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi
}
}
/* Notify process */
- if (pid > -1) {
- const char *sighup = pbx_builtin_getvar_helper(chan, "AGISIGHUP");
- if (ast_strlen_zero(sighup) || !ast_false(sighup)) {
+ sighup = pbx_builtin_getvar_helper(chan, "AGISIGHUP");
+ if (ast_strlen_zero(sighup) || !ast_false(sighup)) {
+ if (pid > -1) {
if (kill(pid, SIGHUP)) {
ast_log(LOG_WARNING, "unable to send SIGHUP to AGI process %d: %s\n", pid, strerror(errno));
} else { /* Give the process a chance to die */
usleep(1);
}
+ waitpid(pid, status, WNOHANG);
+ } else if (agi->fast) {
+ send(agi->ctrl, "HANGUP\n", 7, MSG_OOB);
}
- waitpid(pid, status, WNOHANG);
}
fclose(readf);
return returnstatus;
diff --git a/res/res_odbc.c b/res/res_odbc.c
index 3e0a205ee..070d0eb6a 100644
--- a/res/res_odbc.c
+++ b/res/res_odbc.c
@@ -533,16 +533,27 @@ struct odbc_obj *ast_odbc_request_obj(const char *name, int check)
static odbc_status odbc_obj_disconnect(struct odbc_obj *obj)
{
int res;
+ SQLINTEGER err;
+ short int mlen;
+ unsigned char msg[200], stat[10];
+
ast_mutex_lock(&obj->lock);
res = SQLDisconnect(obj->con);
if (res == ODBC_SUCCESS) {
- ast_log(LOG_WARNING, "res_odbc: disconnected %d from %s [%s]\n", res, obj->parent->name, obj->parent->dsn);
+ ast_log(LOG_DEBUG, "Disconnected %d from %s [%s]\n", res, obj->parent->name, obj->parent->dsn);
} else {
- ast_log(LOG_WARNING, "res_odbc: %s [%s] already disconnected\n",
- obj->parent->name, obj->parent->dsn);
+ ast_log(LOG_DEBUG, "res_odbc: %s [%s] already disconnected\n", obj->parent->name, obj->parent->dsn);
}
+
+ if ((res = SQLFreeHandle(SQL_HANDLE_DBC, obj->con) == ODBC_SUCCESS)) {
+ ast_log(LOG_DEBUG, "Database handle deallocated\n");
+ } else {
+ SQLGetDiagRec(SQL_HANDLE_DBC, obj->con, 1, stat, &err, msg, 100, &mlen);
+ ast_log(LOG_WARNING, "Unable to deallocate database handle? %d errno=%d %s\n", res, (int)err, msg);
+ }
+
obj->up = 0;
ast_mutex_unlock(&obj->lock);
return ODBC_SUCCESS;