[asterisk-commits] juggie: branch juggie/NoLossCDR r78310 - in /team/juggie/NoLossCDR: ./ apps/ ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Aug 6 17:46:36 CDT 2007
Author: juggie
Date: Mon Aug 6 17:46:35 2007
New Revision: 78310
URL: http://svn.digium.com/view/asterisk?view=rev&rev=78310
Log:
merged in changes from CDRbatch
Added:
team/juggie/NoLossCDR/funcs/func_lock.c
- copied unchanged from r78298, team/group/CDRbatch/funcs/func_lock.c
Modified:
team/juggie/NoLossCDR/ (props changed)
team/juggie/NoLossCDR/CHANGES
team/juggie/NoLossCDR/UPGRADE.txt
team/juggie/NoLossCDR/apps/app_dial.c
team/juggie/NoLossCDR/apps/app_exec.c
team/juggie/NoLossCDR/apps/app_externalivr.c
team/juggie/NoLossCDR/apps/app_forkcdr.c
team/juggie/NoLossCDR/apps/app_macro.c
team/juggie/NoLossCDR/apps/app_meetme.c
team/juggie/NoLossCDR/apps/app_osplookup.c
team/juggie/NoLossCDR/apps/app_queue.c
team/juggie/NoLossCDR/apps/app_senddtmf.c
team/juggie/NoLossCDR/apps/app_voicemail.c
team/juggie/NoLossCDR/apps/app_zapras.c
team/juggie/NoLossCDR/build_tools/cflags.xml
team/juggie/NoLossCDR/channels/chan_iax2.c
team/juggie/NoLossCDR/channels/chan_local.c
team/juggie/NoLossCDR/channels/chan_mgcp.c
team/juggie/NoLossCDR/channels/chan_sip.c
team/juggie/NoLossCDR/channels/chan_skinny.c
team/juggie/NoLossCDR/channels/chan_vpb.cc
team/juggie/NoLossCDR/configs/skinny.conf.sample
team/juggie/NoLossCDR/configure
team/juggie/NoLossCDR/configure.ac
team/juggie/NoLossCDR/contrib/scripts/ast_grab_core
team/juggie/NoLossCDR/doc/tex/queuelog.tex
team/juggie/NoLossCDR/funcs/func_cdr.c
team/juggie/NoLossCDR/include/asterisk/autoconfig.h.in
team/juggie/NoLossCDR/include/asterisk/cdr.h
team/juggie/NoLossCDR/include/asterisk/config.h
team/juggie/NoLossCDR/include/asterisk/fskmodem.h
team/juggie/NoLossCDR/include/asterisk/linkedlists.h
team/juggie/NoLossCDR/include/asterisk/lock.h
team/juggie/NoLossCDR/include/asterisk/speech.h
team/juggie/NoLossCDR/include/asterisk/threadstorage.h
team/juggie/NoLossCDR/main/astmm.c
team/juggie/NoLossCDR/main/autoservice.c
team/juggie/NoLossCDR/main/callerid.c
team/juggie/NoLossCDR/main/channel.c
team/juggie/NoLossCDR/main/cli.c
team/juggie/NoLossCDR/main/config.c
team/juggie/NoLossCDR/main/fskmodem.c
team/juggie/NoLossCDR/main/pbx.c
team/juggie/NoLossCDR/main/rtp.c
team/juggie/NoLossCDR/main/tdd.c
team/juggie/NoLossCDR/main/utils.c
team/juggie/NoLossCDR/pbx/pbx_dundi.c
team/juggie/NoLossCDR/res/res_agi.c
team/juggie/NoLossCDR/res/res_features.c
team/juggie/NoLossCDR/res/res_speech.c
team/juggie/NoLossCDR/utils/smsq.c
Propchange: team/juggie/NoLossCDR/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.
Propchange: team/juggie/NoLossCDR/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.
Propchange: team/juggie/NoLossCDR/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Aug 6 17:46:35 2007
@@ -1,1 +1,1 @@
-/team/group/CDRbatch:1-78187 /team/group/CDRfix5:1-77836
+/team/group/CDRbatch:1-78306 /team/group/CDRfix5:1-77836
Modified: team/juggie/NoLossCDR/CHANGES
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/CHANGES?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/CHANGES (original)
+++ team/juggie/NoLossCDR/CHANGES Mon Aug 6 17:46:35 2007
@@ -33,6 +33,10 @@
* MailboxExists converted to dialplan function
* A new option to Dial() for telling IP phones not to count the call
as "missed" when dial times out and cancels.
+ * Added LOCK(), TRYLOCK(), and UNLOCK(), which provide a single level dialplan
+ mutex. No deadlocks are possible, as LOCK() only allows a single lock to be
+ held for any given channel. Also, locks are automatically freed when a
+ channel is hung up.
CLI Changes
-----------
@@ -256,3 +260,32 @@
* The device state functionality in the Local channel driver has been updated
to indicate INUSE or NOT_INUSE when a Local channel is being used as opposed
to just UNKNOWN if the extension exists.
+
+CDR changes
+-----------
+
+ * If you had dialplan that in any way manipulated CDR's, the chances are
+ now good that you will have to rip it out and re-write it!
+ * ForkCDR still exists, but does nothing, and generates a warning. This
+ is not standard obsolescence; it is part of a bug fix that required
+ re-engineering of the system.
+ * By default, Asterisk will only generate a CDR if a bridge was executed.
+ So, no conversation between two endpoints, no CDR. Apps that execute
+ bridges: Dial and Meetme and queue, etc.
+ * the Function CDR_CONTROL() is available to build, set and generate
+ CDR's for non-bridging situations like app and agi calls.
+ * the CDR() function can still be used to set CDR fields before a bridge
+ is formed. It can also be used to set fields in CDRs created by CDR_CONTROL().
+ * Those apps that accepted an arg to update CDR, either still have them (for now),
+ or have had that option removed. The philosophy is a bit different now. A CDR is
+ attached to the channel at the creation of the channel. The channel CDR's start
+ time is set to the time the channel was created. You set up the channel CDR before
+ executing an app that executes a bridge. The originating
+ channel's CDR is copied into a temporary bridge CDR. The bridge CDR's answer time
+ is set when the bridge begins, and the bridge CDR's end time is set when it closes.
+ The bridge CDR is then posted to the backend. The channel cdr start time is updated
+ to the end time of the bridge. Hangup routines are called, and then the channel
+ is destroyed.
+
+
+
Modified: team/juggie/NoLossCDR/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/UPGRADE.txt?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/UPGRADE.txt (original)
+++ team/juggie/NoLossCDR/UPGRADE.txt Mon Aug 6 17:46:35 2007
@@ -71,6 +71,11 @@
* 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
+ these functions in any location where you desire to ensure that only one
+ channel is executing that path at any one time.
CDR:
Modified: team/juggie/NoLossCDR/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_dial.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/apps/app_dial.c (original)
+++ team/juggie/NoLossCDR/apps/app_dial.c Mon Aug 6 17:46:35 2007
@@ -1789,7 +1789,7 @@
ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP); /* set it back the way it was */
}
if (res != AST_PBX_NO_HANGUP_PEER) {
- if (!chan->_softhangup)
+ if (!ast_check_hangup(chan))
chan->hangupcause = peer->hangupcause;
ast_hangup(peer);
}
@@ -1808,7 +1808,7 @@
senddialendevent(chan, pa.status);
ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
- if ((ast_test_flag64(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE)) {
+ if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_KEEPALIVE)) {
if (calldurationlimit)
chan->whentohangup = 0;
res = 0;
Modified: team/juggie/NoLossCDR/apps/app_exec.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_exec.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/apps/app_exec.c (original)
+++ team/juggie/NoLossCDR/apps/app_exec.c Mon Aug 6 17:46:35 2007
@@ -160,38 +160,38 @@
AST_APP_ARG(remainder);
);
AST_DECLARE_APP_ARGS(apps,
- AST_APP_ARG(true);
- AST_APP_ARG(false);
+ AST_APP_ARG(t);
+ AST_APP_ARG(f);
);
char *parse = ast_strdupa(data);
AST_NONSTANDARD_APP_ARGS(expr, parse, '?');
AST_NONSTANDARD_APP_ARGS(apps, expr.remainder, ':');
- if (apps.true && (truedata = strchr(apps.true, '('))) {
+ if (apps.t && (truedata = strchr(apps.t, '('))) {
*truedata++ = '\0';
if ((end = strrchr(truedata, ')')))
*end = '\0';
}
- if (apps.false && (falsedata = strchr(apps.false, '('))) {
+ if (apps.f && (falsedata = strchr(apps.f, '('))) {
*falsedata++ = '\0';
if ((end = strrchr(falsedata, ')')))
*end = '\0';
}
if (pbx_checkcondition(expr.expr)) {
- if (!ast_strlen_zero(apps.true) && (app = pbx_findapp(apps.true))) {
+ if (!ast_strlen_zero(apps.t) && (app = pbx_findapp(apps.t))) {
res = pbx_exec(chan, app, S_OR(truedata, ""));
} else {
- ast_log(LOG_WARNING, "Could not find application! (%s)\n", apps.true);
+ ast_log(LOG_WARNING, "Could not find application! (%s)\n", apps.t);
res = -1;
}
} else {
- if (!ast_strlen_zero(apps.false) && (app = pbx_findapp(apps.false))) {
+ if (!ast_strlen_zero(apps.f) && (app = pbx_findapp(apps.f))) {
res = pbx_exec(chan, app, S_OR(falsedata, ""));
} else {
- ast_log(LOG_WARNING, "Could not find application! (%s)\n", apps.false);
+ ast_log(LOG_WARNING, "Could not find application! (%s)\n", apps.f);
res = -1;
}
}
Modified: team/juggie/NoLossCDR/apps/app_externalivr.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_externalivr.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/apps/app_externalivr.c (original)
+++ team/juggie/NoLossCDR/apps/app_externalivr.c Mon Aug 6 17:46:35 2007
@@ -250,7 +250,6 @@
int res = -1;
int gen_active = 0;
int pid;
- char *argv[32];
char *buf, *command;
FILE *child_commands = NULL;
FILE *child_errors = NULL;
@@ -325,8 +324,8 @@
dup2(child_stderr[1], STDERR_FILENO);
for (i = STDERR_FILENO + 1; i < 1024; i++)
close(i);
- execv(argv[0], argv);
- fprintf(stderr, "Failed to execute '%s': %s\n", argv[0], strerror(errno));
+ execv(args.cmd[0], args.cmd);
+ fprintf(stderr, "Failed to execute '%s': %s\n", args.cmd[0], strerror(errno));
_exit(1);
} else {
/* parent process */
Modified: team/juggie/NoLossCDR/apps/app_forkcdr.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_forkcdr.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/apps/app_forkcdr.c (original)
+++ team/juggie/NoLossCDR/apps/app_forkcdr.c Mon Aug 6 17:46:35 2007
@@ -48,7 +48,8 @@
static char *descrip =
" ForkCDR([options]): Causes the Call Data Record to fork an additional\n"
"cdr record starting from the time of the fork call\n"
-"If the option 'v' is passed all cdr variables will be passed along also.\n";
+"If the option 'v' is passed all cdr variables will be passed along also.\n"
+"NOTE: this app is no longer useful! Refer to the CDR_CONTROL function instead!\n";
static int forkcdr_exec(struct ast_channel *chan, void *data)
@@ -63,7 +64,7 @@
if (!ast_strlen_zero(data))
ast_set2_flag(chan->cdr, strchr(data, 'v'), AST_CDR_FLAG_KEEP_VARS);
- ast_log(LOG_ERROR,"ForkCDR is obsolesced. It will probably not yield correct results any more. Use CDRstart(), CDRanswer(), and CDRclose() functions instead!\n");
+ ast_log(LOG_ERROR,"ForkCDR is obsolesced. It will probably not yield correct results any more. Use CDR_CONTROL(start/answer/close) function instead!\n");
return res;
Modified: team/juggie/NoLossCDR/apps/app_macro.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_macro.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/apps/app_macro.c (original)
+++ team/juggie/NoLossCDR/apps/app_macro.c Mon Aug 6 17:46:35 2007
@@ -385,7 +385,7 @@
}
/* don't stop executing extensions when we're in "h" */
- if (chan->_softhangup && !inhangup) {
+ if (ast_check_hangup(chan) && !inhangup) {
ast_debug(1, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n", chan->exten, chan->macroexten, chan->priority);
goto out;
}
@@ -434,7 +434,7 @@
/* If we're leaving the macro normally, restore original information */
chan->priority = oldpriority;
ast_copy_string(chan->context, oldcontext, sizeof(chan->context));
- if (!(chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO)) {
+ if (!(ast_check_hangup(chan) & AST_SOFTHANGUP_ASYNCGOTO)) {
/* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */
const char *offsets;
ast_copy_string(chan->exten, oldexten, sizeof(chan->exten));
Modified: team/juggie/NoLossCDR/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_meetme.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/apps/app_meetme.c (original)
+++ team/juggie/NoLossCDR/apps/app_meetme.c Mon Aug 6 17:46:35 2007
@@ -719,7 +719,7 @@
int len;
int res = -1;
- if (!chan->_softhangup)
+ if (!ast_check_hangup(chan))
res = ast_autoservice_start(chan);
AST_LIST_LOCK(&confs);
Modified: team/juggie/NoLossCDR/apps/app_osplookup.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_osplookup.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/apps/app_osplookup.c (original)
+++ team/juggie/NoLossCDR/apps/app_osplookup.c Mon Aug 6 17:46:35 2007
@@ -1734,7 +1734,7 @@
ast_debug(1, "OSPFinish: connect '%ld'\n", connect);
ast_debug(1, "OSPFinish: end '%ld'\n", end);
- release = chan->_softhangup ? 0 : 1;
+ release = ast_check_hangup(chan) ? 0 : 1;
if (osp_finish(outhandle, recorded, cause, start, connect, end, release) <= 0) {
ast_debug(1, "OSPFinish: Unable to report usage for outbound call\n");
Modified: team/juggie/NoLossCDR/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_queue.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/apps/app_queue.c (original)
+++ team/juggie/NoLossCDR/apps/app_queue.c Mon Aug 6 17:46:35 2007
@@ -1256,6 +1256,56 @@
AST_LIST_UNLOCK(&queues);
}
return q;
+}
+
+static void update_realtime_members(struct call_queue *q)
+{
+ struct ast_config *member_config = NULL;
+ struct member *m, *prev_m, *next_m;
+ char *interface = NULL;
+
+ member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", q->name , NULL);
+ if (!member_config) {
+ /*This queue doesn't have realtime members*/
+ ast_debug(3, "Queue %s has no realtime members defined. No need for update\n", q->name);
+ return;
+ }
+
+ ast_mutex_lock(&q->lock);
+
+ /* Temporarily set non-dynamic members dead so we can detect deleted ones.*/
+ for (m = q->members; m; m = m->next) {
+ if (!m->dynamic)
+ m->dead = 1;
+ }
+
+ while ((interface = ast_category_browse(member_config, interface))) {
+ rt_handle_member_record(q, interface,
+ S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
+ ast_variable_retrieve(member_config, interface, "penalty"),
+ ast_variable_retrieve(member_config, interface, "paused"));
+ }
+
+ /* Delete all realtime members that have been deleted in DB. */
+ m = q->members;
+ prev_m = NULL;
+ while (m) {
+ next_m = m->next;
+ if (m->dead) {
+ if (prev_m) {
+ prev_m->next = next_m;
+ } else {
+ q->members = next_m;
+ }
+ remove_from_interfaces(m->interface);
+ q->membercount--;
+ free(m);
+ } else {
+ prev_m = m;
+ }
+ m = next_m;
+ }
+ ast_mutex_unlock(&q->lock);
}
static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
@@ -2410,7 +2460,7 @@
{
struct member *cur;
struct callattempt *outgoing = NULL; /* the list of calls we are building */
- int to;
+ int to, orig;
char oldexten[AST_MAX_EXTENSION]="";
char oldcontext[AST_MAX_CONTEXT]="";
char queuename[256]="";
@@ -2444,6 +2494,7 @@
char vars[2048];
int forwardsallowed = 1;
int callcompletedinsl;
+ int noption = 0;
memset(&bridge_config, 0, sizeof(bridge_config));
time(&now);
@@ -2476,11 +2527,15 @@
(*go_on)++;
else
*go_on = qe->parent->membercount;
+ noption = 1;
break;
case 'i':
forwardsallowed = 0;
break;
}
+
+ if(!noption)
+ *go_on = -1;
/* Hold the lock while we setup the outgoing calls */
if (use_weight)
@@ -2528,6 +2583,7 @@
to = (qe->expire - now) * 1000;
else
to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
+ orig = to;
ring_one(qe, outgoing, &numbusies);
ast_mutex_unlock(&qe->parent->lock);
if (use_weight)
@@ -2596,7 +2652,7 @@
}
}
res2 |= ast_autoservice_stop(qe->chan);
- if (peer->_softhangup) {
+ if (ast_check_hangup(peer)) {
/* Agent must have hung up */
ast_log(LOG_WARNING, "Agent on %s hungup on the customer.\n", peer->name);
ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "AGENTDUMP", "%s", "");
@@ -2863,7 +2919,8 @@
} else
ast_log(LOG_WARNING, "Asked to execute an AGI on this channel, but could not find application (agi)!\n");
}
- ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "CONNECT", "%ld|%s", (long) time(NULL) - qe->start, peer->uniqueid);
+ ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "CONNECT", "%ld|%s|%ld", (long) time(NULL) - qe->start, peer->uniqueid,
+ (long)(orig - to > 0 ? (orig - to) / 1000 : 0));
if (qe->parent->eventwhencalled)
manager_event(EVENT_FLAG_AGENT, "AgentConnect",
"Queue: %s\r\n"
@@ -2873,9 +2930,10 @@
"MemberName: %s\r\n"
"Holdtime: %ld\r\n"
"BridgedChannel: %s\r\n"
+ "Ringtime: %ld\r\n"
"%s",
queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
- (long) time(NULL) - qe->start, peer->uniqueid,
+ (long) time(NULL) - qe->start, peer->uniqueid, (long)(orig - to > 0 ? (orig - to) / 1000 : 0),
qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
ast_copy_string(oldcontext, qe->chan->context, sizeof(oldcontext));
ast_copy_string(oldexten, qe->chan->exten, sizeof(oldexten));
@@ -2888,7 +2946,7 @@
qe->chan->exten, qe->chan->context, (long) (callstart - qe->start),
(long) (time(NULL) - callstart));
send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), TRANSFER);
- } else if (qe->chan->_softhangup) {
+ } else if (ast_check_hangup(qe->chan)) {
ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "COMPLETECALLER", "%ld|%ld|%d",
(long) (callstart - qe->start), (long) (time(NULL) - callstart), qe->opos);
send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), CALLER);
@@ -3623,6 +3681,9 @@
ast_queue_log(qe.parent->name, qe.chan->uniqueid,"NONE", "EXITWITHTIMEOUT", "%d|%d|%ld", qe.pos, qe.opos, (long) time(NULL) - qe.start);
break;
}
+
+ /* If using dynamic realtime members, we should regenerate the member list for this queue */
+ update_realtime_members(qe.parent);
/* OK, we didn't get anybody; wait for 'retry' seconds; may get a digit to exit with */
res = wait_a_bit(&qe);
Modified: team/juggie/NoLossCDR/apps/app_senddtmf.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_senddtmf.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/apps/app_senddtmf.c (original)
+++ team/juggie/NoLossCDR/apps/app_senddtmf.c Mon Aug 6 17:46:35 2007
@@ -66,7 +66,7 @@
AST_APP_ARG(timeout);
);
- if (ast_strlen_zero(data)) {
+ if (ast_strlen_zero(vdata)) {
ast_log(LOG_WARNING, "SendDTMF requires an argument (digits or *#aAbBcCdD)\n");
return 0;
}
Modified: team/juggie/NoLossCDR/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_voicemail.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/apps/app_voicemail.c (original)
+++ team/juggie/NoLossCDR/apps/app_voicemail.c Mon Aug 6 17:46:35 2007
@@ -1790,6 +1790,7 @@
#endif
+#ifndef ODBC_STORAGE
static int vm_delete(char *file)
{
char *txt;
@@ -1807,6 +1808,7 @@
unlink(txt);
return ast_filedelete(file, NULL);
}
+#endif
static int inbuf(struct baseio *bio, FILE *fi)
{
@@ -2082,7 +2084,7 @@
fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
else
fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
- fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, getpid(), host);
+ fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host);
if(imap) {
/* additional information needed for IMAP searching */
fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
@@ -2108,7 +2110,7 @@
fprintf(p, "MIME-Version: 1.0" ENDL);
if (attach_user_voicemail) {
/* Something unique. */
- snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, getpid(), (unsigned int)ast_random());
+ snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random());
fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
@@ -4152,8 +4154,14 @@
if (!attach_user_voicemail)
attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
+ if (attach_user_voicemail)
+ RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context);
+
/*XXX possible imap issue, should category be NULL XXX*/
sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
+
+ if (attach_user_voicemail)
+ DISPOSE(todir, msgnum);
}
if (!ast_strlen_zero(vmu->pager))
Modified: team/juggie/NoLossCDR/apps/app_zapras.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_zapras.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/apps/app_zapras.c (original)
+++ team/juggie/NoLossCDR/apps/app_zapras.c Mon Aug 6 17:46:35 2007
@@ -161,7 +161,7 @@
res = wait4(pid, &status, WNOHANG, NULL);
if (!res) {
/* Check for hangup */
- if (chan->_softhangup && !signalled) {
+ if (ast_check_hangup(chan) && !signalled) {
ast_debug(1, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan->name, pid);
kill(pid, SIGTERM);
signalled=1;
Modified: team/juggie/NoLossCDR/build_tools/cflags.xml
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/build_tools/cflags.xml?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/build_tools/cflags.xml (original)
+++ team/juggie/NoLossCDR/build_tools/cflags.xml Mon Aug 6 17:46:35 2007
@@ -8,6 +8,7 @@
<member name="DEBUG_THREADLOCALS" displayname="Enable Thread-Local-Storage Debugging">
</member>
<member name="DETECT_DEADLOCKS" displayname="Detect Deadlocks">
+ <depend>DEBUG_THREADS</depend>
</member>
<member name="DO_CRASH" displayname="Crash on fatal errors">
</member>
Modified: team/juggie/NoLossCDR/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/channels/chan_iax2.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/channels/chan_iax2.c (original)
+++ team/juggie/NoLossCDR/channels/chan_iax2.c Mon Aug 6 17:46:35 2007
@@ -745,6 +745,7 @@
time_t checktime;
ast_mutex_t lock;
ast_cond_t cond;
+ unsigned int ready_for_signal:1;
/*! if this thread is processing a full frame,
some information about that frame will be stored
here, so we can avoid dispatching any more full
@@ -988,6 +989,9 @@
ast_free(oldlist);
}
+/* WARNING: insert_idle_thread should only ever be called within the
+ * context of an iax2_process_thread() thread.
+ */
static void insert_idle_thread(struct iax2_thread *thread)
{
if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
@@ -1013,8 +1017,10 @@
AST_LIST_UNLOCK(&idle_list);
/* If we popped a thread off the idle list, just return it */
- if (thread)
+ if (thread) {
+ memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
return thread;
+ }
/* Pop the head of the dynamic list off */
AST_LIST_LOCK(&dynamic_list);
@@ -1022,8 +1028,10 @@
AST_LIST_UNLOCK(&dynamic_list);
/* If we popped a thread off the dynamic list, just return it */
- if (thread)
+ if (thread) {
+ memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
return thread;
+ }
/* If we can't create a new dynamic thread for any reason, return no thread at all */
if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
@@ -1042,13 +1050,16 @@
ast_cond_destroy(&thread->cond);
ast_mutex_destroy(&thread->lock);
ast_free(thread);
- thread = NULL;
+ return NULL;
}
/* this thread is not processing a full frame (since it is idle),
so ensure that the field for the full frame call number is empty */
- if (thread)
- memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
+ memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
+
+ /* Wait for the thread to be ready before returning it to the caller */
+ while (!thread->ready_for_signal)
+ usleep(1);
return thread;
}
@@ -1511,7 +1522,7 @@
{
/* Close firmware */
if (cur->fwh) {
- munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
+ munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
}
close(cur->fd);
ast_free(cur);
@@ -1607,7 +1618,7 @@
close(fd);
return -1;
}
- fwh = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (fwh == (void *) -1) {
ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
close(fd);
@@ -1618,7 +1629,7 @@
MD5Final(sum, &md5);
if (memcmp(sum, fwh->chksum, sizeof(sum))) {
ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
- munmap(fwh, stbuf.st_size);
+ munmap((void*)fwh, stbuf.st_size);
close(fd);
return -1;
}
@@ -1631,7 +1642,7 @@
break;
/* This version is no newer than what we have. Don't worry about it.
We'll consider it a proper load anyhow though */
- munmap(fwh, stbuf.st_size);
+ munmap((void*)fwh, stbuf.st_size);
close(fd);
return 0;
}
@@ -1644,7 +1655,7 @@
if (cur) {
if (cur->fwh)
- munmap(cur->fwh, cur->mmaplen);
+ munmap((void*)cur->fwh, cur->mmaplen);
if (cur->fd > -1)
close(cur->fd);
cur->fwh = fwh;
@@ -3470,23 +3481,24 @@
ast_mutex_lock(&iaxsl[callno]);
pvt = iaxs[callno];
- if (!strcasecmp(pvt->mohinterpret, "passthrough")) {
- res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
- ast_mutex_unlock(&iaxsl[callno]);
- return res;
- }
switch (condition) {
case AST_CONTROL_HOLD:
- ast_moh_start(c, data, pvt->mohinterpret);
+ if (strcasecmp(pvt->mohinterpret, "passthrough")) {
+ ast_moh_start(c, data, pvt->mohinterpret);
+ goto done;
+ }
break;
case AST_CONTROL_UNHOLD:
- ast_moh_stop(c);
- break;
- default:
- res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
- }
-
+ if (strcasecmp(pvt->mohinterpret, "passthrough")) {
+ ast_moh_stop(c);
+ goto done;
+ }
+ }
+
+ res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
+
+done:
ast_mutex_unlock(&iaxsl[callno]);
return res;
@@ -6262,7 +6274,8 @@
AST_LIST_TRAVERSE(&frame_queue, f, list) {
/* Send a copy immediately */
if ((f->callno == callno) && iaxs[f->callno] &&
- ((unsigned char ) (f->oseqno - last) < 128)) {
+ ((unsigned char ) (f->oseqno - last) < 128) &&
+ (f->retries >= 0)) {
send_packet(f);
}
}
@@ -6713,11 +6726,13 @@
if (errno != ECONNREFUSED && errno != EAGAIN)
ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
handle_error();
- insert_idle_thread(thread);
+ thread->iostate = IAX_IOSTATE_IDLE;
+ signal_condition(&thread->lock, &thread->cond);
return 1;
}
if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
- insert_idle_thread(thread);
+ thread->iostate = IAX_IOSTATE_IDLE;
+ signal_condition(&thread->lock, &thread->cond);
return 1;
}
@@ -6740,7 +6755,8 @@
so queue it up for processing later. */
defer_full_frame(thread, cur);
AST_LIST_UNLOCK(&active_list);
- insert_idle_thread(thread);
+ thread->iostate = IAX_IOSTATE_IDLE;
+ signal_condition(&thread->lock, &thread->cond);
return 1;
} else {
/* this thread is going to process this frame, so mark it */
@@ -8369,27 +8385,61 @@
/* Wait for something to signal us to be awake */
ast_mutex_lock(&thread->lock);
+ /* Flag that we're ready to accept signals */
+ thread->ready_for_signal = 1;
+
/* Put into idle list if applicable */
if (put_into_idle)
insert_idle_thread(thread);
if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
+ struct iax2_thread *t = NULL;
/* Wait to be signalled or time out */
tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
ts.tv_sec = tv.tv_sec;
ts.tv_nsec = tv.tv_usec * 1000;
if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
- ast_mutex_unlock(&thread->lock);
+ /* This thread was never put back into the available dynamic
+ * thread list, so just go away. */
+ if (!put_into_idle) {
+ ast_mutex_unlock(&thread->lock);
+ break;
+ }
AST_LIST_LOCK(&dynamic_list);
- AST_LIST_REMOVE(&dynamic_list, thread, list);
+ /* Account for the case where this thread is acquired *right* after a timeout */
+ if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
+ ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
AST_LIST_UNLOCK(&dynamic_list);
- ast_atomic_dec_and_test(&iaxdynamicthreadcount);
- break; /* exiting the main loop */
+ if (t) {
+ /* This dynamic thread timed out waiting for a task and was
+ * not acquired immediately after the timeout,
+ * so it's time to go away. */
+ ast_mutex_unlock(&thread->lock);
+ break;
+ }
+ /* Someone grabbed our thread *right* after we timed out.
+ * Wait for them to set us up with something to do and signal
+ * us to continue. */
+ tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
+ if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
+ {
+ ast_mutex_unlock(&thread->lock);
+ break;
+ }
}
} else {
ast_cond_wait(&thread->cond, &thread->lock);
}
+
+ /* Go back into our respective list */
+ put_into_idle = 1;
+
ast_mutex_unlock(&thread->lock);
+
+ if (thread->iostate == IAX_IOSTATE_IDLE)
+ continue;
/* Add ourselves to the active list now */
AST_LIST_LOCK(&active_list);
@@ -8426,9 +8476,6 @@
/* Make sure another frame didn't sneak in there after we thought we were done. */
handle_deferred_full_frames(thread);
-
- /* Go back into our respective list */
- put_into_idle = 1;
}
/* I am exiting here on my own volition, I need to clean up my own data structures
Modified: team/juggie/NoLossCDR/channels/chan_local.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/channels/chan_local.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/channels/chan_local.c (original)
+++ team/juggie/NoLossCDR/channels/chan_local.c Mon Aug 6 17:46:35 2007
@@ -246,9 +246,9 @@
we can't get everything. Remember, we'll get another
chance in just a little bit */
if (!ast_mutex_trylock(&(p->chan->_bridge)->lock)) {
- if (!p->chan->_bridge->_softhangup) {
+ if (!ast_check_hangup(p->chan->_bridge)) {
if (!ast_mutex_trylock(&p->owner->lock)) {
- if (!p->owner->_softhangup) {
+ if (!ast_check_hangup(p->owner)) {
ast_channel_masquerade(p->owner, p->chan->_bridge);
ast_set_flag(p, LOCAL_ALREADY_MASQED);
}
@@ -265,9 +265,9 @@
} else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && AST_LIST_EMPTY(&p->chan->readq)) {
/* Masquerade bridged channel into chan */
if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
- if (!p->owner->_bridge->_softhangup) {
+ if (!ast_check_hangup(p->owner->_bridge)) {
if (!ast_mutex_trylock(&p->chan->lock)) {
- if (!p->chan->_softhangup) {
+ if (!ast_check_hangup(p->chan)) {
ast_channel_masquerade(p->chan, p->owner->_bridge);
ast_set_flag(p, LOCAL_ALREADY_MASQED);
}
Modified: team/juggie/NoLossCDR/channels/chan_mgcp.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/channels/chan_mgcp.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/channels/chan_mgcp.c (original)
+++ team/juggie/NoLossCDR/channels/chan_mgcp.c Mon Aug 6 17:46:35 2007
@@ -2061,7 +2061,7 @@
ast_verbose("We're at %s port %d\n", ast_inet_ntoa(p->parent->ourip), ntohs(sin.sin_port));
}
snprintf(v, sizeof(v), "v=0\r\n");
- snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", getpid(), getpid(), ast_inet_ntoa(dest.sin_addr));
+ snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", (int)getpid(), (int)getpid(), ast_inet_ntoa(dest.sin_addr));
snprintf(s, sizeof(s), "s=session\r\n");
snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
snprintf(t, sizeof(t), "t=0 0\r\n");
Modified: team/juggie/NoLossCDR/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/channels/chan_sip.c?view=diff&rev=78310&r1=78309&r2=78310
==============================================================================
--- team/juggie/NoLossCDR/channels/chan_sip.c (original)
+++ team/juggie/NoLossCDR/channels/chan_sip.c Mon Aug 6 17:46:35 2007
@@ -1136,6 +1136,7 @@
/*! \brief Protect the SIP dialog list (of sip_pvt's) */
AST_MUTEX_DEFINE_STATIC(dialoglock);
+#ifndef DETECT_DEADLOCKS
/*! \brief hide the way the list is locked/unlocked */
static void dialoglist_lock(void)
{
@@ -1146,6 +1147,12 @@
{
ast_mutex_unlock(&dialoglock);
}
+#else
+/* we don't want to HIDE the information about where the lock was requested if trying to debug
+ * deadlocks! So, just make these macros! */
+#define dialoglist_lock(x) ast_mutex_lock(&dialoglock)
+#define dialoglist_unlock(x) ast_mutex_unlock(&dialoglock)
+#endif
/*!
* when we create or delete references, make sure to use these
@@ -1644,12 +1651,15 @@
static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req);
static void reg_source_db(struct sip_peer *peer);
static void destroy_association(struct sip_peer *peer);
+static void set_insecure_flags(struct ast_flags *flags, const char *value, int lineno);
static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v);
/* Realtime device support */
static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey);
static struct sip_user *realtime_user(const char *username);
static void update_peer(struct sip_peer *p, int expiry);
+static struct ast_variable *get_insecure_variable_from_config(struct ast_config *config);
+static const char *get_name_from_variable(struct ast_variable *var, const char *newpeername);
static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
@@ -1841,24 +1851,8 @@
get_codec: sip_get_codec,
};
-#ifndef DETECT_DEADLOCKS
-/*! \brief Helper function to lock, hiding the underlying locking mechanism. */
-static void sip_pvt_lock(struct sip_pvt *pvt)
-{
- ast_mutex_lock(&pvt->pvt_lock);
-}
-
-/*! \brief Helper function to unlock pvt, hiding the underlying locking mechanism. */
-static void sip_pvt_unlock(struct sip_pvt *pvt)
-{
- ast_mutex_unlock(&pvt->pvt_lock);
-}
-#else
-/* we don't want to HIDE the information about where the lock was requested if trying to debug
- * deadlocks! So, just make these macros! */
#define sip_pvt_lock(x) ast_mutex_lock(&x->pvt_lock)
#define sip_pvt_unlock(x) ast_mutex_unlock(&x->pvt_lock)
-#endif
/*!
* helper functions to unreference various types of objects.
@@ -2942,12 +2936,36 @@
}
}
+static struct ast_variable *get_insecure_variable_from_config(struct ast_config *config)
+{
+ struct ast_variable *var = NULL;
+ struct ast_flags flags = {0};
+ char *cat = NULL;
+ const char *insecure;
+ while ((cat = ast_category_browse(config, cat))) {
+ insecure = ast_variable_retrieve(config, cat, "insecure");
+ set_insecure_flags(&flags, insecure, -1);
+ if (ast_test_flag(&flags, SIP_INSECURE_PORT)) {
+ var = ast_category_root(config, cat);
+ break;
+ }
+ }
+ return var;
+}
+
+static const char *get_name_from_variable(struct ast_variable *var, const char *newpeername)
+{
+ struct ast_variable *tmp;
+ for (tmp = var; tmp; tmp = tmp->next) {
+ if (!newpeername && !strcasecmp(tmp->name, "name"))
+ newpeername = tmp->value;
+ }
+ return newpeername;
+}
/*! \brief realtime_peer: Get peer from realtime storage
* Checks the "sippeers" realtime family from extconfig.conf
* Checks the "sipregs" realtime family from extconfig.conf if it's configured.
- * \todo Consider adding check of port address when matching here to follow the same
- * algorithm as for static peers. Will we break anything by adding that?
*/
static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_in *sin)
{
@@ -2955,7 +2973,11 @@
struct ast_variable *var = NULL;
struct ast_variable *varregs = NULL;
struct ast_variable *tmp;
+ struct ast_config *peerlist = NULL;
char ipaddr[INET_ADDRSTRLEN];
+ char portstring[6]; /*up to 5 digits plus null terminator*/
+ char *cat = NULL;
+ unsigned short portnum;
int realtimeregs = ast_check_realtime("sipregs");
/* First check on peer name */
@@ -2965,39 +2987,87 @@
varregs = ast_load_realtime("sipregs", "name", newpeername, NULL);
} else if (sin) { /* Then check on IP address for dynamic peers */
ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
- var = ast_load_realtime("sippeers", "host", ipaddr, NULL); /* First check for fixed IP hosts */
+ portnum = ntohs(sin->sin_port);
+ sprintf(portstring, "%u", portnum);
[... 3643 lines stripped ...]
More information about the asterisk-commits
mailing list