Compare commits

...

30 Commits

Author SHA1 Message Date
Asterisk Autobuilder
2301137a1a Importing release summary for 1.8.9.2 release.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.2@354653 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-02-09 19:25:45 +00:00
Matthew Jordan
fc5bbd49d1 Committing r354495, 354542, 354547 for 1.8.9.2
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.2@354641 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-02-09 19:12:53 +00:00
Matthew Jordan
c922f2d636 Create tag for 1.8.9.2
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.2@354575 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-02-09 17:26:12 +00:00
Asterisk Autobuilder
4e02eb640c Importing release summary for 1.8.9.1 release.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.1@354277 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-02-07 15:48:42 +00:00
Jason Parker
51ced73126 Add .lastclean
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.1@354276 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-02-07 15:47:17 +00:00
Jason Parker
5585f1391e Remove old summary files.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.1@354213 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-02-06 21:46:49 +00:00
Asterisk Autobuilder
749814d4e4 Importing release summary for 1.8.9.1 release.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.1@354212 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-02-06 21:43:49 +00:00
Jason Parker
36f22d86bf Update .version and ChangeLog. Merge fixes.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.1@354210 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-02-06 21:40:37 +00:00
Jason Parker
f3c8b03e8a Create tag for Asterisk 1.8.9.1
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.1@354203 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-02-06 21:25:34 +00:00
Asterisk Autobuilder
4ca7f9eb94 Importing release summary for 1.8.9.0 release.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0@353026 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-27 20:21:58 +00:00
Asterisk Autobuilder
37df71eb0d Updated .version and ChangeLog for 1.8.9.0
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0@353013 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-27 20:15:59 +00:00
Asterisk Autobuilder
d8f7594af1 Created tag for 1.8.9.0
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0@352952 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-27 16:50:54 +00:00
Asterisk Autobuilder
5a9db09396 Importing release summary for 1.8.9.0-rc3 release.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc3@352345 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-24 17:47:01 +00:00
Asterisk Autobuilder
950552a797 Updated test results
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc3@352344 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-24 17:44:15 +00:00
Matthew Jordan
16bfc9c8b7 Commit changes: r349731, r352199, r352014, r351504
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc3@352286 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-24 16:19:31 +00:00
Matthew Jordan
61643ac1b9 Create 1.8.9.0-rc3
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc3@352284 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-24 14:44:58 +00:00
Matthew Jordan
9453ae0244 Updated summaries to proper issues
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc2@350728 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-13 21:28:49 +00:00
Asterisk Autobuilder
af0a3adce7 Importing release summary for 1.8.9.0-rc2 release.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc2@350696 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-13 21:20:29 +00:00
Asterisk Autobuilder
2feee9d030 Remove summary files
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc2@350682 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-13 21:16:34 +00:00
Matthew Jordan
ab5779c1bd Merged 1.8.9.0-rc2 blockers
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc2@350606 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-13 17:48:23 +00:00
Matthew Jordan
e8e410a260 Create tag for 1.8.9.0-rc2
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc2@350588 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-13 17:30:06 +00:00
Asterisk Autobuilder
71f88c493a Importing release summary for 1.8.9.0-rc1 release.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc1@349406 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-12-30 15:58:21 +00:00
Asterisk Autobuilder
b15d9d3297 Somehow no .version file was made - adding it
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc1@349405 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-12-30 15:51:20 +00:00
Asterisk Autobuilder
98e7f2d541 Updated release date
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc1@349403 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-12-30 15:25:30 +00:00
Asterisk Autobuilder
f052d93bc3 Updated ChangeLog with test results
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc1@349400 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-12-29 20:58:20 +00:00
Asterisk Autobuilder
64c6dd9b12 Importing release summary for 1.8.9.0-rc1 release.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc1@349395 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-12-29 19:20:32 +00:00
Asterisk Autobuilder
1f568fa72c Add change log for 1.8.9.0
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc1@349394 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-12-29 19:19:18 +00:00
Asterisk Autobuilder
a4c8ab1149 Use autotagged externals
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc1@349393 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-12-29 17:30:06 +00:00
Asterisk Autobuilder
d89e5b1eb3 Importing release summary for 1.8.9.0-rc1 release.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc1@349392 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-12-29 17:29:54 +00:00
Asterisk Autobuilder
47d9f12ab5 Creating tag for the release of asterisk-1.8.9.0-rc1
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/1.8.9.0-rc1@349391 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-12-29 17:28:23 +00:00
11 changed files with 36776 additions and 147 deletions

3
.lastclean Normal file
View File

@@ -0,0 +1,3 @@
39

1
.version Normal file
View File

@@ -0,0 +1 @@
1.8.9.2

36347
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -140,6 +140,7 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
}
/* Save the CallerID because the masquerade turns chan into a ZOMBIE. */
ast_party_id_init(&caller_id);
ast_channel_lock(chan);
ast_party_id_copy(&caller_id, &chan->caller.id);
ast_channel_unlock(chan);

View File

@@ -2346,9 +2346,8 @@ static struct call_queue *load_realtime_queue(const char *queuename)
if (queue_vars) {
member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", queuename, SENTINEL);
if (!member_config) {
ast_log(LOG_ERROR, "no queue_members defined in your config (extconfig.conf).\n");
ast_variables_destroy(queue_vars);
return NULL;
ast_debug(1, "No queue_members defined in config extconfig.conf\n");
member_config = ast_config_new();
}
}
if (q) {

View File

@@ -0,0 +1,74 @@
<!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-1.8.9.2</title></head>
<body>
<h1 align="center"><a name="top">Release Summary</a></h1>
<h3 align="center">asterisk-1.8.9.2</h3>
<h3 align="center">Date: 2012-02-09</h3>
<h3 align="center">&lt;asteriskteam@digium.com&gt;</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="#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-1.8.9.1.</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>
2 mjordan<br/>
2 rmudgett<br/>
1 jrose<br/>
1 mmichelson<br/>
1 russell<br/>
1 twilson<br/>
</td>
<td>
</td>
<td>
</td>
</tr>
</table>
<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/1.8?view=revision&revision=354216">354216</a></td><td>rmudgett</td><td>Improved documentation of CLI "dialplan add extension" command.</td>
<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-19222">ASTERISK-19222</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/1.8?view=revision&revision=354263">354263</a></td><td>jrose</td><td>Fix column duplication bug in module reload for cdr_pgsql.</td>
<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-19216">ASTERISK-19216</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/1.8?view=revision&revision=354348">354348</a></td><td>twilson</td><td>Fix multiple SIP realtime issues</td>
<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-19172">ASTERISK-19172</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/1.8?view=revision&revision=354492">354492</a></td><td>russell</td><td>Remove some unnecessary locking from ast_hangup().</td>
<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/1.8?view=revision&revision=354495">354495</a></td><td>rmudgett</td><td>Fix crash in ParkAndAnnounce.</td>
<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-19311">ASTERISK-19311</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/1.8?view=revision&revision=354542">354542</a></td><td>mjordan</td><td>Fix SIP INFO DTMF handling for non-numeric codes</td>
<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-18924">ASTERISK-18924</a>, <a href="https://issues.asterisk.org/jira/browse/ASTERISK-19290">ASTERISK-19290</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/1.8?view=revision&revision=354545">354545</a></td><td>mmichelson</td><td>Adding reload support to res_fax.so</td>
<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-16712">ASTERISK-16712</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/1.8?view=revision&revision=354547">354547</a></td><td>mjordan</td><td>Clean-up of minor formatting issues in r354542/3/4</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>
CHANGES | 4
apps/app_parkandannounce.c | 1
cdr/cdr_pgsql.c | 132 ++++++++++++------------
channels/chan_sip.c | 115 +++++++--------------
contrib/realtime/postgresql/realtime.sql | 8 +
main/channel.c | 39 +++----
pbx/pbx_config.c | 57 +++++-----
res/res_fax.c | 168 +++++++++++++++++++++----------
8 files changed, 291 insertions(+), 233 deletions(-)
</pre><br/>
<hr/>
</body>
</html>

View File

@@ -0,0 +1,119 @@
Release Summary
asterisk-1.8.9.2
Date: 2012-02-09
<asteriskteam@digium.com>
----------------------------------------------------------------------
Table of Contents
1. Summary
2. Contributors
3. Other Changes
4. 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-1.8.9.1.
----------------------------------------------------------------------
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
2 mjordan
2 rmudgett
1 jrose
1 mmichelson
1 russell
1 twilson
----------------------------------------------------------------------
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 |
|----------+------------+----------------------------+-------------------|
| | | Improved documentation of | |
| 354216 | rmudgett | CLI "dialplan add | ASTERISK-19222 |
| | | extension" command. | |
|----------+------------+----------------------------+-------------------|
| | | Fix column duplication bug | |
| 354263 | jrose | in module reload for | ASTERISK-19216 |
| | | cdr_pgsql. | |
|----------+------------+----------------------------+-------------------|
| 354348 | twilson | Fix multiple SIP realtime | ASTERISK-19172 |
| | | issues | |
|----------+------------+----------------------------+-------------------|
| 354492 | russell | Remove some unnecessary | |
| | | locking from ast_hangup(). | |
|----------+------------+----------------------------+-------------------|
| 354495 | rmudgett | Fix crash in | ASTERISK-19311 |
| | | ParkAndAnnounce. | |
|----------+------------+----------------------------+-------------------|
| 354542 | mjordan | Fix SIP INFO DTMF handling | ASTERISK-18924, |
| | | for non-numeric codes | ASTERISK-19290 |
|----------+------------+----------------------------+-------------------|
| 354545 | mmichelson | Adding reload support to | ASTERISK-16712 |
| | | res_fax.so | |
|----------+------------+----------------------------+-------------------|
| | | Clean-up of minor | |
| 354547 | mjordan | formatting issues in | |
| | | r354542/3/4 | |
+------------------------------------------------------------------------+
----------------------------------------------------------------------
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.
CHANGES | 4
apps/app_parkandannounce.c | 1
cdr/cdr_pgsql.c | 132 ++++++++++++------------
channels/chan_sip.c | 115 +++++++--------------
contrib/realtime/postgresql/realtime.sql | 8 +
main/channel.c | 39 +++----
pbx/pbx_config.c | 57 +++++-----
res/res_fax.c | 168 +++++++++++++++++++++----------
8 files changed, 291 insertions(+), 233 deletions(-)
----------------------------------------------------------------------

View File

@@ -1,7 +1,7 @@
/*
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 1999 - 2006, Digium, Inc.
* Copyright (C) 1999 - 2012, Digium, Inc.
*
* Mark Spencer <markster@digium.com>
*
@@ -374,6 +374,43 @@ static const struct ast_channel_tech agent_tech = {
.set_base_channel = agent_set_base_channel,
};
/*!
* \brief Locks the owning channel for a LOCKED pvt while obeying locking order. The pvt
* must enter this function locked and will be returned locked, but this function will
* unlock the pvt for a short time, so it can't be used while expecting the pvt to remain
* static. If function returns a non NULL channel, it will need to be unlocked and
* unrefed once it is no longer needed.
*
* \param pvt Pointer to the LOCKED agent_pvt for which the owner is needed
* \ret locked channel which owns the pvt at the time of completion. NULL if not available.
*/
static struct ast_channel *agent_lock_owner(struct agent_pvt *pvt)
{
struct ast_channel *owner;
for (;;) {
if (!pvt->owner) { /* No owner. Nothing to do. */
return NULL;
}
/* If we don't ref the owner, it could be killed when we unlock the pvt. */
owner = ast_channel_ref(pvt->owner);
/* Locking order requires us to lock channel, then pvt. */
ast_mutex_unlock(&pvt->lock);
ast_channel_lock(owner);
ast_mutex_lock(&pvt->lock);
/* Check if owner changed during pvt unlock period */
if (owner != pvt->owner) { /* Channel changed. Unref and do another pass. */
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
} else { /* Channel stayed the same. Return it. */
return owner;
}
}
}
/*!
* Adds an agent to the global list of agents.
*
@@ -554,7 +591,11 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
struct ast_frame *f = NULL;
static struct ast_frame answer_frame = { AST_FRAME_CONTROL, { AST_CONTROL_ANSWER } };
int cur_time = time(NULL);
struct ast_channel *owner;
ast_mutex_lock(&p->lock);
owner = agent_lock_owner(p);
CHECK_FORMATS(ast, p);
if (!p->start) {
p->start = cur_time;
@@ -584,13 +625,11 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
int howlong = cur_time - p->start;
if (p->autologoff && (howlong >= p->autologoff)) {
ast_log(LOG_NOTICE, "Agent '%s' didn't answer/confirm within %d seconds (waited %d)\n", p->name, p->autologoff, howlong);
if (p->owner || p->chan) {
while (p->owner && ast_channel_trylock(p->owner)) {
DEADLOCK_AVOIDANCE(&p->lock);
}
if (p->owner) {
ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
ast_channel_unlock(p->owner);
if (owner || p->chan) {
if (owner) {
ast_softhangup(owner, AST_SOFTHANGUP_EXPLICIT);
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
}
while (p->chan && ast_channel_trylock(p->chan)) {
@@ -652,6 +691,11 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
}
}
if (owner) {
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
}
CLEANUP(ast,p);
if (p->chan && !p->chan->_bridge) {
if (strcasecmp(p->chan->tech->type, "Local")) {
@@ -887,6 +931,14 @@ int agent_set_base_channel(struct ast_channel *chan, struct ast_channel *base)
static int agent_hangup(struct ast_channel *ast)
{
struct agent_pvt *p = ast->tech_pvt;
struct ast_channel *indicate_chan = NULL;
char *tmp_moh; /* moh buffer for indicating after unlocking p */
if (p->pending) {
AST_LIST_LOCK(&agents);
AST_LIST_REMOVE(&agents, p, list);
AST_LIST_UNLOCK(&agents);
}
ast_mutex_lock(&p->lock);
p->owner = NULL;
@@ -909,7 +961,7 @@ static int agent_hangup(struct ast_channel *ast)
if (p->start && (ast->_state != AST_STATE_UP)) {
p->start = 0;
} else
p->start = 0;
p->start = 0;
if (p->chan) {
p->chan->_bridge = NULL;
/* If they're dead, go ahead and hang up on the agent now */
@@ -918,15 +970,21 @@ static int agent_hangup(struct ast_channel *ast)
ast_softhangup(p->chan, AST_SOFTHANGUP_EXPLICIT);
ast_channel_unlock(p->chan);
} else if (p->loginstart) {
ast_channel_lock(p->chan);
ast_indicate_data(p->chan, AST_CONTROL_HOLD,
S_OR(p->moh, NULL),
!ast_strlen_zero(p->moh) ? strlen(p->moh) + 1 : 0);
ast_channel_unlock(p->chan);
indicate_chan = ast_channel_ref(p->chan);
tmp_moh = ast_strdupa(p->moh);
}
}
ast_mutex_unlock(&p->lock);
if (indicate_chan) {
ast_channel_lock(indicate_chan);
ast_indicate_data(indicate_chan, AST_CONTROL_HOLD,
S_OR(tmp_moh, NULL),
!ast_strlen_zero(tmp_moh) ? strlen(tmp_moh) + 1 : 0);
ast_channel_unlock(indicate_chan);
indicate_chan = ast_channel_unref(indicate_chan);
}
/* Only register a device state change if the agent is still logged in */
if (!p->loginstart) {
p->logincallerid[0] = '\0';
@@ -934,11 +992,6 @@ static int agent_hangup(struct ast_channel *ast)
ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
}
if (p->pending) {
AST_LIST_LOCK(&agents);
AST_LIST_REMOVE(&agents, p, list);
AST_LIST_UNLOCK(&agents);
}
if (p->abouttograb) {
/* Let the "about to grab" thread know this isn't valid anymore, and let it
kill it later */
@@ -1491,6 +1544,8 @@ static force_inline int powerof(unsigned int d)
/*!
* Lists agents and their status to the Manager API.
* It is registered on load_module() and it gets called by the manager backend.
* This function locks both the pvt and the channel that owns it for a while, but
* does not keep these locks.
* \param s
* \param m
* \returns
@@ -1513,7 +1568,9 @@ static int action_agents(struct mansession *s, const struct message *m)
astman_send_ack(s, m, "Agents will follow");
AST_LIST_LOCK(&agents);
AST_LIST_TRAVERSE(&agents, p, list) {
ast_mutex_lock(&p->lock);
struct ast_channel *owner;
ast_mutex_lock(&p->lock);
owner = agent_lock_owner(p);
/* Status Values:
AGENT_LOGGEDOFF - Agent isn't logged in
@@ -1528,16 +1585,14 @@ static int action_agents(struct mansession *s, const struct message *m)
if (p->chan) {
loginChan = ast_strdupa(p->chan->name);
if (p->owner && p->owner->_bridge) {
if (owner && owner->_bridge) {
talkingto = S_COR(p->chan->caller.id.number.valid,
p->chan->caller.id.number.str, "n/a");
ast_channel_lock(p->owner);
if ((bridge = ast_bridged_channel(p->owner))) {
if ((bridge = ast_bridged_channel(owner))) {
talkingtoChan = ast_strdupa(bridge->name);
} else {
talkingtoChan = "n/a";
}
ast_channel_unlock(p->owner);
status = "AGENT_ONCALL";
} else {
talkingto = "n/a";
@@ -1551,6 +1606,11 @@ static int action_agents(struct mansession *s, const struct message *m)
status = "AGENT_LOGGEDOFF";
}
if (owner) {
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
}
astman_append(s, "Event: Agents\r\n"
"Agent: %s\r\n"
"Name: %s\r\n"
@@ -1582,14 +1642,14 @@ static int agent_logoff(const char *agent, int soft)
ret = 0;
if (p->owner || p->chan) {
if (!soft) {
struct ast_channel *owner;
ast_mutex_lock(&p->lock);
owner = agent_lock_owner(p);
while (p->owner && ast_channel_trylock(p->owner)) {
DEADLOCK_AVOIDANCE(&p->lock);
}
if (p->owner) {
ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
ast_channel_unlock(p->owner);
if (owner) {
ast_softhangup(owner, AST_SOFTHANGUP_EXPLICIT);
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
}
while (p->chan && ast_channel_trylock(p->chan)) {
@@ -1726,7 +1786,9 @@ static char *agents_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *
AST_LIST_LOCK(&agents);
AST_LIST_TRAVERSE(&agents, p, list) {
struct ast_channel *owner;
ast_mutex_lock(&p->lock);
owner = agent_lock_owner(p);
if (p->pending) {
if (p->group)
ast_cli(a->fd, "-- Pending call to group %d\n", powerof(p->group));
@@ -1739,10 +1801,11 @@ static char *agents_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *
username[0] = '\0';
if (p->chan) {
snprintf(location, sizeof(location), "logged in on %s", p->chan->name);
if (p->owner && ast_bridged_channel(p->owner))
if (owner && ast_bridged_channel(owner)) {
snprintf(talkingto, sizeof(talkingto), " talking to %s", ast_bridged_channel(p->owner)->name);
else
} else {
strcpy(talkingto, " is idle");
}
online_agents++;
} else {
strcpy(location, "not logged in");
@@ -1755,6 +1818,11 @@ static char *agents_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *
username, location, talkingto, music);
count_agents++;
}
if (owner) {
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
}
ast_mutex_unlock(&p->lock);
}
AST_LIST_UNLOCK(&agents);
@@ -1795,21 +1863,32 @@ static char *agents_show_online(struct ast_cli_entry *e, int cmd, struct ast_cli
AST_LIST_LOCK(&agents);
AST_LIST_TRAVERSE(&agents, p, list) {
struct ast_channel *owner;
agent_status = 0; /* reset it to offline */
ast_mutex_lock(&p->lock);
owner = agent_lock_owner(p);
if (!ast_strlen_zero(p->name))
snprintf(username, sizeof(username), "(%s) ", p->name);
else
username[0] = '\0';
if (p->chan) {
snprintf(location, sizeof(location), "logged in on %s", p->chan->name);
if (p->owner && ast_bridged_channel(p->owner))
snprintf(talkingto, sizeof(talkingto), " talking to %s", ast_bridged_channel(p->owner)->name);
else
if (owner && ast_bridged_channel(owner)) {
snprintf(talkingto, sizeof(talkingto), " talking to %s", ast_bridged_channel(owner)->name);
} else {
strcpy(talkingto, " is idle");
}
agent_status = 1;
online_agents++;
}
if (owner) {
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
}
if (!ast_strlen_zero(p->moh))
snprintf(music, sizeof(music), " (musiconhold is '%s')", p->moh);
if (agent_status)
@@ -2381,12 +2460,16 @@ static int agents_data_provider_get(const struct ast_data_search *search,
AST_LIST_LOCK(&agents);
AST_LIST_TRAVERSE(&agents, p, list) {
struct ast_channel *owner;
data_agent = ast_data_add_node(data_root, "agent");
if (!data_agent) {
continue;
}
ast_mutex_lock(&p->lock);
owner = agent_lock_owner(p);
if (!(p->pending)) {
ast_data_add_str(data_agent, "id", p->agent);
ast_data_add_structure(agent_pvt, data_agent, p);
@@ -2397,17 +2480,25 @@ static int agents_data_provider_get(const struct ast_data_search *search,
if (!data_channel) {
ast_mutex_unlock(&p->lock);
ast_data_remove_node(data_root, data_agent);
if (owner) {
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
}
continue;
}
ast_channel_data_add_structure(data_channel, p->chan, 0);
if (p->owner && ast_bridged_channel(p->owner)) {
if (owner && ast_bridged_channel(owner)) {
data_talkingto = ast_data_add_node(data_agent, "talkingto");
if (!data_talkingto) {
ast_mutex_unlock(&p->lock);
ast_data_remove_node(data_root, data_agent);
if (owner) {
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
}
continue;
}
ast_channel_data_add_structure(data_talkingto, ast_bridged_channel(p->owner), 0);
ast_channel_data_add_structure(data_talkingto, ast_bridged_channel(owner), 0);
}
} else {
ast_data_add_node(data_agent, "talkingto");
@@ -2415,6 +2506,12 @@ static int agents_data_provider_get(const struct ast_data_search *search,
}
ast_data_add_str(data_agent, "musiconhold", p->moh);
}
if (owner) {
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
}
ast_mutex_unlock(&p->lock);
/* if this agent doesn't match remove the added agent. */

View File

@@ -3860,6 +3860,7 @@ static int __sip_autodestruct(const void *data)
ast_channel_unref(owner);
} else if (p->refer && !p->alreadygone) {
ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid);
stop_media_flows(p);
transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid);
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
@@ -9121,6 +9122,10 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
/* Ensure RTCP is enabled since it may be inactive
if we're coming back from a T.38 session */
ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1);
/* Ensure audio RTCP reads are enabled */
if (p->owner) {
ast_channel_set_fd(p->owner, 1, ast_rtp_instance_fd(p->rtp, 1));
}
if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
ast_clear_flag(&p->flags[0], SIP_DTMF);
@@ -9137,6 +9142,10 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
} else if (udptlportno > 0) {
if (debug)
ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n");
/* Prevent audio RTCP reads */
if (p->owner) {
ast_channel_set_fd(p->owner, 1, -1);
}
/* Silence RTCP while audio RTP is inactive */
ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 0);
} else {
@@ -18519,7 +18528,8 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
/* Need to check the media/type */
if (!strcasecmp(c, "application/dtmf-relay") ||
!strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
!strcasecmp(c, "application/vnd.nortelnetworks.digits") ||
!strcasecmp(c, "application/dtmf")) {
unsigned int duration = 0;
if (!p->owner) { /* not a PBX call */
@@ -18528,91 +18538,62 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
return;
}
/* Try getting the "signal=" part */
if (ast_strlen_zero(c = get_body(req, "Signal", '=')) && ast_strlen_zero(c = get_body(req, "d", '='))) {
ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
transmit_response(p, "200 OK", req); /* Should return error */
return;
/* If dtmf-relay or vnd.nortelnetworks.digits, parse the signal and duration;
* otherwise use the body as the signal */
if (strcasecmp(c, "application/dtmf")) {
const char *msg_body;
if ( ast_strlen_zero(msg_body = get_body(req, "Signal", '='))
&& ast_strlen_zero(msg_body = get_body(req, "d", '='))) {
ast_log(LOG_WARNING, "Unable to retrieve DTMF signal for INFO message on "
"call %s\n", p->callid);
transmit_response(p, "200 OK", req);
return;
}
ast_copy_string(buf, msg_body, sizeof(buf));
if (!ast_strlen_zero((msg_body = get_body(req, "Duration", '=')))) {
sscanf(msg_body, "%30u", &duration);
}
} else {
ast_copy_string(buf, c, sizeof(buf));
/* Type is application/dtmf, simply use what's in the message body */
get_msg_text(buf, sizeof(buf), req);
}
if (!ast_strlen_zero((c = get_body(req, "Duration", '='))))
duration = atoi(c);
if (!duration)
duration = 100; /* 100 ms */
/* An empty message body requires us to send a 200 OK */
if (ast_strlen_zero(buf)) {
transmit_response(p, "200 OK", req);
return;
}
if ('0' <= buf[0] && buf[0] <= '9') {
event = buf[0] - '0';
} else if (buf[0] == '*') {
if (!duration) {
duration = 100; /* 100 ms */
}
if (buf[0] == '*') {
event = 10;
} else if (buf[0] == '#') {
event = 11;
} else if (buf[0] == '!') {
event = 16;
} else if ('A' <= buf[0] && buf[0] <= 'D') {
event = 12 + buf[0] - 'A';
} else if ('a' <= buf[0] && buf[0] <= 'd') {
event = 12 + buf[0] - 'a';
} else if (buf[0] == '!') {
event = 16;
} else {
/* Unknown digit */
event = 0;
} else if ((sscanf(buf, "%30u", &event) != 1) || event > 16) {
ast_log(AST_LOG_WARNING, "Unable to convert DTMF event signal code to a valid "
"value for INFO message on call %s\n", p->callid);
transmit_response(p, "200 OK", req);
return;
}
if (event == 16) {
/* send a FLASH event */
struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } };
ast_queue_frame(p->owner, &f);
if (sipdebug)
if (sipdebug) {
ast_verbose("* DTMF-relay event received: FLASH\n");
} else {
/* send a DTMF event */
struct ast_frame f = { AST_FRAME_DTMF, };
if (event < 10) {
f.subclass.integer = '0' + event;
} else if (event == 10) {
f.subclass.integer = '*';
} else if (event == 11) {
f.subclass.integer = '#';
} else if (event < 16) {
f.subclass.integer = 'A' + (event - 12);
}
f.len = duration;
ast_queue_frame(p->owner, &f);
if (sipdebug)
ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer);
}
transmit_response(p, "200 OK", req);
return;
} else if (!strcasecmp(c, "application/dtmf")) {
/*! \todo Note: Doesn't read the duration of the DTMF. Should be fixed. */
unsigned int duration = 0;
if (!p->owner) { /* not a PBX call */
transmit_response(p, "481 Call leg/transaction does not exist", req);
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
return;
}
get_msg_text(buf, sizeof(buf), req);
duration = 100; /* 100 ms */
if (ast_strlen_zero(buf)) {
transmit_response(p, "200 OK", req);
return;
}
event = atoi(buf);
if (event == 16) {
/* send a FLASH event */
struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH }, };
ast_queue_frame(p->owner, &f);
if (sipdebug)
ast_verbose("* DTMF-relay event received: FLASH\n");
} else {
/* send a DTMF event */
struct ast_frame f = { AST_FRAME_DTMF, };
@@ -18622,20 +18603,17 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
f.subclass.integer = '*';
} else if (event == 11) {
f.subclass.integer = '#';
} else if (event < 16) {
f.subclass.integer = 'A' + (event - 12);
} else {
/* Unknown digit. */
f.subclass.integer = '0';
f.subclass.integer = 'A' + (event - 12);
}
f.len = duration;
ast_queue_frame(p->owner, &f);
if (sipdebug)
if (sipdebug) {
ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer);
}
}
transmit_response(p, "200 OK", req);
return;
} else if (!strcasecmp(c, "application/media_control+xml")) {
/* Eh, we'll just assume it's a fast picture update for now */
if (p->owner)
@@ -20202,15 +20180,22 @@ static void handle_response_notify(struct sip_pvt *p, int resp, const char *rest
case 200: /* Notify accepted */
/* They got the notify, this is the end */
if (p->owner) {
if (!p->refer) {
ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name);
ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_UNSPECIFIED);
if (p->refer) {
ast_log(LOG_NOTICE, "Got OK on REFER Notify message\n");
} else {
ast_debug(4, "Got OK on REFER Notify message\n");
ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name);
/*
* XXX There is discrepancy on whether a hangup should be queued
* or not. This code used to be duplicated in two places, and the more
* frequently hit area had this disabled, making it the de facto
* "correct" way to go.
*
* ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_UNSPECIFIED);
*/
}
} else {
if (p->subscribed == NONE) {
ast_debug(4, "Got 200 accepted on NOTIFY\n");
if (p->subscribed == NONE && !p->refer) {
ast_debug(4, "Got 200 accepted on NOTIFY %s\n", p->callid);
pvt_set_needdestroy(p, "received 200 response");
}
if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
@@ -20235,6 +20220,9 @@ static void handle_response_notify(struct sip_pvt *p, int resp, const char *rest
pvt_set_needdestroy(p, "failed to authenticate NOTIFY");
}
break;
case 481: /* Call leg does not exist */
pvt_set_needdestroy(p, "Received 481 response for NOTIFY");
break;
}
}
@@ -20829,6 +20817,9 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
} else if (sipmethod == SIP_MESSAGE) {
/* More good gravy! */
handle_response_message(p, resp, rest, req, seqno);
} else if (sipmethod == SIP_NOTIFY) {
/* The gravy train continues to roll */
handle_response_notify(p, resp, rest, req, seqno);
} else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
switch(resp) {
case 100: /* 100 Trying */
@@ -20844,8 +20835,6 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
p->authtries = 0; /* Reset authentication counter */
if (sipmethod == SIP_INVITE) {
handle_response_invite(p, resp, rest, req, seqno);
} else if (sipmethod == SIP_NOTIFY) {
handle_response_notify(p, resp, rest, req, seqno);
} else if (sipmethod == SIP_REGISTER) {
handle_response_register(p, resp, rest, req, seqno);
} else if (sipmethod == SIP_SUBSCRIBE) {
@@ -20860,8 +20849,6 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
case 407: /* Proxy auth required */
if (sipmethod == SIP_INVITE)
handle_response_invite(p, resp, rest, req, seqno);
else if (sipmethod == SIP_NOTIFY)
handle_response_notify(p, resp, rest, req, seqno);
else if (sipmethod == SIP_SUBSCRIBE)
handle_response_subscribe(p, resp, rest, req, seqno);
else if (p->registry && sipmethod == SIP_REGISTER)
@@ -20936,8 +20923,6 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
handle_response_invite(p, resp, rest, req, seqno);
} else if (sipmethod == SIP_SUBSCRIBE) {
handle_response_subscribe(p, resp, rest, req, seqno);
} else if (sipmethod == SIP_NOTIFY) {
pvt_set_needdestroy(p, "received 481 response");
} else if (sipmethod == SIP_BYE) {
/* The other side has no transaction to bye,
just assume it's all right then */
@@ -21094,24 +21079,6 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
ast_debug(1, "Got 200 OK on CANCEL\n");
/* Wait for 487, then destroy */
} else if (sipmethod == SIP_NOTIFY) {
/* They got the notify, this is the end */
if (p->owner) {
if (p->refer) {
ast_debug(1, "Got 200 OK on NOTIFY for transfer\n");
} else
ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
/* ast_queue_hangup(p->owner); Disabled */
} else {
if (!p->subscribed && !p->refer) {
pvt_set_needdestroy(p, "transaction completed");
}
if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
/* Ready to send the next state we have on queue */
ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
}
}
} else if (sipmethod == SIP_BYE) {
pvt_set_needdestroy(p, "transaction completed");
}
@@ -21133,8 +21100,6 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
handle_response_invite(p, resp, rest, req, seqno);
} else if (sipmethod == SIP_BYE) {
pvt_set_needdestroy(p, "received 481 response");
} else if (sipmethod == SIP_NOTIFY) {
pvt_set_needdestroy(p, "received 481 response");
} else if (sipdebug) {
ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
}
@@ -29356,6 +29321,12 @@ static int setup_srtp(struct sip_srtp **srtp)
static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struct sip_srtp **srtp, const char *a)
{
/* If no RTP instance exists for this media stream don't bother processing the crypto line */
if (!rtp) {
ast_debug(3, "Received offer with crypto line for media stream that is not enabled\n");
return FALSE;
}
if (strncasecmp(a, "crypto:", 7)) {
return FALSE;
}

View File

@@ -4096,6 +4096,17 @@ int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct a
if (!f || (f->frametype == AST_FRAME_CONTROL &&
(f->subclass.integer == AST_CONTROL_HANGUP || f->subclass.integer == AST_CONTROL_BUSY ||
f->subclass.integer == AST_CONTROL_CONGESTION))) {
/*
* If the bridge was broken for a hangup that isn't real, then
* then don't run the h extension, because the channel isn't
* really hung up. This should really only happen with AST_SOFTHANGUP_ASYNCGOTO,
* but it doesn't hurt to check AST_SOFTHANGUP_UNBRIDGE either.
*/
ast_channel_lock(chan);
if (chan->_softhangup & (AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE)) {
ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT);
}
ast_channel_unlock(chan);
res = -1;
break;
}

View File

@@ -949,6 +949,7 @@ int ast_streamfile(struct ast_channel *chan, const char *filename, const char *p
struct ast_filestream *fs;
struct ast_filestream *vfs=NULL;
char fmt[256];
off_t pos;
int seekattempt;
int res;
@@ -961,12 +962,17 @@ int ast_streamfile(struct ast_channel *chan, const char *filename, const char *p
/* check to see if there is any data present (not a zero length file),
* done this way because there is no where for ast_openstream_full to
* return the file had no data. */
seekattempt = fseek(fs->f, -1, SEEK_END);
if (seekattempt && errno == EINVAL) {
/* Zero-length file, as opposed to a pipe */
return 0;
pos = ftello(fs->f);
seekattempt = fseeko(fs->f, -1, SEEK_END);
if (seekattempt) {
if (errno == EINVAL) {
/* Zero-length file, as opposed to a pipe */
return 0;
} else {
ast_seekstream(fs, 0, SEEK_SET);
}
} else {
ast_seekstream(fs, 0, SEEK_SET);
fseeko(fs->f, pos, SEEK_SET);
}
vfs = ast_openvstream(chan, filename, preflang);