* Added member option ignorebusy this when set and ringinuse is not
will allow per member control of multiple calls as ringinuse does for
the Queue.
- * Added global option check_state_unknown to enforce checking of device state
- when the device state is unknown app_queue will see unknown as available.
Applications
------------
+2013-01-09 Asterisk Development Team <asteriskteam@digium.com>
+
+ * Asterisk 11.2.0-rc2 Released.
+
+ * Fix pjproject compilation in certain circumstances.
+
+ On a fresh checkout of Asterisk 11, running make before ./configure
+ could cause the pjproject subdirectory to get in an odd state that
+ would prevent compilation. This patch by Tilghman prevents that from
+ occurring.
+
+ (closes issue ASTERISK-20681)
+ Patch-by: Tilghman Lesher
+
+ * AST-2012-014: Resolve crashes due to large stack allocations when
+ using TCP
+
+ Asterisk had several places where messages received over various
+ network transports may be copied in a single stack allocation. In
+ the case of TCP, since multiple packets in a stream may be
+ concatenated together, this can lead to large allocations that
+ overflow the stack.
+
+ This patch modifies those portions of Asterisk using TCP to either
+ favor heap allocations or use an upper bound to ensure that the
+ stack will not overflow:
+ * For SIP, the allocation now has an upper limit
+ * For HTTP, the allocation is now a heap allocation instead of a
+ stack allocation
+ * For XMPP, the allocation has been eliminated since it was
+ unnecessary.
+
+ This patch contains the fix for both res_jabber and res_xmpp.
+
+ * AST-2012-015: Prevent exhaustion of system resources through
+ exploitation of event cache
+
+ Asterisk maintains an internal cache for devices in the event
+ subsystem. The device state cache holds the state of each device
+ known to Asterisk, such that consumers of device state information
+ can query for the last known state for a particular device, even if
+ it is not part of an active call. The concept of a device in
+ Asterisk can include entities that do not have a physical
+ representation. One way that this occurred was when anonymous calls
+ are allowed in Asterisk. A device was automatically created and
+ stored in the cache for each anonymous call that occurred; this was
+ possible in the SIP and IAX2 channel drivers and through channel
+ drivers that utilized the res_jabber/res_xmpp resource modules (Gtalk,
+ Jingle, and Motif). These devices are never removed from the system,
+ allowing anonymous call to potentially exhaust a system's resources.
+
+ This patch changes the event cache subsystem and device state
+ management to no longer cache devices that are not associated with a
+ physical entity.
+
+ * Revert bad ringinuse=no patch.
+
+ With the option ringinuse=no set, the patch committed previous for
+ ASTERISK-16115 causes non-SIP queue members to never be called
+ because the device state is checked after a channel is created to
+ determine if the member is busy. These queue members always get the
+ "Member %s is busy, cannot dial" message.
+
+ Most channel drivers other than chan_sip use the default device
+ state handling. The default device state is considered in use or
+ unknown if the channel exists or not, respectively.
+
+ * Fix multiple calls to a queue member that is only in queue.
+
+ When ringinuse=no queue members can receive more than one call if
+ these calls happen at nearly the same time. This patch fixes it so a
+ queu member does not receive more than one call from a queue. note
+ that this fix does not prevent multiple calls to a member if hte
+ member is in more than one queue (see ASTERISK-16115).
+
2012-12-10 Asterisk Development Team <asteriskteam@digium.com>
* Asterisk 11.2.0-rc1 Released.
part of a character set in the dialplan extensions. The code now
consistently ignores these characters when matching dialplan extensions.
+* Removed the queues.conf check_state_unknown option. It is no longer
+ necessary.
+
From 11.0 to 11.1:
Queues:
void conf_handle_first_join(struct conference_bridge *conference_bridge)
{
- ast_devstate_changed(AST_DEVICE_INUSE, "confbridge:%s", conference_bridge->name);
+ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", conference_bridge->name);
}
void conf_handle_second_active(struct conference_bridge *conference_bridge)
/* This device changed state now - if this is the first user */
if (conf->users == 1)
- ast_devstate_changed(AST_DEVICE_INUSE, "meetme:%s", conf->confno);
+ ast_devstate_changed(AST_DEVICE_INUSE, (conf->isdynamic ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), "meetme:%s", conf->confno);
ast_mutex_unlock(&conf->playlock);
/* Change any states */
if (!conf->users) {
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "meetme:%s", conf->confno);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, (conf->isdynamic ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), "meetme:%s", conf->confno);
}
/* This flag is meant to kill a conference with only one participant remaining. */
|| trunk_ref == exclude)
continue;
trunk_ref->state = state;
- ast_devstate_changed(sla_state_to_devstate(state),
- "SLA:%s_%s", station->name, trunk->name);
+ ast_devstate_changed(sla_state_to_devstate(state), AST_DEVSTATE_CACHABLE,
+ "SLA:%s_%s", station->name, trunk->name);
break;
}
}
{
ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD_BYME;
- ast_devstate_changed(AST_DEVICE_ONHOLD, "SLA:%s_%s",
- event->station->name, event->trunk_ref->trunk->name);
+ ast_devstate_changed(AST_DEVICE_ONHOLD, AST_DEVSTATE_CACHABLE, "SLA:%s_%s",
+ event->station->name, event->trunk_ref->trunk->name);
sla_change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_ONHOLD,
INACTIVE_TRUNK_REFS, event->trunk_ref);
sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
else {
trunk_ref->state = SLA_TRUNK_STATE_UP;
- ast_devstate_changed(AST_DEVICE_INUSE,
- "SLA:%s_%s", station->name, trunk_ref->trunk->name);
+ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE,
+ "SLA:%s_%s", station->name, trunk_ref->trunk->name);
}
} else if (trunk_ref->state == SLA_TRUNK_STATE_RINGING) {
struct sla_ringing_trunk *ringing_trunk;
/*! \brief queues.conf [general] option */
static int log_membername_as_agent = 0;
-/*! \brief queues.conf [general] option */
-static int check_state_unknown = 0;
-
/*! \brief name of the ringinuse field in the realtime database */
static char *realtime_ringinuse_field;
struct call_queue *lastqueue; /*!< Last queue we received a call */
unsigned int dead:1; /*!< Used to detect members deleted in realtime */
unsigned int delme:1; /*!< Flag to delete entry on reload */
+ unsigned int call_pending:1; /*!< TRUE if the Q is attempting to place a call to the member. */
char rt_uniqueid[80]; /*!< Unique id of realtime member entry */
unsigned int ringinuse:1; /*!< Flag to ring queue members even if their status is 'inuse' */
};
if (found_member) {
found = 1;
if (avail) {
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s_avail", q->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
} else {
- ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
}
}
* AST_DEVICE_INUSE indicates no members are available.
* AST_DEVICE_NOT_INUSE indicates a member is available.
*/
- ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
}
static void clear_queue(struct call_queue *q)
ast_copy_string(qe->context, q->context, sizeof(qe->context));
q->count++;
if (q->count == 1) {
- ast_devstate_changed(AST_DEVICE_RINGING, "Queue:%s", q->name);
+ ast_devstate_changed(AST_DEVICE_RINGING, AST_DEVSTATE_CACHABLE, "Queue:%s", q->name);
}
res = 0;
char posstr[20];
q->count--;
if (!q->count) {
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s", q->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s", q->name);
}
/* Take us out of the queue */
return vars;
}
+/*!
+ * \internal
+ * \brief Check if the member status is available.
+ *
+ * \param status Member status to check if available.
+ *
+ * \retval non-zero if the member status is available.
+ */
+static int member_status_available(int status)
+{
+ return status == AST_DEVICE_NOT_INUSE || status == AST_DEVICE_UNKNOWN;
+}
+
+/*!
+ * \internal
+ * \brief Clear the member call pending flag.
+ *
+ * \param mem Queue member.
+ *
+ * \return Nothing
+ */
+static void member_call_pending_clear(struct member *mem)
+{
+ ao2_lock(mem);
+ mem->call_pending = 0;
+ ao2_unlock(mem);
+}
+
+/*!
+ * \internal
+ * \brief Set the member call pending flag.
+ *
+ * \param mem Queue member.
+ *
+ * \retval non-zero if call pending flag was already set.
+ */
+static int member_call_pending_set(struct member *mem)
+{
+ int old_pending;
+
+ ao2_lock(mem);
+ old_pending = mem->call_pending;
+ mem->call_pending = 1;
+ ao2_unlock(mem);
+
+ return old_pending;
+}
+
+/*!
+ * \internal
+ * \brief Determine if can ring a queue entry.
+ *
+ * \param qe Queue entry to check.
+ * \param call Member call attempt.
+ *
+ * \retval non-zero if an entry can be called.
+ */
+static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)
+{
+ if (call->member->paused) {
+ ast_debug(1, "%s paused, can't receive call\n", call->interface);
+ return 0;
+ }
+
+ if (!call->member->ringinuse && !member_status_available(call->member->status)) {
+ ast_debug(1, "%s not available, can't receive call\n", call->interface);
+ return 0;
+ }
+
+ if ((call->lastqueue && call->lastqueue->wrapuptime && (time(NULL) - call->lastcall < call->lastqueue->wrapuptime))
+ || (!call->lastqueue && qe->parent->wrapuptime && (time(NULL) - call->lastcall < qe->parent->wrapuptime))) {
+ ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
+ (call->lastqueue ? call->lastqueue->name : qe->parent->name),
+ call->interface);
+ return 0;
+ }
+
+ if (use_weight && compare_weight(qe->parent, call->member)) {
+ ast_debug(1, "Priority queue delaying call to %s:%s\n",
+ qe->parent->name, call->interface);
+ return 0;
+ }
+
+ if (!call->member->ringinuse) {
+ if (member_call_pending_set(call->member)) {
+ ast_debug(1, "%s has another call pending, can't receive call\n",
+ call->interface);
+ return 0;
+ }
+
+ /*
+ * The queue member is available. Get current status to be sure
+ * because the device state and extension state callbacks may
+ * not have updated the status yet.
+ */
+ if (!member_status_available(get_queue_member_status(call->member))) {
+ ast_debug(1, "%s actually not available, can't receive call\n",
+ call->interface);
+ member_call_pending_clear(call->member);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
/*!
* \brief Part 2 of ring_one
*
char tech[256];
char *location;
const char *macrocontext, *macroexten;
- enum ast_device_state newstate;
/* on entry here, we know that tmp->chan == NULL */
- if (tmp->member->paused) {
- ast_debug(1, "%s paused, can't receive call\n", tmp->interface);
- if (ast_channel_cdr(qe->chan)) {
- ast_cdr_busy(ast_channel_cdr(qe->chan));
- }
- tmp->stillgoing = 0;
- (*busies)++;
- return 0;
- }
-
- if ((tmp->lastqueue && tmp->lastqueue->wrapuptime && (time(NULL) - tmp->lastcall < tmp->lastqueue->wrapuptime)) ||
- (!tmp->lastqueue && qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime))) {
- ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
- (tmp->lastqueue ? tmp->lastqueue->name : qe->parent->name), tmp->interface);
- if (ast_channel_cdr(qe->chan)) {
- ast_cdr_busy(ast_channel_cdr(qe->chan));
- }
- tmp->stillgoing = 0;
- (*busies)++;
- return 0;
- }
-
- if (!tmp->member->ringinuse) {
- if (check_state_unknown && (tmp->member->status == AST_DEVICE_UNKNOWN)) {
- newstate = ast_device_state(tmp->member->interface);
- if (newstate != tmp->member->status) {
- ast_log(LOG_WARNING, "Found a channel matching iterface %s while status was %s changed to %s\n",
- tmp->member->interface, ast_devstate2str(tmp->member->status), ast_devstate2str(newstate));
- ast_devstate_changed_literal(newstate, tmp->member->interface);
- }
- }
- if ((tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
- ast_debug(1, "%s in use, can't receive call\n", tmp->interface);
- if (ast_channel_cdr(qe->chan)) {
- ast_cdr_busy(ast_channel_cdr(qe->chan));
- }
- tmp->stillgoing = 0;
- (*busies)++;
- return 0;
- }
- }
-
- if (use_weight && compare_weight(qe->parent,tmp->member)) {
- ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
+ if (!can_ring_entry(qe, tmp)) {
if (ast_channel_cdr(qe->chan)) {
ast_cdr_busy(ast_channel_cdr(qe->chan));
}
tmp->stillgoing = 0;
- (*busies)++;
+ ++*busies;
return 0;
}
+ ast_assert(tmp->member->ringinuse || tmp->member->call_pending);
ast_copy_string(tech, tmp->interface, sizeof(tech));
if ((location = strchr(tech, '/'))) {
/* Request the peer */
tmp->chan = ast_request(tech, ast_channel_nativeformats(qe->chan), qe->chan, location, &status);
if (!tmp->chan) { /* If we can't, just go on to the next call */
- if (ast_channel_cdr(qe->chan)) {
- ast_cdr_busy(ast_channel_cdr(qe->chan));
- }
- tmp->stillgoing = 0;
-
ao2_lock(qe->parent);
- update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
qe->parent->rrpos++;
qe->linpos++;
ao2_unlock(qe->parent);
- (*busies)++;
+ member_call_pending_clear(tmp->member);
+
+ if (ast_channel_cdr(qe->chan)) {
+ ast_cdr_busy(ast_channel_cdr(qe->chan));
+ }
+ tmp->stillgoing = 0;
+ ++*busies;
return 0;
}
ast_channel_unlock(tmp->chan);
ast_channel_unlock(qe->chan);
- ao2_lock(tmp->member);
- update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
- if (!qe->parent->ringinuse && (tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
- ast_verb(1, "Member %s is busy, cannot dial", tmp->member->interface);
- res = -1;
- }
- else {
- /* Place the call, but don't wait on the answer */
- res = ast_call(tmp->chan, location, 0);
- }
- ao2_unlock(tmp->member);
- if (res) {
+ /* Place the call, but don't wait on the answer */
+ if ((res = ast_call(tmp->chan, location, 0))) {
/* Again, keep going even if there's an error */
ast_verb(3, "Couldn't call %s\n", tmp->interface);
do_hang(tmp);
- (*busies)++;
- update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
+ member_call_pending_clear(tmp->member);
+ ++*busies;
return 0;
- } else if (qe->parent->eventwhencalled) {
+ }
+
+ if (qe->parent->eventwhencalled) {
char vars[2048];
ast_channel_lock_both(tmp->chan, qe->chan);
ast_verb(3, "Called %s\n", tmp->interface);
}
- update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
+ member_call_pending_clear(tmp->member);
return 1;
}
}
if (!num_available_members(q)) {
- ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
}
res = RES_OKAY;
new_member->status, new_member->paused);
if (is_member_available(new_member)) {
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s_avail", q->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
}
ao2_ref(new_member, -1);
}
if (is_member_available(mem)) {
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s_avail", q->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
} else if (!num_available_members(q)) {
- ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
}
ast_queue_log(q->name, "NONE", mem->membername, (paused ? "PAUSE" : "UNPAUSE"), "%s", S_OR(reason, ""));
if ((general_val = ast_variable_retrieve(cfg, "general", "log_membername_as_agent"))) {
log_membername_as_agent = ast_true(general_val);
}
- check_state_unknown = 0;
- if ((general_val = ast_variable_retrieve(cfg, "general", "check_state_unknown"))) {
- check_state_unknown = ast_true(general_val);
- }
}
/*! \brief reload information pertaining to a single member
while ((mem = ao2_iterator_next(&mem_iter))) {
if ((mem->status != AST_DEVICE_UNAVAILABLE) && (mem->status != AST_DEVICE_INVALID)) {
++qmemcount;
- if (((mem->status == AST_DEVICE_NOT_INUSE) || (mem->status == AST_DEVICE_UNKNOWN)) && !(mem->paused)) {
+ if (member_status_available(mem->status) && !mem->paused) {
++qmemavail;
}
}
static void transition_to_empty(struct conference_bridge_user *cbu)
{
/* Set device state to "not in use" */
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "confbridge:%s", cbu->conference_bridge->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", cbu->conference_bridge->name);
conf_ended(cbu->conference_bridge);
}
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><title>Release Summary - asterisk-11.2.0-rc1</title></head>
-<body>
-<h1 align="center"><a name="top">Release Summary</a></h1>
-<h3 align="center">asterisk-11.2.0-rc1</h3>
-<h3 align="center">Date: 2012-12-09</h3>
-<h3 align="center"><asteriskteam@digium.com></h3>
-<hr/>
-<h2 align="center">Table of Contents</h2>
-<ol>
- <li><a href="#summary">Summary</a></li>
- <li><a href="#contributors">Contributors</a></li>
- <li><a href="#issues">Closed Issues</a></li>
- <li><a href="#commits">Other Changes</a></li>
- <li><a href="#diffstat">Diffstat</a></li>
-</ol>
-<hr/>
-<a name="summary"><h2 align="center">Summary</h2></a>
-<center><a href="#top">[Back to Top]</a></center><br/><p>This release includes only bug fixes. The changes included were made only to address problems that have been identified in this release series. Users should be able to safely upgrade to this version if this release series is already in use. Users considering upgrading from a previous release series are strongly encouraged to review the UPGRADE.txt document as well as the CHANGES document for information about upgrading to this release series.</p>
-<p>The data in this summary reflects changes that have been made since the previous release, asterisk-11.1.0.</p>
-<hr/>
-<a name="contributors"><h2 align="center">Contributors</h2></a>
-<center><a href="#top">[Back to Top]</a></center><br/><p>This table lists the people who have submitted code, those that have tested patches, as well as those that reported issues on the issue tracker that were resolved in this release. For coders, the number is how many of their patches (of any size) were committed into this release. For testers, the number is the number of times their name was listed as assisting with testing a patch. Finally, for reporters, the number is the number of issues that they reported that were closed by commits that went into this release.</p>
-<table width="100%" border="0">
-<tr>
-<td width="33%"><h3>Coders</h3></td>
-<td width="33%"><h3>Testers</h3></td>
-<td width="33%"><h3>Reporters</h3></td>
-</tr>
-<tr valign="top">
-<td>
-22 rmudgett<br/>
-4 jcolp<br/>
-4 jrose<br/>
-4 mjordan<br/>
-4 mmichelson<br/>
-3 dlee<br/>
-2 elguero<br/>
-2 russell<br/>
-2 tilghman<br/>
-1 alecdavis<br/>
-1 Andre Luis<br/>
-1 beagles<br/>
-1 file<br/>
-1 James Le Cuirot<br/>
-1 Jeremiah Gowdy<br/>
-1 jkroon<br/>
-1 kmoore<br/>
-1 pkiefer<br/>
-1 Rusty Newton<br/>
-1 seanbright<br/>
-1 wdoekes<br/>
-</td>
-<td>
-3 rmudgett<br/>
-1 alecdavis<br/>
-1 elguero<br/>
-1 Jared Smith<br/>
-1 mjordan<br/>
-1 Rusty Newton<br/>
-1 Steven T. Wheeler<br/>
-</td>
-<td>
-4 mjordan<br/>
-1 alecdavis<br/>
-1 andrel<br/>
-1 chewi<br/>
-1 coopvr<br/>
-1 deti<br/>
-1 dlee<br/>
-1 eabad<br/>
-1 elguero<br/>
-1 ibc<br/>
-1 jgowdy<br/>
-1 jkroon<br/>
-1 joshoa<br/>
-1 jrose<br/>
-1 jsmith<br/>
-1 mcargile<br/>
-1 p_lindheimer<br/>
-1 rmudgett<br/>
-1 sruffell<br/>
-1 supertle<br/>
-1 swheeler<br/>
-1 tomo1657<br/>
-1 tootai<br/>
-1 vldmr<br/>
-1 wimpy<br/>
-</td>
-</tr>
-</table>
-<hr/>
-<a name="issues"><h2 align="center">Closed Issues</h2></a>
-<center><a href="#top">[Back to Top]</a></center><br/><p>This is a list of all issues from the issue tracker that were closed by changes that went into this release.</p>
-<h3>Category: Applications/app_confbridge</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20655">ASTERISK-20655</a>: Cannot reset pin with CONFBRIDGE(user,pin)<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377228">377228</a><br/>
-Reporter: wimpy<br/>
-Coders: rmudgett<br/>
-<br/>
-<h3>Category: Applications/app_meetme</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20486">ASTERISK-20486</a>: MeetMe Unable to write frame to channel after SIP channel hangs up.<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376310">376310</a><br/>
-Reporter: mcargile<br/>
-Coders: jrose<br/>
-<br/>
-<h3>Category: Applications/app_queue</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-19918">ASTERISK-19918</a>: MoH (Music on Hold) is stopped after call in a queue is terminated<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376217">376217</a><br/>
-Reporter: eabad<br/>
-Coders: beagles<br/>
-<br/>
-<h3>Category: Applications/app_voicemail</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20280">ASTERISK-20280</a>: In app_voicemail we attempt to play the sound "vm-urgent-removed", which should be "vm-marked-nonurgent"<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376264">376264</a><br/>
-Reporter: tomo1657<br/>
-Testers: Rusty Newton<br/>
-Coders: Rusty Newton<br/>
-<br/>
-<h3>Category: Channels/General</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20414">ASTERISK-20414</a>: Timeout antipattern using ast_waitfor_nandfds<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376014">376014</a><br/>
-Reporter: dlee<br/>
-Coders: mmichelson<br/>
-<br/>
-<h3>Category: Channels/chan_bridge</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20492">ASTERISK-20492</a>: Stuck DTMF when using ChannelRedirect to split a two channel bridge<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=375966">375966</a><br/>
-Reporter: jgowdy<br/>
-Testers: rmudgett<br/>
-Coders: Jeremiah Gowdy, rmudgett<br/>
-<br/>
-<h3>Category: Channels/chan_dahdi/SS7</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20204">ASTERISK-20204</a>: Asterisk not rejecting call setup on CIC that is down<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376060">376060</a><br/>
-Reporter: supertle<br/>
-Coders: rmudgett<br/>
-<br/>
-<h3>Category: Channels/chan_local</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20769">ASTERISK-20769</a>: Memory leak of local_pvt in chan_local.<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376870">376870</a><br/>
-Reporter: rmudgett<br/>
-Testers: rmudgett<br/>
-Coders: rmudgett<br/>
-<br/>
-<h3>Category: Channels/chan_motif</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20671">ASTERISK-20671</a>: Add Who Hung Up support to the Motif channel driver<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377462">377462</a><br/>
-Reporter: mjordan<br/>
-Coders: jcolp<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20751">ASTERISK-20751</a>: chan_motif leaves UDP ports open<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377021">377021</a><br/>
-Reporter: joshoa<br/>
-Coders: jcolp<br/>
-<br/>
-<h3>Category: Channels/chan_sip/General</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20226">ASTERISK-20226</a>: Segfault in chan_sip while performing connected line update<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376917">376917</a><br/>
-Reporter: jsmith<br/>
-Testers: Jared Smith<br/>
-Coders: mmichelson<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20486">ASTERISK-20486</a>: MeetMe Unable to write frame to channel after SIP channel hangs up.<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376310">376310</a><br/>
-Reporter: mcargile<br/>
-Coders: jrose<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20570">ASTERISK-20570</a>: Asterisk, when acting as the UAS in Session Timer negotiation, fails to add required header in 200 response ("Require: timer")<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376550">376550</a><br/>
-Reporter: mjordan<br/>
-Coders: mmichelson<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20643">ASTERISK-20643</a>: SIP ICE support - remove hardcoded limitation on SDP size, make ICE support disabled by default in SIP, maybe provide a better warning message<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376130">376130</a><br/>
-Reporter: coopvr<br/>
-Coders: jcolp<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20724">ASTERISK-20724</a>: Fix natdetected flag being set when VIA doesn't include port in address<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376836">376836</a><br/>
-Reporter: elguero<br/>
-Coders: elguero<br/>
-<br/>
-<h3>Category: Channels/chan_sip/SRTP</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20499">ASTERISK-20499</a>: Crash in libsrtp srtp_unprotect_rtcp when SIP channel is bridged with non-optimizing Local channel<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377262">377262</a><br/>
-Reporter: tootai<br/>
-Coders: jrose<br/>
-<br/>
-<h3>Category: Channels/chan_sip/TCP-TLS</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20763">ASTERISK-20763</a>: Memory Leak in chan_sip with TLS enabled clients<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377259">377259</a><br/>
-Reporter: deti<br/>
-Coders: jcolp<br/>
-<br/>
-<h3>Category: Channels/chan_sip/WebSocket</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20745">ASTERISK-20745</a>: In MESSAGE received over WebSocket, the body last char is cut<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376822">376822</a><br/>
-Reporter: ibc<br/>
-Coders: pkiefer<br/>
-<br/>
-<h3>Category: Codecs/codec_dahdi</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-19921">ASTERISK-19921</a>: codec_dahdi: Wrong number of encoder/decoder channels.<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377383">377383</a><br/>
-Reporter: sruffell<br/>
-Coders: kmoore<br/>
-<br/>
-<h3>Category: Contrib/General</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20756">ASTERISK-20756</a>: Asterisk sippeers.sql columns place error cause peer to be without codecs when setting disallow=all under MySQL<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377433">377433</a><br/>
-Reporter: andrel<br/>
-Coders: Andre Luis<br/>
-<br/>
-<h3>Category: Core/Channels</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20492">ASTERISK-20492</a>: Stuck DTMF when using ChannelRedirect to split a two channel bridge<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=375966">375966</a><br/>
-Reporter: jgowdy<br/>
-Testers: rmudgett<br/>
-Coders: Jeremiah Gowdy, rmudgett<br/>
-<br/>
-<h3>Category: Core/ManagerInterface</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20677">ASTERISK-20677</a>: Action Challenge not working with allowmultiplelogin=no<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376727">376727</a><br/>
-Reporter: vldmr<br/>
-Coders: jrose<br/>
-<br/>
-<h3>Category: Core/PBX</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-19205">ASTERISK-19205</a>: Most Unique pattern matching broken when trailing "-" is part of extension<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376690">376690</a><br/>
-Reporter: p_lindheimer<br/>
-Testers: rmudgett<br/>
-Coders: rmudgett<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20639">ASTERISK-20639</a>: Dynamic hints are not properly initialized when the extension contains an underscore.<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376144">376144</a><br/>
-Reporter: swheeler<br/>
-Testers: Steven T. Wheeler, elguero<br/>
-Coders: elguero<br/>
-<br/>
-<h3>Category: General</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-19463">ASTERISK-19463</a>: Asterisk deadlocks during startup with mutex errors<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376441">376441</a><br/>
-Reporter: mjordan<br/>
-Testers: mjordan<br/>
-Coders: mjordan<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20226">ASTERISK-20226</a>: Segfault in chan_sip while performing connected line update<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376917">376917</a><br/>
-Reporter: jsmith<br/>
-Testers: Jared Smith<br/>
-Coders: mmichelson<br/>
-<br/>
-<h3>Category: PBX/General</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20628">ASTERISK-20628</a>: [patch] - main/pbx.c - ShowDialPlan generates with error if no Exten: was presented and there are no exten => lines present<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376168">376168</a><br/>
-Reporter: jkroon<br/>
-Coders: jkroon<br/>
-<br/>
-<h3>Category: PBX/pbx_spool</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20593">ASTERISK-20593</a>: [patch] Future-dated call files are ignored when astspooldir is relative<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376234">376234</a><br/>
-Reporter: chewi<br/>
-Coders: James Le Cuirot<br/>
-<br/>
-<h3>Category: Resources/res_monitor</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20641">ASTERISK-20641</a>: Erroneous error messages from Monitor when using options 'i' and 'o'<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376391">376391</a><br/>
-Reporter: jrose<br/>
-Coders: jrose<br/>
-<br/>
-<h3>Category: Tests/testsuite</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-19463">ASTERISK-19463</a>: Asterisk deadlocks during startup with mutex errors<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376441">376441</a><br/>
-Reporter: mjordan<br/>
-Testers: mjordan<br/>
-Coders: mjordan<br/>
-<br/>
-<h3>Category: Utilities/General</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20505">ASTERISK-20505</a>: Migrate hashtest/hashtest2 to be unit tests<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376339">376339</a><br/>
-Reporter: mjordan<br/>
-Coders: dlee<br/>
-<br/>
-<hr/>
-<a name="commits"><h2 align="center">Commits Not Associated with an Issue</h2></a>
-<center><a href="#top">[Back to Top]</a></center><br/><p>This is a list of all changes that went into this release that did not directly close an issue from the issue tracker. The commits may have been marked as being related to an issue. If that is the case, the issue numbers are listed here, as well.</p>
-<table width="100%" border="1">
-<tr><td><b>Revision</b></td><td><b>Author</b></td><td><b>Summary</b></td><td><b>Issues Referenced</b></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376048">376048</a></td><td>rmudgett</td><td>Add MALLOC_DEBUG enhancements.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376089">376089</a></td><td>mmichelson</td><td>Fix a "set but not used" warning on newer gccs.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376343">376343</a></td><td>dlee</td><td>Fixed extconf.c breakage introduced in r376306.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376415">376415</a></td><td>mjordan</td><td>Add a test event that reports changes in ConfBridge state</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376471">376471</a></td><td>wdoekes</td><td>Fix most leftover non-opaque ast_str uses.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376561">376561</a></td><td>dlee</td><td>Added missing newlines to websocket ast_logs.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376588">376588</a></td><td>mjordan</td><td>Re-initialize logmsgs mutex upon logger initialization to prevent lock errors</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-19463">ASTERISK-19463</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376629">376629</a></td><td>rmudgett</td><td>Made AST_LIST_REMOVE() simpler and use better names.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376659">376659</a></td><td>rmudgett</td><td>Remove unnecessary channel module references.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376760">376760</a></td><td>rmudgett</td><td>Enhance MALLOC_DEBUG CLI commands.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376790">376790</a></td><td>rmudgett</td><td>Add MALLOC_DEBUG atexit unreleased malloc memory summary.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376866">376866</a></td><td>rmudgett</td><td>Fix compile error.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20724">ASTERISK-20724</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376921">376921</a></td><td>seanbright</td><td>Minor spelling fix to the VOLUME documentation.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376952">376952</a></td><td>rmudgett</td><td>chan_misdn: Fix sending RELEASE_COMPLETE in response to SETUP.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376983">376983</a></td><td>file</td><td>Tweak extension used for incoming calls received on Motif.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377039">377039</a></td><td>rmudgett</td><td>Fix CCSS CLI commands and logger level not unregistered.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20649">ASTERISK-20649</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377071">377071</a></td><td>rmudgett</td><td>Cleanup CDR resources on exit.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20649">ASTERISK-20649</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377075">377075</a></td><td>rmudgett</td><td>Cleanup CLI resources on exit and CLI command registration errors.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20649">ASTERISK-20649</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377106">377106</a></td><td>rmudgett</td><td>Cleanup config cache on exit.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20649">ASTERISK-20649</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377137">377137</a></td><td>rmudgett</td><td>Cleanup core main on exit.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20649">ASTERISK-20649</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377167">377167</a></td><td>rmudgett</td><td>Cleanup ast_run_atexits() atexits list.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20649">ASTERISK-20649</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377195">377195</a></td><td>russell</td><td>Add libuuid to install_prereq for Fedora.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377213">377213</a></td><td>rmudgett</td><td>confbridge: Update online XML documentation.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377244">377244</a></td><td>rmudgett</td><td>Fix registering core show codecs/codec CLI commands twice.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377319">377319</a></td><td>mjordan</td><td>Fix memory leak in 'manager show event' when command entered incorrectly</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377340">377340</a></td><td>russell</td><td>Add CLI tab completion to 'acl show'.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377355">377355</a></td><td>rmudgett</td><td>confbridge: Fix some resource leaks on conference teardown.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377401">377401</a></td><td>rmudgett</td><td>MALLOC_DEBUG: Only wait if we want atexit allocation dumps.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377505">377505</a></td><td>tilghman</td><td>Remove some dead code and additionally handle a case that wasn't handled.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377511">377511</a></td><td>tilghman</td><td>Improve documentation by making all of the colors used readable,</td>
-<td></td></tr></table>
-<hr/>
-<a name="diffstat"><h2 align="center">Diffstat Results</h2></a>
-<center><a href="#top">[Back to Top]</a></center><br/><p>This is a summary of the changes to the source code that went into this release that was generated using the diffstat utility.</p>
-<pre>
-UPGRADE.txt | 6
-addons/cdr_mysql.c | 11
-addons/res_config_mysql.c | 3
-apps/app_celgenuserevent.c | 9
-apps/app_confbridge.c | 148 ++--
-apps/app_dial.c | 14
-apps/app_jack.c | 4
-apps/app_meetme.c | 15
-apps/app_queue.c | 26
-apps/app_record.c | 27
-apps/app_voicemail.c | 2
-apps/app_waitforring.c | 25
-apps/confbridge/conf_config_parser.c | 126 ++-
-apps/confbridge/conf_state.c | 5
-channels/chan_agent.c | 14
-channels/chan_dahdi.c | 42 -
-channels/chan_iax2.c | 14
-channels/chan_local.c | 21
-channels/chan_motif.c | 27
-channels/chan_sip.c | 208 +++--
-channels/misdn/isdn_lib.c | 17
-channels/sig_analog.c | 22
-channels/sig_pri.c | 12
-channels/sig_ss7.c | 51 -
-channels/sip/include/sip.h | 1
-codecs/codec_dahdi.c | 2
-configs/motif.conf.sample | 5
-configs/sip.conf.sample | 5
-contrib/realtime/mysql/sippeers.sql | 2
-contrib/scripts/install_prereq | 2
-funcs/func_volume.c | 2
-include/asterisk/_private.h | 1
-include/asterisk/astmm.h | 3
-include/asterisk/channel.h | 8
-include/asterisk/features.h | 12
-include/asterisk/hashtab.h | 3
-include/asterisk/linkedlists.h | 58 -
-include/asterisk/lock.h | 16
-include/asterisk/time.h | 14
-include/asterisk/utils.h | 29
-main/asterisk.c | 352 ++++++----
-main/astmm.c | 1223 ++++++++++++++++++++++++++++++-----
-main/ccss.c | 2
-main/cdr.c | 46 -
-main/channel.c | 150 +++-
-main/channel_internal_api.c | 21
-main/cli.c | 41 +
-main/config.c | 14
-main/features.c | 27
-main/format.c | 6
-main/indications.c | 2
-main/lock.c | 2
-main/logger.c | 11
-main/manager.c | 7
-main/named_acl.c | 25
-main/pbx.c | 532 +++++++++++----
-main/rtp_engine.c | 16
-main/security_events.c | 2
-main/stdtime/localtime.c | 14
-main/utils.c | 69 +
-main/xmldoc.c | 8
-pbx/pbx_dundi.c | 31
-pbx/pbx_spool.c | 2
-res/res_fax.c | 128 ++-
-res/res_http_websocket.c | 12
-res/res_monitor.c | 32
-res/res_rtp_asterisk.c | 2
-res/res_srtp.c | 4
-tests/test_astobj2_thrash.c | 353 ++++++++++
-tests/test_hashtab_thrash.c | 321 +++++++++
-utils/Makefile | 7
-utils/extconf.c | 1
-utils/hashtest.c | 410 -----------
-utils/hashtest2.c | 418 -----------
-utils/utils.xml | 8
-75 files changed, 3469 insertions(+), 1842 deletions(-)
-</pre><br/>
-<hr/>
-</body>
-</html>
+++ /dev/null
- Release Summary
-
- asterisk-11.2.0-rc1
-
- Date: 2012-12-09
-
- <asteriskteam@digium.com>
-
- ----------------------------------------------------------------------
-
- Table of Contents
-
- 1. Summary
- 2. Contributors
- 3. Closed Issues
- 4. Other Changes
- 5. Diffstat
-
- ----------------------------------------------------------------------
-
- Summary
-
- [Back to Top]
-
- This release includes only bug fixes. The changes included were made only
- to address problems that have been identified in this release series.
- Users should be able to safely upgrade to this version if this release
- series is already in use. Users considering upgrading from a previous
- release series are strongly encouraged to review the UPGRADE.txt document
- as well as the CHANGES document for information about upgrading to this
- release series.
-
- The data in this summary reflects changes that have been made since the
- previous release, asterisk-11.1.0.
-
- ----------------------------------------------------------------------
-
- Contributors
-
- [Back to Top]
-
- This table lists the people who have submitted code, those that have
- tested patches, as well as those that reported issues on the issue tracker
- that were resolved in this release. For coders, the number is how many of
- their patches (of any size) were committed into this release. For testers,
- the number is the number of times their name was listed as assisting with
- testing a patch. Finally, for reporters, the number is the number of
- issues that they reported that were closed by commits that went into this
- release.
-
- Coders Testers Reporters
- 22 rmudgett 3 rmudgett 4 mjordan
- 4 jcolp 1 alecdavis 1 alecdavis
- 4 jrose 1 elguero 1 andrel
- 4 mjordan 1 Jared Smith 1 chewi
- 4 mmichelson 1 mjordan 1 coopvr
- 3 dlee 1 Rusty Newton 1 deti
- 2 elguero 1 Steven T. Wheeler 1 dlee
- 2 russell 1 eabad
- 2 tilghman 1 elguero
- 1 alecdavis 1 ibc
- 1 Andre Luis 1 jgowdy
- 1 beagles 1 jkroon
- 1 file 1 joshoa
- 1 James Le Cuirot 1 jrose
- 1 Jeremiah Gowdy 1 jsmith
- 1 jkroon 1 mcargile
- 1 kmoore 1 p_lindheimer
- 1 pkiefer 1 rmudgett
- 1 Rusty Newton 1 sruffell
- 1 seanbright 1 supertle
- 1 wdoekes 1 swheeler
- 1 tomo1657
- 1 tootai
- 1 vldmr
- 1 wimpy
-
- ----------------------------------------------------------------------
-
- Closed Issues
-
- [Back to Top]
-
- This is a list of all issues from the issue tracker that were closed by
- changes that went into this release.
-
- Category: Applications/app_confbridge
-
- ASTERISK-20655: Cannot reset pin with CONFBRIDGE(user,pin)
- Revision: 377228
- Reporter: wimpy
- Coders: rmudgett
-
- Category: Applications/app_meetme
-
- ASTERISK-20486: MeetMe Unable to write frame to channel after SIP channel
- hangs up.
- Revision: 376310
- Reporter: mcargile
- Coders: jrose
-
- Category: Applications/app_queue
-
- ASTERISK-19918: MoH (Music on Hold) is stopped after call in a queue is
- terminated
- Revision: 376217
- Reporter: eabad
- Coders: beagles
-
- Category: Applications/app_voicemail
-
- ASTERISK-20280: In app_voicemail we attempt to play the sound
- "vm-urgent-removed", which should be "vm-marked-nonurgent"
- Revision: 376264
- Reporter: tomo1657
- Testers: Rusty Newton
- Coders: Rusty Newton
-
- Category: Channels/General
-
- ASTERISK-20414: Timeout antipattern using ast_waitfor_nandfds
- Revision: 376014
- Reporter: dlee
- Coders: mmichelson
-
- Category: Channels/chan_bridge
-
- ASTERISK-20492: Stuck DTMF when using ChannelRedirect to split a two
- channel bridge
- Revision: 375966
- Reporter: jgowdy
- Testers: rmudgett
- Coders: Jeremiah Gowdy, rmudgett
-
- Category: Channels/chan_dahdi/SS7
-
- ASTERISK-20204: Asterisk not rejecting call setup on CIC that is down
- Revision: 376060
- Reporter: supertle
- Coders: rmudgett
-
- Category: Channels/chan_local
-
- ASTERISK-20769: Memory leak of local_pvt in chan_local.
- Revision: 376870
- Reporter: rmudgett
- Testers: rmudgett
- Coders: rmudgett
-
- Category: Channels/chan_motif
-
- ASTERISK-20671: Add Who Hung Up support to the Motif channel driver
- Revision: 377462
- Reporter: mjordan
- Coders: jcolp
-
- ASTERISK-20751: chan_motif leaves UDP ports open
- Revision: 377021
- Reporter: joshoa
- Coders: jcolp
-
- Category: Channels/chan_sip/General
-
- ASTERISK-20226: Segfault in chan_sip while performing connected line
- update
- Revision: 376917
- Reporter: jsmith
- Testers: Jared Smith
- Coders: mmichelson
-
- ASTERISK-20486: MeetMe Unable to write frame to channel after SIP channel
- hangs up.
- Revision: 376310
- Reporter: mcargile
- Coders: jrose
-
- ASTERISK-20570: Asterisk, when acting as the UAS in Session Timer
- negotiation, fails to add required header in 200 response ("Require:
- timer")
- Revision: 376550
- Reporter: mjordan
- Coders: mmichelson
-
- ASTERISK-20643: SIP ICE support - remove hardcoded limitation on SDP size,
- make ICE support disabled by default in SIP, maybe provide a better
- warning message
- Revision: 376130
- Reporter: coopvr
- Coders: jcolp
-
- ASTERISK-20724: Fix natdetected flag being set when VIA doesn't include
- port in address
- Revision: 376836
- Reporter: elguero
- Coders: elguero
-
- Category: Channels/chan_sip/SRTP
-
- ASTERISK-20499: Crash in libsrtp srtp_unprotect_rtcp when SIP channel is
- bridged with non-optimizing Local channel
- Revision: 377262
- Reporter: tootai
- Coders: jrose
-
- Category: Channels/chan_sip/TCP-TLS
-
- ASTERISK-20763: Memory Leak in chan_sip with TLS enabled clients
- Revision: 377259
- Reporter: deti
- Coders: jcolp
-
- Category: Channels/chan_sip/WebSocket
-
- ASTERISK-20745: In MESSAGE received over WebSocket, the body last char is
- cut
- Revision: 376822
- Reporter: ibc
- Coders: pkiefer
-
- Category: Codecs/codec_dahdi
-
- ASTERISK-19921: codec_dahdi: Wrong number of encoder/decoder channels.
- Revision: 377383
- Reporter: sruffell
- Coders: kmoore
-
- Category: Contrib/General
-
- ASTERISK-20756: Asterisk sippeers.sql columns place error cause peer to be
- without codecs when setting disallow=all under MySQL
- Revision: 377433
- Reporter: andrel
- Coders: Andre Luis
-
- Category: Core/Channels
-
- ASTERISK-20492: Stuck DTMF when using ChannelRedirect to split a two
- channel bridge
- Revision: 375966
- Reporter: jgowdy
- Testers: rmudgett
- Coders: Jeremiah Gowdy, rmudgett
-
- Category: Core/ManagerInterface
-
- ASTERISK-20677: Action Challenge not working with allowmultiplelogin=no
- Revision: 376727
- Reporter: vldmr
- Coders: jrose
-
- Category: Core/PBX
-
- ASTERISK-19205: Most Unique pattern matching broken when trailing "-" is
- part of extension
- Revision: 376690
- Reporter: p_lindheimer
- Testers: rmudgett
- Coders: rmudgett
-
- ASTERISK-20639: Dynamic hints are not properly initialized when the
- extension contains an underscore.
- Revision: 376144
- Reporter: swheeler
- Testers: Steven T. Wheeler, elguero
- Coders: elguero
-
- Category: General
-
- ASTERISK-19463: Asterisk deadlocks during startup with mutex errors
- Revision: 376441
- Reporter: mjordan
- Testers: mjordan
- Coders: mjordan
-
- ASTERISK-20226: Segfault in chan_sip while performing connected line
- update
- Revision: 376917
- Reporter: jsmith
- Testers: Jared Smith
- Coders: mmichelson
-
- Category: PBX/General
-
- ASTERISK-20628: [patch] - main/pbx.c - ShowDialPlan generates with error
- if no Exten: was presented and there are no exten => lines present
- Revision: 376168
- Reporter: jkroon
- Coders: jkroon
-
- Category: PBX/pbx_spool
-
- ASTERISK-20593: [patch] Future-dated call files are ignored when
- astspooldir is relative
- Revision: 376234
- Reporter: chewi
- Coders: James Le Cuirot
-
- Category: Resources/res_monitor
-
- ASTERISK-20641: Erroneous error messages from Monitor when using options
- 'i' and 'o'
- Revision: 376391
- Reporter: jrose
- Coders: jrose
-
- Category: Tests/testsuite
-
- ASTERISK-19463: Asterisk deadlocks during startup with mutex errors
- Revision: 376441
- Reporter: mjordan
- Testers: mjordan
- Coders: mjordan
-
- Category: Utilities/General
-
- ASTERISK-20505: Migrate hashtest/hashtest2 to be unit tests
- Revision: 376339
- Reporter: mjordan
- Coders: dlee
-
- ----------------------------------------------------------------------
-
- Commits Not Associated with an Issue
-
- [Back to Top]
-
- This is a list of all changes that went into this release that did not
- directly close an issue from the issue tracker. The commits may have been
- marked as being related to an issue. If that is the case, the issue
- numbers are listed here, as well.
-
- +------------------------------------------------------------------------+
- | Revision | Author | Summary | Issues Referenced |
- |----------+------------+----------------------------+-------------------|
- | 376048 | rmudgett | Add MALLOC_DEBUG | |
- | | | enhancements. | |
- |----------+------------+----------------------------+-------------------|
- | 376089 | mmichelson | Fix a "set but not used" | |
- | | | warning on newer gccs. | |
- |----------+------------+----------------------------+-------------------|
- | 376343 | dlee | Fixed extconf.c breakage | |
- | | | introduced in r376306. | |
- |----------+------------+----------------------------+-------------------|
- | | | Add a test event that | |
- | 376415 | mjordan | reports changes in | |
- | | | ConfBridge state | |
- |----------+------------+----------------------------+-------------------|
- | 376471 | wdoekes | Fix most leftover | |
- | | | non-opaque ast_str uses. | |
- |----------+------------+----------------------------+-------------------|
- | 376561 | dlee | Added missing newlines to | |
- | | | websocket ast_logs. | |
- |----------+------------+----------------------------+-------------------|
- | | | Re-initialize logmsgs | |
- | 376588 | mjordan | mutex upon logger | ASTERISK-19463 |
- | | | initialization to prevent | |
- | | | lock errors | |
- |----------+------------+----------------------------+-------------------|
- | | | Made AST_LIST_REMOVE() | |
- | 376629 | rmudgett | simpler and use better | |
- | | | names. | |
- |----------+------------+----------------------------+-------------------|
- | 376659 | rmudgett | Remove unnecessary channel | |
- | | | module references. | |
- |----------+------------+----------------------------+-------------------|
- | 376760 | rmudgett | Enhance MALLOC_DEBUG CLI | |
- | | | commands. | |
- |----------+------------+----------------------------+-------------------|
- | | | Add MALLOC_DEBUG atexit | |
- | 376790 | rmudgett | unreleased malloc memory | |
- | | | summary. | |
- |----------+------------+----------------------------+-------------------|
- | 376866 | rmudgett | Fix compile error. | ASTERISK-20724 |
- |----------+------------+----------------------------+-------------------|
- | 376921 | seanbright | Minor spelling fix to the | |
- | | | VOLUME documentation. | |
- |----------+------------+----------------------------+-------------------|
- | | | chan_misdn: Fix sending | |
- | 376952 | rmudgett | RELEASE_COMPLETE in | |
- | | | response to SETUP. | |
- |----------+------------+----------------------------+-------------------|
- | | | Tweak extension used for | |
- | 376983 | file | incoming calls received on | |
- | | | Motif. | |
- |----------+------------+----------------------------+-------------------|
- | | | Fix CCSS CLI commands and | |
- | 377039 | rmudgett | logger level not | ASTERISK-20649 |
- | | | unregistered. | |
- |----------+------------+----------------------------+-------------------|
- | 377071 | rmudgett | Cleanup CDR resources on | ASTERISK-20649 |
- | | | exit. | |
- |----------+------------+----------------------------+-------------------|
- | | | Cleanup CLI resources on | |
- | 377075 | rmudgett | exit and CLI command | ASTERISK-20649 |
- | | | registration errors. | |
- |----------+------------+----------------------------+-------------------|
- | 377106 | rmudgett | Cleanup config cache on | ASTERISK-20649 |
- | | | exit. | |
- |----------+------------+----------------------------+-------------------|
- | 377137 | rmudgett | Cleanup core main on exit. | ASTERISK-20649 |
- |----------+------------+----------------------------+-------------------|
- | 377167 | rmudgett | Cleanup ast_run_atexits() | ASTERISK-20649 |
- | | | atexits list. | |
- |----------+------------+----------------------------+-------------------|
- | 377195 | russell | Add libuuid to | |
- | | | install_prereq for Fedora. | |
- |----------+------------+----------------------------+-------------------|
- | 377213 | rmudgett | confbridge: Update online | |
- | | | XML documentation. | |
- |----------+------------+----------------------------+-------------------|
- | | | Fix registering core show | |
- | 377244 | rmudgett | codecs/codec CLI commands | |
- | | | twice. | |
- |----------+------------+----------------------------+-------------------|
- | | | Fix memory leak in | |
- | 377319 | mjordan | 'manager show event' when | |
- | | | command entered | |
- | | | incorrectly | |
- |----------+------------+----------------------------+-------------------|
- | 377340 | russell | Add CLI tab completion to | |
- | | | 'acl show'. | |
- |----------+------------+----------------------------+-------------------|
- | | | confbridge: Fix some | |
- | 377355 | rmudgett | resource leaks on | |
- | | | conference teardown. | |
- |----------+------------+----------------------------+-------------------|
- | | | MALLOC_DEBUG: Only wait if | |
- | 377401 | rmudgett | we want atexit allocation | |
- | | | dumps. | |
- |----------+------------+----------------------------+-------------------|
- | | | Remove some dead code and | |
- | 377505 | tilghman | additionally handle a case | |
- | | | that wasn't handled. | |
- |----------+------------+----------------------------+-------------------|
- | | | Improve documentation by | |
- | 377511 | tilghman | making all of the colors | |
- | | | used readable, | |
- +------------------------------------------------------------------------+
-
- ----------------------------------------------------------------------
-
- Diffstat Results
-
- [Back to Top]
-
- This is a summary of the changes to the source code that went into this
- release that was generated using the diffstat utility.
-
- UPGRADE.txt | 6
- addons/cdr_mysql.c | 11
- addons/res_config_mysql.c | 3
- apps/app_celgenuserevent.c | 9
- apps/app_confbridge.c | 148 ++--
- apps/app_dial.c | 14
- apps/app_jack.c | 4
- apps/app_meetme.c | 15
- apps/app_queue.c | 26
- apps/app_record.c | 27
- apps/app_voicemail.c | 2
- apps/app_waitforring.c | 25
- apps/confbridge/conf_config_parser.c | 126 ++-
- apps/confbridge/conf_state.c | 5
- channels/chan_agent.c | 14
- channels/chan_dahdi.c | 42 -
- channels/chan_iax2.c | 14
- channels/chan_local.c | 21
- channels/chan_motif.c | 27
- channels/chan_sip.c | 208 +++--
- channels/misdn/isdn_lib.c | 17
- channels/sig_analog.c | 22
- channels/sig_pri.c | 12
- channels/sig_ss7.c | 51 -
- channels/sip/include/sip.h | 1
- codecs/codec_dahdi.c | 2
- configs/motif.conf.sample | 5
- configs/sip.conf.sample | 5
- contrib/realtime/mysql/sippeers.sql | 2
- contrib/scripts/install_prereq | 2
- funcs/func_volume.c | 2
- include/asterisk/_private.h | 1
- include/asterisk/astmm.h | 3
- include/asterisk/channel.h | 8
- include/asterisk/features.h | 12
- include/asterisk/hashtab.h | 3
- include/asterisk/linkedlists.h | 58 -
- include/asterisk/lock.h | 16
- include/asterisk/time.h | 14
- include/asterisk/utils.h | 29
- main/asterisk.c | 352 ++++++----
- main/astmm.c | 1223 ++++++++++++++++++++++++++++++-----
- main/ccss.c | 2
- main/cdr.c | 46 -
- main/channel.c | 150 +++-
- main/channel_internal_api.c | 21
- main/cli.c | 41 +
- main/config.c | 14
- main/features.c | 27
- main/format.c | 6
- main/indications.c | 2
- main/lock.c | 2
- main/logger.c | 11
- main/manager.c | 7
- main/named_acl.c | 25
- main/pbx.c | 532 +++++++++++----
- main/rtp_engine.c | 16
- main/security_events.c | 2
- main/stdtime/localtime.c | 14
- main/utils.c | 69 +
- main/xmldoc.c | 8
- pbx/pbx_dundi.c | 31
- pbx/pbx_spool.c | 2
- res/res_fax.c | 128 ++-
- res/res_http_websocket.c | 12
- res/res_monitor.c | 32
- res/res_rtp_asterisk.c | 2
- res/res_srtp.c | 4
- tests/test_astobj2_thrash.c | 353 ++++++++++
- tests/test_hashtab_thrash.c | 321 +++++++++
- utils/Makefile | 7
- utils/extconf.c | 1
- utils/hashtest.c | 410 -----------
- utils/hashtest2.c | 418 -----------
- utils/utils.xml | 8
- 75 files changed, 3469 insertions(+), 1842 deletions(-)
-
- ----------------------------------------------------------------------
if (p->chan) {
ast_channel_internal_bridged_channel_set(p->chan, NULL);
p->chan = NULL;
- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
+ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
p->acknowledged = 0;
}
} else {
} else {
/* Agent hung-up */
p->chan = NULL;
- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
+ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
}
if (!res) {
if (!p->loginstart) {
p->logincallerid[0] = '\0';
} else {
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
}
if (p->abouttograb) {
}
ast_mutex_unlock(&p->lock);
AST_LIST_UNLOCK(&agents);
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
while (res >= 0) {
ast_mutex_lock(&p->lock);
if (p->deferlogoff && p->chan) {
if (ast_tvdiff_ms(ast_tvnow(), p->lastdisc) > 0) {
ast_debug(1, "Wrapup time for %s expired!\n", p->agent);
p->lastdisc = ast_tv(0, 0);
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
if (p->ackcall) {
check_beep(p, 0);
} else {
ast_queue_log("NONE", ast_channel_uniqueid(chan), agent, "AGENTLOGOFF", "%s|%ld", ast_channel_name(chan), logintime);
ast_verb(2, "Agent '%s' logged out\n", p->agent);
/* If there is no owner, go ahead and kill it now */
- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
+ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
if (p->dead && !p->owner) {
ast_mutex_destroy(&p->lock);
ast_cond_destroy(&p->app_complete_cond);
}
if (pri->congestion_devstate != new_state) {
pri->congestion_devstate = new_state;
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/congestion", pri->span);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "DAHDI/I%d/congestion", pri->span);
}
#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
/* Update the span threshold device state and report any change. */
}
if (pri->threshold_devstate != new_state) {
pri->threshold_devstate = new_state;
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/threshold", pri->span);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "DAHDI/I%d/threshold", pri->span);
}
#endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
}
if (dashptr) {
*dashptr = '\0';
}
- ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
+ ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+ ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, device_name);
for (v = i->vars ; v ; v = v->next)
pbx_builtin_setvar_helper(tmp, v->name, v->value);
}
/*! \brief Create new call, interface with the PBX core */
-static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const char *linkedid)
+static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const char *linkedid, unsigned int cachable)
{
struct ast_channel *tmp;
struct chan_iax2_pvt *i;
i->owner = tmp;
i->capability = capability;
+ if (!cachable) {
+ ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+ }
+
/* Set inherited variables */
if (i->vars) {
for (v = i->vars ; v ; v = v->next)
/* if challenge has been sent, but no challenge response if given, reject. */
goto return_unref;
}
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
/* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
res = 0;
if (!ast_test_flag64(peer, IAX_TEMPONLY))
ast_db_del("IAX/Registry", peer->name);
register_peer_exten(peer, 0);
- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
+ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
if (iax2_regfunk)
iax2_regfunk(peer->name, 0);
}
}
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
if (p->expire == -1) {
ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\nPort: %d\r\n", p->name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
register_peer_exten(p, 1);
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
} else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
register_peer_exten(p, 0);
ast_db_del("IAX/Registry", p->name);
- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */
+ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
}
/* Update the host */
/* Verify that the host is really there */
(f.frametype == AST_FRAME_IAX)) {
if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
- if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
+ if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL,
+ ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
ast_variables_destroy(ies.vars);
ast_mutex_unlock(&iaxsl[fr->callno]);
return 1;
if (iaxs[fr->callno]->pingtime <= peer->maxms) {
ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
}
} else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
if (iaxs[fr->callno]->pingtime > peer->maxms) {
ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
+ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
}
}
peer->lastms = iaxs[fr->callno]->pingtime;
using_prefs);
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
- if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
+ if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1)))
iax2_destroy(fr->callno);
else if (ies.vars) {
struct ast_datastore *variablestore;
iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
- if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
+ if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1)))
iax2_destroy(fr->callno);
else if (ies.vars) {
struct ast_datastore *variablestore;
if (peer->lastms > -1) {
ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
+ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
}
if ((callno = peer->callno) > 0) {
ast_mutex_lock(&iaxsl[callno]);
ast_string_field_set(iaxs[callno], host, pds.peer);
}
- c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? ast_channel_linkedid(requestor) : NULL);
+ c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? ast_channel_linkedid(requestor) : NULL, cai.found);
+
ast_mutex_unlock(&iaxsl[callno]);
if (c) {
ast_channel_tech_pvt_set(tmp, p);
ast_channel_tech_pvt_set(tmp2, p);
+ ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+ ast_set_flag(ast_channel_flags(tmp2), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+
p->owner = tmp;
p->chan = tmp2;
p->u_owner = ast_module_user_add(p->owner);
int authenticated, time_t start, struct sip_threadinfo *me)
{
int res, content_length, after_poll = 1, need_poll = 1;
+ size_t datalen = ast_str_strlen(req->data);
char buf[1024] = "";
int timeout = -1;
-
- /* Read in headers one line at a time */
- while (ast_str_strlen(req->data) < 4 || strncmp(REQ_OFFSET_TO_STR(req, data->used - 4), "\r\n\r\n", 4)) {
- if (!tcptls_session->client && !authenticated) {
- if ((timeout = sip_check_authtimeout(start)) < 0) {
- ast_debug(2, "SIP SSL server failed to determine authentication timeout\n");
+
+ /* Read in headers one line at a time */
+ while (datalen < 4 || strncmp(REQ_OFFSET_TO_STR(req, data->used - 4), "\r\n\r\n", 4)) {
+ if (!tcptls_session->client && !authenticated) {
+ if ((timeout = sip_check_authtimeout(start)) < 0) {
+ ast_debug(2, "SIP TLS server failed to determine authentication timeout\n");
return -1;
}
if (timeout == 0) {
- ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
+ ast_debug(2, "SIP TLS server timed out\n");
return -1;
}
} else {
after_poll = 1;
res = ast_wait_for_input(tcptls_session->fd, timeout);
if (res < 0) {
- ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
+ ast_debug(2, "SIP TLS server :: ast_wait_for_input returned %d\n", res);
return -1;
} else if (res == 0) {
/* timeout */
- ast_debug(2, "SIP TCP server timed out\n");
+ ast_debug(2, "SIP TLS server timed out\n");
return -1;
}
}
return -1;
}
ast_str_append(&req->data, 0, "%s", buf);
+
+ datalen = ast_str_strlen(req->data);
+ if (datalen > SIP_MAX_PACKET_SIZE) {
+ ast_log(LOG_WARNING, "Rejecting TLS packet from '%s' because way too large: %zu\n",
+ ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
+ return -1;
+ }
}
copy_request(reqcpy, req);
parse_request(reqcpy);
}
if (timeout == 0) {
- ast_debug(2, "SIP SSL server timed out\n");
+ ast_debug(2, "SIP TLS server timed out\n");
return -1;
}
} else {
after_poll = 1;
res = ast_wait_for_input(tcptls_session->fd, timeout);
if (res < 0) {
- ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
+ ast_debug(2, "SIP TLS server :: ast_wait_for_input returned %d\n", res);
return -1;
} else if (res == 0) {
/* timeout */
- ast_debug(2, "SIP TCP server timed out\n");
+ ast_debug(2, "SIP TLS server timed out\n");
return -1;
}
}
}
content_length -= strlen(buf);
ast_str_append(&req->data, 0, "%s", buf);
+
+ datalen = ast_str_strlen(req->data);
+ if (datalen > SIP_MAX_PACKET_SIZE) {
+ ast_log(LOG_WARNING, "Rejecting TLS packet from '%s' because way too large: %zu\n",
+ ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
+ return -1;
+ }
}
}
/*! \todo XXX If there's no Content-Length or if the content-length and what
enum message_integrity message_integrity = MESSAGE_FRAGMENT;
while (message_integrity == MESSAGE_FRAGMENT) {
+ size_t datalen;
+
if (ast_str_strlen(tcptls_session->overflow_buf) == 0) {
char readbuf[4097];
int timeout;
ast_str_append(&req->data, 0, "%s", ast_str_buffer(tcptls_session->overflow_buf));
ast_str_reset(tcptls_session->overflow_buf);
}
+
+ datalen = ast_str_strlen(req->data);
+ if (datalen > SIP_MAX_PACKET_SIZE) {
+ ast_log(LOG_WARNING, "Rejecting TCP packet from '%s' because way too large: %zu\n",
+ ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
+ return -1;
+ }
message_integrity = check_message_integrity(&req->data, &tcptls_session->overflow_buf);
}
}
me->threadid = pthread_self();
- ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
+ ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP");
/* set up pollfd to watch for reads on both the socket and the alert_pipe */
fds[0].fd = tcptls_session->fd;
}
if (timeout == 0) {
- ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
+ ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP");
goto cleanup;
}
} else {
if (ast_str_strlen(tcptls_session->overflow_buf) == 0) {
res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */
if (res < 0) {
- ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
+ ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "TLS": "TCP", res);
goto cleanup;
} else if (res == 0) {
/* timeout */
- ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
+ ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP");
goto cleanup;
}
}
}
}
- ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
+ ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP");
cleanup:
if (tcptls_session && !tcptls_session->client && !authenticated) {
}
if (p) {
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->name);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", p->name);
sip_unref_peer(p, "update_call_counter: sip_unref_peer from call counter");
}
return 0;
ast_jb_configure(tmp, &global_jbconf);
}
+ if (!i->relatedpeer) {
+ ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+ }
/* Set channel variables for this call from configuration */
for (v = i->chanvars ; v ; v = v->next) {
char valuebuf[1024];
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
register_peer_exten(peer, FALSE); /* Remove regexten */
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
/* Do we need to release this peer from memory?
Only for realtime peers and autocreated peers
ast_atomic_fetchadd_int(&p->relatedpeer->onhold, (hold ? +1 : -1));
/* Request device state update */
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->relatedpeer->name);
-
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, (ast_test_flag(ast_channel_flags(p->owner), AST_FLAG_DISABLE_DEVSTATE_CACHE) ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE),
+ "SIP/%s", p->relatedpeer->name);
+
return;
}
} else {
update_peer_lastmsgssent(peer, -1, 0);
}
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
}
if (res < 0) {
switch (res) {
ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
peer->name, s, pingtime, peer->maxms);
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
if (sip_cfg.peer_rtupdate) {
ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL);
}
/* Don't send a devstate change if nothing changed. */
if (peer->lastms > -1) {
peer->lastms = -1;
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
}
/* Try again quickly */
AST_LIST_TRAVERSE(&l->sublines, subline, list) {
ast_extension_state_add(subline->context, subline->exten, skinny_extensionstate_cb, subline->container);
}
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s", l->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
--instance;
}
break;
l->instance = 0;
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
unregister_exten(l);
- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Skinny/%s", l->name);
+ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
}
}
}
event, d->name, instance, callreference);
break;
}
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "Skinny/%s", l->name);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
return 1;
}
transmit_ringer_mode(d, SKINNY_RING_OFF);
d->hookstate = SKINNY_OFFHOOK;
- ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s", l->name);
+ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
if (sub && sub->substate == SUBSTATE_HOLD) {
return 1;
return 0;
}
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s", l->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
dumpsub(sub, 0);
return 0;
}
- ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s", l->name);
+ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
switch(event) {
case SOFTKEY_NONE:
return 0;
}
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s", l->name);
-
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
+
if (sub) {
dumpsub(sub, 1);
} else { /* No sub, maybe an SLA call */
#define SIP_MAX_HEADERS 64 /*!< Max amount of SIP headers to read */
#define SIP_MAX_LINES 256 /*!< Max amount of lines in SIP attachment (like SDP) */
+#define SIP_MAX_PACKET_SIZE 20480 /*!< Max SIP packet size */
#define SIP_MIN_PACKET 4096 /*!< Initialize size of memory to allocate for packets */
#define MAX_HISTORY_ENTRIES 50 /*!< Max entires in the history list for a sip_pvt */
;
;log_membername_as_agent = no
;
-; app_queue allows calls to members in a "Unknown" state to be treated as available
-; setting check_state_unknown = yes will cause app_queue to query the channel driver
-; to better determine the state this only applies to queues with ringinuse set
-; appropriately.
-;
-;check_state_unknown = no
-;
;[markq]
;
; A sample call queue
ast_db_put(astdb_family, data, value);
- ast_devstate_changed(state_val, "Custom:%s", data);
+ ast_devstate_changed(state_val, AST_DEVSTATE_CACHABLE, "Custom:%s", data);
return 0;
}
ast_db_put(astdb_family, dev, state);
- ast_devstate_changed(state_val, "Custom:%s", dev);
+ ast_devstate_changed(state_val, AST_DEVSTATE_CACHABLE, "Custom:%s", dev);
return CLI_SUCCESS;
}
if (dev_name <= (const char *) 1)
continue;
ast_devstate_changed(ast_devstate_val(db_entry->data),
- "Custom:%s\n", dev_name);
+ AST_DEVSTATE_CACHABLE, "Custom:%s\n", dev_name);
}
ast_db_freetree(db_tree);
db_tree = NULL;
* some non-traditional dialplans (like AGI) to continue to function.
*/
AST_FLAG_DISABLE_WORKAROUNDS = (1 << 20),
+ /*! Disable device state event caching. This allows allows channel
+ * drivers to selectively prevent device state events from being cached
+ * by certain channels such as anonymous calls which have no persistent
+ * represenatation that can be tracked.
+ */
+ AST_FLAG_DISABLE_DEVSTATE_CACHE = (1 << 21),
};
/*! \brief ast_bridge_config flags */
AST_DEVICE_TOTAL, /*/ Total num of device states, used for testing */
};
+/*! \brief Device State Cachability
+ * \note This is used to define the cachability of a device state when set.
+ */
+enum ast_devstate_cache {
+ AST_DEVSTATE_NOT_CACHABLE, /*!< This device state is not cachable */
+ AST_DEVSTATE_CACHABLE, /*!< This device state is cachable */
+};
+
/*! \brief Devicestate provider call back */
typedef enum ast_device_state (*ast_devstate_prov_cb_type)(const char *data);
* \brief Tells Asterisk the State for Device is changed
*
* \param state the new state of the device
+ * \param cachable whether this device state is cachable
* \param fmt device name like a dial string with format parameters
*
* The new state of the device will be sent off to any subscribers
* \retval 0 on success
* \retval -1 on failure
*/
-int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...)
- __attribute__((format(printf, 2, 3)));
+int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt, ...)
+ __attribute__((format(printf, 3, 4)));
/*!
* \brief Tells Asterisk the State for Device is changed
*
* \param state the new state of the device
+ * \param cachable whether this device state is cachable
* \param device device name like a dial string with format parameters
*
* The new state of the device will be sent off to any subscribers
* \retval 0 on success
* \retval -1 on failure
*/
-int ast_devstate_changed_literal(enum ast_device_state state, const char *device);
+int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device);
/*!
* \brief Tells Asterisk the State for Device is changed.
AST_EVENT_IE_PRESENCE_SUBTYPE = 0x003b,
AST_EVENT_IE_PRESENCE_MESSAGE = 0x003c,
+ /*!
+ * \brief Event non-cachability flag
+ * Used by: All events
+ * Payload type: UINT
+ */
+ AST_EVENT_IE_CACHABLE = 0x003d,
/*! \brief Must be the last IE value +1 */
- AST_EVENT_IE_TOTAL = 0x003d,
+ AST_EVENT_IE_TOTAL = 0x003e,
};
/*!
"Notification of CCSS state change to '%s', device state '%s' for device '%s'\n",
cc_state_to_string(state), ast_devstate2str(devstate), device);
- ast_devstate_changed(devstate, "ccss:%s", device);
+ ast_devstate_changed(devstate, AST_DEVSTATE_CACHABLE, "ccss:%s", device);
}
#define CC_OFFER_TIMER_DEFAULT 20 /* Seconds */
* instance is dead, we don't know the state of all other possible
* instances.
*/
- ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
+ ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE) ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), device_name);
}
ast_channel_nativeformats_set(chan, ast_format_cap_destroy(ast_channel_nativeformats(chan)));
/* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver
* for this channel is using the callback method for device state. If we pass in an actual state here
* we override what they are saying the state is and things go amuck. */
- ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
+ ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE) ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), name);
/* setstate used to conditionally report Newchannel; this is no more */
/*** DOCUMENTATION
ast_data_add_bool(tree, "BRIDGE_HANGUP_RUN", ast_test_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_HANGUP_RUN));
ast_data_add_bool(tree, "BRIDGE_HANGUP_DONT", ast_test_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_HANGUP_DONT));
ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS));
+ ast_data_add_bool(tree, "DISABLE_DEVSTATE_CACHE", ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE));
}
int ast_channel_data_add_structure(struct ast_data *tree,
struct state_change {
AST_LIST_ENTRY(state_change) list;
+ enum ast_devstate_cache cachable;
char device[1];
};
AST_LIST_ENTRY(devstate_change) entry;
uint32_t state;
struct ast_eid eid;
+ enum ast_devstate_cache cachable;
char device[1];
};
return res;
}
-static void devstate_event(const char *device, enum ast_device_state state)
+static void devstate_event(const char *device, enum ast_device_state state, int cachable)
{
struct ast_event *event;
enum ast_event_type event_type;
ast_debug(3, "device '%s' state '%d'\n", device, state);
if (!(event = ast_event_new(event_type,
- AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device,
- AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state,
- AST_EVENT_IE_END))) {
+ AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device,
+ AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state,
+ AST_EVENT_IE_CACHABLE, AST_EVENT_IE_PLTYPE_UINT, cachable,
+ AST_EVENT_IE_END))) {
return;
}
- ast_event_queue_and_cache(event);
+ if (cachable) {
+ ast_event_queue_and_cache(event);
+ } else {
+ ast_event_queue(event);
+ }
}
/*! Called by the state change thread to find out what the state is, and then
* to queue up the state change event */
-static void do_state_change(const char *device)
+static void do_state_change(const char *device, int cachable)
{
enum ast_device_state state;
ast_debug(3, "Changing state for %s - state %d (%s)\n", device, state, ast_devstate2str(state));
- devstate_event(device, state);
+ devstate_event(device, state, cachable);
}
-int ast_devstate_changed_literal(enum ast_device_state state, const char *device)
+int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
{
struct state_change *change;
*/
if (state != AST_DEVICE_UNKNOWN) {
- devstate_event(device, state);
+ devstate_event(device, state, cachable);
} else if (change_thread == AST_PTHREADT_NULL || !(change = ast_calloc(1, sizeof(*change) + strlen(device)))) {
/* we could not allocate a change struct, or */
/* there is no background thread, so process the change now */
- do_state_change(device);
+ do_state_change(device, cachable);
} else {
/* queue the change */
strcpy(change->device, device);
+ change->cachable = cachable;
AST_LIST_LOCK(&state_changes);
AST_LIST_INSERT_TAIL(&state_changes, change, list);
ast_cond_signal(&change_pending);
int ast_device_state_changed_literal(const char *dev)
{
- return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, dev);
+ return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, dev);
}
-int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...)
+int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt, ...)
{
char buf[AST_MAX_EXTENSION];
va_list ap;
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- return ast_devstate_changed_literal(state, buf);
+ return ast_devstate_changed_literal(state, cachable, buf);
}
int ast_device_state_changed(const char *fmt, ...)
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, buf);
+ return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, buf);
}
/*! \brief Go through the dev state change queue and update changes in the dev state thread */
/* Process each state change */
while ((current = next)) {
next = AST_LIST_NEXT(current, list);
- do_state_change(current->device);
+ do_state_change(current->device, current->cachable);
ast_free(current);
}
}
collection->num_states++;
}
-static void process_collection(const char *device, struct change_collection *collection)
+static void process_collection(const char *device, enum ast_devstate_cache cachable, struct change_collection *collection)
{
int i;
struct ast_devstate_aggregate agg;
return;
}
- ast_event_queue_and_cache(event);
+ if (cachable) {
+ ast_event_queue_and_cache(event);
+ } else {
+ ast_event_queue(event);
+ }
}
static void handle_devstate_change(struct devstate_change *sc)
/* Populate the collection of device states from the cache */
ast_event_dump_cache(tmp_sub);
- process_collection(sc->device, &collection);
+ process_collection(sc->device, sc->cachable, &collection);
ast_event_sub_destroy(tmp_sub);
}
const char *device;
const struct ast_eid *eid;
uint32_t state;
+ enum ast_devstate_cache cachable = AST_DEVSTATE_CACHABLE;
device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID);
state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
+ cachable = ast_event_get_ie_uint(event, AST_EVENT_IE_CACHABLE);
if (ast_strlen_zero(device) || !eid) {
ast_log(LOG_ERROR, "Invalid device state change event received\n");
strcpy(sc->device, device);
sc->eid = *eid;
sc->state = state;
+ sc->cachable = cachable;
ast_mutex_lock(&devstate_collector.lock);
AST_LIST_INSERT_TAIL(&devstate_collector.devstate_change_q, sc, entry);
[AST_EVENT_IE_RECEIVED_HASH] = { AST_EVENT_IE_PLTYPE_STR, "ReceivedHash" },
[AST_EVENT_IE_USING_PASSWORD] = { AST_EVENT_IE_PLTYPE_UINT, "UsingPassword" },
[AST_EVENT_IE_ATTEMPTED_TRANSPORT] = { AST_EVENT_IE_PLTYPE_STR, "AttemptedTransport" },
-
+ [AST_EVENT_IE_CACHABLE] = { AST_EVENT_IE_PLTYPE_UINT, "Cachable" },
};
const char *ast_event_get_type_name(const struct ast_event *event)
ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'",
exten, context, ast_devstate2str(state));
- ast_devstate_changed(state, "park:%s@%s", exten, context);
+ ast_devstate_changed(state, AST_DEVSTATE_CACHABLE, "park:%s@%s", exten, context);
}
/*! \brief metermaids callback from devicestate.c */
int content_length = 0;
struct ast_variable *v, *post_vars=NULL, *prev = NULL;
char *buf, *var, *val;
+ int res;
for (v = headers; v; v = v->next) {
if (!strcasecmp(v->name, "Content-Type")) {
for (v = headers; v; v = v->next) {
if (!strcasecmp(v->name, "Content-Length")) {
- content_length = atoi(v->value) + 1;
+ content_length = atoi(v->value);
break;
}
}
- if (!content_length) {
+ if (content_length <= 0) {
return NULL;
}
- buf = ast_alloca(content_length);
- if (!fgets(buf, content_length, ser->f)) {
+ buf = ast_malloc(content_length + 1);
+ if (!buf) {
return NULL;
}
+ res = fread(buf, 1, content_length, ser->f);
+ if (res < content_length) {
+ /* Error, distinguishable by ferror() or feof(), but neither
+ * is good. */
+ goto done;
+ }
+ buf[content_length] = '\0';
+
while ((val = strsep(&buf, "&"))) {
var = strsep(&val, "=");
if (val) {
prev = v;
}
}
+
+done:
+ ast_free(buf);
return post_vars;
}
program_prefix=${target_alias}-
ac_config_headers="$ac_config_headers pjlib/include/pj/compat/os_auto.h pjlib/include/pj/compat/m_auto.h pjmedia/include/pjmedia/config_auto.h pjmedia/include/pjmedia-codec/config_auto.h pjsip/include/pjsip/sip_autoconf.h"
-ac_config_files="$ac_config_files build.mak build/os-auto.mak build/cc-auto.mak pjlib/build/os-auto.mak pjlib-util/build/os-auto.mak pjmedia/build/os-auto.mak pjsip/build/os-auto.mak third_party/build/os-auto.mak third_party/build/portaudio/os-auto.mak"
+ac_config_files="$ac_config_files build.mak build/os-auto.mak pjlib/build/os-auto.mak pjlib-util/build/os-auto.mak pjmedia/build/os-auto.mak pjsip/build/os-auto.mak third_party/build/os-auto.mak third_party/build/portaudio/os-auto.mak"
"pjsip/include/pjsip/sip_autoconf.h") CONFIG_HEADERS="$CONFIG_HEADERS pjsip/include/pjsip/sip_autoconf.h" ;;
"build.mak") CONFIG_FILES="$CONFIG_FILES build.mak" ;;
"build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES build/os-auto.mak" ;;
- "build/cc-auto.mak") CONFIG_FILES="$CONFIG_FILES build/cc-auto.mak" ;;
"pjlib/build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES pjlib/build/os-auto.mak" ;;
"pjlib-util/build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES pjlib-util/build/os-auto.mak" ;;
"pjmedia/build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES pjmedia/build/os-auto.mak" ;;
])
AC_CONFIG_FILES([build.mak
build/os-auto.mak
- build/cc-auto.mak
pjlib/build/os-auto.mak
pjlib-util/build/os-auto.mak
pjmedia/build/os-auto.mak
#
-include cc-$(CC_NAME).mak
-#
-# Include auto configured compiler specification.
-# This will override the compiler settings above.
-# Currently this is made OPTIONAL, to prevent people
-# from getting errors because they don't re-run ./configure
-# after downloading new PJSIP.
-#
--include $(PJDIR)/build/cc-auto.mak
-
#
# Include global machine specific definitions
#
* but haven't hit the end event yet, go ahead and set the devicestate to the current busy status */
if (event->bs_start_sched < 0 && event->bs_end_sched >= 0) {
if (!calendar_is_busy(event->owner)) {
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Calendar:%s", event->owner->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
} else {
- ast_devstate_changed(AST_DEVICE_BUSY, "Calendar:%s", event->owner->name);
+ ast_devstate_changed(AST_DEVICE_BUSY, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
}
}
/* We can have overlapping events, so ignore the event->busy_state and check busy state
* based on all events in the calendar */
if (!calendar_is_busy(event->owner)) {
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Calendar:%s", event->owner->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
} else {
- ast_devstate_changed(AST_DEVICE_BUSY, "Calendar:%s", event->owner->name);
+ ast_devstate_changed(AST_DEVICE_BUSY, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
}
event = ast_calendar_unref_event(event);
static void aji_create_affiliations(struct aji_client *client, const char *node);
static iks* aji_pubsub_iq_create(struct aji_client *client, const char *type);
static void aji_publish_device_state(struct aji_client *client, const char * device,
- const char *device_state);
+ const char *device_state, unsigned int cachable);
static int aji_handle_pubsub_error(void *data, ikspak *pak);
static int aji_handle_pubsub_event(void *data, ikspak *pak);
static void aji_pubsub_subscribe(struct aji_client *client, const char *node);
static void aji_devstate_cb(const struct ast_event *ast_event, void *data);
static void aji_mwi_cb(const struct ast_event *ast_event, void *data);
static iks* aji_build_publish_skeleton(struct aji_client *client, const char *node,
- const char *event_type);
+ const char *event_type, unsigned int cachable);
/* No transports in this version */
/*
static int aji_create_transport(char *label, struct aji_client *client);
*/
static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
{
- char *aux = NULL, *parse = NULL;
+ char *parse = NULL;
int timeout;
int jidlen, resourcelen;
struct timeval start;
continue;
}
found = 1;
- aux = ast_strdupa(tmp->message);
+ ast_copy_string(buf, tmp->message, buflen);
AST_LIST_REMOVE_CURRENT(list);
aji_message_destroy(tmp);
break;
ast_log(LOG_NOTICE, "Timed out : no message received from %s\n", args.jid);
return -1;
}
- ast_copy_string(buf, aux, buflen);
return 0;
}
{
const char *device;
const char *device_state;
+ unsigned int cachable;
struct aji_client *client;
if (ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(ast_event, AST_EVENT_IE_EID)))
{
client = ASTOBJ_REF((struct aji_client *) data);
device = ast_event_get_ie_str(ast_event, AST_EVENT_IE_DEVICE);
device_state = ast_devstate_str(ast_event_get_ie_uint(ast_event, AST_EVENT_IE_STATE));
- aji_publish_device_state(client, device, device_state);
+ cachable = ast_event_get_ie_uint(ast_event, AST_EVENT_IE_CACHABLE);
+ aji_publish_device_state(client, device, device_state, cachable);
ASTOBJ_UNREF(client, ast_aji_client_destroy);
}
*/
static int aji_handle_pubsub_event(void *data, ikspak *pak)
{
- char *item_id, *device_state, *context;
+ char *item_id, *device_state, *context, *cachable_str;
int oldmsgs, newmsgs;
iks *item, *item_content;
struct ast_eid pubsub_eid;
struct ast_event *event;
+ unsigned int cachable = AST_DEVSTATE_CACHABLE;
+
item = iks_find(iks_find(iks_find(pak->x, "event"), "items"), "item");
if (!item) {
ast_log(LOG_ERROR, "Could not parse incoming PubSub event\n");
}
if (!strcasecmp(iks_name(item_content), "state")) {
device_state = iks_find_cdata(item, "state");
+ if ((cachable_str = iks_find_cdata(item, "cachable"))) {
+ sscanf(cachable_str, "%30d", &cachable);
+ }
if (!(event = ast_event_new(AST_EVENT_DEVICE_STATE_CHANGE,
- AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, item_id, AST_EVENT_IE_STATE,
- AST_EVENT_IE_PLTYPE_UINT, ast_devstate_val(device_state), AST_EVENT_IE_EID,
- AST_EVENT_IE_PLTYPE_RAW, &pubsub_eid, sizeof(pubsub_eid),
- AST_EVENT_IE_END))) {
+ AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, item_id, AST_EVENT_IE_STATE,
+ AST_EVENT_IE_PLTYPE_UINT, ast_devstate_val(device_state), AST_EVENT_IE_EID,
+ AST_EVENT_IE_PLTYPE_RAW, &pubsub_eid, sizeof(pubsub_eid),
+ AST_EVENT_IE_END))) {
return IKS_FILTER_EAT;
}
} else if (!strcasecmp(iks_name(item_content), "mailbox")) {
iks_name(item_content));
return IKS_FILTER_EAT;
}
- ast_event_queue_and_cache(event);
+
+ if (cachable == AST_DEVSTATE_CACHABLE) {
+ ast_event_queue_and_cache(event);
+ } else {
+ ast_event_queue(event);
+ }
+
return IKS_FILTER_EAT;
}
* \return iks *
*/
static iks* aji_build_publish_skeleton(struct aji_client *client, const char *node,
- const char *event_type)
+ const char *event_type, unsigned int cachable)
{
iks *request = aji_pubsub_iq_create(client, "set");
iks *pubsub, *publish, *item;
}
item = iks_insert(publish, "item");
iks_insert_attrib(item, "id", node);
- return item;
+ if (cachable == AST_DEVSTATE_NOT_CACHABLE) {
+ iks *options, *x, *field_form_type, *field_persist;
+
+ options = iks_insert(pubsub, "publish-options");
+ x = iks_insert(options, "x");
+ iks_insert_attrib(x, "xmlns", "jabber:x:data");
+ iks_insert_attrib(x, "type", "submit");
+ field_form_type = iks_insert(x, "field");
+ iks_insert_attrib(field_form_type, "var", "FORM_TYPE");
+ iks_insert_attrib(field_form_type, "type", "hidden");
+ iks_insert_cdata(iks_insert(field_form_type, "value"), "http://jabber.org/protocol/pubsub#publish-options", 0);
+ field_persist = iks_insert(x, "field");
+ iks_insert_attrib(field_persist, "var", "pubsub#persist_items");
+ iks_insert_cdata(iks_insert(field_persist, "value"), "0", 1);
+ }
+
+ return item;
}
/*!
* \return void
*/
static void aji_publish_device_state(struct aji_client *client, const char *device,
- const char *device_state)
+ const char *device_state, unsigned int cachable)
{
- iks *request = aji_build_publish_skeleton(client, device, "device_state");
+ iks *request = aji_build_publish_skeleton(client, device, "device_state", cachable);
iks *state;
- char eid_str[20];
+ char eid_str[20], cachable_str[2];
if (ast_test_flag(&pubsubflags, AJI_PUBSUB_AUTOCREATE)) {
if (ast_test_flag(&pubsubflags, AJI_XEP0248)) {
aji_create_pubsub_node(client, "leaf", device, "device_state");
state = iks_insert(request, "state");
iks_insert_attrib(state, "xmlns", "http://asterisk.org");
iks_insert_attrib(state, "eid", eid_str);
+ snprintf(cachable_str, sizeof(cachable_str), "%u", cachable);
+ iks_insert_attrib(state, "cachable", cachable_str);
iks_insert_cdata(state, device_state, strlen(device_state));
ast_aji_send(client, iks_root(request));
iks_delete(request);
char eid_str[20];
iks *mailbox_node, *request;
snprintf(full_mailbox, sizeof(full_mailbox), "%s@%s", mailbox, context);
- request = aji_build_publish_skeleton(client, full_mailbox, "message_waiting");
+ request = aji_build_publish_skeleton(client, full_mailbox, "message_waiting", 1);
ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
mailbox_node = iks_insert(request, "mailbox");
iks_insert_attrib(mailbox_node, "xmlns", "http://asterisk.org");
* \return iks *
*/
static iks* xmpp_pubsub_build_publish_skeleton(struct ast_xmpp_client *client, const char *node,
- const char *event_type)
+ const char *event_type, unsigned int cachable)
{
RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
iks *request, *pubsub, *publish, *item;
item = iks_insert(publish, "item");
iks_insert_attrib(item, "id", node);
+ if (cachable == AST_DEVSTATE_NOT_CACHABLE) {
+ iks *options, *x, *field_form_type, *field_persist;
+
+ options = iks_insert(pubsub, "publish-options");
+ x = iks_insert(options, "x");
+ iks_insert_attrib(x, "xmlns", "jabber:x:data");
+ iks_insert_attrib(x, "type", "submit");
+ field_form_type = iks_insert(x, "field");
+ iks_insert_attrib(field_form_type, "var", "FORM_TYPE");
+ iks_insert_attrib(field_form_type, "type", "hidden");
+ iks_insert_cdata(iks_insert(field_form_type, "value"), "http://jabber.org/protocol/pubsub#publish-options", 0);
+ field_persist = iks_insert(x, "field");
+ iks_insert_attrib(field_persist, "var", "pubsub#persist_items");
+ iks_insert_cdata(iks_insert(field_persist, "value"), "0", 1);
+ }
+
return item;
}
snprintf(full_mailbox, sizeof(full_mailbox), "%s@%s", mailbox, context);
- if (!(request = xmpp_pubsub_build_publish_skeleton(client, full_mailbox, "message_waiting"))) {
+ if (!(request = xmpp_pubsub_build_publish_skeleton(client, full_mailbox, "message_waiting", AST_DEVSTATE_CACHABLE))) {
return;
}
* \return void
*/
static void xmpp_pubsub_publish_device_state(struct ast_xmpp_client *client, const char *device,
- const char *device_state)
+ const char *device_state, unsigned int cachable)
{
RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
iks *request, *state;
- char eid_str[20];
+ char eid_str[20], cachable_str[2];
- if (!cfg || !cfg->global || !(request = xmpp_pubsub_build_publish_skeleton(client, device, "device_state"))) {
+ if (!cfg || !cfg->global || !(request = xmpp_pubsub_build_publish_skeleton(client, device, "device_state", cachable))) {
return;
}
state = iks_insert(request, "state");
iks_insert_attrib(state, "xmlns", "http://asterisk.org");
iks_insert_attrib(state, "eid", eid_str);
+ snprintf(cachable_str, sizeof(cachable_str), "%u", cachable);
+ iks_insert_attrib(state, "cachable", cachable_str);
iks_insert_cdata(state, device_state, strlen(device_state));
ast_xmpp_client_send(client, iks_root(request));
iks_delete(request);
{
struct ast_xmpp_client *client = data;
const char *device, *device_state;
+ unsigned int cachable;
if (ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(ast_event, AST_EVENT_IE_EID))) {
/* If the event didn't originate from this server, don't send it back out. */
device = ast_event_get_ie_str(ast_event, AST_EVENT_IE_DEVICE);
device_state = ast_devstate_str(ast_event_get_ie_uint(ast_event, AST_EVENT_IE_STATE));
- xmpp_pubsub_publish_device_state(client, device, device_state);
+ cachable = ast_event_get_ie_uint(ast_event, AST_EVENT_IE_CACHABLE);
+ xmpp_pubsub_publish_device_state(client, device, device_state, cachable);
}
/*!
*/
static int xmpp_pubsub_handle_event(void *data, ikspak *pak)
{
- char *item_id, *device_state, *context;
+ char *item_id, *device_state, *context, *cachable_str;
int oldmsgs, newmsgs;
iks *item, *item_content;
struct ast_eid pubsub_eid;
struct ast_event *event;
+ unsigned int cachable = AST_DEVSTATE_CACHABLE;
item = iks_find(iks_find(iks_find(pak->x, "event"), "items"), "item");
if (!item) {
ast_log(LOG_ERROR, "Could not parse incoming PubSub event\n");
}
if (!strcasecmp(iks_name(item_content), "state")) {
device_state = iks_find_cdata(item, "state");
+ if ((cachable_str = iks_find_cdata(item, "cachable"))) {
+ sscanf(cachable_str, "%30d", &cachable);
+ }
if (!(event = ast_event_new(AST_EVENT_DEVICE_STATE_CHANGE,
AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, item_id, AST_EVENT_IE_STATE,
AST_EVENT_IE_PLTYPE_UINT, ast_devstate_val(device_state), AST_EVENT_IE_EID,
iks_name(item_content));
return IKS_FILTER_EAT;
}
- ast_event_queue_and_cache(event);
+
+ if (cachable == AST_DEVSTATE_CACHABLE) {
+ ast_event_queue_and_cache(event);
+ } else {
+ ast_event_queue(event);
+ }
+
return IKS_FILTER_EAT;
}
{
RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
- char *aux = NULL, *parse = NULL;
+ char *parse = NULL;
int timeout, jidlen, resourcelen, found = 0;
struct timeval start;
long diff = 0;
continue;
}
found = 1;
- aux = ast_strdupa(message->message);
+ ast_copy_string(buf, message->message, buflen);
AST_LIST_REMOVE_CURRENT(list);
xmpp_message_destroy(message);
break;
ast_log(LOG_NOTICE, "Timed out : no message received from %s\n", args.jid);
return -1;
}
- ast_copy_string(buf, aux, buflen);
return 0;
}