[Pkg-voip-commits] [asterisk] 02/08: Imported Upstream version 13.6.0~dfsg

tzafrir at debian.org tzafrir at debian.org
Sun Apr 24 13:49:06 UTC 2016


This is an automated email from the git hooks/post-receive script.

tzafrir pushed a commit to branch master
in repository asterisk.

commit 86ba0fd0565db5e140881320be3f1ed5d8dd913f
Author: Tzafrir Cohen <tzafrir at debian.org>
Date:   Sun Nov 8 04:22:13 2015 +0200

    Imported Upstream version 13.6.0~dfsg
---
 .version                                           |    2 +-
 CHANGES                                            |   35 +
 ChangeLog                                          | 1908 +++++++++++++++++++-
 Makefile                                           |    1 +
 UPGRADE.txt                                        |    6 +
 addons/chan_ooh323.c                               |    1 +
 addons/ooh323c/src/ooq931.c                        |    6 +-
 apps/app_dial.c                                    |  156 +-
 apps/app_page.c                                    |   28 +-
 apps/app_queue.c                                   |  412 +++--
 apps/app_record.c                                  |    3 +-
 asterisk-13.5.0-summary.html                       |  441 -----
 asterisk-13.5.0-summary.txt                        | 1141 ------------
 asterisk-13.6.0-summary.html                       |  322 ++++
 asterisk-13.6.0-summary.txt                        |  839 +++++++++
 bridges/bridge_holding.c                           |    6 +-
 channels/chan_dahdi.c                              |   55 +-
 channels/chan_pjsip.c                              |   18 +-
 channels/chan_sip.c                                |   78 +-
 channels/chan_skinny.c                             |   26 +-
 channels/pjsip/dialplan_functions.c                |    5 +
 channels/sip/include/security_events.h             |    3 +-
 channels/sip/security_events.c                     |    5 +-
 codecs/codec_gsm.c                                 |   29 +-
 codecs/codec_ilbc.c                                |   28 +-
 codecs/codec_lpc10.c                               |   41 +-
 codecs/codec_speex.c                               |   60 +-
 configure                                          |   63 +
 configure.ac                                       |    6 +
 .../versions/154177371065_add_default_from_user.py |   22 +
 contrib/realtime/mssql/mssql_config.sql            |    8 +-
 contrib/realtime/mysql/mysql_config.sql            |    6 +
 contrib/realtime/oracle/oracle_config.sql          |    8 +-
 contrib/realtime/postgresql/postgresql_config.sql  |    6 +-
 contrib/scripts/astversion                         |  536 ++++++
 contrib/scripts/install_prereq                     |    2 +-
 include/asterisk/autoconfig.h.in                   |    3 +
 include/asterisk/format.h                          |   23 +
 include/asterisk/logger.h                          |   44 +
 include/asterisk/res_pjsip.h                       |   40 +
 include/asterisk/res_pjsip_session.h               |    6 +
 include/asterisk/rtp_engine.h                      |   18 +-
 include/asterisk/stasis_app.h                      |   15 +
 main/audiohook.c                                   |   43 +-
 main/bridge_channel.c                              |    7 +
 main/channel.c                                     |    9 +-
 main/config_options.c                              |    4 +
 main/dial.c                                        |   25 +-
 main/endpoints.c                                   |    3 +-
 main/format.c                                      |   11 +
 main/logger.c                                      |  272 ++-
 main/pbx.c                                         |  146 +-
 main/rtp_engine.c                                  |  153 +-
 main/sched.c                                       |  143 +-
 main/sorcery.c                                     |    4 +
 main/stasis_endpoints.c                            |   78 +-
 main/taskprocessor.c                               |   12 +-
 main/translate.c                                   |   55 +-
 main/utils.c                                       |    4 +-
 res/ari/ari_model_validators.c                     |  445 ++++-
 res/ari/ari_model_validators.h                     |  118 ++
 res/ari/ari_websockets.c                           |    9 +-
 res/ari/config.c                                   |   72 +-
 res/ari/resource_asterisk.c                        |  127 ++
 res/ari/resource_asterisk.h                        |   63 +
 res/ari/resource_events.c                          |   24 +-
 res/ari/resource_events.h                          |    2 +
 res/parking/parking_applications.c                 |   65 +
 res/res_ari.c                                      |   19 +-
 res/res_ari_asterisk.c                             |  300 ++-
 res/res_ari_events.c                               |    6 +
 res/res_config_sqlite.c                            |    8 +
 res/res_format_attr_silk.c                         |   24 +
 res/res_http_websocket.c                           |   80 +-
 res/res_pjsip.c                                    |  131 +-
 res/res_pjsip/config_global.c                      |   18 +
 res/res_pjsip/location.c                           |   51 +-
 res/res_pjsip/pjsip_configuration.c                |    4 +
 res/res_pjsip/presence_xml.c                       |   31 +-
 res/res_pjsip_diversion.c                          |    4 +-
 res/res_pjsip_multihomed.c                         |   23 +-
 res/res_pjsip_nat.c                                |    2 +-
 res/res_pjsip_pidf_digium_body_supplement.c        |    2 +-
 res/res_pjsip_pubsub.c                             |   80 +-
 res/res_pjsip_sdp_rtp.c                            |   70 +-
 res/res_pjsip_session.c                            |   37 +-
 res/res_pjsip_t38.c                                |   15 +-
 res/res_pjsip_transport_websocket.c                |    5 +-
 res/res_rtp_asterisk.c                             |   79 +-
 res/res_stasis.c                                   |   45 +-
 res/res_stasis_device_state.c                      |   54 +-
 res/stasis/app.c                                   |  335 ++--
 res/stasis/app.h                                   |   15 +-
 res/stasis/messaging.c                             |   44 +-
 rest-api-templates/ari_model_validators.c.mustache |    2 +-
 rest-api/api-docs/applications.json                |    2 +-
 rest-api/api-docs/asterisk.json                    |  130 +-
 rest-api/api-docs/bridges.json                     |    2 +-
 rest-api/api-docs/channels.json                    |    2 +-
 rest-api/api-docs/deviceStates.json                |    2 +-
 rest-api/api-docs/endpoints.json                   |    2 +-
 rest-api/api-docs/events.json                      |  109 +-
 rest-api/api-docs/mailboxes.json                   |    2 +-
 rest-api/api-docs/playbacks.json                   |    2 +-
 rest-api/api-docs/recordings.json                  |    2 +-
 rest-api/api-docs/sounds.json                      |    2 +-
 rest-api/resources.json                            |    2 +-
 tests/test_core_format.c                           |  105 ++
 108 files changed, 7668 insertions(+), 2535 deletions(-)

diff --git a/.version b/.version
index c92af7f..649e128 100644
--- a/.version
+++ b/.version
@@ -1 +1 @@
-13.5.0
\ No newline at end of file
+13.6.0
\ No newline at end of file
diff --git a/CHANGES b/CHANGES
index ef16ba6..231ef2a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,38 @@
 ==============================================================================
 
 ------------------------------------------------------------------------------
+--- Functionality changes from Asterisk 13.5.0 to Asterisk 13.6.0 ------------
+------------------------------------------------------------------------------
+
+Dialplan Functions
+------------------
+ * The CHANNEL function, when used on a PJSIP channel, now exposes a 'call-id'
+   extraction option when using with the 'pjsip' signalling option. It will
+   return the SIP Call-ID associated with the INVITE request that established
+   the PJSIP channel.
+
+ARI
+------------------
+ * Two new endpoint related events are now available: PeerStatusChange and
+   ContactStatusChange. In particular, these events are useful when subscribing
+   to all event sources, as they provide additional endpoint related
+   information beyond the addition/removal of channels from an endpoint.
+   The ARI version has been bumped to 1.9.0 as a result.
+
+ * Added the ability to subscribe to all ARI events in Asterisk, regardless
+   of whether the application 'controls' the resource. This is useful for
+   scenarios where an ARI application merely wants to observe the system,
+   as opposed to control it. There are two ways to accomplish this:
+   (1) Via the WebSocket connection URI. A new query paramter, 'subscribeAll',
+       has been added that, when present and True, will subscribe all
+       specified applications to all ARI event sources in Asterisk.
+   (2) Via the applications resource. An ARI client can, at any time, subscribe
+       to all resources in an event source merely by not providing an explicit
+       resource. For example, subscribing to an event source of 'channels:'
+       as opposed to 'channels:12345' will subscribe the application to all
+       channels.
+
+------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 13.4.0 to Asterisk 13.5.0 ------------
 ------------------------------------------------------------------------------
 
@@ -33,6 +65,9 @@ ARI
    deletion. Sorcery derived objects that are manipulated by this resource
    must have a sorcery wizard that supports the desired operations.
 
+ * A new feature has been added that allows for the rotation of log channels
+   through HTTP requests.
+
 
 res_pjsip
 ------------------
diff --git a/ChangeLog b/ChangeLog
index fa24c3d..4d431b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,26 +1,1912 @@
-2015-08-07 19:14 +0000  Asterisk Development Team <asteriskteam at digium.com>
+2015-10-09 21:48 +0000  Asterisk Development Team <asteriskteam at digium.com>
 
-	* asterisk 13.5.0 Released.
+	* asterisk 13.6.0 Released.
 
-2015-08-07 14:10 +0000 [ccb72a8e60]  Matt Jordan <mjordan at digium.com>
+2015-10-09 16:48 +0000 [68d2a14e1a]  Kevin Harwell <kharwell at lunkwill>
 
-	* Release summaries: Add summaries for 13.5.0
+	* Release summaries: Add summaries for 13.6.0
 
-2015-08-07 14:05 +0000 [96ec40eb70]  Matt Jordan <mjordan at digium.com>
+2015-10-09 16:45 +0000 [cc0eff5651]  Kevin Harwell <kharwell at lunkwill.digium.internal>
 
 	* Release summaries: Remove previous versions
 
-2015-08-07 14:05 +0000 [3e526f11c3]  Matt Jordan <mjordan at digium.com>
+2015-10-09 16:45 +0000 [8cd191b885]  Kevin Harwell <kharwell at lunkwill>
 
-	* .version: Update for 13.5.0
+	* .version: Update for 13.6.0
 
-2015-08-07 14:05 +0000 [68823f7438]  Matt Jordan <mjordan at digium.com>
+2015-10-09 16:45 +0000 [a3777c24fd]  Kevin Harwell <kharwell at lunkwill>
 
-	* .lastclean: Update for 13.5.0
+	* .lastclean: Update for 13.6.0
 
-2015-08-07 14:05 +0000 [d3526317bc]  Matt Jordan <mjordan at digium.com>
+2015-10-09 16:45 +0000 [68121cef21]  Kevin Harwell <kharwell at lunkwill>
 
-	* realtime: Add database scripts for 13.5.0
+	* realtime: Add database scripts for 13.6.0
+
+2015-10-07 18:42 +0000  Asterisk Development Team <asteriskteam at digium.com>
+
+	* asterisk 13.6.0-rc3 Released.
+
+2015-10-07 13:41 +0000 [9da83dbd15]  Kevin Harwell <kharwell at lunkwill>
+
+	* Release summaries: Add summaries for 13.6.0-rc3
+
+2015-10-07 13:41 +0000 [8c60f9326c]  Kevin Harwell <kharwell at lunkwill.digium.internal>
+
+	* Release summaries: Remove previous versions
+
+2015-10-07 13:41 +0000 [316d47755b]  Kevin Harwell <kharwell at lunkwill>
+
+	* .version: Update for 13.6.0-rc3
+
+2015-10-07 13:41 +0000 [74a86d0a72]  Kevin Harwell <kharwell at lunkwill>
+
+	* .lastclean: Update for 13.6.0-rc3
+
+2015-10-07 13:41 +0000 [4c39bea6f0]  Kevin Harwell <kharwell at lunkwill>
+
+	* realtime: Add database scripts for 13.6.0-rc3
+
+2015-10-06 20:43 +0000 [10e790f81a]  Matt Jordan <mjordan at digium.com>
+
+	* res/res_rtp_asterisk: Fix assignment after ao2 decrement
+
+	  When we decide we will no longer schedule an RTCP write, we remove the
+	  reference to the RTP instance, then assign -1 to the stored scheduler ID
+	  in case something else comes along and wants to see if anything is scheduled.
+
+	  That scheduler ID is on the RTP instance. After 60a9172d7ef2 was merged to
+	  fix the regression introduced by 3cf0f29310, this improper assignment on a
+	  potentially destroyed object started getting tripped on the build agents.
+
+	  Frankly, this should have been crashing a lot more often earlier. I can only
+	  assume that the timing was changed just enough by both changes to start
+	  actually hitting this problem.
+
+	  As it is, simply moving the assignment prior to the ao2 deference is sufficient
+	  to keep the RTP instance from being referenced when it is very, truly,
+	  aboslutely dead.
+
+	  (Note that it is still good practice to assign -1 to the scheduler ID when we
+	  know we won't be scheduling it again, as the ao2 deref *may* not always destroy
+	  the ao2 object.)
+
+	  ASTERISK-25449
+
+	  Change-Id: Ie6d3cb4adc7b1a6c078b1c38c19fc84cf787cda7
+
+2015-10-06 18:40 +0000  Asterisk Development Team <asteriskteam at digium.com>
+
+	* asterisk 13.6.0-rc2 Released.
+
+2015-10-06 13:40 +0000 [a44f6aa046]  Kevin Harwell <kharwell at lunkwill>
+
+	* Release summaries: Add summaries for 13.6.0-rc2
+
+2015-10-06 13:40 +0000 [dd74af7e46]  Kevin Harwell <kharwell at lunkwill.digium.internal>
+
+	* Release summaries: Remove previous versions
+
+2015-10-06 13:40 +0000 [a11a78ca34]  Kevin Harwell <kharwell at lunkwill>
+
+	* .version: Update for 13.6.0-rc2
+
+2015-10-06 13:40 +0000 [570329ec8a]  Kevin Harwell <kharwell at lunkwill>
+
+	* .lastclean: Update for 13.6.0-rc2
+
+2015-10-06 13:40 +0000 [51c9ff47f6]  Kevin Harwell <kharwell at lunkwill>
+
+	* realtime: Add database scripts for 13.6.0-rc2
+
+2015-10-05 21:34 +0000 [754daeca0a]  Matt Jordan <mjordan at digium.com>
+
+	* Fix improper usage of scheduler exposed by 5c713fdf18f
+
+	  When 5c713fdf18f was merged, it allowed for scheduled items to have an ID of
+	  '0' returned. While this was valid per the documentation for the API, it was
+	  apparently never returned previously. As a result, several users of the
+	  scheduler API viewed the result as being invalid, causing them to reschedule
+	  already scheduled items or otherwise fail in interesting ways.
+
+	  This patch corrects the users such that they view '0' as valid, and a returned
+	  ID of -1 as being invalid.
+
+	  Note that the failing HEP RTCP tests now pass with this patch. These tests
+	  failed due to a duplicate scheduling of the RTCP transmissions.
+
+	  ASTERISK-25449 #close
+
+	  Change-Id: I019a9aa8b6997584f66876331675981ac9e07e39
+2015-09-30 13:42 +0000 [9913d47697]  Joshua Colp <jcolp at digium.com>
+
+	* res_rtp_asterisk: Move "Set role" warning to be debug.
+
+	  In practice the set_role API callback can be invoked even
+	  when no ICE is present on an RTP instance. This can occur
+	  if ICE has not been enabled on it.
+
+	  ASTERISK-25438 #close
+
+	  Change-Id: I0e17e4316f0f0d7f095c78c3d4fd73a913b6ba69
+	  (cherry picked from commit 56ed7b9dd560e468be31684e56a8070b88ae0205)
+
+2015-09-29 21:15 +0000  Asterisk Development Team <asteriskteam at digium.com>
+
+	* asterisk 13.6.0-rc1 Released.
+
+2015-09-29 16:12 +0000 [bba1c4066b]  Kevin Harwell <kharwell at lunkwill>
+
+	* Release summaries: Add summaries for 13.6.0-rc1
+
+2015-09-29 16:08 +0000 [82c4aecdbb]  Kevin Harwell <kharwell at lunkwill>
+
+	* .version: Update for 13.6.0-rc1
+
+2015-09-29 16:08 +0000 [bc18db7388]  Kevin Harwell <kharwell at lunkwill>
+
+	* .lastclean: Update for 13.6.0-rc1
+
+2015-09-29 16:08 +0000 [b9c53f95e3]  Kevin Harwell <kharwell at lunkwill>
+
+	* realtime: Add database scripts for 13.6.0-rc1
+
+2015-09-29 14:53 +0000 [d30939b6e8]  Kevin Harwell <kharwell at digium.com>
+
+	* ARI: Changed version from 1.8.0 to 1.9.0
+
+	  Change-Id: I510991c60d28d171f47c4b58bba4947f7fc71b13
+
+2015-09-25 18:37 +0000 [5f19c9bade]  Richard Mudgett <rmudgett at digium.com>
+
+	* res/ari/config.c: Fix user sort compare function.
+
+	  Made use the ao2 sort compare template function and OBJ_SEARCH_xxx
+	  identifiers.
+
+	  Change-Id: Ic53005dc5aafa7a36c72300dd89b75fb63c92f4c
+
+2015-09-25 17:26 +0000 [3a85764039]  Richard Mudgett <rmudgett at digium.com>
+
+	* res/ari/config.c: Optimize conf_alloc() object init.
+
+	  * Now conf_alloc() has more off nominal error checking.
+
+	  * Eliminated RAII_VAR() use in conf_alloc().
+
+	  * Eliminated a dubius shortcut when destroying cfg->general in
+	  conf_destructor() that would cause a crash if cfg->general failed to get
+	  allocated.
+
+	  * Add some ACO registration section comments.
+
+	  Change-Id: Ia40c2b1b2d0777d641605118ae019c5a73865e1a
+
+2015-09-25 16:48 +0000 [028033e5a8]  Richard Mudgett <rmudgett at digium.com>
+
+	* res/ari/config.c: Fix conf_alloc() object init.
+
+	  Need to finish initializing the string fields in the ao2 object before
+	  putting any default strings into them.
+
+	  ASTERISK-25383 #close
+	  Reported by:  yaron nahum
+
+	  Change-Id: I9f7f3a03f0c4991a01593abf8697b9a587c0ea84
+
+2015-09-27 20:45 +0000 [90165e306d]  Matt Jordan <mjordan at digium.com>
+
+	* res/res_stasis: Fix accidental subscription to 'all' bridge topic
+
+	  When b99a7052621700a1aa641a1c24308f5873275fc8 was merged, subscribing to a
+	  NULL bridge will now cause app_subscribe_bridge to implicitly subscribe to
+	  all bridges. Unfortunately, the res_stasis control loop did not check that
+	  a bridge changing on a channel's control object was actually also non-NULL.
+	  As a result, app_subscribe_bridge will be called with a NULL bridge when a
+	  channel leaves a bridge. This causes a new subscription to be made to the
+	  bridge. If an application has also subscribed to the bridge, the application
+	  will now have two subscriptions:
+	  (1) The explicit one created by the app
+	  (2) The implicit one accidentally created by the control structure
+
+	  As a result, the 'BridgeDestroyed' event can be sent multiple times. This
+	  patch corrects the control loop such that it only subscribes an application
+	  to a new bridge if the bridge pointer is non-NULL.
+
+	  ASTERISK-24870
+
+	  Change-Id: I3510e55f6bc36517c10597ead857b964463c9f4f
+
+2015-09-04 13:51 +0000 [e1223ff6db]  Scott Griepentrog <scott at griepentrog.com>
+
+	* Scripts: check file versions of Asterisk and dependencies
+
+	  To help in diagnosing mismatched modules and libraries, this
+	  script scans for version, repository, and source information
+	  and reports what is found.
+
+	  ASTERISK-25376 #close
+	  Reported by: Ashley Sanders
+
+	  Change-Id: Ib0642d0fb96712476f59760d6d137a24633fe2d6
+
+2015-09-24 14:56 +0000 [6b1e7583c1]  Richard Mudgett <rmudgett at digium.com>
+
+	* app_queue.c: Force COLP update if outgoing channel name changed.
+
+	  * When a call is answered and the outgoing channel name has changed then
+	  force a connected line update because the channel is no longer the same.
+	  The channel was masqueraded into by another channel.  This is usually
+	  because of a call pickup.
+
+	  Note: Forwarded calls are handled in a controlled manner so the original
+	  channel name is replaced with the forwarded channel.
+
+	  ASTERISK-25423 #close
+	  Reported by: John Hardin
+
+	  Change-Id: Ie275ea9e99c092ad369db23e0feb08c44498c172
+
+2015-09-24 14:20 +0000 [6bf304bf25]  Richard Mudgett <rmudgett at digium.com>
+
+	* app_queue.c: Factor out a connected line update routine.
+
+	  Replace inlined code with update_connected_line_from_peer().
+
+	  ASTERISK-25423
+	  Reported by: John Hardin
+
+	  Change-Id: I33bbd033596fcb0208d41d8970369b4e87b806f3
+
+2015-09-24 13:27 +0000 [e36b5f1e8e]  Richard Mudgett <rmudgett at digium.com>
+
+	* app_dial.c: Make 'A' option pass COLP updates.
+
+	  While the 'A' option is playing the announcement file allow the caller and
+	  peer to exchange COLP update frames.
+
+	  ASTERISK-25423
+	  Reported by: John Hardin
+
+	  Change-Id: Iac6cf89b56d26452c6bb88e9363622bbf23895f9
+
+2015-09-24 12:59 +0000 [747bfac895]  Richard Mudgett <rmudgett at digium.com>
+
+	* app_dial.c: Force COLP update if outgoing channel name changed.
+
+	  * When a call is answered and the outgoing channel name has changed then
+	  force a connected line update because the channel is no longer the same.
+	  The channel was masqueraded into by another channel.  This is usually
+	  because of a call pickup.
+
+	  Note: Forwarded calls are handled in a controlled manner so the original
+	  channel name is replaced with the forwarded channel.
+
+	  ASTERISK-25423
+	  Reported by: John Hardin
+
+	  Change-Id: I2e01f7a698fbbc8c26344a59c2be40c6cd98b00c
+
+2015-09-24 12:37 +0000 [14481d9aa0]  Richard Mudgett <rmudgett at digium.com>
+
+	* app_dial.c: Factor out a connected line update routine.
+
+	  Replace inlined code with update_connected_line_from_peer().
+
+	  ASTERISK-25423
+	  Reported by: John Hardin
+
+	  Change-Id: Ia14f18def417645cd7fb453e1bdac682630a5091
+
+2015-09-23 17:41 +0000 [bbeda190c3]  Richard Mudgett <rmudgett at digium.com>
+
+	* app_dial.c: Remove some no-op code.
+
+	  Change-Id: Ice1884a94315d3cb7e3bbd47a9fba76a27276c54
+
+2015-09-23 14:02 +0000 [f050fa76eb]  Mark Michelson <mmichelson at digium.com>
+
+	* logger: Prevent duplicate dynamic channels from being added.
+
+	  There was a problem observed where the "logger add channel" CLI command
+	  would allow for a channel with the same name to be added multiple times.
+	  This would result in each message being written out to the same file
+	  multiple times.
+
+	  The problem was due to the difference in how logger channel filenames
+	  are stored versus the format they are allowed to be presented when they
+	  are added. For instance, if adding the logger channel "foo" through the
+	  CLI, the result would be a logger channel with the file name
+	  /var/log/asterisk/foo being stored. So when trying to add another "foo"
+	  channel, "foo" would not match "/var/log/asterisk/foo" so we'd happily
+	  add the duplicate channel.
+
+	  The fix presented here is to introduce two new methods in the logger
+	  code:
+	   * make_filename(): given a logger channel name, this creates the
+	     filename for that logger channel.
+	   * find_logchannel(): given a logger channel name, this calls
+	     make_filename() and then traverses the list of logchannels in order
+	     to find a match.
+
+	  This change has made use of make_filename() and find_logchannel()
+	  throughout to more consistently behave.
+
+	  ASTERISK-25305 #close
+	  Reported by Mark Michelson
+
+	  Change-Id: I892d52954d6007d8bc453c3cbdd9235dec9c4a36
+
+2015-09-24 14:49 +0000 [629458d349]  Mark Michelson <mmichelson at digium.com>
+
+	* Do not swallow frames on channels leaving bridges.
+
+	  When leaving a bridge, indications on a channel could be swallowed by
+	  the internal indication logic because it appears that the channel is on
+	  its way to be hung up anyway. One such situation where this is
+	  detrimental is when channels on hold are redirected out of a bridge. The
+	  AST_CONTROL_UNHOLD indication from the bridging code is swallowed,
+	  leaving the channel in question to still appear to be on hold.
+
+	  The fix here is to modify the logic inside ast_indicate_data() to not
+	  drop the indication if the channel is simply leaving a bridge. This way,
+	  channels on hold redirected out of a bridge revert to their expected "in
+	  use" state after the redirection.
+
+	  ASTERISK-25418 #close
+	  Reported by Mark Michelson
+
+	  Change-Id: If6115204dfa0551c050974ee138fabd15f978949
+
+2015-09-22 17:08 +0000 [5f15cd93f0]  Richard Mudgett <rmudgett at digium.com>
+
+	* app_page.c: Fix crash when forwarding with a predial handler.
+
+	  Page uses the async method of dialing with the dial API.  When a call gets
+	  forwarded there is no calling channel available.  If the predial handler
+	  was set then the calling channel could not be put into auto-service
+	  for the forwarded call because it doesn't exist.  A crash is the result.
+
+	  * Moved the callee predial parameter string processing to before the
+	  string is passed to the dial API rather than having the dial API do it.
+	  There are a few benefits do doing this.  The first is the predial
+	  parameter string processing doesn't need to be done for each channel
+	  called by the dial API.  The second is in async mode and the forwarded
+	  channel is to have the predial handler executed on it then the
+	  non-existent calling channel does not need to be present to process the
+	  predial parameter string.
+
+	  * Don't start auto-service on a non-existent calling channel to execute
+	  the predial handler when the dial API is in async mode and forwarding a
+	  call.
+
+	  ASTERISK-25384 #close
+	  Reported by: Chet Stevens
+
+	  Change-Id: If53892b286d29f6cf955e2545b03dcffa2610981
+
+2015-09-03 21:19 +0000 [b50e372394]  Matt Jordan <mjordan at digium.com>
+
+	* ARI: Add events for Contact and Peer Status changes
+
+	  This patch adds support for receiving events regarding Peer status changes
+	  and Contact status changes. This is particularly useful in scenarios where
+	  we are subscribed to all endpoints and channels, where we often want to know
+	  more about the state of channel technology specific items than a single
+	  endpoint's state.
+
+	  ASTERISK-24870
+
+	  Change-Id: I6137459cdc25ce27efc134ad58abf065653da4e9
+
+2015-09-04 12:24 +0000 [3502c0431d]  Matt Jordan <mjordan at digium.com>
+
+	* res/res_stasis_device_state: Allow for subscribing to 'all' device state
+
+	  This patch adds support for subscribing to all device state changes. This is
+	  done either by subscribing to an empty device, e.g., 'eventSource=deviceState:',
+	  or by the WebSocket connection specifying that it wants all state in the
+	  system.
+
+	  ASTERISK-24870
+
+	  Change-Id: I9cfeca1c9e2231bd7ea73e45919111d44d2eda32
+
+2015-09-04 12:25 +0000 [4c9f613309]  Matt Jordan <mjordan at digium.com>
+
+	* ARI: Add the ability to subscribe to all events
+
+	  This patch adds the ability to subscribe to all events. There are two possible
+	  ways to accomplish this:
+	  (1) On initial WebSocket connection. This patch adds a new query parameter,
+	      'subscribeAll'. If present and True, Asterisk will subscribe the
+	      applications to all ARI events.
+	  (2) Via the applications resource. When subscribing in this manner, an ARI
+	      client should merely specify a blank resource name, i.e., 'channels:'
+	      instead of 'channels:12354'. This will subscribe the application to all
+	      resources of the 'channels' type.
+
+	  ASTERISK-24870 #close
+
+	  Change-Id: I4a943b4db24442cf28bc64b24bfd541249790ad6
+
+2015-09-21 08:16 +0000 [ec514ad64d]  Elazar Broad <elazar at thebroadfamily.com>
+
+	* core/logging: Fix logging to more than one syslog channel
+
+	  Currently, Asterisk will log to the last configured syslog
+	  channel in logger.conf. This is due to the fact that the
+	  final call to openlog() supersedes all of the previous calls.
+	  This commit removes the call to openlog() and passes the
+	  facility to ast_log_vsyslog(), along with utilizing the
+	  LOG_MAKEPRI macro to ensure that the message is routed to
+	  the correct facility and with the correct priority.
+
+	  ASTERISK-25407 #close
+	  Reported by: Elazar Broad
+	  Tested by: Elazar Broad
+
+	  Change-Id: Ie2a2416bc00cce1b04e99ef40917c2011953ddd2
+
+2015-09-21 18:06 +0000 [aeddee39fb]  Kevin Harwell <kharwell at digium.com>
+
+	* app_record: RECORDED_FILE variable not being populated
+
+	  The RECORDED_FILE variable is empty unless a '%d' is specified in the filename.
+	  This patch makes it so the variable is always set to the filename.
+
+	  ASTERISK-25410 #close
+
+	  Change-Id: I4ec826d8eb582ae2ad184e717be8668b74d37653
+
+2015-09-16 08:22 +0000 [2bd27d1222]  Joshua Colp <jcolp at digium.com>
+
+	* pbx: Update device and presence state when changing a hint extension.
+
+	  When changing a hint extension without removing the hint first the
+	  device state and presence state is not updated. This causes the state
+	  of the hint to be that of the previous extension and not the current
+	  one. This state is kept until a state change occurs as a result of
+	  something (presence state change, device state change).
+
+	  This change updates the hint with the current device and presence
+	  state of the new extension when it is changed. Any state callbacks
+	  which may have been added before the hint extension is changed are
+	  also informed of the new device and presence state if either have
+	  changed.
+
+	  ASTERISK-25394 #close
+
+	  Change-Id: If268f1110290e502c73dd289c9e7e7b27bc8432f
+
+2015-09-17 16:34 +0000 [c94f46080f]  Scott Griepentrog <scott at griepentrog.com>
+
+	* CHAOS: avoid crash if string create fails
+
+	  Validate string buffer allocation before using them.
+
+	  ASTERISK-25323
+
+	  Change-Id: Ib9c338bdc1e53fb8b81366f0b39482b83ef56ce0
+
+2015-09-17 04:52 +0000 [b59c4d82b5]  Walter Doekes <walter+asterisk at wjd.nu>
+
+	* chan_sip: Fix From header truncation for extremely long CALLERID(name).
+
+	  The CALLERID(num) and CALLERID(name) and other info are placed into the
+	  `char from[256]` in initreqprep. If the name was too long, the addr-spec
+	  and params wouldn't fit.
+
+	  Code is moved around so the addr-spec with params is placed there first,
+	  and then fitting in as much of the display-name as possible.
+
+	  ASTERISK-25396 #close
+
+	  Change-Id: I33632baf024f01b6a00f8c7f35c91e5f68c40260
+
+2015-09-17 16:59 +0000 [4cc59533b9]  Richard Mudgett <rmudgett at digium.com>
+
+	* CHAOS: res_pjsip_diversion avoid crash if allocation fails
+
+	  Validate ast_malloc buffer returned before using it in
+	  set_redirecting_value().
+
+	  ASTERISK-25323
+
+	  Change-Id: I15d2ed7cb0546818264c0bf251aa40adeae83253
+
+2015-09-17 16:47 +0000 [4fb95bbc4e]  Kevin Harwell <kharwell at digium.com>
+
+	* app_queue: AgentComplete event has wrong reason
+
+	  When a queued caller transfers an agent to another extension sometimes the
+	  raised AgentComplete event has a reason of "caller" and sometimes "transfer".
+	  Since a transfer has taken place this should always be transfer. This occurs
+	  because sometimes the stasis hangup event arrives before the transfer event
+	  thus writing a different reason out.
+
+	  With this patch, when a hangup event is received during a transfer it will
+	  check to see if the channel that is hanging up is part of a transfer. If so
+	  it will return and let the subsequently received transfer event handler take
+	  care of the cleanup.
+
+	  ASTERISK-25399 #close
+
+	  Change-Id: Ic63c49bd9a5ed463ea7a032fd2ea3d63bc81a50d
+
+2015-09-17 13:09 +0000 [fb6b5c684b]  Scott Griepentrog <scott at griepentrog.com>
+
+	* PJSIP: avoid crash when getting rtp peer
+
+	  Although unlikely, if the tech private is returned as
+	  a NULL, chan_pjsip_get_rtp_peer() would crash.
+
+	  ASTERISK-25323
+
+	  Change-Id: Ie231369bfa7da926fb2b9fdaac228261a3152e6a
+
+2015-09-17 11:31 +0000 [6409e7b11a]  Kevin Harwell <kharwell at digium.com>
+
+	* app_queue: Crash when transferring
+
+	  During some transfer scenarios involving queues Asterisk would sometimes
+	  crash when trying to obtain a channel snapshot (could happen on caller or
+	  member channels). This occurred because the underlying channel had already
+	  disappeared when trying to obtain the latest snapshot.
+
+	  This patch adds a reference to both the member and caller channels that
+	  extends to the lifetime of the queue'd call, thus making sure the channels
+	  will always exist when retrieving the latest snapshots.
+
+	  ASTERISK-25185 #close
+	  Reported by: Etienne Lessard
+
+	  Change-Id: Ic397fa68fb4ff35fbc378e745da9246a7b552128
+
+2015-09-16 17:36 +0000 [fe5077b1f8]  Mark Michelson <mmichelson at digium.com>
+
+	* res_pjsip_pubsub: Eliminate race during initial NOTIFY.
+
+	  There is a slim chance of a race condition occurring where two threads
+	  can both attempt to manipulate the same area.
+
+	  Thread A can be handling an incoming initial SUBSCRIBE request. Thread A
+	  lets the specific subscription handler know that the subscription has
+	  been established.
+
+	  At this point, Thread B may detect a state change on the subscribed
+	  resource and queue up a notification task on Thread C, the subscription
+	  serializer thread.
+
+	  Now Thread A attempts to generate the initial NOTIFY request to send to
+	  the subscriber at the same time that Thread C attempts to generate a
+	  state change NOTIFY request to send to the subscriber.
+
+	  The result is that Threads A and C can step on the same memory area,
+	  resulting in a crash. The crash has been observed as happening when
+	  attempting to allocate more space to hold the body for the NOTIFY.
+
+	  The solution presented here is to queue the subscription establishment
+	  and initial NOTIFY generation onto the subscription serializer thread
+	  (Thread C in the above scenario). This way, there is no way that a state
+	  change notification can occur before the initial NOTIFY is sent, and if
+	  there is a quick succession of NOTIFYs, we can guarantee that the two
+	  NOTIFY requests will be sent in succession.
+
+	  Change-Id: I5a89a77b5f2717928c54d6efb9955e5f6f5cf815
+
+2015-08-28 15:42 +0000 [b88c54fa4b]  Alexander Traud <pabstraud at compuserve.com>
+
+	* translate: Fix transcoding while different in frame size.
+
+	  When Asterisk translates between codecs, each with a different frame size (for
+	  example between iLBC 30 and Speex-WB), too large frames were created by
+	  ast_trans_frameout. Now, ast_trans_frameout is called with the correct frame
+	  length, creating several frames when necessary. Affects all transcoding modules
+	  which used ast_trans_frameout: GSM, iLBC, LPC10, and Speex.
+
+	  ASTERISK-25353 #close
+
+	  Change-Id: I2e229569d73191d66a4e43fef35432db24000212
+
+2015-09-10 17:19 +0000 [5c713fdf18]  Mark Michelson <mmichelson at digium.com>
+
+	* scheduler: Use queue for allocating sched IDs.
+
+	  It has been observed that on long-running busy systems, a scheduler
+	  context can eventually hit INT_MAX for its assigned IDs and end up
+	  overflowing into a very low negative number. When this occurs, this can
+	  result in odd behaviors, because a negative return is interpreted by
+	  callers as being a failure. However, the item actually was successfully
+	  scheduled. The result may be that a freed item remains in the scheduler,
+	  resulting in a crash at some point in the future.
+
+	  The scheduler can overflow because every time that an item is added to
+	  the scheduler, a counter is bumped and that counter's current value is
+	  assigned as the new item's ID.
+
+	  This patch introduces a new method for assigning scheduler IDs. Instead
+	  of assigning from a counter, a queue of available IDs is maintained.
+	  When assigning a new ID, an ID is pulled from the queue. When a
+	  scheduler item is released, its ID is pushed back onto the queue. This
+	  way, IDs may be reused when they become available, and the growth of ID
+	  numbers is directly related to concurrent activity within a scheduler
+	  context rather than the uptime of the system.
+
+	  Change-Id: I532708eef8f669d823457d7fefdad9a6078b99b2
+
+2015-08-21 21:50 +0000 [865377fc38]  Rodrigo Ramírez Norambuena <a at rodrigoramirez.com>
+
+	* chan_sip.c: Validation on module reload
+
+	  Change validation on reload module because now used the cli function for
+	  reload. The sip_reload() function never fail and ever return NULL for this
+	  reason on reload() now use the call the sip_reload() and return
+	  AST_MODULE_LOAD_SUCCESS.
+
+	  This problem is dectected on reload by PUT method on ARI, getting always
+	  404 http code when the module is reloaded.
+
+	  ASTERISK-25325 #close
+	  Reporte by: Rodrigo Ramírez Norambuena
+
+	  Change-Id: I41215877fb2cfc589e0d4d464000cf6825f4d7fb
+
+2015-08-21 17:39 +0000 [e75aff53e6]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_pjsip_pubsub.c: Mark ast_sip_create_subscription() as not used.
+
+	  Change-Id: I2b8db18eac36c01a5c7eb9467699124e203fd093
+
+2015-09-09 12:24 +0000 [4d91d01df1]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_pjsip_pubsub.c: Add some notification comments.
+
+	  Change-Id: Ie62ff1f4b7adc1a12fa0303f53926af249b25e20
+
+2015-08-21 18:01 +0000 [f36a9d1221]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_pjsip_pubsub.c: Set dlg_status code instead of sending SIP response.
+
+	  We should not try to send a SIP response message because we may be
+	  restoring a persistent subscription where we are not responding to a SIP
+	  request.
+
+	  Change-Id: Id89167ef90320c5563f37e632db0dda6cb9e7dec
+
+2015-08-21 17:40 +0000 [94582f8fab]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_pjsip_pubsub.c: Fix off-nominal memory leak.
+
+	  Fix off-nominal visited vector leak in build_resource_tree().
+
+	  Change-Id: If0399c7941c9c0b1038bcfb7b9a371760977831c
+
+2015-08-21 15:26 +0000 [8b3ed52239]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_pjsip_pubsub.c: Fix one byte buffer overrun error.
+
+	  ast_sip_pubsub_register_body_generator() did not account for the null
+	  terminator set by sprintf() in the allocated output buffer.
+
+	  Change-Id: I388688a132e479bca6ad1c19275eae0070969ae2
+
+2015-08-21 15:25 +0000 [4329bd1e4c]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_pjsip_pubsub.c: Use ast_alloca() instead of alloca().
+
+	  Change-Id: Ia396096b4fedc2874649ca11137612c3f55e83e3
+
+2015-08-21 11:04 +0000 [a456a20ecf]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_pjsip_pubsub.c: Add missing error return in load_module().
+
+	  Change-Id: I15debd0f717f16ee2f78e7f56151c3b3b97b72fc
+
+2015-08-21 11:03 +0000 [f58f4c6e27]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_pjsip/location.c: Use the builtin ao2_callback() match function instead.
+
+	  Change-Id: I364906d6d2bad3472929986704a0286b9a2cbe3f
+
+2015-09-10 09:49 +0000 [9d1f176e29]  Mark Michelson <mmichelson at digium.com>
+
+	* res_pjsip: Copy default_from_user to avoid crash.
+
+	  The default_from_user retrieval function was pulling the
+	  default_from_user from the global configuration struct in an unsafe way.
+	  If using a database as a backend configuration store, the global
+	  configuration struct is short-lived, so grabbing a pointer from it
+	  results in referencing freed memory.
+
+	  The fix here is to copy the default_from_user value out of the global
+	  configuration struct.
+
+	  Thanks go to John Hardin for discovering this problem and proposing the
+	  patch on which this fix is based.
+
+	  ASTERISK-25390 #close
+	  Reported by Mark Michelson
+
+	  Change-Id: I6b96067a495c1259da768f4012d44e03e7c6148c
+
+2015-09-10 08:39 +0000 [1dd0e220bf]  Matt Jordan <mjordan at digium.com>
+
+	* res/res_pjsip_nat: Ignore REGISTER requests when looking for a Record-Route
+
+	  We will only rewrite the Contact header if there is no Record-Route header in
+	  the received request. If a malfunctioning proxy places a Record-Route header
+	  into a REGISTER request, we will decide that we shouldn't update the IP/port
+	  in the Contact header, and we will end up storing a contact with an AoR that
+	  contains the NAT'd IP address.
+
+	  While it is nice to have the proxy *not* send a Record-Route in a REGISTER
+	  request, it's also a good idea to not process the header in a non-dialog
+	  message. This patch updates the code to explicitly ignore the Record-Route
+	  header in REGISTER requests.
+
+	  ASTERISK-25387 #close
+
+	  Change-Id: I4bd3bcccc4003d460cc354d986b0dea2e433ef3f
+
+2015-09-03 21:15 +0000 [4eedd9ef9d]  Matt Jordan <mjordan at digium.com>
+
+	* main/config_options: Check for existance of internal object before derefing
+
+	  Asterisk can load and register an object type while still having an invalid
+	  sorcery mapping. This can cause an issue when a creation call is invoked.
+	  For example, mis-configuring PJSIP's endpoint identifier by IP address mapping
+	  in sorcery.conf will cause the sorcery mechanism to be invalidated; however, a
+	  subsequent ARI invocation to create the object will cause a crash, as the
+	  internal type may not be registered as sorcery expects.
+
+	  Merely checking for a NULL pointer here solves the issue.
+
+	  Change-Id: I54079fb94a1440992f4735a9a1bbf1abb1c601ac
+2015-09-09 16:46 +0000 [71408df2b8]  Alexander Anikin <may213 at yandex.ru>
+
+	* chan_ooh323: Add ProgressIndicator IE with inband info available
+
+	  Add ProgressIndicator IE with inband info present to Progress and
+	  Alerting Q.931 message
+
+	  ASTERISK-25227 #close
+	  Reported by: Alexandr Dranchuk
+
+	  Change-Id: I326ad13cb1db9a72b3fd902bafed3c28a3684203
+2015-09-08 10:35 +0000 [f72f9ceefc]  Scott Griepentrog <scott at griepentrog.com>
+
+	* pjsip: avoid possible crash req_caps allocation failure
+
+	  Make certain that the pjsip session has not failed to
+	  allocate the format capabilities structure, which can
+	  otherwise cause a crash when referenced.
+
+	  ASTERISK-25323
+
+	  Change-Id: I602790ba12714741165e441cc64a3ecde4cb5750
+
+2015-09-03 14:07 +0000 [fbf720db91]  Jonathan Rose <jrose at digium.com>
+
+	* ParkAndAnnounce: Add variable inheritance
+
+	  In Asterisk 11, the announcer channel would receive channel variables
+	  from the channel being parked by means of normal channel inheritance.
+	  This functionality was lost during the big res_parking project in
+	  Asterisk 12. This patch restores that functionality.
+
+	  ASTERISK-25369 #close
+	  Review: https://gerrit.asterisk.org/#/c/1180/
+
+	  Change-Id: Ie47e618330114ad2ea91e2edcef1cb6f341eed6e
+
+2015-09-04 16:33 +0000 [695f26cbb7]  David M. Lee <dlee at respoke.io>
+
+	* res_rtp_asterisk: Add more ICE debugging
+
+	  In working through a recent ICE negotiation bug, I found the debug
+	  logging in res_rtp_asterisk to be lacking. This patch adds a number of
+	  debug and warning statements that were helpful.
+
+	  Change-Id: I950c6d8f13a41f14b3d6334b4cafe7d4e997be80
+2015-09-01 10:16 +0000 [4ed9c9a280]  Guido Falsi <madpilot at freebsd.org>
+
+	* Core/General: Add #ifdef needed on FreeBSD.
+
+	  pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED on FreeBSD
+	  too.
+
+	  ASTERISK-25310 #close
+	  Reported by: Guido Falsi
+
+	  Change-Id: Iae6befac9028b5b9795f86986a4a08a1ae6ab7c4
+
+2015-09-08 07:21 +0000 [5469caa9dd]  Joshua Colp <jcolp at digium.com>
+
+	* res_pjsip: Use hash for contact object identity instead of Contact URI.
+
+	  In the wild it is possible for Contact URIs to be quite long as
+	  parameters can exist on them. This can present a problem when storing
+	  them in the AstDB as the URI is used as part of the object name and
+	  there is a fixed length limit for the AstDB. This will cause
+	  the contact to not get stored.
+
+	  This change uses the MD5 hash of the Contact URI as part of the
+	  object name instead. This has a fixed length which is guaranteed
+	  to not exceed the AstDB length limit.
+
+	  ASTERISK-25295 #close
+
+	  Change-Id: Ie8252a75331ca00b41b9f308f42cc1fbdf701a02
+
+2015-09-07 13:19 +0000 [480c443e26]  Alexander Anikin <may213 at yandex.ru>
+
+	* chan_ooh323: call ast_rtp_instance_stop on ooh323_destroy
+
+	      Call ast_rtp_instance_stop on ooh323_destroy to free resources
+	      allocated by rtp instance
+
+	      ASTERISK-25299 #close
+	      Report by: Alexandr Dranchuk
+
+	  Change-Id: I455096bd7da016b871afe90af86067c2c7c9f33f
+
+2015-09-07 11:15 +0000 [c3e6debdb9]  Matt Jordan <mjordan at digium.com>
+
+	* res/res_pjsip: Purge contacts when an AoR is deleted
+
+	  When an AoR is deleted by an external mechanism, such as through ARI, we
+	  currently do not remove dynamic contacts that were created for that AoR as a
+	  result of a received REGISTER request. As a result, re-creating the AoR will
+	  cause the dynamic contact to be interpreted as a persistent contact, leading
+	  to some rather strange state being created for the contacts/endpoints.
+
+	  This patch adds a sorcery observer for the 'aor' object. When a delete is
+	  issued on the underlying sorcery object, the observer is called, and all
+	  contacts created and persisted in sorcery for that AoR are also removed. Note
+	  that we don't want to perform this action when an AO2 object that is an AoR is
+	  destroyed, as the AoR can still exist in the backing storage (and we would
+	  thus be removing valid contacts from an AoR that still "exists".)
+
+	  ASTERISK-25381 #close
+
+	  Change-Id: I6697e51ef6b2858b5d63401f35dc378bb0f90328
+
+2015-09-05 14:58 +0000 [78d0b9d97e]  Matt Jordan <mjordan at digium.com>
+
+	* channels/pjsip/dialplan_functions: Add an option for extracting the SIP call-id
+
+	  This patch adds a new option to the CHANNEL function that allows for the
+	  extraction of the SIP call-id. It is used in conjunction with the 'pjsip'
+	  option, and will return the Call-ID of the INVITE request that established
+	  the PJSIP channel.
+
+	  ASTERISK-25352
+
+	  Change-Id: I278d1f8bcfe3a53c5aa1dadebc14e92b0abd476a
+
+2015-09-04 16:06 +0000 [61c6c6aa6c]  David M. Lee <dlee at respoke.io>
+
+	* Fix when remote candidates exceed PJ_ICE_MAX_CAND
+
+	  We were passing the wrong count into pj_ice_sess_create_check_list(),
+	  causing the create to fail if we ever received more than PJ_ICE_MAX_CAND
+	  candidates.
+
+	  Change-Id: I0303d8e1ecb20a8de9fe629a3209d216c4028378
+
+2015-09-04 14:40 +0000 [ac62928d6b]  Mark Michelson <mmichelson at digium.com>
+
+	* res_pjsip: Change default from user value.
+
+	  When Asterisk sends an outbound SIP request, if there is no direct
+	  reason to place a specific value for the username in the From header,
+	  Asterisk would generate a UUID. For example, this would happen when
+	  sending outbound OPTIONS requests when qualifying or when sending
+	  outbound INVITE requests when originating (if no explicit caller ID were
+	  provided). The issue is that some SIP providers reject these sorts of
+	  requests with a "Name too long" error response.
+
+	  This patch aims to fix this by changing the default outbound username in
+	  From headers to "asterisk". This value can be overridden by changing the
+	  default_from_user option in the global options if desired.
+
+	  ASTERISK-25377 #close
+	  Reported by Mark Michelson
+
+	  Change-Id: I6a4d34a56ff73ff4f661b0075aeba5461b7f3190
+
+2015-09-04 09:26 +0000 [6002472a62]  Scott Griepentrog <scott at griepentrog.com>
+
+	* endpoint snapshot: avoid second cleanup on alloc failure
+
+	  In ast_endpoint_snapshot_create(), a failure to init the
+	  string fields results in two attempts to ao2_cleanup the
+	  same pointer.  Removed RAII_VAR to eliminate problem.
+
+	  ASTERISK-25375 #close
+	  Reported by: Scott Griepentrog
+
+	  Change-Id: If4d9dfb1bbe3836b623642ec690b6d49b25e8979
+
+2015-09-04 05:33 +0000 [d32e516c7c]  Martin Tomec <tomec.martin at gmail.com>
+
+	* res/pjsip: Mark WSS transport as secure
+
+	  Pjsip is refusing to use unsecure transport with "sips" in url.
+	  WSS should be considered as secure transport.
+
+	  ASTERISK-24602 #comment Partially fixed by setting WSS as secure
+
+	  Change-Id: Iddac406c6deba6240c41a603b8859dfefe1a5353
+
+2015-09-02 17:26 +0000 [ad9cb6c2ce]  Mark Michelson <mmichelson at digium.com>
+
+	* res_pjsip: Fix contact refleak on stateful responses.
+
+	  When sending a stateful response, creation of the transaction can fail,
+	  most commonly because we are trying to create a transaction from a
+	  retransmitted request. When creation of the transaction fails, we end up
+	  leaking a reference to a contact that was bumped when the response was
+	  created.
+
+	  This patch adds the missing deref and fixes the reference leak.
+
+	  Change-Id: I2f97ad512aeb1b17e87ca29ae0abacb4d6395f07
+
+2015-09-02 12:41 +0000 [cc1363209e]  Joshua Colp <jcolp at digium.com>
+
+	* pbx: Fix crash when issuing "core show hints" with long pattern match.
+
+	  When issuing the "core show hints" CLI command a combination of both
+	  the hint extension and context is created. This uses a fixed size
+	  buffer expecting that the extension will not exceed maximum extension
+	  length. When the extension is actually a pattern match this constraint
+	  does not hold true, and the extension may exceed the maximum extension
+	  length. In this case extra characters are written past the end of the
+	  fixed size buffer.
+
+	  This change makes it so the construction of the combined hint extension
+	  and context can not exceed the size of the buffer.
+
+	  ASTERISK-25367 #close
+
+	  Change-Id: Idfa1b95d0d4dc38e675be7c1de8900b3f981f499
+
+2015-09-01 09:05 +0000 [d58c8d73af]  Mark Michelson <mmichelson at digium.com>
+
+	* res_pjsip_pubsub: re-re-fix persistent subscription storage.
+
+	  A recent change to res_pjsip_pubsub switched to using pjsip_msg_print as
+	  a means of writing an appropriate packet to persistent storage. While
+	  this partially solved the issue, it had its own problems.
+	  pjsip_msg_print will always add a Content-Length header to the message
+	  it prints. Frequent restarts of Asterisk can result in persistent
+	  subscriptions being written with five or more Content-Length headers. In
+	  addition, sometimes some apparent corruption of individual headers could
+	  be seen.
+
+	  This aims to fix the problem by not running a parsed message through an
+	  interpreter but rather by taking the raw message and saving it. The
+	  logic for what to save is going to be different depending on whether a
+	  SUBSCRIBE was received from the wire or if it was pulled from
+	  persistence. When receiving a packet from the wire, when using a
+	  streaming transport, the rdata->pkt_info.packet may contain multiple SIP
+	  messages or fragments. However, the rdata->msg_info.msg_buf will always
+	  contain the current SIP message to be processed. When pulling from
+	  persistence, though, the rdata->msg_info.msg_buf will be NULL since no
+	  transport actually handled the packet. However, since we know that we
+	  will always ever pull one SIP message from persistence, we are free to
+	  save directly from rdata->pkt_info.packet instead.
+
+	  ASTERISK-25365 #close
+	  Reported by Mark Michelson
+
+	  Change-Id: I33153b10d0b4dc8e3801aaaee2f48173b867855b
+
+2015-08-31 15:24 +0000 [03fe79f29e]  Mark Michelson <mmichelson at digium.com>
+
+	* Fix deadlock on presence state changes.
+
+	  A deadlock was observed where three threads were competing for different
+	  locks:
+
+	  * One thread held the hints lock and was attempting to lock a specific
+	    hint.
+	  * One thread was holding the specific hint's lock and was attempting to
+	    lock the contexts lock
+	  * One thread was holding the contexts lock and attempting to lock the
+	    hints lock.
+
+	  Clearly the second thread was doing the wrong thing here. The fix for
+	  this is to make sure that the hint's lock is not held on presence state
+	  changes. Something similar is already done (and commented about) for
+	  device state changes.
+
+	  ASTERISK-25362 #close
+	  Reported by Mark Michelson
+
+	  Change-Id: I15ec2416b92978a4c0c08273b2d46cb21aff97e2
+
+2015-08-29 10:36 +0000 [a676ba2aad]  Joshua Colp <jcolp at digium.com>
+
+	* taskprocessor: Fix race condition between unreferencing and finding.
+
+	  When unreferencing a taskprocessor its reference count is checked
+	  to determine if it should be unlinked from the taskprocessors
+	  container and its listener shut down. In between the time when the
+	  reference count is checked and unlinking it is possible for
+	  another thread to jump in, find it, and get a reference to it. If
+	  the thread then uses the taskprocessor it may find that it is not
+	  in the state it expects.
+
+	  This change locks the taskprocessors container during almost the
+	  entire unreference operation to ensure that any other thread which
+	  may attempt to find the taskprocessor has to wait.
+
+	  ASTERISK-25295
+
+	  Change-Id: Icb842db82fe1cf238da55df92e95938a4419377c
+
+2015-08-28 20:22 +0000 [1b1561f4c8]  Joshua Colp <jcolp at digium.com>
+
+	* res_pjsip_sdp_rtp: Fix multiple keepalive scheduled items.
+
+	  The keepalive support in res_pjsip_sdp_rtp currently assumes
+	  that a stream will only be negotiated once. This is false.
+	  If the stream is replaced and later added back it can be
+	  negotiated again causing multiple keepalive scheduled items
+	  to exist. This change explicitly deletes the existing
+	  keepalive scheduled item before adding the new one.
+
+	  The res_pjsip_sdp_rtp module also does not stop RTP
+	  keepalives or timeout timer if the stream has been
+	  replaced. This change adds a callback to the session media
+	  interface to allow a media stream to be stopped without
+	  the resources being destroyed. This allows the scheduled
+	  items and RTP to be stopped when the stream no longer
+	  exists.
+
+	  ASTERISK-25356 #close
+
+	  Change-Id: Ibe6a7cc0927c87326fd5f1c0d4ad889dbfbea1de
+
+2015-08-28 19:57 +0000 [85e1cb51b2]  Joshua Colp <jcolp at digium.com>
+
+	* sched: ast_sched_del may return prematurely due to spurious wakeup
+
+	  When deleting a scheduled item if the item in question is currently
+	  executing the ast_sched_del function waits until it has completed.
+	  This is accomplished using ast_cond_wait. Unfortunately the
+	  ast_cond_wait function can suffer from spurious wakeups so the
+	  predicate needs to be checked after it returns to make sure it has
+	  really woken up as a result of being signaled.
+
+	  This change adds a loop around the ast_cond_wait to make sure that
+	  it only exits when the executing task has really completed.
+
+	  ASTERISK-25355 #close
+
+	  Change-Id: I51198270eb0b637c956c61aa409f46283432be61
+
+2015-08-27 12:26 +0000 [c2c7319082]  Joshua Colp <jcolp at digium.com>
+
+	* res_pjsip_session: Don't invoke session supplements twice for BYE requests.
+
+	  When a BYE request is received the PJSIP invite session implementation
+	  creates and sends a 200 OK response before we are aware of it. This
+	  causes the INVITE session state callback to be called into and ultimately
+	  the session supplements run on the BYE request. Once this response has
+	  been sent the normal transaction state callback is invoked which
+	  invokes the session supplements on the BYE request again. This can
+	  be problematic in particular with res_pjsip_rfc3326 as it may
+	  attempt to update the hangup cause code on the channel while it is
+	  in the process of being hung up.
+
+	  This change makes it so the session supplements are only invoked
+	  once by the INVITE session state callback.
+
+	  ASTERISK-25318 #close
+
+	  Change-Id: I69c17df55ccbb61ef779ac38cc8c6b411376c19a
+
+2015-08-26 15:26 +0000 [6862c2a167]  Scott Griepentrog <scott at griepentrog.com>
+
+	* Chaos: handle failed allocation in get_media_encryption_type
+
+	  If the ast_strndup() call fails to allocate a copy of the
+	  transport string for parsing, fail gracefully.
+
+	  ASTERISK-25323
+	  Reported by: Scott Griepentrog
+
+	  Change-Id: Ia4b905ce6d03da53fea526224455c1044b1a5a28
+
+2015-08-26 14:25 +0000 [f1cd636658]  Scott Griepentrog <scott at griepentrog.com>
+
+	* Chaos: make hangup NULL tolerant
+
+	  In chan_pjsip_new, if allocation of the pvt
+	  structure fails, ast_hangup is called.  But
+	  it was written to assume pvt was valid, and
+	  this change corrects that.
+
+	  ASTERISK-25323
+	  Reported by: Scott Griepentrog
+
+	  Change-Id: I5f47860fe9cee4cd56abd3f79b108678ab72cc87
+
+2015-08-26 05:40 +0000 [c01111223f]  Joshua Colp <jcolp at digium.com>
+
+	* chan_sip: Allow call pickup to set the hangup cause.
+
+	  The call pickup implementation in chan_sip currently sets the channel
+	  hangup cause to "normal clearing" if call pickup is successfully
+	  performed. This action overwrites the "answered elsewhere" hangup cause
+	  set by the call pickup code and can result in the SIP device in
+	  question showing a missed call when it should not.
+
+	  This change sets the hangup cause to "normal clearing" as a
+	  default initially but allows the call pickup to change it as
+	  needed.
+
+	  ASTERISK-25346 #close
+
+	  Change-Id: I00ac2c269cee9e29586ee2c65e83c70e52a02cff
+
+2015-08-25 07:17 +0000 [2a4eee0cd9]  Joshua Colp <jcolp at digium.com>
+
+	* res_pjsip: Add common ast_sip_get_host_ip API.
+
+	  Modules commonly used the pj_gethostip function for retrieving the
+	  IP address of the host. This function does not cache the result and may
+	  result in a DNS lookup occurring, or additional work. If the DNS
+	  server is unreachable or network issues arise this can cause the
+	  pj_gethostip function to block for a period of time.
+
+	  This change adds an ast_sip_get_host_ip and ast_sip_get_host_ip_string
+	  function which does the same thing but caches the host IP address at
+	  module load time. This results in no additional work being done each
+	  time the local host IP address is needed.
+
+	  ASTERISK-25342 #close
+
+	  Change-Id: I3205deb679b01fa5ac05a94b623bfd620a2abe1e
+
+2015-08-24 11:04 +0000 [7c4d0c3506]  Joshua Colp <jcolp at digium.com>
+
+	* res_pjsip_pubsub: On recreated notify fail deleted sub_tree is referenced
+
+	  When recreating a subscription it is possible for a freed sub_tree
+	  to be referenced when the initial NOTIFY fails to be created.
+
+	  Change-Id: I681c215309aad01b21d611c2de47b3b0a6022788
+
+2015-08-24 06:21 +0000 [6c2dab1e88]  Joshua Colp <jcolp at digium.com>
+
+	* bridge: Kick channel from bridge if hung up during action.
+
+	  When executing an action in a bridge it is possible for the
+	  channel to be hung up without the bridge becoming aware of it.
+	  This is most easily reproducible by hanging up when the bridge
+	  is streaming DTMF due to a feature timeout. This change makes
+	  it so after action execution the channel is checked to determine
+	  if it has been hung up and if it has it is kicked from the bridge.
+
+	  ASTERISK-25341 #close
+
+	  Change-Id: I6dd8b0c3f5888da1c57afed9e8a802ae0a053062
+
+2015-08-23 18:26 +0000 [bc6fe07f5c]  Matt Jordan <mjordan at digium.com>
+
+	* res_pjsip/pjsip_configuration: Disregard empty auth values
+
+	  When an endpoint is backed by a non-static conf file backend (such as
+	  the AstDB or Realtime), the 'auth' object may be returned as being an
+	  empty string. Currently, res_pjsip will interpret that as being a valid
+	  auth object, and will attempt to authenticate inbound requests. This
+	  isn't desired; is an auth value is empty (which the name of an auth
+	  object cannot be), we should instead interpret that as being an invalid
+	  auth object and skip it.
+
+	  ASTERISK-25339 #close
+
+	  Change-Id: Ic32b0c6eb5575107d5164a8c40099e687cd722c7
+
+2015-08-19 12:10 +0000 [0582776f7f]  Richard Mudgett <rmudgett at digium.com>
+
+	* ari/ari_websockets.c: Fix ast_debug parameter type mismatch.
+
+	  This is a type mismatch fix of the debugging commit
+	  c63316eec10e1990a88bf4712238d6deb375bfa9 made to find out why
+	  a testsuite test was failing only on one of the continuous
+	  integration build agents.
+
+	  Change-Id: Iba34f6e87cec331f6ac80e4daff6476ea6f00a75
+
+2015-08-19 10:30 +0000 [504213f542]  Scott Griepentrog <scott at griepentrog.com>
+
+	* contrib: script install_prereq should install sqlite3
+
+	  Asterisk needs the sqlite 3 library, which is package
+	  sqlite-devel in CentOS. By adding this package to the
+	  script, a problem with configure failing is resolved.
+
+	  ASTERISK-25331 #close
+	  Reported by: Kevin Harwell
+
+	  Change-Id: I90efaf6a01914fea03f21e5cdbd91c348f44b0ec
+
+2015-08-18 16:06 +0000 [77518d5434]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_http_websocket.c: Fix some off nominal path cleanup.
+
+	  * Remove extraneous unlock on off-nominal path.
+	  * Add missing HTTP error reply.
+
+	  Change-Id: I1f402bfe448fba8696b507477cab5f060ccd9b2b
+
+2015-08-18 14:46 +0000 [c61547fee6]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_ari.c: Add missing off nominal unlock and remove a RAII_VAR().
+
+	  Change-Id: I0c5e7b34057f26dadb39489c4dac3015c52f5dbf
+
+2015-08-17 16:41 +0000 [bd867cd078]  Richard Mudgett <rmudgett at digium.com>
+
+	* app_queue.c: Extract some functions for simpler code.
+
+	  * Extract set_queue_member_pause() from set_member_paused() for simpler
+	  and more consistent code.
+
+	  * Extract set_queue_member_ringinuse() from
+	  set_member_ringinuse_help_members() for simpler code.
+
+	  Change-Id: Iecc1f4119c63347341d7ea6b65f5fc4963706306
+
+2015-08-14 12:55 +0000 [e5f5b9f384]  Richard Mudgett <rmudgett at digium.com>
+
+	* app_queue.c: Fix setting QUEUE_MEMBER 'paused' and 'ringinuse'.
+
+	  Setting the 'paused' and 'ringinuse' options on a queue member using the
+	  dialplan function QUEUE_MEMBER did not behave the same way as the
+	  equivalent dialplan applications or AMI actions.
+
+	  * Made queue_function_mem_write() call the set_member_paused() and
+	  set_member_value() for the 'paused' and 'ringinuse' options respectively.
+	  A beneficial side effect is that the queue name is now optional and sets
+	  the value in all queues the interface is a member.
+
+	  * Update QUEUE_MEMBER XML documentation.
+
+	  * Fix error checking in QUEUE_MEMBER() write.
+
+	  ASTERISK-25215 #close
+	  Reported by: Lorne Gaetz
+
+	  Change-Id: I3a016be8dc94d63a9cc155295ff9c9afa5f707cb
+
+2015-08-17 13:34 +0000 [ded51e3d77]  Richard Mudgett <rmudgett at digium.com>
+
+	* app_queue.c: Fix error checking in QUEUE_MEMBER() read.
+
+	  Change-Id: I7294e13d27875851c2f4ef6818adba507509d224
+
+2015-08-17 11:00 +0000 [ab373f2cef]  Scott Griepentrog <scott at griepentrog.com>
+
+	* CHAOS: prevent sorcery object with null id
+
+	  When allocating a sorcery object, fail if the
+	  id value was not allocated.
+
+	  ASTERISK-25323
+	  Reported by: Scott Griepentrog
+
+	  Change-Id: I152133fb7545a4efcf7a0080ada77332d038669e
+
+2015-08-14 15:46 +0000 [b719f56c72]  Mark Michelson <mmichelson at digium.com>
+
+	* res_pjsip_sdp_rtp: Restore removed NULL check.
+
+	  When sending an RTP keepalive, we need to be sure we're not dealing with
+	  a NULL RTP instance. There had been a NULL check, but the commit that
+	  added the rtp_timeout and rtp_hold_timeout options removed the NULL
+	  check.
+
+	  Change-Id: I2d7dcd5022697cfc6bf3d9e19245419078e79b64
+
+2015-08-13 12:30 +0000 [cea5dc7b8a]  Richard Mudgett <rmudgett at digium.com>
+
+	* audiohook.c: Simplify variable usage in audiohook_read_frame_both().
+
+	  Change-Id: I58bed58631a94295b267991c5b61a3a93c167f0c
+
+2015-08-13 12:22 +0000 [b3a56bee83]  Richard Mudgett <rmudgett at digium.com>
+
+	* audiohook.c: Fix MixMonitor crash when using the r() or t() options.
+
+	  The built frame format in audiohook_read_frame_both() is now set to a
+	  signed linear format before the rx and tx frames are duplicated instead of
+	  only for the mixed audio frame duplication.
+
+	  ASTERISK-25322 #close
+	  Reported by Sean Pimental
+
+	  Change-Id: I86f85b5c48c49e4e2d3b770797b9d484250a1538
+
+2015-08-12 12:59 +0000 [25af2d71c8]  Kevin Harwell <kharwell at digium.com>
+
+	* chan_sip.c: wrong peer searched in sip_report_security_event
+
+	  In chan_sip, after handling an incoming invite a security event is raised
+	  describing authorization (success, failure, etc...). However, it was doing
+	  a lookup of the peer by extension. This is fine for register messages, but
+	  in the case of an invite it may search and find the wrong peer, or a non
+	  existent one (for instance, in the case of call pickup). Also, if the peers
+	  are configured through realtime this may cause an unnecessary database lookup
+	  when caching is enabled.
+
+	  This patch makes it so that sip_report_security_event searches by IP address
+	  when looking for a peer instead of by extension after an invite is processed.
+
+	  ASTERISK-25320 #close
+
+	  Change-Id: I9b3f11549efb475b6561c64f0e6da1a481d98bc4
+2015-08-13 05:26 +0000 [e18c300550]  Joshua Colp <jcolp at digium.com>
+
+	* res_http_websocket: When shutting down a session don't close closed socket
+
+	  Due to the use of ast_websocket_close in session termination it is
+	  possible for the underlying socket to already be closed when the
+	  session is terminated. This occurs when the close frame is attempted
+	  to be written out but fails.
+
+	  Change-Id: I7572583529a42a7dc911ea77a974d8307d5c0c8b
+2015-08-11 05:24 +0000 [b4e9416138]  Joshua Colp <jcolp at digium.com>
+
+	* res_http_websocket: Forcefully terminate on write errors.
+
+	  The res_http_websocket module will currently attempt to close
+	  the WebSocket connection if fatal cases occur, such as when
+	  attempting to write out data and being unable to. When the
+	  fatal cases occur the code attempts to write a WebSocket close
+	  frame out to have the remote side close the connection. If
+	  writing this fails then the connection is not terminated.
+
+	  This change forcefully terminates the connection if the
+	  WebSocket is to be closed but is unable to send the close frame.
+
+	  ASTERISK-25312 #close
+
+	  Change-Id: I10973086671cc192a76424060d9ec8e688602845
+
+2015-08-10 13:43 +0000 [256bc52b66]  Richard Mudgett <rmudgett at digium.com>
+
+	* chan_dahdi.c: Flush the DAHDI write buffer after starting DTMF.
+
+	  Pressing DTMF digits on a phone to go out on a DAHDI channel can result in
+	  the digit not being recognized or even heard by the peer.
+
+	  Phone -> Asterisk -> DAHDI/channel
+
+	  Turns out the DAHDI behavior with DTMF generation (and any other generated
+	  tones) is exposed by the "buffers=" setting in chan_dahdi.conf.  When
+	  Asterisk requests to start sending DTMF then DAHDI waits until its write
+	  buffer is empty before generating any samples for the DTMF tones.  When
+	  Asterisk subsequently requests DAHDI to stop sending DTMF then DAHDI
+	  immediately stops generating the DTMF samples.  As a result, the more
+	  samples there are in the DAHDI write buffer the shorter the time DTMF
+	  actually gets sent on the wire.  If there are more samples in the write
+	  buffer than the time DTMF is supposed to be sent then no DTMF gets sent on
+	  the wire.  With the "buffers=12,half" setting and each buffer representing
+	  20 ms of samples then the DAHDI write buffer is going to contain around
+	  120 ms of samples.  For DTMF to be recognized by the peer the actual sent
+	  DTMF duration needs to be a minimum of 40 ms.  Therefore, the intended
+	  duration needs to be a minimum of 160 ms for the peer to receive the
+	  minimum DTMF digit duration to recognize it.
+
+	  A simple and effective solution to work around the DAHDI behavior is for
+	  Asterisk to flush the DAHDI write buffer when sending DTMF so the full
+	  duration of DTMF is actually sent on the wire.  When someone is going to
+	  send DTMF they are not likely to be talking before sending the tones so
+	  the flushed write samples are expected to just contain silence.
+
+	  * Made dahdi_digit_begin() flush the DAHDI write buffer after requesting
+	  to send a DTMF digit.
+
+	  ASTERISK-25315 #close
+	  Reported by John Hardin
+
+	  Change-Id: Ib56262c708cb7858082156bfc70ebd0a220efa6a
+
+2015-08-05 14:21 +0000 [800e0ea48d]  Richard Mudgett <rmudgett at digium.com>
+
+	* chan_dahdi.c: Lock private struct for ast_write().
+
+	  There is a window of opportunity for DTMF to not go out if an audio frame
+	  is in the process of being written to DAHDI while another thread starts
+	  sending DTMF.  The thread sending the audio frame could be past the
+	  currently dialing check before being preempted by another thread starting
+	  a DTMF generation request.  When the thread sending the audio frame
+	  resumes it will then cause DAHDI to stop the DTMF tone generation.  The
+	  result is no DTMF goes out.
+
+	  * Made dahdi_write() lock the private struct before writing to the DAHDI
+	  file descriptor.
+
+	  ASTERISK-25315
+	  Reported by John Hardin
+
+	  Change-Id: Ib4e0264cf63305ed5da701188447668e72ec9abb
+
+2015-08-10 18:23 +0000 [c126afe18f]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_pjsip.c: Fix crash from corrupt saved SUBSCRIBE message.
+
+	  If the saved SUBSCRIBE message is not parseable for whatever reason then
+	  Asterisk could crash when libpjsip tries to parse the message and adds an
+	  error message to the parse error list.
+
+	  * Made ast_sip_create_rdata() initialize the parse error rdata list.  The
+	  list is checked after parsing to see that it remains empty for the
+	  function to return successful.
+
+	  ASTERISK-25306
+	  Reported by Mark Michelson
+
+	  Change-Id: Ie0677f69f707503b1a37df18723bd59418085256
+
+2015-08-10 07:40 +0000 [f68c995bc9]  Alexander Traud <pabstraud at compuserve.com>
+
+	* chan_sip: Fix negotiation of iLBC 30.
+
+	  iLBC 20 was advertised in a SIP/SDP negotiation. However, only iLBC 30 is
+	  supported. Removes "a=fmtp:x mode=y" from SDP. Because of RFC 3952 section 5,
+	  only iLBC 30 is negotiated now.
+
+	  ASTERISK-25309 #close
+
+	  Change-Id: I92d724600a183eec3114da0ac607b994b1a793da
+
+2015-08-09 18:42 +0000 [8e194047ac]  Matt Jordan <mjordan at digium.com>
+
+	* res/res_format_attr_silk: Expose format attributes to other modules
+
+	  This patch adds the .get callback to the format attribute module, such
+	  that the Asterisk core or other third party modules can query for the
+	  negotiated format attributes.
+
+	  Change-Id: Ia24f55cf9b661d651ce89b4f4b023d921380f19c
+
+2015-08-09 17:56 +0000 [a0f451c35e]  Matt Jordan <mjordan at digium.com>
+
+	* main/format: Add an API call for retrieving format attributes
+
+	  Some codecs that may be a third party library to Asterisk need to have
+	  knowledge of the format attributes that were negotiated. Unfortunately,
+	  when the great format migration of Asterisk 13 occurred, that ability
+	  was lost.
+
+	  This patch adds an API call, ast_format_attribute_get, to the core
+	  format API, along with updates to the unit test to check the new API
+	  call. A new callback is also now available for format attribute modules,
+	  such that they can provide the format attribute values they manage.
+
+	  Note that the API returns a void *. This is done as the format attribute
+	  modules themselves may store format attributes in any particular manner
+	  they like. Care should be taken by consumers of the API to check the
+	  return value before casting and dereferencing. Consumers will obviously
+	  need to have a priori knowledge of the type of the format attribute as
+	  well.
+
+	  Change-Id: Ieec76883dfb46ecd7aff3dc81a52c81f4dc1b9e3
+
+2015-08-07 22:11 +0000 [26f0559a94]  David M. Lee <dlee at respoke.io>
+
+	* Replace htobe64 with htonll
+
+	  We don't have a compatability function to fill in a missing htobe64; but
+	  we already have one for the identical htonll.
+
+	  Change-Id: Ic0a95db1c5b0041e14e6b127432fb533b97e4cac
+
+2015-08-07 14:20 +0000 [df9ce36366]  Scott Emidy <jemidy at digium.com>
+
+	* ARI: Retrieve existing log channels
+
+	  An http request can be sent to get the existing Asterisk logs.
+
+	  The command "curl -v -u user:pass -X GET 'http://localhost:8088
+	  /ari/asterisk/logging'" can be run in the terminal to access the
+	  newly implemented functionality.
+
+	  * Retrieve all existing log channels
+
+	  ASTERISK-25252
+
+	  Change-Id: I7bb08b93e3b938c991f3f56cc5d188654768a808
+
+2015-08-07 11:14 +0000 [e9f1bc08cb]  Scott Emidy <jemidy at digium.com>
+
+	* ARI: Creating log channels
+
+	  An http request can be sent to create a log channel
+	  in Asterisk.
+
+	  The command "curl -v -u user:pass -X POST
+	  'http://localhost:088/ari/asterisk/logging/mylog?
+	  configuration=notice,warning'" can be run in the terminal
+	  to access the newly implemented functionality for ARI.
+
+	  * Ability to create log channels using ARI
+
+	  ASTERISK-25252
+
+	  Change-Id: I9a20e5c75716dfbb6b62fd3474faf55be20bd782
+
+2015-08-06 15:18 +0000 [78364132ce]  Scott Emidy <jemidy at digium.com>
+
+	* ARI: Deleting log channels
+
+	  An http request can be sent to delete a log channel
+	  in Asterisk.
+
+	  The command "curl -v -u user:pass -X DELETE 'http://localhost:8088
+	  /ari/asterisk/logging/mylog'" can be run in the terminal
+	  to access the newly implemented functionally for ARI.
+
+	  * Able to delete log channels using ARI
+
+	  ASTERISK-25252
+
+	  Change-Id: Id6eeb54ebcc511595f0418d586ff55914bc3aae6
+
+2015-08-06 12:48 +0000 [e25569ef95]  Mark Michelson <mmichelson at digium.com>
+
+	* res_pjsip_pubsub: More accurately persist packet.
+
+	  The pjsip_rx_data structure has a pkt_info.packet field on it that is
+	  the packet that was read from the transport. For datagram transports,
+	  the packet read from the transport will correspond to the SIP message
+	  that arrived. For streamed transports, however, it is possible to read
+	  multiple SIP messages in one packet.
+
+	  In a recent case, Asterisk crashed on a system where TCP was being used.
+	  This is because at some point, a read from the TCP socket resulted in a
+	  200 OK response as well as an incoming SUBSCRIBE request being stored in
+	  rdata->pkt_info.packet. When the SUBSCRIBE was processed, the
+	  combination 200 OK and SUBSCRIBE was saved in persistent storage. Later,
+	  a restart of Asterisk resulted in the crash because the persistent
+	  subscription recreation code ended up building the 200 OK response
+	  instead of a SUBSCRIBE request, and we attempted to access
+	  request-specific data.
+
+	  The fix here is to use the pjsip_msg_print() function in order to
+	  persist SUBSCRIBE requests. This way, rather than using the raw socket
+	  data, we use the parsed SIP message that PJSIP has given us. If we
+	  receive multiple SIP messages from a single read, we will be sure only
+	  to save off the relevant SIP message. There also is a safeguard put in
+	  place to make sure that if we do end up reconstructing a SIP response,
+	  it will not cause a crash.
+
+	  ASTERISK-25306 #close
+	  Reported by Mark Michelson
+
+	  Change-Id: I4bf16f7b76a2541d10b55de82bcd14c6e542afb2
+
+2015-08-04 16:12 +0000 [8521a86367]  Joshua Colp <jcolp at digium.com>
+
+	* res_pjsip: Ensure sanitized XML is NULL terminated.
+
+	  The ast_sip_sanitize_xml function is used to sanitize
+	  a string for placement into XML. This is done by examining
+	  an input string and then appending values to an output
+	  buffer. The function used by its implementation, strncat,
+	  has specific behavior that was not taken into account.
+	  If the size of the input string exceeded the available
+	  output buffer size it was possible for the sanitization
+	  function to write past the output buffer itself causing
+	  a crash. The crash would either occur because it was
+	  writing into memory it shouldn't be or because the resulting
+	  string was not NULL terminated.
+
+	  This change keeps count of how much remaining space is
+	  available in the output buffer for text and only allows
+	  strncat to use that amount.
+
+	  Since this was exposed by the res_pjsip_pidf_digium_body_supplement
+	  module attempting to send a large message the maximum allowed
+	  message size has also been increased in it.
+
+	  A unit test has also been added which confirms that the
+	  ast_sip_sanitize_xml function is providing NULL terminated
+	  output even when the input length exceeds the output
+	  buffer size.
+
+	  ASTERISK-25304 #close
+
+	  Change-Id: I743dd9809d3e13d722df1b0509dfe34621398302
+
+2015-08-05 05:23 +0000 [9a12804e59]  Joshua Colp <jcolp at digium.com>
+
+	* res_rtp_asterisk: Don't leak temporary key when enabling PFS.
+
+	  A change recently went in which enabled perfect forward secrecy for
+	  DTLS in res_rtp_asterisk. This was accomplished two different ways
+	  depending on the availability of a feature in OpenSSL. The fallback
+	  method created a temporary instance of a key but did not free it.
+	  This change fixes that.
+
+	  ASTERISK-25265
+
+	  Change-Id: Iadc031b67a91410bbefb17ffb4218d615d051396
+2015-08-04 09:47 +0000 [27dc2094e9]  Mark Michelson <mmichelson at digium.com>
+
+	* res_http_websocket: Debug write lengths.
+
+	  Commit 39cc28f6ea2140ad6d561fd4c9e9a66f065cecee attempted to fix a
+	  test failure observed on 32 bit test agents by ensuring that a cast from
+	  a 32 bit unsigned integer to a 64 bit unsigned integer was happening in
+	  a predictable place. As it turns out, this did not cause test runs to
+	  succeed.
+
+	  This commit adds several redundant debug messages that print the payload
+	  lengths of websocket frames. The idea here is that this commit will not
+	  cause tests to succeed for the faulty test agent, but we might deduce
+	  where the fault lies more easily this way by observing at what point the
+	  expected value (537) changes to some ungangly huge number.
+
+	  If you are wondering why something like this is being committed to the
+	  branch, keep in mind that in commit
+	  39cc28f6ea2140ad6d561fd4c9e9a66f065cecee I noted that the observed test
+	  failures only happen when automated tests are run. Attempts to run the
+	  tests by hand manually on the test agent result in the tests passing.
+
+	  Change-Id: I14a65c19d8af40dadcdbd52348de3b0016e1ae8d
+
+2015-08-03 11:06 +0000 [39cc28f6ea]  Mark Michelson <mmichelson at digium.com>
+
+	* res_http_websocket: Avoid passing strlen() to ast_websocket_write().
+
+	  We have seen a rash of test failures on a 32-bit build agent. Commit
+	  48698a5e21d7307f61b5fb2bd39fd593bc1423ca solved an obvious problem where
+	  we were not encoding a 64-bit value correctly over the wire. This
+	  commit, however, did not solve the test failures.
+
+	  In the failing tests, ARI is attempting to send a 537 byte text frame
+	  over a websocket. When sending a frame this small, 16 bits are all that
+	  is required in order to encode the payload length on the websocket
+	  frame. However, ast_websocket_write() thinks that the payload length is
+	  greater than 65535 and therefore writes out a 64 bit payload length.
+	  Inspecting this payload length, the lower 32 bits are exactly what we
+	  would expect it to be, 537 in hex. The upper 32 bits, are junk values
+	  that are not expected to be there.
+
+	  In the failure, we are passing the result of strlen() to a function that
+	  expects a uint64_t parameter to be passed in. strlen() returns a size_t,
+	  which on this 32-bit machine is 32 bits wide. Normally, passing a 32-bit
+	  unsigned value to somewhere where a 64-bit unsigned value is expected
+	  would cause no problems. In fact, in manual runs of failing tests, this
+	  works just fine. However, ast_websocket_write() uses the Asterisk
+	  optional API, which means that rather than a simple function call, there
+	  are a series of macros that are used for its declaration and
+	  implementation. These macros may be causing some sort of error to occur
+	  when converting from a 32 bit quantity to a 64 bit quantity.
+
+	  This commit changes the logic by making existing ast_websocket_write()
+	  calls use ast_websocket_write_string() instead. Within
+	  ast_websocket_write_string(), the 64-bit converted strlen is saved in a
+	  local variable, and that variable is passed to ast_websocket_write()
+	  instead.
+
+	  Note that this commit message is full of speculation rather than
+	  certainty. This is because the observed test failures, while always
+	  present in automated test runs, never occur when tests are manually
+	  attempted on the same test agent. The idea behind this commit is to fix
+	  a theoretical issue by performing changes that should, at the least,
+	  cause no harm. If it turns out that this change does not fix the failing
+	  tests, then this commit should be reverted.
+
+	  Change-Id: I4458dd87d785ca322b89c152b223a540a3d23e67
+
+2015-07-28 05:33 +0000 [aed068844c]  Mark Duncan <mark at syon.co.jp>
+
+	* res/res_rtp_asterisk: Add ECDH support
+
+	  This will add ECDH support to Asterisk. It will
+	  detect auto ECDH support in OpenSSL
+	  (1.0.2b and above) during ./configure. If this is
+	  available, it will use it,
+	  otherwise it will fall back to prime256v1 (this
+	  behavior is consistent with
+	  other projects such as Apache and nginx).
+
+	  This fixes WebRTC being broken in Firefox 38+ due
+	  to Firefox now only supporting
+	  ciphers with perfect forward secrecy.
+
+	  ASTERISK-25265 #close
+
+	  Change-Id: I8c13b33a2a79c0bde2e69e4ba6afa5ab9351465b
+
+2015-07-29 14:17 +0000 [1ae762634c]  Benjamin Ford <bford at digium.com>
+
+	* ARI: Rotate log channels.
+
+	  An http request can be sent to rotate a specified log channel.
+	  If the channel does not exist, an error response will be
+	  returned.
+
+	  The command "curl -v -u user:pass -X PUT 'http://localhost:8088
+	  /ari/asterisk/logging/logChannelName/rotate'" can be run in the
+	  terminal to access this new functionality.
+
+	  * Added the ability to rotate log files through ARI
+
+	  ASTERISK-25252
+
+	  Change-Id: Iaefa21cbbc1b29effb33004ee3d89c977e76ab01
+
+2015-07-29 13:49 +0000 [aeeb170fc4]  Richard Mudgett <rmudgett at digium.com>
+
+	* rtp_engine.c: Fix performance issue with several channel drivers that use RTP.
+
+	  ast_rtp_codecs_get_payload() gets called once or twice for every received
+	  RTP frame so it would be nice to not allocate an ao2 object to then have
+	  it destroyed shortly thereafter.  The ao2 object gets allocated only if
+	  the payload type is not set by the channel driver as a negotiated value.
+	  The issue affects chan_skinny, chan_unistim, chan_rtp, and chan_ooh323.
+
+	  * Made static_RTP_PT[] an array of ao2 objects that
+	  ast_rtp_codecs_get_payload() can return instead of an array of structs
+	  that must be copied into a created ao2 object.
+
+	  ASTERISK-25296 #close
+	  Reported by: Richard Mudgett
+
+	  Change-Id: Icb6de5cd90bfae07d44403a1352963db9109dac0
+
+2015-07-29 17:00 +0000 [84262749d2]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_rtp_asterisk.c: Fix off-nominal crash potential.
+
+	  ASTERISK-25296
+	  Reported by: Richard Mudgett
+
+	  Change-Id: I08549fb7c3ab40a559f41a3940f3732a4059b55b
+
+2015-07-29 13:48 +0000 [1519eb44a7]  Richard Mudgett <rmudgett at digium.com>
+
+	* rtp_engine.c: Must protect mime_types_len with mime_types_lock.
+
+	  Change-Id: I44220dd369cc151ebf5281d5119d84bb9e54d54e
+
+2015-07-24 18:42 +0000 [a93b7a927c]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_pjsip_sdp_rtp.c: Fix processing wrong SDP media list.
+
+	  Change-Id: I7c076826c2d3c6ae8c923ca73b7a71980cca11f2
+
+2015-07-24 18:38 +0000 [741fa0d26d]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_pjsip_sdp_rtp.c: Fixup some whitespace.
+
+	  Change-Id: Ib4eb7ef7dcaf93ddc26538f0a498aaf110d7a973
+
+2015-07-27 19:10 +0000 [89b21fd9a3]  Richard Mudgett <rmudgett at digium.com>
+
+	* rtp_engine.h: No sense allowing payload types larger than RFC allows.
+
+	  * Tweaked add_static_payload() to not use magic numbers.
+
+	  Change-Id: I1719ff0f6d3ce537a91572501eae5bcd912a420b
+
+2015-07-23 14:04 +0000 [7427c7f13b]  Richard Mudgett <rmudgett at digium.com>
+
+	* rtp_engine.c: Minor tweaks.
+
+	  * Fix off nominial ref leak of new_type in
+	  ast_rtp_codecs_payloads_set_m_type().
+
+	  * No need to lock static_RTP_PT_lock in
+	  ast_rtp_codecs_payloads_set_m_type() and
+	  ast_rtp_codecs_payloads_set_rtpmap_type_rate() before the payload type
+	  parameter sanity check.
+
+	  * No need to create ast_rtp_payload_type ao2 objects with a lock since the
+	  lock is not used.
+
+	  Change-Id: I64dd1bb4dfabdc7e981e3f61448beac9bb7504d4
+
+2015-07-23 12:41 +0000 [e20f435b60]  Richard Mudgett <rmudgett at digium.com>
+
+	* rtp_engine.h: Misc comment fixes.
+
+	  Change-Id: If98139264d5d97427b4685ecbdc54518f725bc43
+
+2015-07-17 16:23 +0000 [bc5d7f9c37]  Richard Mudgett <rmudgett at digium.com>
+
+	* chan_sip.c: Tweak glue->update_peer() parameter nil value.
+
+	  Change glue->update_peer() parameter from 0 to NULL to better indicate it
+	  is a pointer.
+
+	  Change-Id: I8ff2e5087f0e19f6998e3488a712a2470cc823bd
+
+2015-07-30 17:05 +0000 [13eb491e35]  Richard Mudgett <rmudgett at digium.com>
+
+	* res_pjsip_session.c: Fix crashes seen when call cancelled.
+
+	  Two testsuite tests crashed in the same place as a result of an INVITE
+	  being CANCELed.
+
+	  tests/channels/pjsip/resolver/srv/failover/in_dialog/transport_unspecified
+	  tests/channels/pjsip/resolver/srv/failover/in_dialog/transport_tcp
+
+	  The session pointer is no longer in the inv->mod_data[session_module.id]
+	  location because the INVITE transaction has reached the terminated state.
+
+	  ASTERISK-25297 #close
+	  Reported by: Richard Mudgett
+
+	  Change-Id: Idb75fdca0321f5447d5dac737a632a5f03614427
+
+2015-07-29 14:35 +0000 [48698a5e21]  Mark Michelson <mmichelson at digium.com>
+
+	* res_http_websocket: Properly encode 64 bit payload
+
+	  A test agent was continuously failing all ARI tests when run against
+	  Asterisk 13. As it turns out, the reason for this is that on those test
+	  runs, for some reason we decided to use the super extended 64 bit
+	  payload length for websocket text frames instead of the extended 16 bit
+	  payload length. For 64-bit payloads, the expected byte order over the
+	  network is
+
+	  7, 6, 5, 4, 3, 2, 1, 0
+
+	  However, we were sending the payload as
+
+	  3, 2, 1, 0, 7, 6, 5, 4
+
+	  This meant that we were saying to expect an absolutely MASSIVE payload
+	  to arrive. Since we did not follow through on this expected payload
+	  size, the client would sit patiently waiting for the rest of the payload
+	  to arrive until the test would time out.
+
+	  With this change, we use the htobe64() function instead of htonl() so
+	  that a 64-bit byte-swap is performed instead of a 32 bit byte-swap.
+
+	  Change-Id: Ibcd8552392845fbcdd017a8c8c1043b7fe35964a
+
+2015-07-29 12:23 +0000 [10ba72a927]  Mark Michelson <mmichelson at digium.com>
+
+	* Add a test event for inband ringing.
+
+	  This event is necessary for the bridge_wait_e_options test to be able to
+	  confirm that ringing is being played on the local channel that runs the
+	  BridgeWait() application with the e(r) option.
+
+	  ASTERISK-25292 #close
+	  Reported by Kevin Harwell
+
+	  Change-Id: Ifd3d3d2bebc73344d4b5310d0d55c7675359d72e
+
+2015-07-16 12:16 +0000 [8458b8d441]  Jonathan Rose <jrose at digium.com>
+
+	* holding_bridge: ensure moh participants get frames
+
+	  Currently, if a blank musiconhold.conf is used, musiconhold will fail
+	  to start for a channel going into a holding bridge with an anticipation
+	  of getting music on hold. That being the case, no frames will be written
+	  to the channel and that can pose a problem for blind transfers in PJSIP
+	  which may rely on frames being written to get past the REFER framehook.
+	  This patch makes holding bridges start a silence generator if starting
+	  music on hold fails and makes it so that if no music on hold functions
+	  are installed that the ast_moh_start function will report a failure so
+	  that consumers of that function will be able to respond appropriately.
+
+	  ASTERISK-25271 #close
+
+	  Change-Id: I06f066728604943cba0bb0b39fa7cf658a21cd99
 
 2015-07-24 22:20 +0000  Asterisk Development Team <asteriskteam at digium.com>
 
diff --git a/Makefile b/Makefile
index 8180a4f..46b7193 100644
--- a/Makefile
+++ b/Makefile
@@ -579,6 +579,7 @@ main-bininstall:
 	+ at DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" ASTLIBDIR="$(ASTLIBDIR)" $(SUBMAKE) -C main bininstall
 
 bininstall: _all installdirs $(SUBDIRS_INSTALL) main-bininstall
+	$(INSTALL) -m 755 contrib/scripts/astversion "$(DESTDIR)$(ASTSBINDIR)/"
 	$(INSTALL) -m 755 contrib/scripts/astgenkey "$(DESTDIR)$(ASTSBINDIR)/"
 	$(INSTALL) -m 755 contrib/scripts/autosupport "$(DESTDIR)$(ASTSBINDIR)/"
 	if [ ! -f /sbin/launchd ]; then \
diff --git a/UPGRADE.txt b/UPGRADE.txt
index 766ab23..27ca0e6 100644
--- a/UPGRADE.txt
+++ b/UPGRADE.txt
@@ -21,6 +21,12 @@
 === UPGRADE-12.txt  -- Upgrade info for 11 to 12
 ===========================================================
 
+From 13.5.0 to 13.6.0:
+
+ARI:
+ - The version of ARI has been updated to 1.9.0 to reflect the backwards
+   compatible changes outlined in the CHANGES file.
+
 From 13.4.0 to 13.5.0:
 
 AMI:
diff --git a/addons/chan_ooh323.c b/addons/chan_ooh323.c
index 6268ad0..ef67b78 100644
--- a/addons/chan_ooh323.c
+++ b/addons/chan_ooh323.c
@@ -4115,6 +4115,7 @@ int ooh323_destroy(struct ooh323_pvt *p)
 		}
 
 		if (cur->rtp) {
+			ast_rtp_instance_stop(cur->rtp);
 			ast_rtp_instance_destroy(cur->rtp);
 			cur->rtp = NULL;
 		}
diff --git a/addons/ooh323c/src/ooq931.c b/addons/ooh323c/src/ooq931.c
index 86ecd92..cbc4afb 100644
--- a/addons/ooh323c/src/ooq931.c
+++ b/addons/ooh323c/src/ooq931.c
@@ -758,14 +758,14 @@ int ooEncodeH225Message(OOH323CallData *call, Q931Message *pq931Msg,
       i += pq931Msg->causeIE->length;
    } 
       
-   /*Add progress indicator IE 
-   if(pq931Msg->messageType == Q931AlertingMsg || pq931Msg->messageType == Q931CallProceedingMsg)
+   /* Add progress indicator IE */
+   if(pq931Msg->messageType == Q931AlertingMsg || pq931Msg->messageType == Q931ProgressMsg)
    {
       msgbuf[i++] = Q931ProgressIndicatorIE;
       msgbuf[i++] = 2; //Length is 2 octet
       msgbuf[i++] = 0x80; //PI=8
       msgbuf[i++] = 0x88;
-  }*/
+   }
 
    /*Add display ie. for all but Status message as per ASTERISK-18748 */
    if(!ooUtilsIsStrEmpty(call->ourCallerId) && (pq931Msg->messageType != Q931StatusMsg))
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 56070b8..6c8501d 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -704,6 +704,8 @@ struct chanlist {
 	const char *tech;
 	/*! Channel device addressing.  (Stored in stuff[]) */
 	const char *number;
+	/*! Original channel name.  Must be freed.  Could be NULL if allocation failed. */
+	char *orig_chan_name;
 	uint64_t flags;
 	/*! Saved connected party info from an AST_CONTROL_CONNECTED_LINE. */
 	struct ast_party_connected_line connected;
@@ -722,6 +724,7 @@ static void chanlist_free(struct chanlist *outgoing)
 {
 	ast_party_connected_line_free(&outgoing->connected);
 	ast_aoc_destroy_decoded(outgoing->aoc_s_rate_list);
+	ast_free(outgoing->orig_chan_name);
 	ast_free(outgoing);
 }
 
@@ -1047,6 +1050,34 @@ static void publish_dial_end_event(struct ast_channel *in, struct dial_head *out
 	}
 }
 
+/*!
+ * \internal
+ * \brief Update connected line on chan from peer.
+ * \since 13.6.0
+ *
+ * \param chan Channel to get connected line updated.
+ * \param peer Channel providing connected line information.
+ * \param is_caller Non-zero if chan is the calling channel.
+ *
+ * \return Nothing
+ */
+static void update_connected_line_from_peer(struct ast_channel *chan, struct ast_channel *peer, int is_caller)
+{
+	struct ast_party_connected_line connected_caller;
+
+	ast_party_connected_line_init(&connected_caller);
+
+	ast_channel_lock(peer);
+	ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(peer));
+	ast_channel_unlock(peer);
+	connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
+	if (ast_channel_connected_line_sub(peer, chan, &connected_caller, 0)
+		&& ast_channel_connected_line_macro(peer, chan, &connected_caller, is_caller, 0)) {
+		ast_channel_update_connected_line(chan, &connected_caller, NULL);
+	}
+	ast_party_connected_line_free(&connected_caller);
+}
+
 static struct ast_channel *wait_for_answer(struct ast_channel *in,
 	struct dial_head *out_chans, int *to, struct ast_flags64 *peerflags,
 	char *opt_args[],
@@ -1067,7 +1098,6 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
 	int single = outgoing && !AST_LIST_NEXT(outgoing, node);
 	int caller_entertained = outgoing
 		&& ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
-	struct ast_party_connected_line connected_caller;
 	struct ast_str *featurecode = ast_str_alloca(AST_FEATURE_MAX_LEN + 1);
 	int cc_recall_core_id;
 	int is_cc_recall;
@@ -1075,7 +1105,6 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
 	int num_ringing = 0;
 	struct timeval start = ast_tvnow();
 
-	ast_party_connected_line_init(&connected_caller);
 	if (single) {
 		/* Turn off hold music, etc */
 		if (!caller_entertained) {
@@ -1096,15 +1125,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
 
 		if (!ast_test_flag64(outgoing, OPT_IGNORE_CONNECTEDLINE)
 			&& !ast_test_flag64(outgoing, DIAL_CALLERID_ABSENT)) {
-			ast_channel_lock(outgoing->chan);
-			ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(outgoing->chan));
-			ast_channel_unlock(outgoing->chan);
-			connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
-			if (ast_channel_connected_line_sub(outgoing->chan, in, &connected_caller, 0) &&
-				ast_channel_connected_line_macro(outgoing->chan, in, &connected_caller, 1, 0)) {
-				ast_channel_update_connected_line(in, &connected_caller, NULL);
-			}
-			ast_party_connected_line_free(&connected_caller);
+			update_connected_line_from_peer(in, outgoing->chan, 1);
 		}
 	}
 
@@ -1158,22 +1179,21 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
 			if (ast_test_flag64(o, DIAL_STILLGOING) && ast_channel_state(c) == AST_STATE_UP) {
 				if (!peer) {
 					ast_verb(3, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
-					if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
+					if (o->orig_chan_name
+						&& strcmp(o->orig_chan_name, ast_channel_name(c))) {
+						/*
+						 * The channel name changed so we must generate COLP update.
+						 * Likely because a call pickup channel masqueraded in.
+						 */
+						update_connected_line_from_peer(in, c, 1);
+					} else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
 						if (o->pending_connected_update) {
 							if (ast_channel_connected_line_sub(c, in, &o->connected, 0) &&
 								ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
 								ast_channel_update_connected_line(in, &o->connected, NULL);
 							}
 						} else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
-							ast_channel_lock(c);
-							ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(c));
-							ast_channel_unlock(c);
-							connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
-							if (ast_channel_connected_line_sub(c, in, &connected_caller, 0) &&
-								ast_channel_connected_line_macro(c, in, &connected_caller, 1, 0)) {
-								ast_channel_update_connected_line(in, &connected_caller, NULL);
-							}
-							ast_party_connected_line_free(&connected_caller);
+							update_connected_line_from_peer(in, c, 1);
 						}
 					}
 					if (o->aoc_s_rate_list) {
@@ -1228,19 +1248,14 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
 				do_forward(o, &num, peerflags, single, caller_entertained, &orig,
 					forced_clid, stored_clid);
 
-				if (single && o->chan
-					&& !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)
-					&& !ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
-					ast_channel_lock(o->chan);
-					ast_connected_line_copy_from_caller(&connected_caller,
-						ast_channel_caller(o->chan));
-					ast_channel_unlock(o->chan);
-					connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
-					if (ast_channel_connected_line_sub(o->chan, in, &connected_caller, 0) &&
-						ast_channel_connected_line_macro(o->chan, in, &connected_caller, 1, 0)) {
-						ast_channel_update_connected_line(in, &connected_caller, NULL);
+				if (o->chan) {
+					ast_free(o->orig_chan_name);
+					o->orig_chan_name = ast_strdup(ast_channel_name(o->chan));
+					if (single
+						&& !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)
+						&& !ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
+						update_connected_line_from_peer(in, o->chan, 1);
 					}
-					ast_party_connected_line_free(&connected_caller);
 				}
 				continue;
 			}
@@ -1264,22 +1279,21 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
 					/* This is our guy if someone answered. */
 					if (!peer) {
 						ast_verb(3, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
-						if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
+						if (o->orig_chan_name
+							&& strcmp(o->orig_chan_name, ast_channel_name(c))) {
+							/*
+							 * The channel name changed so we must generate COLP update.
+							 * Likely because a call pickup channel masqueraded in.
+							 */
+							update_connected_line_from_peer(in, c, 1);
+						} else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
 							if (o->pending_connected_update) {
 								if (ast_channel_connected_line_sub(c, in, &o->connected, 0) &&
 									ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
 									ast_channel_update_connected_line(in, &o->connected, NULL);
 								}
 							} else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
-								ast_channel_lock(c);
-								ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(c));
-								ast_channel_unlock(c);
-								connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
-								if (ast_channel_connected_line_sub(c, in, &connected_caller, 0) &&
-									ast_channel_connected_line_macro(c, in, &connected_caller, 1, 0)) {
-									ast_channel_update_connected_line(in, &connected_caller, NULL);
-								}
-								ast_party_connected_line_free(&connected_caller);
+								update_connected_line_from_peer(in, c, 1);
 							}
 						}
 						if (o->aoc_s_rate_list) {
@@ -2524,6 +2538,9 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
 
 		ast_channel_stage_snapshot_done(tc);
 
+		/* Save the original channel name to detect call pickup masquerading in. */
+		tmp->orig_chan_name = ast_strdup(ast_channel_name(tc));
+
 		ast_channel_unlock(tc);
 		ast_channel_unlock(chan);
 
@@ -2707,7 +2724,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
 			chans[0] = chan;
 			chans[1] = peer;
 
-			/* we need to stream the announcment while monitoring the caller for a hangup */
+			/* we need to stream the announcement while monitoring the caller for a hangup */
 
 			/* stream the file */
 			res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], ast_channel_language(peer));
@@ -2731,34 +2748,50 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
 
 				active_chan = ast_waitfor_n(chans, 2, &ms);
 				if (active_chan) {
+					struct ast_channel *other_chan;
 					struct ast_frame *fr = ast_read(active_chan);
+
 					if (!fr) {
 						ast_autoservice_chan_hangup_peer(chan, peer);
 						res = -1;
 						goto done;
 					}
-					switch(fr->frametype) {
-						case AST_FRAME_DTMF_END:
-							digit = fr->subclass.integer;
-							if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
-								ast_stopstream(peer);
-								res = ast_senddigit(chan, digit, 0);
+					switch (fr->frametype) {
+					case AST_FRAME_DTMF_END:
+						digit = fr->subclass.integer;
+						if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
+							ast_stopstream(peer);
+							res = ast_senddigit(chan, digit, 0);
+						}
+						break;
+					case AST_FRAME_CONTROL:
+						switch (fr->subclass.integer) {
+						case AST_CONTROL_HANGUP:
+							ast_frfree(fr);
+							ast_autoservice_chan_hangup_peer(chan, peer);
+							res = -1;
+							goto done;
+						case AST_CONTROL_CONNECTED_LINE:
+							/* Pass COLP update to the other channel. */
+							if (active_chan == chan) {
+								other_chan = peer;
+							} else {
+								other_chan = chan;
 							}
-							break;
-						case AST_FRAME_CONTROL:
-							switch (fr->subclass.integer) {
-								case AST_CONTROL_HANGUP:
-									ast_frfree(fr);
-									ast_autoservice_chan_hangup_peer(chan, peer);
-									res = -1;
-									goto done;
-								default:
-									break;
+							if (ast_channel_connected_line_sub(active_chan, other_chan, fr, 1)
+								&& ast_channel_connected_line_macro(active_chan,
+									other_chan, fr, other_chan == chan, 1)) {
+								ast_indicate_data(other_chan, fr->subclass.integer,
+									fr->data.ptr, fr->datalen);
 							}
 							break;
 						default:
-							/* Ignore all others */
 							break;
+						}
+						break;
+					default:
+						/* Ignore all others */
+						break;
 					}
 					ast_frfree(fr);
 				}
@@ -2786,7 +2819,6 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
 			if (ast_pbx_start(peer)) {
 				ast_autoservice_chan_hangup_peer(chan, peer);
 			}
-			hanguptree(&out_chans, NULL, ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE) ? 1 : 0);
 			if (continue_exec)
 				*continue_exec = 1;
 			res = 0;
diff --git a/apps/app_page.c b/apps/app_page.c
index f5e1460..cd87e06 100644
--- a/apps/app_page.c
+++ b/apps/app_page.c
@@ -249,12 +249,18 @@ static void page_state_callback(struct ast_dial *dial)
 
 static int page_exec(struct ast_channel *chan, const char *data)
 {
-	char *tech, *resource, *tmp;
-	char confbridgeopts[128], originator[AST_CHANNEL_NAME];
+	char *tech;
+	char *resource;
+	char *tmp;
+	char *predial_callee = NULL;
+	char confbridgeopts[128];
+	char originator[AST_CHANNEL_NAME];
 	struct page_options options = { { 0, }, { 0, } };
 	unsigned int confid = ast_random();
 	struct ast_app *app;
-	int res = 0, pos = 0, i = 0;
+	int res = 0;
+	int pos = 0;
+	int i = 0;
 	struct ast_dial **dial_list;
 	unsigned int num_dials;
 	int timeout = 0;
@@ -310,6 +316,15 @@ static int page_exec(struct ast_channel *chan, const char *data)
 		return -1;
 	}
 
+	/* PREDIAL: Preprocess any callee gosub arguments. */
+	if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLEE)
+		&& !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLEE])) {
+		ast_replace_subargument_delimiter(options.opts[OPT_ARG_PREDIAL_CALLEE]);
+		predial_callee =
+			(char *) ast_app_expand_sub_args(chan, options.opts[OPT_ARG_PREDIAL_CALLEE]);
+	}
+
+	/* PREDIAL: Run gosub on the caller's channel */
 	if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLER)
 		&& !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLER])) {
 		ast_replace_subargument_delimiter(options.opts[OPT_ARG_PREDIAL_CALLER]);
@@ -360,9 +375,8 @@ static int page_exec(struct ast_channel *chan, const char *data)
 		/* Set ANSWER_EXEC as global option */
 		ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, confbridgeopts);
 
-		if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLEE)
-			&& !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLEE])) {
-			ast_dial_option_global_enable(dial, AST_DIAL_OPTION_PREDIAL, options.opts[OPT_ARG_PREDIAL_CALLEE]);
+		if (predial_callee) {
+			ast_dial_option_global_enable(dial, AST_DIAL_OPTION_PREDIAL, predial_callee);
 		}
 
 		if (timeout) {
@@ -383,6 +397,8 @@ static int page_exec(struct ast_channel *chan, const char *data)
 		dial_list[pos++] = dial;
 	}
 
+	ast_free(predial_callee);
+
 	if (!ast_test_flag(&options.flags, PAGE_QUIET)) {
 		res = ast_streamfile(chan, "beep", ast_channel_language(chan));
 		if (!res)
diff --git a/apps/app_queue.c b/apps/app_queue.c
index c0018b5..6dfb143 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -542,7 +542,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 			Count number of members answering a queue.
 		</synopsis>
 		<syntax>
-			<parameter name="queuename" required="true" />
+			<parameter name="queuename" required="false" />
 			<parameter name="option" required="true">
 				<enumlist>
 					<enum name="logged">
@@ -558,13 +558,22 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 						<para>Returns the total number of members for the specified queue.</para>
 					</enum>
 					<enum name="penalty">
-						<para>Gets or sets queue member penalty.</para>
+						<para>Gets or sets queue member penalty.  If
+						<replaceable>queuename</replaceable> is not specified
+						when setting the penalty then the penalty is set in all queues
+						the interface is a member.</para>
 					</enum>
 					<enum name="paused">
-						<para>Gets or sets queue member paused status.</para>
+						<para>Gets or sets queue member paused status.  If
+						<replaceable>queuename</replaceable> is not specified
+						when setting the paused status then the paused status is set
+						in all queues the interface is a member.</para>
 					</enum>
 					<enum name="ringinuse">
-						<para>Gets or sets queue member ringinuse.</para>
+						<para>Gets or sets queue member ringinuse.  If
+						<replaceable>queuename</replaceable> is not specified
+						when setting ringinuse then ringinuse is set
+						in all queues the interface is a member.</para>
 					</enum>
 				</enumlist>
 			</parameter>
@@ -572,10 +581,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 		</syntax>
 		<description>
 			<para>Allows access to queue counts [R] and member information [R/W].</para>
-			<para>
-				<replaceable>queuename</replaceable> is required for all operations
-				<replaceable>interface</replaceable> is required for all member operations.
-			</para>
+			<para><replaceable>queuename</replaceable> is required for all read operations.</para>
+			<para><replaceable>interface</replaceable> is required for all member operations.</para>
 		</description>
 		<see-also>
 			<ref type="application">Queue</ref>
@@ -1439,6 +1446,8 @@ struct callattempt {
 	/*! TRUE if the call is still active */
 	unsigned int stillgoing:1;
 	struct ast_aoc_decoded *aoc_s_rate_list;
+	/*! Original channel name.  Must be freed.  Could be NULL if allocation failed. */
+	char *orig_chan_name;
 };
 
 
@@ -3944,6 +3953,7 @@ static void callattempt_free(struct callattempt *doomed)
 		ao2_ref(doomed->member, -1);
 	}
 	ast_party_connected_line_free(&doomed->connected);
+	ast_free(doomed->orig_chan_name);
 	ast_free(doomed);
 }
 
@@ -4275,6 +4285,9 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
 		ast_channel_exten_set(tmp->chan, ast_channel_exten(qe->chan));
 	}
 
+	/* Save the original channel name to detect call pickup masquerading in. */
+	tmp->orig_chan_name = ast_strdup(ast_channel_name(tmp->chan));
+
 	ast_channel_unlock(tmp->chan);
 	ast_channel_unlock(qe->chan);
 
@@ -4554,6 +4567,34 @@ static void rna(int rnatime, struct queue_ent *qe, struct ast_channel *peer, cha
 	return;
 }
 
+/*!
+ * \internal
+ * \brief Update connected line on chan from peer.
+ * \since 13.6.0
+ *
+ * \param chan Channel to get connected line updated.
+ * \param peer Channel providing connected line information.
+ * \param is_caller Non-zero if chan is the calling channel.
+ *
+ * \return Nothing
+ */
+static void update_connected_line_from_peer(struct ast_channel *chan, struct ast_channel *peer, int is_caller)
+{
+	struct ast_party_connected_line connected_caller;
+
+	ast_party_connected_line_init(&connected_caller);
+
+	ast_channel_lock(peer);
+	ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(peer));
+	ast_channel_unlock(peer);
+	connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
+	if (ast_channel_connected_line_sub(peer, chan, &connected_caller, 0)
+		&& ast_channel_connected_line_macro(peer, chan, &connected_caller, is_caller, 0)) {
+		ast_channel_update_connected_line(chan, &connected_caller, NULL);
+	}
+	ast_party_connected_line_free(&connected_caller);
+}
+
 #define AST_MAX_WATCHERS 256
 /*!
  * \brief Wait for a member to answer the call
@@ -4588,12 +4629,9 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
 #ifdef HAVE_EPOLL
 	struct callattempt *epollo;
 #endif
-	struct ast_party_connected_line connected_caller;
 	char *inchan_name;
 	struct timeval start_time_tv = ast_tvnow();
 
-	ast_party_connected_line_init(&connected_caller);
-
 	ast_channel_lock(qe->chan);
 	inchan_name = ast_strdupa(ast_channel_name(qe->chan));
 	ast_channel_unlock(qe->chan);
@@ -4671,22 +4709,21 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
 			if (o->stillgoing && (o->chan) &&  (ast_channel_state(o->chan) == AST_STATE_UP)) {
 				if (!peer) {
 					ast_verb(3, "%s answered %s\n", ochan_name, inchan_name);
-					if (!o->block_connected_update) {
+					if (o->orig_chan_name
+						&& strcmp(o->orig_chan_name, ochan_name)) {
+						/*
+						 * The channel name changed so we must generate COLP update.
+						 * Likely because a call pickup channel masqueraded in.
+						 */
+						update_connected_line_from_peer(in, o->chan, 1);
+					} else if (!o->block_connected_update) {
 						if (o->pending_connected_update) {
 							if (ast_channel_connected_line_sub(o->chan, in, &o->connected, 0) &&
 								ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) {
 								ast_channel_update_connected_line(in, &o->connected, NULL);
 							}
 						} else if (!o->dial_callerid_absent) {
-							ast_channel_lock(o->chan);
-							ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(o->chan));
-							ast_channel_unlock(o->chan);
-							connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
-							if (ast_channel_connected_line_sub(o->chan, in, &connected_caller, 0) &&
-								ast_channel_connected_line_macro(o->chan, in, &connected_caller, 1, 0)) {
-								ast_channel_update_connected_line(in, &connected_caller, NULL);
-							}
-							ast_party_connected_line_free(&connected_caller);
+							update_connected_line_from_peer(in, o->chan, 1);
 						}
 					}
 					if (o->aoc_s_rate_list) {
@@ -4767,6 +4804,9 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
 							ast_party_connected_line_copy(&o->connected, ast_channel_connected(in));
 						}
 
+						ast_free(o->orig_chan_name);
+						o->orig_chan_name = ast_strdup(ast_channel_name(o->chan));
+
 						ast_channel_req_accountcodes(o->chan, in, AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
 
 						if (!ast_channel_redirecting(o->chan)->from.number.valid
@@ -4842,22 +4882,21 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
 								ast_verb(3, "%s answered %s\n", ochan_name, inchan_name);
 								ast_channel_publish_dial(qe->chan, o->chan, on, "ANSWER");
 								publish_dial_end_event(qe->chan, outgoing, o->chan, "CANCEL");
-								if (!o->block_connected_update) {
+								if (o->orig_chan_name
+									&& strcmp(o->orig_chan_name, ochan_name)) {
+									/*
+									 * The channel name changed so we must generate COLP update.
+									 * Likely because a call pickup channel masqueraded in.
+									 */
+									update_connected_line_from_peer(in, o->chan, 1);
+								} else if (!o->block_connected_update) {
 									if (o->pending_connected_update) {
 										if (ast_channel_connected_line_sub(o->chan, in, &o->connected, 0) &&
 											ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) {
 											ast_channel_update_connected_line(in, &o->connected, NULL);
 										}
 									} else if (!o->dial_callerid_absent) {
-										ast_channel_lock(o->chan);
-										ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(o->chan));
-										ast_channel_unlock(o->chan);
-										connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
-										if (ast_channel_connected_line_sub(o->chan, in, &connected_caller, 0) &&
-											ast_channel_connected_line_macro(o->chan, in, &connected_caller, 1, 0)) {
-											ast_channel_update_connected_line(in, &connected_caller, NULL);
-										}
-										ast_party_connected_line_free(&connected_caller);
+										update_connected_line_from_peer(in, o->chan, 1);
 									}
 								}
 								if (o->aoc_s_rate_list) {
@@ -5557,6 +5596,10 @@ struct queue_stasis_data {
 	struct local_optimization caller_optimize;
 	/*! Local channel optimization details for the member */
 	struct local_optimization member_optimize;
+	/*! Member channel */
+	struct ast_channel *member_channel;
+	/*! Caller channel */
+	struct ast_channel *caller_channel;
 };
 
 /*!
@@ -5574,6 +5617,9 @@ static void queue_stasis_data_destructor(void *obj)
 	ao2_cleanup(queue_data->member);
 	queue_unref(queue_data->queue);
 	ast_string_field_free_memory(queue_data);
+
+	ao2_ref(queue_data->member_channel, -1);
+	ao2_ref(queue_data->caller_channel, -1);
 }
 
 /*!
@@ -5620,6 +5666,16 @@ static struct queue_stasis_data *queue_stasis_data_alloc(struct queue_ent *qe,
 	queue_data->caller_pos = qe->opos;
 	ao2_ref(mem, +1);
 	queue_data->member = mem;
+
+	/*
+	 * During transfers it's possible for both the member and/or caller
+	 * channel(s) to not be available. Adding a reference here ensures
+	 * that the channels remain until app_queue is completely done with
+	 * them.
+	 */
+	queue_data->member_channel = ao2_bump(peer);
+	queue_data->caller_channel = ao2_bump(qe->chan);
+
 	return queue_data;
 }
 
@@ -5991,7 +6047,9 @@ static void handle_hangup(void *userdata, struct stasis_subscription *sub,
 	}
 
 	chan = ast_channel_get_by_name(channel_blob->snapshot->name);
-	if (chan && ast_channel_has_role(chan, AST_TRANSFERER_ROLE_NAME)) {
+	if (chan && (ast_channel_has_role(chan, AST_TRANSFERER_ROLE_NAME) ||
+		     !ast_strlen_zero(pbx_builtin_getvar_helper(chan, "ATTENDEDTRANSFER")) ||
+		     !ast_strlen_zero(pbx_builtin_getvar_helper(chan, "BLINDTRANSFER")))) {
 		/* Channel that is hanging up is doing it as part of a transfer.
 		 * We'll get a transfer event later
 		 */
@@ -6965,6 +7023,55 @@ static int publish_queue_member_pause(struct call_queue *q, struct member *membe
 	return 0;
 }
 
+/*!
+ * \internal
+ * \brief Set the pause status of the specific queue member.
+ *
+ * \param q Which queue the member belongs.
+ * \param mem Queue member being paused/unpaused.
+ * \param reason Why is this happening (Can be NULL/empty for no reason given.)
+ * \param paused Set to 1 if the member is being paused or 0 to unpause.
+ *
+ * \pre The q is locked on entry.
+ *
+ * \return Nothing
+ */
+static void set_queue_member_pause(struct call_queue *q, struct member *mem, const char *reason, int paused)
+{
+	if (mem->paused == paused) {
+		ast_debug(1, "%spausing already-%spaused queue member %s:%s\n",
+			(paused ? "" : "un"), (paused ? "" : "un"), q->name, mem->interface);
+	}
+
+	if (mem->realtime) {
+		if (update_realtime_member_field(mem, q->name, "paused", paused ? "1" : "0")) {
+			ast_log(LOG_WARNING, "Failed %spause update of realtime queue member %s:%s\n",
+				(paused ? "" : "un"), q->name, mem->interface);
+		}
+	}
+
+	mem->paused = paused;
+	ast_devstate_changed(mem->paused ? QUEUE_PAUSED_DEVSTATE : QUEUE_UNPAUSED_DEVSTATE,
+		AST_DEVSTATE_CACHABLE, "Queue:%s_pause_%s", q->name, mem->interface);
+
+	if (queue_persistent_members) {
+		dump_queue_members(q);
+	}
+
+	if (is_member_available(q, mem)) {
+		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, AST_DEVSTATE_CACHABLE,
+			"Queue:%s_avail", q->name);
+	}
+
+	ast_queue_log(q->name, "NONE", mem->membername, (paused ? "PAUSE" : "UNPAUSE"),
+		"%s", S_OR(reason, ""));
+
+	publish_queue_member_pause(q, mem, reason);
+}
+
 static int set_member_paused(const char *queuename, const char *interface, const char *reason, int paused)
 {
 	int found = 0;
@@ -6978,55 +7085,30 @@ static int set_member_paused(const char *queuename, const char *interface, const
 			struct member *mem;
 
 			if ((mem = interface_exists(q, interface))) {
-				if (mem->paused == paused) {
-					ast_debug(1, "%spausing already-%spaused queue member %s:%s\n", (paused ? "" : "un"), (paused ? "" : "un"), q->name, interface);
+				/*
+				 * Before we do the PAUSE/UNPAUSE, log if this was a
+				 * PAUSEALL/UNPAUSEALL but only on the first found entry.
+				 */
+				++found;
+				if (found == 1
+					&& ast_strlen_zero(queuename)) {
+					/*
+					 * XXX In all other cases, we use the queue name,
+					 * but since this affects all queues, we cannot.
+					 */
+					ast_queue_log("NONE", "NONE", mem->membername,
+						(paused ? "PAUSEALL" : "UNPAUSEALL"), "%s", "");
 				}
 
-				if (mem->realtime) {
-					if (update_realtime_member_field(mem, q->name, "paused", paused ? "1" : "0")) {
-						ast_log(LOG_WARNING, "Failed %spausing realtime queue member %s:%s\n", (paused ? "" : "un"), q->name, interface);
-						ao2_ref(mem, -1);
-						ao2_unlock(q);
-						queue_t_unref(q, "Done with iterator");
-						continue;
-					}
-				}
-
-				mem->paused = paused;
-				ast_devstate_changed(mem->paused ? QUEUE_PAUSED_DEVSTATE : QUEUE_UNPAUSED_DEVSTATE,
-					AST_DEVSTATE_CACHABLE, "Queue:%s_pause_%s", q->name, mem->interface);
-				found++;
-
-				/* Before we do the PAUSE/UNPAUSE log, if this was a PAUSEALL/UNPAUSEALL, log that here, but only on the first found entry. */
-				if (found == 1) {
-
-					/* XXX In all other cases, we use the membername, but since this affects all queues, we cannot */
-					if (ast_strlen_zero(queuename)) {
-						ast_queue_log("NONE", "NONE", interface, (paused ? "PAUSEALL" : "UNPAUSEALL"), "%s", "");
-					}
-				}
-
-				if (queue_persistent_members) {
-					dump_queue_members(q);
-				}
-
-				if (is_member_available(q, mem)) {
-					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, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
-				}
-
-				ast_queue_log(q->name, "NONE", mem->membername, (paused ? "PAUSE" : "UNPAUSE"), "%s", S_OR(reason, ""));
-
-				publish_queue_member_pause(q, mem, reason);
+				set_queue_member_pause(q, mem, reason, paused);
 				ao2_ref(mem, -1);
 			}
-		}
 
-		if (!ast_strlen_zero(queuename) && !strcasecmp(queuename, q->name)) {
-			ao2_unlock(q);
-			queue_t_unref(q, "Done with iterator");
-			break;
+			if (!ast_strlen_zero(queuename)) {
+				ao2_unlock(q);
+				queue_t_unref(q, "Done with iterator");
+				break;
+			}
 		}
 
 		ao2_unlock(q);
@@ -7072,6 +7154,31 @@ static int set_member_penalty_help_members(struct call_queue *q, const char *int
 	return foundinterface;
 }
 
+/*!
+ * \internal
+ * \brief Set the ringinuse value of the specific queue member.
+ *
+ * \param q Which queue the member belongs.
+ * \param mem Queue member being set.
+ * \param ringinuse Set to 1 if the member is called when inuse.
+ *
+ * \pre The q is locked on entry.
+ *
+ * \return Nothing
+ */
+static void set_queue_member_ringinuse(struct call_queue *q, struct member *mem, int ringinuse)
+{
+	if (mem->realtime) {
+		update_realtime_member_field(mem, q->name, realtime_ringinuse_field,
+			ringinuse ? "1" : "0");
+	}
+
+	mem->ringinuse = ringinuse;
+
+	ast_queue_log(q->name, "NONE", mem->interface, "RINGINUSE", "%d", ringinuse);
+	queue_publish_member_blob(queue_member_ringinuse_type(), queue_member_blob_create(q, mem));
+}
+
 static int set_member_ringinuse_help_members(struct call_queue *q, const char *interface, int ringinuse)
 {
 	struct member *mem;
@@ -7080,17 +7187,7 @@ static int set_member_ringinuse_help_members(struct call_queue *q, const char *i
 	ao2_lock(q);
 	if ((mem = interface_exists(q, interface))) {
 		foundinterface++;
-		if (mem->realtime) {
-			char rtringinuse[80];
-
-			sprintf(rtringinuse, "%i", ringinuse);
-			update_realtime_member_field(mem, q->name, realtime_ringinuse_field, rtringinuse);
-		}
-
-		mem->ringinuse = ringinuse;
-
-		ast_queue_log(q->name, "NONE", interface, "RINGINUSE", "%d", ringinuse);
-		queue_publish_member_blob(queue_member_ringinuse_type(), queue_member_blob_create(q, mem));
+		set_queue_member_ringinuse(q, mem, ringinuse);
 		ao2_ref(mem, -1);
 	}
 	ao2_unlock(q);
@@ -8001,12 +8098,29 @@ static int queue_function_exists(struct ast_channel *chan, const char *cmd, char
 	return 0;
 }
 
+static struct member *get_interface_helper(struct call_queue *q, const char *interface)
+{
+	struct member *m;
+
+	if (ast_strlen_zero(interface)) {
+		ast_log(LOG_ERROR, "QUEUE_MEMBER: Missing required interface argument.\n");
+		return NULL;
+	}
+
+	m = interface_exists(q, interface);
+	if (!m) {
+		ast_log(LOG_ERROR, "Queue member interface '%s' not in queue '%s'.\n",
+			interface, q->name);
+	}
+	return m;
+}
+
 /*!
  * \brief Get number either busy / free / ready or total members of a specific queue
  * \brief Get or set member properties penalty / paused / ringinuse
  * \retval number of members (busy / free / ready / total) or member info (penalty / paused / ringinuse)
  * \retval -1 on error
-*/
+ */
 static int queue_function_mem_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 {
 	int count = 0;
@@ -8023,14 +8137,18 @@ static int queue_function_mem_read(struct ast_channel *chan, const char *cmd, ch
 	buf[0] = '\0';
 
 	if (ast_strlen_zero(data)) {
-		ast_log(LOG_ERROR, "Missing required argument. %s(<queuename>,<option>[<interface>])\n", cmd);
+		ast_log(LOG_ERROR,
+			"Missing required argument. %s(<queuename>,<option>[,<interface>])\n",
+			cmd);
 		return -1;
 	}
 
 	AST_STANDARD_APP_ARGS(args, data);
 
-	if (args.argc < 2) {
-		ast_log(LOG_ERROR, "Missing required argument. %s(<queuename>,<option>[<interface>])\n", cmd);
+	if (ast_strlen_zero(args.queuename) || ast_strlen_zero(args.option)) {
+		ast_log(LOG_ERROR,
+			"Missing required argument. %s(<queuename>,<option>[,<interface>])\n",
+			cmd);
 		return -1;
 	}
 
@@ -8069,27 +8187,29 @@ static int queue_function_mem_read(struct ast_channel *chan, const char *cmd, ch
 				ao2_ref(m, -1);
 			}
 			ao2_iterator_destroy(&mem_iter);
-		} else if (!strcasecmp(args.option, "count") || ast_strlen_zero(args.option)) {
+		} else if (!strcasecmp(args.option, "count")) {
 			count = ao2_container_count(q->members);
-		} else if (!strcasecmp(args.option, "penalty") && !ast_strlen_zero(args.interface) &&
-			   ((m = interface_exists(q, args.interface)))) {
-			count = m->penalty;
-			ao2_ref(m, -1);
-		} else if (!strcasecmp(args.option, "paused") && !ast_strlen_zero(args.interface) &&
-			   ((m = interface_exists(q, args.interface)))) {
-			count = m->paused;
-			ao2_ref(m, -1);
-		} else if ( (!strcasecmp(args.option, "ignorebusy") || !strcasecmp(args.option, "ringinuse")) &&
-			   !ast_strlen_zero(args.interface) &&
-			   ((m = interface_exists(q, args.interface)))) {
-			count = m->ringinuse;
-			ao2_ref(m, -1);
-		} else if (!ast_strlen_zero(args.interface)) {
-			ast_log(LOG_ERROR, "Queue member interface %s not in queue %s\n",
-				args.interface, args.queuename);
+		} else if (!strcasecmp(args.option, "penalty")) {
+			m = get_interface_helper(q, args.interface);
+			if (m) {
+				count = m->penalty;
+				ao2_ref(m, -1);
+			}
+		} else if (!strcasecmp(args.option, "paused")) {
+			m = get_interface_helper(q, args.interface);
+			if (m) {
+				count = m->paused;
+				ao2_ref(m, -1);
+			}
+		} else if ((!strcasecmp(args.option, "ignorebusy") /* ignorebusy is legacy */
+			|| !strcasecmp(args.option, "ringinuse"))) {
+			m = get_interface_helper(q, args.interface);
+			if (m) {
+				count = m->ringinuse;
+				ao2_ref(m, -1);
+			}
 		} else {
-			ast_log(LOG_ERROR, "Unknown option %s provided to %s, valid values are: "
-				"logged, free, ready, count, penalty, paused, ringinuse\n", args.option, cmd);
+			ast_log(LOG_ERROR, "%s: Invalid option '%s' provided.\n", cmd, args.option);
 		}
 		ao2_unlock(q);
 		queue_t_unref(q, "Done with temporary reference in QUEUE_MEMBER()");
@@ -8106,9 +8226,6 @@ static int queue_function_mem_read(struct ast_channel *chan, const char *cmd, ch
 static int queue_function_mem_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
 {
 	int memvalue;
-	struct call_queue *q;
-	struct member *m;
-	char rtvalue[80];
 
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(queuename);
@@ -8117,65 +8234,48 @@ static int queue_function_mem_write(struct ast_channel *chan, const char *cmd, c
 	);
 
 	if (ast_strlen_zero(data)) {
-		ast_log(LOG_ERROR, "Missing argument. QUEUE_MEMBER(<queuename>,<option>,<interface>)\n");
+		ast_log(LOG_ERROR,
+			"Missing required argument. %s([<queuename>],<option>,<interface>)\n",
+			cmd);
 		return -1;
 	}
 
 	AST_STANDARD_APP_ARGS(args, data);
 
-	if (args.argc < 3) {
-		ast_log(LOG_ERROR, "Missing argument. QUEUE_MEMBER_PENALTY(<queuename>,<interface>)\n");
+	if (ast_strlen_zero(args.option)
+		|| ast_strlen_zero(args.interface)) {
+		ast_log(LOG_ERROR,
+			"Missing required argument. %s([<queuename>],<option>,<interface>)\n",
+			cmd);
 		return -1;
 	}
 
-	if (ast_strlen_zero(args.interface) && ast_strlen_zero(args.option)) {
-		ast_log (LOG_ERROR, "<interface> and <option> parameter's can't be null\n");
-		return -1;
-	}
+	/*
+	 * If queuename is empty then the option will be
+	 * set for the interface in all queues.
+	 */
 
 	memvalue = atoi(value);
 	if (!strcasecmp(args.option, "penalty")) {
-		/* if queuename = NULL then penalty will be set for interface in all the queues.*/
 		if (set_member_value(args.queuename, args.interface, MEMBER_PENALTY, memvalue)) {
-			ast_log(LOG_ERROR, "Invalid interface, queue or penalty\n");
+			ast_log(LOG_ERROR, "Invalid interface, queue, or penalty\n");
 			return -1;
 		}
-	} else if ((q = find_load_queue_rt_friendly(args.queuename))) {
-		ao2_lock(q);
-		if ((m = interface_exists(q, args.interface))) {
-			sprintf(rtvalue, "%s",(memvalue <= 0) ? "0" : "1");
-			if (!strcasecmp(args.option, "paused")) {
-				if (m->realtime) {
-					update_realtime_member_field(m, q->name, args.option, rtvalue);
-				}
-				m->paused = (memvalue <= 0) ? 0 : 1;
-				ast_devstate_changed(m->paused ? QUEUE_PAUSED_DEVSTATE : QUEUE_UNPAUSED_DEVSTATE,
-					AST_DEVSTATE_CACHABLE, "Queue:%s_pause_%s", q->name, args.interface);
-
-			} else if ((!strcasecmp(args.option, "ignorebusy")) || (!strcasecmp(args.option, "ringinuse"))) {
-				if (m->realtime) {
-					update_realtime_member_field(m, q->name, args.option, rtvalue);
-				}
-
-				m->ringinuse = (memvalue <= 0) ? 0 : 1;
-			} else {
-				ast_log(LOG_ERROR, "Invalid option, only penalty , paused or ringinuse/ignorebusy are valid\n");
-				ao2_ref(m, -1);
-				ao2_unlock(q);
-				ao2_ref(q, -1);
-				return -1;
-			}
-			ao2_ref(m, -1);
-		} else {
-			ao2_unlock(q);
-			ao2_ref(q, -1);
-			ast_log(LOG_ERROR, "Invalid interface for queue\n");
+	} else if (!strcasecmp(args.option, "paused")) {
+		memvalue = (memvalue <= 0) ? 0 : 1;
+		if (set_member_paused(args.queuename, args.interface, NULL, memvalue)) {
+			ast_log(LOG_ERROR, "Invalid interface or queue\n");
 			return -1;
 		}
-		ao2_unlock(q);
-		ao2_ref(q, -1);
-        } else {
-		ast_log(LOG_ERROR, "Invalid queue\n");
+	} else if (!strcasecmp(args.option, "ignorebusy") /* ignorebusy is legacy */
+		|| !strcasecmp(args.option, "ringinuse")) {
+		memvalue = (memvalue <= 0) ? 0 : 1;
+		if (set_member_value(args.queuename, args.interface, MEMBER_RINGINUSE, memvalue)) {
+			ast_log(LOG_ERROR, "Invalid interface or queue\n");
+			return -1;
+		}
+	} else {
+		ast_log(LOG_ERROR, "%s: Invalid option '%s' provided.\n", cmd, args.option);
 		return -1;
 	}
 	return 0;
diff --git a/apps/app_record.c b/apps/app_record.c
index 43a1e49..31a54e6 100644
--- a/apps/app_record.c
+++ b/apps/app_record.c
@@ -294,9 +294,10 @@ static int record_exec(struct ast_channel *chan, const char *data)
 			}
 			count++;
 		} while (ast_fileexists(tmp, ext, ast_channel_language(chan)) > 0);
-		pbx_builtin_setvar_helper(chan, "RECORDED_FILE", tmp);
 	} else
 		ast_copy_string(tmp, args.filename, sizeof(tmp));
+
+	pbx_builtin_setvar_helper(chan, "RECORDED_FILE", tmp);
 	/* end of routine mentioned */
 
 	if (ast_channel_state(chan) != AST_STATE_UP) {
diff --git a/asterisk-13.5.0-summary.html b/asterisk-13.5.0-summary.html
deleted file mode 100644
index 2bf83a6..0000000
--- a/asterisk-13.5.0-summary.html
+++ /dev/null
@@ -1,441 +0,0 @@
-<!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"><title>Release Summary - asterisk-13.5.0</title><h1 align="center"><a name="top">Release Summary</a></h1><h3 align="center">asterisk-13.5.0</h3><h3 align="center">Date: 2015-08-07</h3><h3 align="center"><asteriskteam at 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="#closed_issues">Closed Issues</a></li>
-<li><a href="#open_issues">Open 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><p>This release is a point release of an existing major version. The changes included were made to address problems that have been identified in this release series, or are minor, backwards compatible new features or improvements. Users should be able to safely upgrade to this version if this release series is already in use. Users considering upgrading from a previous version a [...]
-<tr><th width="33%">Coders</th><th width="33%">Testers</th><th width="33%">Reporters</th></tr>
-<tr valign="top"><td width="33%">33 Matt Jordan <mjordan at digium.com><br/>33 Richard Mudgett <rmudgett at digium.com><br/>15 Joshua Colp <jcolp at digium.com><br/>11 Mark Michelson <mmichelson at digium.com><br/>6 gtjoseph <george.joseph at fairview5.com><br/>6 Benjamin Ford <bford at digium.com><br/>5 Walter Doekes <walter+asterisk at wjd.nu><br/>5 Corey Farrell <git at cfware.com><br/>4 Kevin Harwell <kharwell at digium.com><br/>4 Ivan Poddubny <ivan.poddubny at gmail.com><br/>2 ibercom <ibercom123 at gmail.com><br/ [...]
-</table><hr><a name="closed_issues"><h2 align="center">Closed Issues</h2></a><center><a href="#top">[Back to Top]</a></center><p>This is a list of all issues from the issue tracker that were closed by changes that went into this release.</p><h3>Improvement</h3><h4>Category: Core/General</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25256">ASTERISK-25256</a>: [patch]Post AMI VarSet to empty string events when Asterisk deletes a dialplan variable.<br/>Reported by: Richard M [...]
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=875aee4c09a1780ac57b38fbb74a7bec2503fba0">[875aee4c09]</a> Richard Mudgett -- pbx.c: Post AMI VarSet event if delete a non-empty dialplan variable.</li>
-</ul><br><h4>Category: Core/PBX</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25040">ASTERISK-25040</a>: pbx: Improve performance of reloads by making hint destruction more performant<br/>Reported by: Matt Jordan<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=399cd8bcd9e53f30d4a36b67200281407f27798e">[399cd8bcd9]</a> Matt Jordan -- main/pbx: Resolve case sensitivity regression in PBX hints</li>
-</ul><br><h4>Category: Core/Sorcery</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25067">ASTERISK-25067</a>: Sorcery Caching: Implement a new caching module<br/>Reported by: Matt Jordan<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=b74b07136973b2c753acff02f6e88326de7a5ef0">[b74b071369]</a> Joshua Colp -- res_sorcery_memory_cache: Backport to 13</li>
-</ul><br><h4>Category: Resources/res_pjsip</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25114">ASTERISK-25114</a>: res_pjsip:  Add AMI events for chan_pjsip contact lifecycle changes<br/>Reported by: George Joseph<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=262d590819b123b1f57196beef8aca45c4aa0d09">[262d590819]</a> gtjoseph -- res_pjsip: Add AMI events for chan_pjsip contact lifecycle changes</li>
-</ul><br><h4>Category: Resources/res_pjsip_outbound_registration</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25072">ASTERISK-25072</a>: res_pjsip_outbound_registration: line functionality. Additional check for using the request URI<br/>Reported by: Dmitriy Serov<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=42476e66333a9b9841b56b2207760a70b1b835d1">[42476e6633]</a> demon-ru -- res_pjsip_outbound_registration: Check request URI for line.</li>
-</ul><br><h3>Bug</h3><h4>Category: Applications/app_chanspy</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25247">ASTERISK-25247</a>: choppy audio when spying on a g722 channel, chan_sip or chan_pjsip<br/>Reported by: hristo<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f1493f900e76304ecf28eed30d37fba8e54d926b">[f1493f900e]</a> Joshua Colp -- audiohook: Read the correct number of samples based on audiohook format.</li>
-</ul><br><h4>Category: Applications/app_confbridge</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25253">ASTERISK-25253</a>: confbridge volume options and other volume controls such as func_volume don't work<br/>Reported by: Dmitriy Serov<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f509730cb93875ba0a78835fd38b8dbd1cdff3f7">[f509730cb9]</a> Joshua Colp -- audiohook: Use manipulated frame instead of dropping it.</li>
-</ul><br><h4>Category: Applications/app_dial</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25212">ASTERISK-25212</a>: [patch]Segfault when using DEBUG_FD_LEAKS<br/>Reported by: Walter Doekes<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=6551e16e03cc8e172d9ad8f75a040750a29a5e6e">[6551e16e03]</a> Walter Doekes -- astfd: Fix buffer overflow in DEBUG_FD_LEAKS.</li>
-</ul><br><h4>Category: Applications/app_directory</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25087">ASTERISK-25087</a>: Asterisk segfault when using Directory application with alias option and specific mailbox configuration<br/>Reported by: Chet Stevens<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a2f4d03c87bb67892a8b846c59bd26e9163054e9">[a2f4d03c87]</a> Richard Mudgett -- app_directory: Fix crash when using the alias option 'a'.</li>
-</ul><br><h4>Category: Bridges/bridge_native_rtp</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25240">ASTERISK-25240</a>: bridge_native_rtp: Direct media wrongfully started when completing attended transfer<br/>Reported by: Joshua Colp<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=d558b00c8503a002bc8f0173fd1e5f911fc6483e">[d558b00c85]</a> Joshua Colp -- bridge_native_rtp.c: Don't start native RTP bridging after attended transfer.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25171">ASTERISK-25171</a>: Early completion of feature code attended transfer results in intermittent one-way audio, "ghost ringing" and robotic sound.<br/>Reported by: Rusty Newton<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e4a2ef9e4ef27488609bb01fc55e965cd93a9ad5">[e4a2ef9e4e]</a> Joshua Colp -- channel: Remove ignore of answer on non-outgoing channels.</li>
-</ul><br><h4>Category: CDR/General</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24344">ASTERISK-24344</a>: CDR_PROP(disable) disables CDR only for first dialed party<br/>Reported by: Janusz Karolak<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=de8c7f46ed0c1212054b6b6cfd33663549ebd94c">[de8c7f46ed]</a> Matt Jordan -- main/cdr: Carry over the disable flag when 'disable all' is specified</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24443">ASTERISK-24443</a>: CDR fields (dst, dcontext) empty in transfer call started from Macro<br/>Reported by: Arveno Santoro<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=78ea356e78a4dc7c88b2212d1c4bf700bc5c5701">[78ea356e78]</a> Matt Jordan -- main/cdr: Copy context/exten on chained CDRs for parallel dials in subroutines</li>
-</ul><br><h4>Category: Channels/chan_dahdi</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25257">ASTERISK-25257</a>: [patch]channels/sig_pri.h -> sig_pri_span -> force_restart_unavailable_chans in wrong scope<br/>Reported by: Patric Marschall<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=abb14ac5b8d833176560716199521aa260dc2d0e">[abb14ac5b8]</a> Patric Marschall -- sig_pri.h: force_restart_unavailable_chans in wrong scope</li>
-</ul><br><h4>Category: Channels/chan_iax2</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24983">ASTERISK-24983</a>: IAX deadlock between hangup and scheduled actions (ex. largrq)<br/>Reported by: Y Ateya<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=cf98c744d5bb7e5f015f201bc79c58462f7aaaed">[cf98c744d5]</a> Yousf Ateya -- chan_iax2: Prevent deadlock between hangup and sending lagrq/ping</li>
-</ul><br><h4>Category: Channels/chan_local</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25250">ASTERISK-25250</a>: chan_sip - Despite the channel being answered, caller on a call established via Local channel continues to hear ringback<br/>Reported by: Etienne Lessard<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f63552052710d2b0a0f33b8fd93dd00083f74b74">[f635520527]</a> Mark Michelson -- Local channels: Alternate solution to ringback problem.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=54b25c80c8387aea9eb20f9f4f077486cbdf3e5d">[54b25c80c8]</a> Mark Michelson -- Local channels: Do not block control -1 payloads.</li>
-</ul><br><h4>Category: Channels/chan_mgcp</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25220">ASTERISK-25220</a>: [patch]Closing of fd -1 in chan_mgcp.c<br/>Reported by: Walter Doekes<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a5a262be78113f58d54e45da69225d1ee856a51e">[a5a262be78]</a> Walter Doekes -- chan_mgcp: Don't call close on fd -1.</li>
-</ul><br><h4>Category: Channels/chan_pjsip</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25258">ASTERISK-25258</a>: chan_pjsip: Incorrect format switch on received RTP packet<br/>Reported by: Joshua Colp<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=2c626ceb64e11f7d18b97023f09072a992060121">[2c626ceb64]</a> Joshua Colp -- chan_pjsip: Don't change formats when frame of unsupported format is received.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25183">ASTERISK-25183</a>: PJSIP: Crash on NULL channel in chan_pjsip_incoming_response despite previous checks for NULL channel<br/>Reported by: Matt Jordan<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=653f2087e0d2edc9df8a0154c09e2e608e13a5c5">[653f2087e0]</a> Richard Mudgett -- res_pjsip_session.c: Fix crash on call disconnect.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=ada7346792452f021911063668997f79fdabc1f1">[ada7346792]</a> Richard Mudgett -- res_pjsip: Need to use the same serializer for a pjproject SIP transaction.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25091">ASTERISK-25091</a>: Asterisk REST API - bridge.addChannel crash asterisk when calling channel hangup while adding to bridge<br/>Reported by: Ilya Trikoz<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=9015bb4c8c9882de35066c6586189ab78268a12f">[9015bb4c8c]</a> Mark Michelson -- Resolve race conditions involving Stasis bridges.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25156">ASTERISK-25156</a>: chan_pjsip’s CHAN_START cel event lacks the correct context and exten<br/>Reported by: cloos<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=30a0f2d9acd0f7c14013d830a0b4bf673d0af2d0">[30a0f2d9ac]</a> Matt Jordan -- chan_pjsip: Set the context and extension on the channel when created</li>
-</ul><br><h4>Category: Channels/chan_sip/CodecHandling</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25182">ASTERISK-25182</a>: [patch] on CLI sip reload, new codecs get appended only<br/>Reported by: Alexander Traud<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a419c69def639745ac9988b3800501f68dfef350">[a419c69def]</a> Alexander Traud -- chan_sip: Reload peer without its old capabilities.</li>
-</ul><br><h4>Category: Channels/chan_sip/General</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25250">ASTERISK-25250</a>: chan_sip - Despite the channel being answered, caller on a call established via Local channel continues to hear ringback<br/>Reported by: Etienne Lessard<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f63552052710d2b0a0f33b8fd93dd00083f74b74">[f635520527]</a> Mark Michelson -- Local channels: Alternate solution to ringback problem.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=54b25c80c8387aea9eb20f9f4f077486cbdf3e5d">[54b25c80c8]</a> Mark Michelson -- Local channels: Do not block control -1 payloads.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-22805">ASTERISK-22805</a>: res_rtp_asterisk: Crash when calling BIO_ctrl_pending in dtls_srtp_check_pending when dialed by JSSIP <br/>Reported by: Dmitry Burilov<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=05e8e1498207055374312f43fb80fcf0b9d5ab45">[05e8e14982]</a> Joshua Colp -- res_rtp_asterisk: Prevent simultaneous access to DTLS SSL context.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25212">ASTERISK-25212</a>: [patch]Segfault when using DEBUG_FD_LEAKS<br/>Reported by: Walter Doekes<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=6551e16e03cc8e172d9ad8f75a040750a29a5e6e">[6551e16e03]</a> Walter Doekes -- astfd: Fix buffer overflow in DEBUG_FD_LEAKS.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25202">ASTERISK-25202</a>: Hints extension state broken between 13.3.2 and 13.4<br/>Reported by: cervajs<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=399cd8bcd9e53f30d4a36b67200281407f27798e">[399cd8bcd9]</a> Matt Jordan -- main/pbx: Resolve case sensitivity regression in PBX hints</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25171">ASTERISK-25171</a>: Early completion of feature code attended transfer results in intermittent one-way audio, "ghost ringing" and robotic sound.<br/>Reported by: Rusty Newton<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e4a2ef9e4ef27488609bb01fc55e965cd93a9ad5">[e4a2ef9e4e]</a> Joshua Colp -- channel: Remove ignore of answer on non-outgoing channels.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25163">ASTERISK-25163</a>: Deadlock in chan_sip between reload of sip peer container and MWI Stasis callback<br/>Reported by: Dmitriy Serov<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=74616ae43d4e24e914ee612846a464da5b241b9b">[74616ae43d]</a> Joshua Colp -- chan_sip: Destroy peers without holding peers container lock.</li>
-</ul><br><h4>Category: Channels/chan_sip/IPv6</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25100">ASTERISK-25100</a>: asterisk coredump if host has an IPv6 address that end with ::80<br/>Reported by: Mark Petersen<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=97a6ce1717bd0c4b1b4305f10f13fd5ec9bb7441">[97a6ce1717]</a> Ivan Poddubny -- Astobj2: Correctly treat hash_fn returning INT_MIN</li>
-</ul><br><h4>Category: Channels/chan_sip/Interoperability</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25154">ASTERISK-25154</a>: [patch]fromtag may need to be updated after successful call dialog match<br/>Reported by: Damian Ivereigh<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=3f57f3f8ec63752ccd1d87d7c6737f64043cb8a9">[3f57f3f8ec]</a> Damian Ivereigh -- chan_sip.c: Update dialog fromtag after request with auth</li>
-</ul><br><h4>Category: Channels/chan_sip/SRTP</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24550">ASTERISK-24550</a>: res_rtp_asterisk: Crash in ast_rtp_on_ice_complete during DTLS handshake<br/>Reported by: Osaulenko Alexander<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=05e8e1498207055374312f43fb80fcf0b9d5ab45">[05e8e14982]</a> Joshua Colp -- res_rtp_asterisk: Prevent simultaneous access to DTLS SSL context.</li>
-</ul><br><h4>Category: Channels/chan_sip/Transfers</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25226">ASTERISK-25226</a>: chan_sip: Channel leak in branch 13 on early replaces call pickup<br/>Reported by: Walter Doekes<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e0f565663b49e14c15d7b5e6e9ff7396956b91f6">[e0f565663b]</a> Walter Doekes -- chan_sip: Fix early call pickup channel leak.</li>
-</ul><br><h4>Category: Codecs/codec_adpcm</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24717">ASTERISK-24717</a>: ASAN: global-buffer-overflow codec_{ilbc | gsm | adpcm | ipc10}<br/>Reported by: Badalian Vyacheslav<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=888bb49618cdf952a00481ea148c0be462593f29">[888bb49618]</a> Ivan Poddubny -- Fix buffer overflow in slin sample frames generation.</li>
-</ul><br><h4>Category: Codecs/codec_gsm</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24717">ASTERISK-24717</a>: ASAN: global-buffer-overflow codec_{ilbc | gsm | adpcm | ipc10}<br/>Reported by: Badalian Vyacheslav<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=888bb49618cdf952a00481ea148c0be462593f29">[888bb49618]</a> Ivan Poddubny -- Fix buffer overflow in slin sample frames generation.</li>
-</ul><br><h4>Category: Codecs/codec_ilbc</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24717">ASTERISK-24717</a>: ASAN: global-buffer-overflow codec_{ilbc | gsm | adpcm | ipc10}<br/>Reported by: Badalian Vyacheslav<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=888bb49618cdf952a00481ea148c0be462593f29">[888bb49618]</a> Ivan Poddubny -- Fix buffer overflow in slin sample frames generation.</li>
-</ul><br><h4>Category: Codecs/codec_lpc10</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24717">ASTERISK-24717</a>: ASAN: global-buffer-overflow codec_{ilbc | gsm | adpcm | ipc10}<br/>Reported by: Badalian Vyacheslav<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=888bb49618cdf952a00481ea148c0be462593f29">[888bb49618]</a> Ivan Poddubny -- Fix buffer overflow in slin sample frames generation.</li>
-</ul><br><h4>Category: Core/Bridging</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25250">ASTERISK-25250</a>: chan_sip - Despite the channel being answered, caller on a call established via Local channel continues to hear ringback<br/>Reported by: Etienne Lessard<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f63552052710d2b0a0f33b8fd93dd00083f74b74">[f635520527]</a> Mark Michelson -- Local channels: Alternate solution to ringback problem.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=54b25c80c8387aea9eb20f9f4f077486cbdf3e5d">[54b25c80c8]</a> Mark Michelson -- Local channels: Do not block control -1 payloads.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24782">ASTERISK-24782</a>: StasisEnd event not present for channel that was swapped out for another after completing attended transfer<br/>Reported by: John Bigelow<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=97ee0ee6c6d5f37591183339999d8cb936bf517a">[97ee0ee6c6]</a> Kevin Harwell -- bridge.c: Fixed race condition during attended transfer</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=35a99b639474f9140fc294c184bb8f0afb1936cf">[35a99b6394]</a> Kevin Harwell -- bridge.c: Hangup attended transfer target if bridged</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25157">ASTERISK-25157</a>: bridging: Performing a blonde transfer does not result in connected line updates<br/>Reported by: Joshua Colp<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=dbb067279e7d7555c5090546572a0d01f796fe55">[dbb067279e]</a> Joshua Colp -- bridge: When performing a blonde transfer update connected line information.</li>
-</ul><br><h4>Category: Core/CodecInterface</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25172">ASTERISK-25172</a>: Crash in channels/sip/sip blind transfer/caller_refer_only test in ast_format_cap_append_from_cap during ast_request<br/>Reported by: Matt Jordan<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e99e654d75a2428ce4b8bc504acf2ec1927779ed">[e99e654d75]</a> Joshua Colp -- app_dial: Hold reference to calling channel formats when dialing outbound.</li>
-</ul><br><h4>Category: Core/General</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25255">ASTERISK-25255</a>: Missing AMI VarSet events when setting to an empty string.<br/>Reported by: Richard Mudgett<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e31cb6b2484bbf5726c59b263f13b995e60d537d">[e31cb6b248]</a> Richard Mudgett -- strings.h: Fix issues with escape string functions.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25201">ASTERISK-25201</a>: Crash in PJSIP distributor on already free'd threadpool<br/>Reported by: Matt Jordan<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=653f2087e0d2edc9df8a0154c09e2e608e13a5c5">[653f2087e0]</a> Richard Mudgett -- res_pjsip_session.c: Fix crash on call disconnect.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25212">ASTERISK-25212</a>: [patch]Segfault when using DEBUG_FD_LEAKS<br/>Reported by: Walter Doekes<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=6551e16e03cc8e172d9ad8f75a040750a29a5e6e">[6551e16e03]</a> Walter Doekes -- astfd: Fix buffer overflow in DEBUG_FD_LEAKS.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-22559">ASTERISK-22559</a>: gcc 4.6 and higher supports weakref attribute but asterisk doesn't detect it.<br/>Reported by: ibercom<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=3046bc17ed81d13899147c6e2138d0189250a8f4">[3046bc17ed]</a> ibercom -- weakref attribute detection broken with gcc 4.6 and higher</li>
-</ul><br><h4>Category: Core/ManagerInterface</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24934">ASTERISK-24934</a>: [patch]Asterisk manager output does not escape control characters<br/>Reported by: warren smith<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e31cb6b2484bbf5726c59b263f13b995e60d537d">[e31cb6b248]</a> Richard Mudgett -- strings.h: Fix issues with escape string functions.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f5d5aa67dcdc274770c47b1a801a449fb83c2f79">[f5d5aa67dc]</a> Kevin Harwell -- AMI: Escape string values.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24900">ASTERISK-24900</a>: Manager event ParkedCallSwap is not documented<br/>Reported by: Rusty Newton<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=723a9d4225d78391e91d9554b5df65424eed5969">[723a9d4225]</a> Mark Michelson -- Parking: Add documentation for AMI ParkedCallSwap event.</li>
-</ul><br><h4>Category: Core/ManagerInterface/NewFeature</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25189">ASTERISK-25189</a>: AMI: Add Linkedid header to standard channel snapshot information.<br/>Reported by: Richard Mudgett<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=890c92378649b99cc5281494914ec719d2bf0284">[890c923786]</a> Richard Mudgett -- AMI: Add Linkedid to the standard channel snapshot AMI event headers.</li>
-</ul><br><h4>Category: Core/PBX</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25094">ASTERISK-25094</a>: PBX core: Investigate thread safety issues<br/>Reported by: Corey Farrell<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=55c8daf88b94f74e334ab246c51bdb7b469eedc4">[55c8daf88b]</a> Corey Farrell -- Fix unsafe uses of ast_context pointers.</li>
-</ul><br><h4>Category: Core/RTP</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25219">ASTERISK-25219</a>: [patch]Source and destination overlap in memcpy in rtp_engine.c<br/>Reported by: Walter Doekes<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=b835312b4c2e1fcd3f7efb5ae45a0c4d10d4d5f7">[b835312b4c]</a> Walter Doekes -- rtp_engine: Skip useless self-assignment in ast_rtp_engine_unload_format.</li>
-</ul><br><h4>Category: Core/Sorcery</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25165">ASTERISK-25165</a>: Testsuite - Sorcery memory cache leaks<br/>Reported by: Corey Farrell<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=156395e743189649280066c1497292bb97ed022d">[156395e743]</a> Mark Michelson -- res_sorcery_realtime: Fix leak of sorcery object type.</li>
-</ul><br><h4>Category: Core/Stasis</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25137">ASTERISK-25137</a>: endpoint stasis messages are delivered twice<br/>Reported by: Vitezslav Novy<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=35c699086ae2fd81b2473307ccb2ae79ad32375a">[35c699086a]</a> gtjoseph -- endpoint/stasis: Eliminate duplicate events on endpoint status change</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25121">ASTERISK-25121</a>: Stasis: Fix unsafe use of stasis_unsubscribe in modules.<br/>Reported by: Corey Farrell<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=0d266cbe025e30ce18121f43dbb6b11620b4d5e1">[0d266cbe02]</a> Corey Farrell -- Stasis: Fix unsafe use of stasis_unsubscribe in modules.</li>
-</ul><br><h4>Category: Documentation</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24867">ASTERISK-24867</a>: Docs for 'e' option in ResetCDR say to use CDR_PROP instead, CDR_PROP docs are unclear<br/>Reported by: Rusty Newton<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=62c64c3bd1938280cf671afd6708d6026c0b8e49">[62c64c3bd1]</a> Rusty Newton -- Documentation: A couple of trivial fixes in sip.conf.sample and func_cdr.c</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24853">ASTERISK-24853</a>: Documentation claims chan_sip outbound registrations support WS or WSS as valid transports (not true)<br/>Reported by: PSDK<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=62c64c3bd1938280cf671afd6708d6026c0b8e49">[62c64c3bd1]</a> Rusty Newton -- Documentation: A couple of trivial fixes in sip.conf.sample and func_cdr.c</li>
-</ul><br><h4>Category: Functions/func_talkdetect</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24988">ASTERISK-24988</a>: func_talkdetect: Test is bouncing sporadically<br/>Reported by: Joshua Colp<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=5ac65ddfb46f715490b4eccbef57dc6f424e9bc2">[5ac65ddfb4]</a> Matt Jordan -- res/ari: Register Stasis application on WebSocket attempt</li>
-</ul><br><h4>Category: Resources/res_ari</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25091">ASTERISK-25091</a>: Asterisk REST API - bridge.addChannel crash asterisk when calling channel hangup while adding to bridge<br/>Reported by: Ilya Trikoz<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=9015bb4c8c9882de35066c6586189ab78268a12f">[9015bb4c8c]</a> Mark Michelson -- Resolve race conditions involving Stasis bridges.</li>
-</ul><br><h4>Category: Resources/res_ari_bridges</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25091">ASTERISK-25091</a>: Asterisk REST API - bridge.addChannel crash asterisk when calling channel hangup while adding to bridge<br/>Reported by: Ilya Trikoz<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=9015bb4c8c9882de35066c6586189ab78268a12f">[9015bb4c8c]</a> Mark Michelson -- Resolve race conditions involving Stasis bridges.</li>
-</ul><br><h4>Category: Resources/res_crypto</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24550">ASTERISK-24550</a>: res_rtp_asterisk: Crash in ast_rtp_on_ice_complete during DTLS handshake<br/>Reported by: Osaulenko Alexander<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=05e8e1498207055374312f43fb80fcf0b9d5ab45">[05e8e14982]</a> Joshua Colp -- res_rtp_asterisk: Prevent simultaneous access to DTLS SSL context.</li>
-</ul><br><h4>Category: Resources/res_http_websocket</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24963">ASTERISK-24963</a>: ASAN: heap-use-after-free with PJSIP and WSS<br/>Reported by: Badalian Vyacheslav<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8af6c9cf6bc9f8217fd96f59a6f248330583bdb9">[8af6c9cf6b]</a> Ivan Poddubny -- res_pjsip_transport_websocket: Fix use-after-free bugs.</li>
-</ul><br><h4>Category: Resources/res_mwi_external_ami</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25117">ASTERISK-25117</a>: res_mwi_external_ami: Fix manager action registrations.<br/>Reported by: Corey Farrell<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e7edb59db6dfb543300f43c8055adda4ab1fd1c9">[e7edb59db6]</a> Corey Farrell -- res_mwi_external_ami: Use module version of AMI registration.</li>
-</ul><br><h4>Category: Resources/res_parking</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25254">ASTERISK-25254</a>: Crash if dialplan sets ATTENDEDTRANSFER to an empty string before Park.<br/>Reported by: Richard Mudgett<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=c782320c68633c9b1b805affaec1bfe604370d7f">[c782320c68]</a> Richard Mudgett -- res_parking: Fix crash if ATTENDEDTRANSFER set empty before Park.</li>
-</ul><br><h4>Category: Resources/res_pjsip</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25201">ASTERISK-25201</a>: Crash in PJSIP distributor on already free'd threadpool<br/>Reported by: Matt Jordan<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=653f2087e0d2edc9df8a0154c09e2e608e13a5c5">[653f2087e0]</a> Richard Mudgett -- res_pjsip_session.c: Fix crash on call disconnect.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25168">ASTERISK-25168</a>: Random Core Dumps on Asterisk 13.4 PJSIP, in ast_channel_name at channel_internal_api.c<br/>Reported by: Carl Fortin<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=0d67e04359505a06409d8211bb0c2b65fe82125f">[0d67e04359]</a> Richard Mudgett -- res_pjsip_mwi.c: Fix MWI subscription memory corruption crash.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=0422433f4722e6e692b0c84342e048feff344e80">[0422433f47]</a> Richard Mudgett -- PJSIP XML, XPIDF: Fix buffer size overwrite memory corruption error.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8ea214aed782424a884b9a2f67d6dca270854e83">[8ea214aed7]</a> Richard Mudgett -- PJSIP FAX: Fix T.38 automatic reject timer NULL channel pointer dereferences.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25115">ASTERISK-25115</a>: Crash related to func sip_resolve_invoke_user_callback of res_pjsip/pjsip_resolver.c<br/>Reported by: John Bigelow<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=ada7346792452f021911063668997f79fdabc1f1">[ada7346792]</a> Richard Mudgett -- res_pjsip: Need to use the same serializer for a pjproject SIP transaction.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25171">ASTERISK-25171</a>: Early completion of feature code attended transfer results in intermittent one-way audio, "ghost ringing" and robotic sound.<br/>Reported by: Rusty Newton<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e4a2ef9e4ef27488609bb01fc55e965cd93a9ad5">[e4a2ef9e4e]</a> Joshua Colp -- channel: Remove ignore of answer on non-outgoing channels.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25158">ASTERISK-25158</a>: res_pjsip: Add option to use AAL2 packing when negotiating g.726<br/>Reported by: Kevin Harwell<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=31c77b157b84527b1a68d96f7a23c3e7b242ee99">[31c77b157b]</a> Kevin Harwell -- res_pjsip: Add option to force G.726 to be treated as AAL2 packed.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25096">ASTERISK-25096</a>: [patch]Segfault when registering over websockets with PJSIP (in ast_sockaddr_isnull at /include/asterisk/netsock2.h)<br/>Reported by: Josh Kitchens<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8af6c9cf6bc9f8217fd96f59a6f248330583bdb9">[8af6c9cf6b]</a> Ivan Poddubny -- res_pjsip_transport_websocket: Fix use-after-free bugs.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25116">ASTERISK-25116</a>: res_pjsip:  Two PeerStatus AMI messages are sent for every status change<br/>Reported by: George Joseph<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=35c699086ae2fd81b2473307ccb2ae79ad32375a">[35c699086a]</a> gtjoseph -- endpoint/stasis: Eliminate duplicate events on endpoint status change</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25131">ASTERISK-25131</a>: chan_pjsip: In-dialog authentication not handled.<br/>Reported by: Richard Mudgett<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=fe21f2e52f1b6629a254cc2f34345c4de6ec4293">[fe21f2e52f]</a> Richard Mudgett -- res_pjsip_session: Fix in-dialog authentication.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25105">ASTERISK-25105</a>: res_pjsip:  Possible incompatibility between qualify_timeout and pjproject-2.4<br/>Reported by: George Joseph<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=60e2fbfe624680d7df948aab243d77ff111e4f4e">[60e2fbfe62]</a> gtjoseph -- res_pjsip: Refactor endpt_send_transaction (qualify_timeout)</li>
-</ul><br><h4>Category: Resources/res_pjsip_mwi</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25180">ASTERISK-25180</a>: res_pjsip_mwi: Unsolicited MWI requires reload<br/>Reported by: Joshua Colp<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=80e82dc97f85ce55bbdb311ea2dce641df388c70">[80e82dc97f]</a> Joshua Colp -- res_pjsip_mwi: Set up unsolicited MWI upon registration.</li>
-</ul><br><h4>Category: Resources/res_pjsip_nat</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25196">ASTERISK-25196</a>: res_pjsip_nat: rewrite_contact should not be applied to Contact header when Record-Route headers are present<br/>Reported by: Mark Michelson<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=24eec5a10b43c7642ac555b75ed05b054b5e51df">[24eec5a10b]</a> Mark Michelson -- res_pjsip_nat: Adjust when contact should be rewritten.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=028fa546201658ee0c91bc159363e8240ea06067">[028fa54620]</a> Mark Michelson -- res_pjsip_nat: Rewrite route set when required.</li>
-</ul><br><h4>Category: Resources/res_pjsip_outbound_registration</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24907">ASTERISK-24907</a>: res_pjsip_outbound_registration: crash during unload if registration attempts are still occuring<br/>Reported by: Kevin Harwell<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=0ec461a637ecfdd641cd9a9ce62b766472acde46">[0ec461a637]</a> Richard Mudgett -- res_pjsip_outbound_registration.c: Add a serializer shutdown group.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=84c12f9e0c810c4816444dbd2bb8a6f4e5bfc1f9">[84c12f9e0c]</a> Richard Mudgett -- threadpool, res_pjsip: Add serializer group shutdown API calls.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=602c4b74b500fb6fbe3ae3f6e13d2502edbdd56c">[602c4b74b5]</a> Richard Mudgett -- res_pjsip_outbound_registration.c: Fix handle_client_state_destruction() refs</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8c6a95a9ac605c53d1a5863528ff940221684ea3">[8c6a95a9ac]</a> Richard Mudgett -- res_pjsip_outbound_registration.c: Use ast_sorcery_object_unregister() API</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=20f3d77ab9cfa7f16c7d34956c660d302a71bc53">[20f3d77ab9]</a> Richard Mudgett -- sorcery: Add ast_sorcery_object_unregister() API call.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=4313f32969bc727d667712bba574d7eb875e5b05">[4313f32969]</a> Richard Mudgett -- res_pjsip_outbound_registration.c: Reorder load_module() and unload_module().</li>
-</ul><br><h4>Category: Resources/res_pjsip_refer</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25204">ASTERISK-25204</a>: res_pjsip_refer: Duplicated Referred-By or Replaces headers on outbound INVITEs.<br/>Reported by: Mark Michelson<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=05a2cc129396df9d75d1dbafc040eca117f982ba">[05a2cc1293]</a> Mark Michelson -- res_pjsip_refer: Prevent sending duplicate headers.</li>
-</ul><br><h4>Category: Resources/res_pjsip_session</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25131">ASTERISK-25131</a>: chan_pjsip: In-dialog authentication not handled.<br/>Reported by: Richard Mudgett<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=fe21f2e52f1b6629a254cc2f34345c4de6ec4293">[fe21f2e52f]</a> Richard Mudgett -- res_pjsip_session: Fix in-dialog authentication.</li>
-</ul><br><h4>Category: Resources/res_pjsip_transport_websocket</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25122">ASTERISK-25122</a>: Large SIP packet received via pjsip over websocket crashes Asterisk <br/>Reported by: Ivan Poddubny<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=554bd1e39c704a20226c1f8573fe30a327e9ae98">[554bd1e39c]</a> Ivan Poddubny -- res_pjsip_transport_websocket: Fix crash on receiving large SIP packets</li>
-</ul><br><h4>Category: Resources/res_rtp_asterisk</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25103">ASTERISK-25103</a>: Roundup - investigate Asterisk DTLS crashes<br/>Reported by: Rusty Newton<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=7ff1ac8797a479ae5416d7c51a761552ecde011e">[7ff1ac8797]</a> Joshua Colp -- res_rtp_asterisk: Ensure DTLS timeout timer is -1 if DTLS is not used.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=05e8e1498207055374312f43fb80fcf0b9d5ab45">[05e8e14982]</a> Joshua Colp -- res_rtp_asterisk: Prevent simultaneous access to DTLS SSL context.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=55137c3d123626e3a4621bd325b36b62e634abc5">[55137c3d12]</a> Joshua Colp -- res/res_http_websocket: Don't send HTTP response fragmented.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-22805">ASTERISK-22805</a>: res_rtp_asterisk: Crash when calling BIO_ctrl_pending in dtls_srtp_check_pending when dialed by JSSIP <br/>Reported by: Dmitry Burilov<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=05e8e1498207055374312f43fb80fcf0b9d5ab45">[05e8e14982]</a> Joshua Colp -- res_rtp_asterisk: Prevent simultaneous access to DTLS SSL context.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24651">ASTERISK-24651</a>: [patch] Fix race condition in DTLS<br/>Reported by: Badalian Vyacheslav<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=05e8e1498207055374312f43fb80fcf0b9d5ab45">[05e8e14982]</a> Joshua Colp -- res_rtp_asterisk: Prevent simultaneous access to DTLS SSL context.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24832">ASTERISK-24832</a>: [patch]DTLS-crashes within openssl <br/>Reported by: Stefan Engström<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=05e8e1498207055374312f43fb80fcf0b9d5ab45">[05e8e14982]</a> Joshua Colp -- res_rtp_asterisk: Prevent simultaneous access to DTLS SSL context.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25127">ASTERISK-25127</a>: DTLS crashes following "Unable to cancel schedule ID" in dtls_srtp_check_pending<br/>Reported by: Dade Brandon<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=05e8e1498207055374312f43fb80fcf0b9d5ab45">[05e8e14982]</a> Joshua Colp -- res_rtp_asterisk: Prevent simultaneous access to DTLS SSL context.</li>
-</ul><br><h4>Category: Resources/res_srtp</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24550">ASTERISK-24550</a>: res_rtp_asterisk: Crash in ast_rtp_on_ice_complete during DTLS handshake<br/>Reported by: Osaulenko Alexander<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=05e8e1498207055374312f43fb80fcf0b9d5ab45">[05e8e14982]</a> Joshua Colp -- res_rtp_asterisk: Prevent simultaneous access to DTLS SSL context.</li>
-</ul><br><h4>Category: Resources/res_stasis</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24782">ASTERISK-24782</a>: StasisEnd event not present for channel that was swapped out for another after completing attended transfer<br/>Reported by: John Bigelow<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=97ee0ee6c6d5f37591183339999d8cb936bf517a">[97ee0ee6c6]</a> Kevin Harwell -- bridge.c: Fixed race condition during attended transfer</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=35a99b639474f9140fc294c184bb8f0afb1936cf">[35a99b6394]</a> Kevin Harwell -- bridge.c: Hangup attended transfer target if bridged</li>
-</ul><br><h4>Category: Resources/res_timing_kqueue</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-19277">ASTERISK-19277</a>: [patch]endlessly repeating error: "poll failed: Bad file descriptor"<br/>Reported by: Barry Chern<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f4dd9560cf6a50621172c34c2d9887041aaf8a3a">[f4dd9560cf]</a> Walter Doekes -- res_timing: Don't close FD 0 when out of open files.</li>
-</ul><br><h4>Category: Resources/res_timing_timerfd</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-19277">ASTERISK-19277</a>: [patch]endlessly repeating error: "poll failed: Bad file descriptor"<br/>Reported by: Barry Chern<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f4dd9560cf6a50621172c34c2d9887041aaf8a3a">[f4dd9560cf]</a> Walter Doekes -- res_timing: Don't close FD 0 when out of open files.</li>
-</ul><br><h4>Category: Tests/testsuite</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25165">ASTERISK-25165</a>: Testsuite - Sorcery memory cache leaks<br/>Reported by: Corey Farrell<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=156395e743189649280066c1497292bb97ed022d">[156395e743]</a> Mark Michelson -- res_sorcery_realtime: Fix leak of sorcery object type.</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25172">ASTERISK-25172</a>: Crash in channels/sip/sip blind transfer/caller_refer_only test in ast_format_cap_append_from_cap during ast_request<br/>Reported by: Matt Jordan<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e99e654d75a2428ce4b8bc504acf2ec1927779ed">[e99e654d75]</a> Joshua Colp -- app_dial: Hold reference to calling channel formats when dialing outbound.</li>
-</ul><br><h4>Category: pjproject/pjsip</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24963">ASTERISK-24963</a>: ASAN: heap-use-after-free with PJSIP and WSS<br/>Reported by: Badalian Vyacheslav<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8af6c9cf6bc9f8217fd96f59a6f248330583bdb9">[8af6c9cf6b]</a> Ivan Poddubny -- res_pjsip_transport_websocket: Fix use-after-free bugs.</li>
-</ul><br><h3>New Feature</h3><h4>Category: Channels/chan_pjsip</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25259">ASTERISK-25259</a>: chan_pjsip: Add rtptimeout support<br/>Reported by: Joshua Colp<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=27497217912a82ca243a9d5e9acfbbb597faf323">[2749721791]</a> Joshua Colp -- pjsip: Add rtp_timeout and rtp_timeout_hold endpoint options.</li>
-</ul><br><h4>Category: Resources/res_ari</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25238">ASTERISK-25238</a>: ARI: Support push configuration<br/>Reported by: Matt Jordan<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8bcf6d2801d1b1ed7073ab560bdbe3d0047b1b2c">[8bcf6d2801]</a> Matt Jordan -- ARI: Add support for push configuration of dynamic object</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=bb76b88bafebd69bba31d85acd24fa5d46f3d59a">[bb76b88baf]</a> Matt Jordan -- main/sorcery: Don't fail object set creation from JSON if field fails</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=5f13c2226a35f465ab70c8e25a885f1f3cdaa1c5">[5f13c2226a]</a> Matt Jordan -- main/format_cap: Parse capabilities generated by ast_format_cap_get_names</li>
-</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25173">ASTERISK-25173</a>: ARI: Add the ability to load/reload/unload an Asterisk module<br/>Reported by: Matt Jordan<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=3384e64ef62b0f61dec9f4b4f345b6db74348ae3">[3384e64ef6]</a> Benjamin Ford -- ARI: Fixed unload mode for unload module.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=1aafadf8148a7cf66f73beeb6fe711d98b678fc5">[1aafadf814]</a> Benjamin Ford -- ARI: Added new functionality to reload a single module.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=9dcae23cfceedece83568d2194df00ca62f7d53c">[9dcae23cfc]</a> Benjamin Ford -- ARI: Added new functionality to unload a single module.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=c219a98d2b46a61996518fd2791b7bb4437969fb">[c219a98d2b]</a> Benjamin Ford -- ARI: Added new functionality to load a single module.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=73e35d20deb57281874939f553fea9fdced2e260">[73e35d20de]</a> Benjamin Ford -- ARI: Added new functionality to get information on a single module.</li>
-</ul><br><h4>Category: Resources/res_pjsip_sdp_rtp</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25259">ASTERISK-25259</a>: chan_pjsip: Add rtptimeout support<br/>Reported by: Joshua Colp<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=27497217912a82ca243a9d5e9acfbbb597faf323">[2749721791]</a> Joshua Colp -- pjsip: Add rtp_timeout and rtp_timeout_hold endpoint options.</li>
-</ul><br><hr><a name="open_issues"><h2 align="center">Open Issues</h2></a><center><a href="#top">[Back to Top]</a></center><p>This is a list of all open issues from the issue tracker that were referenced by changes that went into this release.</p><h3>Bug</h3><h4>Category: Core/Sorcery</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25141">ASTERISK-25141</a>: pjsip_options: Contact reference leak<br/>Reported by: Corey Farrell<ul>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=5dc9fb4198f2081f3996c89fb42aaffc0f326df8">[5dc9fb4198]</a> gtjoseph -- res_pjsip/location: Fix ref leak in contact_apply_handler</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=9e7827e3ac057f22bc17823a44778b76270c5901">[9e7827e3ac]</a> Corey Farrell -- pjsip_configuration: Fix leak in persistent_endpoint_update_state.</li>
-<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=857166b5e5dbdb81b4c25a42f36842a394989768">[857166b5e5]</a> gtjoseph -- res_pjsip/location:  Fix memory leak in permanent_uri_handler</li>
-</ul><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><p>This is a list of all changes that went into this release that did not reference a JIRA issue.</p><table width="100%" border="1">
-<tr><th>Revision</th><th>Author</th><th>Summary</th></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=96ec40eb70ed8f79b3c4ffdf50cea416f2a12a99">96ec40eb70</a></td><td>Matt Jordan</td><td>Release summaries: Remove previous versions</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=3e526f11c3ca8b02a2bd3526579d9cc921de937f">3e526f11c3</a></td><td>Matt Jordan</td><td>.version: Update for 13.5.0</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=68823f74386c7d2d7b5735a905ed6e103bf69a1c">68823f7438</a></td><td>Matt Jordan</td><td>.lastclean: Update for 13.5.0</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=d3526317bcf1141ecfa244da1d18eed812f32eaf">d3526317bc</a></td><td>Matt Jordan</td><td>realtime: Add database scripts for 13.5.0</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=59b6e5db769d77f5f2ba41869fbcab0ae6e98696">59b6e5db76</a></td><td>Matt Jordan</td><td>ChangeLog: Updated for 13.5.0-rc1</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a4b527393b0e712aecb7b255b3c503f141f2caad">a4b527393b</a></td><td>Matt Jordan</td><td>Release summaries: Add summaries for 13.5.0-rc1</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=158b0b8ebf512849ac2b2b5b8418006d672718c4">158b0b8ebf</a></td><td>Matt Jordan</td><td>.version: Update for 13.5.0-rc1</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a0a7650e34e8b60ed4c6f486f172f134d8efe84e">a0a7650e34</a></td><td>Matt Jordan</td><td>.lastclean: Update for 13.5.0-rc1</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=4d238af086b72adc48fff0138c4f31400357b0bd">4d238af086</a></td><td>Matt Jordan</td><td>realtime: Add database scripts for 13.5.0-rc1</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f78a4b52b8ed7b5b367c3465652a7ce98fe9175d">f78a4b52b8</a></td><td>Matt Jordan</td><td>Bump the ARI version to 1.8.0</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=b4e19e414adfdd1d5eea792ce1a3dc61d5a7874d">b4e19e414a</a></td><td>Mark Michelson</td><td>res_pjsip: Add rtp_keepalive to sample config file.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a23adcca3d747f14590ddf7860f72418a4475866">a23adcca3d</a></td><td>Michael Cargile</td><td>res/res_musiconhold: Add a warning when MOH does not exist</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=03064daeb2bc78339400b0c05f657032a3e27011">03064daeb2</a></td><td>Matt Jordan</td><td>res/res_sorcery_config: Prevent crash from misconfigured sorcery.conf</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=243c0d1609d193130f24d4586070036fdb900f0f">243c0d1609</a></td><td>Richard Mudgett</td><td>parking_applications.c: Fix ast_verb() line terminator.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=2735dd5b2dd7cbc9ef2a8cf2573f53338f36fb62">2735dd5b2d</a></td><td>Richard Mudgett</td><td>res_pjsip_session.c: Extract sip_session_defer_termination_stop_timer().</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=3d0ca343ca4c3f81e8739bc5a7aaed12b89a207e">3d0ca343ca</a></td><td>Richard Mudgett</td><td>res_pjsip_session.c: Add some helpful comments and minor tweaks.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8d08bb179ce16e52f2340664c3c6aa4fb6432733">8d08bb179c</a></td><td>Richard Mudgett</td><td>res_pjsip_session.c: Fix off nominal crash potential in debug message.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=0a1a550593b6aa00df9f9e3c3643ba402c4c0193">0a1a550593</a></td><td>Matt Jordan</td><td>apps/app_dictate: Fix typo in attribution</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=0b6ff77afbad10b96a31932dd697e06748281d80">0b6ff77afb</a></td><td>Matt Jordan</td><td>res/res_sorcery_astdb: Add a debugging message for when retrieval by ID fails</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=2f0d6d346c83db96b13b0f37d90a8ac48453bbe3">2f0d6d346c</a></td><td>Matt Jordan</td><td>res/res_pjsip_outbound_registration: Fix WARNING message</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=cd2213f1ae7ef14b9a7d50984a5dd4b431a8e195">cd2213f1ae</a></td><td>Matt Jordan</td><td>res_pjsip/configuration: Fix a variety of default value problems</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=2e4bdbd78adb4df16af1132df8e58f464e039cd4">2e4bdbd78a</a></td><td>Matt Jordan</td><td>main/sorcery: Provide log messages when a wizard does not support an operation</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=2325b106fd61817d6be65195b5568945cd5e3084">2325b106fd</a></td><td>Matt Jordan</td><td>tests/test_devicestate: Add additional tests for the device state API</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=328f0be806cc8236288c8760007ab149a865a196">328f0be806</a></td><td>Matt Jordan</td><td>main/devicestate: Prevent duplicate registration of device state providers</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=bee41eec6291d11cb47e7cda1b5abbedb44dccfc">bee41eec62</a></td><td>Matt Jordan</td><td>res/res_sorcery_memory_cache: Fix test registration issues</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=4d738e9026055665bbf7ce99dd03ace1782a674e">4d738e9026</a></td><td>Matt Jordan</td><td>tests/test_sorcery_memory_cache_thrash: Fix test loading problems</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=47ea312b2402bf31a0f1ccb9d73a6b8b7d814b09">47ea312b24</a></td><td>Benjamin Ford</td><td>ARI: Added new functionality to get all module information.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=38bace4fbb8d2c47cc38230645de2aa0769726fb">38bace4fbb</a></td><td>Richard Mudgett</td><td>res_pjsip_t38.c: Fix always false if test.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=2f7688c7881d79f8ac1deb311766208f28468cf2">2f7688c788</a></td><td>Richard Mudgett</td><td>res_pjsip_mwi.c: Use safer loop coding in mwi_subscription_mailboxes_str().</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=74be3a50d79b7b76f6c567e63c3adc7d3f1f135d">74be3a50d7</a></td><td>Richard Mudgett</td><td>res_pjsip_mwi.c: Eliminate a simple RAII_VAR.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=589e93617a77e2523bda05f5b275d4501a072cd7">589e93617a</a></td><td>Richard Mudgett</td><td>res_pjsip_mwi.c: Fix mid-line log message line breaks.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=49f81ddb85a4460ae69569a87a0ea1ae264e3019">49f81ddb85</a></td><td>Matt Jordan</td><td>Makefile: Remove coverage files on 'make clean'</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=78a1f4aa4683702f5c5747b677a7944cb94866c3">78a1f4aa46</a></td><td>Richard Mudgett</td><td>chan_vpb.cc: Fix compiler warning Jenkins found.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8e07ab145d7e4085968696a17fc7167d8ee2ad06">8e07ab145d</a></td><td>Matt Jordan</td><td>sorcery/realtime: Add a bit of debug and warning messages for bad configs</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a5e9c4e9b2faf10aef7635879e2a5cce1be9119b">a5e9c4e9b2</a></td><td>Matt Jordan</td><td>res/res_corosync: Always decline module load, instead of failing</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=2602a7484be67353ac70691e7e75a54983d4d773">2602a7484b</a></td><td>Richard Mudgett</td><td>test.c: Add unit test registration checks for summary and description.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=2b0482d699e44d1f4159bd68d30b2a6a80d21ca8">2b0482d699</a></td><td>Richard Mudgett</td><td>Unit tests: Fix unit test description strings.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=036bc0012f1af3b41268a9f8d4cbbdb11f8995bc">036bc0012f</a></td><td>Richard Mudgett</td><td>res_pjsip_outbound_registration.c: Add missing line endings to CLI commands</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=bec7435945282ef8d646f2a63494995286bebb9f">bec7435945</a></td><td>Richard Mudgett</td><td>res_pjsip_outbound_registration.c: Eliminate simple RAII_VAR() usage.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=c2519fdf1c8ff99e966c3e868f75305cd3826475">c2519fdf1c</a></td><td>Richard Mudgett</td><td>res_pjsip_outbound_registration.c: Misc code cleanups.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a2b718f4f625c02da3d36546d680836dfb8ef9bd">a2b718f4f6</a></td><td>Richard Mudgett</td><td>res_pjsip.h: Fix some doxygen comments.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=32ddf6d86b9f47a044f293eea2401b5a34c68595">32ddf6d86b</a></td><td>Richard Mudgett</td><td>taskprocessor.c: Remove extra unref from off-nominal path.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e0090216db3e6d4b7796bbb0b230225bfdbe068e">e0090216db</a></td><td>ibercom</td><td>CLI: Cosmetic issue - core show uptime</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=d908272b7e03d8b5002e4d3d83bcf8725c57afdd">d908272b7e</a></td><td>David M. Lee</td><td>Fixes for OS X</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=1558a891293dd96ba71a3cedf0caa1968067ba5e">1558a89129</a></td><td>gtjoseph</td><td>Revert "endpoint/stasis: Eliminate duplicate events on endpoint status change"</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=5a42397018f8b850b3901de0a09b8befad602b37">5a42397018</a></td><td>Joshua Colp</td><td>sorcery: Fix cache creation callback.</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=51ffed5e6123c0f2b816067ebbd27b9dbd85d2d5">51ffed5e61</a></td><td>Matt Jordan</td><td>res/res_pjsip_pubsub: Note that 'dialog' is also a valid event type for RLS</td></tr>
-<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=7950b65e4f707d36cb8d17e82288e913c4d86f22">7950b65e4f</a></td><td>Matt Jordan</td><td>res/res_pjsip_exten_state: Fix confusing NOTICE message</td></tr>
-</table><hr><a name="diffstat"><h2 align="center">Diffstat Results</h2></a><center><a href="#top">[Back to Top]</a></center><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>asterisk-13.4.0-summary.html                                                      |   18
-asterisk-13.4.0-summary.txt                                                       |   87
-b/.version                                                                        |    2
-b/CHANGES                                                                         |   41
-b/ChangeLog                                                                       | 2194 ++++++++
-b/Makefile                                                                        |    4
-b/Makefile.moddir_rules                                                           |    1
-b/UPGRADE.txt                                                                     |   11
-b/apps/Makefile                                                                   |    2
-b/apps/app_dial.c                                                                 |   20
-b/apps/app_dictate.c                                                              |    2
-b/apps/app_directory.c                                                            |   48
-b/apps/app_meetme.c                                                               |   18
-b/autoconf/ast_gcc_attribute.m4                                                   |    2
-b/bridges/bridge_native_rtp.c                                                     |   28
-b/channels/Makefile                                                               |    8
-b/channels/chan_dahdi.c                                                           |   14
-b/channels/chan_iax2.c                                                            |  144
-b/channels/chan_mgcp.c                                                            |   18
-b/channels/chan_pjsip.c                                                           |   17
-b/channels/chan_sip.c                                                             |   45
-b/channels/chan_skinny.c                                                          |   10
-b/channels/chan_vpb.cc                                                            |    5
-b/channels/misdn/Makefile                                                         |    2
-b/channels/sig_pri.c                                                              |    2
-b/channels/sig_pri.h                                                              |    2
-b/codecs/gsm/Makefile                                                             |    2
-b/configs/samples/pjsip.conf.sample                                               |   14
-b/configs/samples/sip.conf.sample                                                 |    2
-b/configure                                                                       |   22
-b/contrib/ast-db-manage/config/versions/26f10cadc157_add_pjsip_timeout_options.py |   24
-b/contrib/ast-db-manage/config/versions/28b8e71e541f_add_g726_non_standard.py     |   30
-b/contrib/ast-db-manage/config/versions/498357a710ae_add_rtp_keepalive.py         |   22
-b/contrib/realtime/mssql/mssql_config.sql                                         |   28
-b/contrib/realtime/mysql/mysql_config.sql                                         |   20
-b/contrib/realtime/oracle/oracle_config.sql                                       |   28
-b/contrib/realtime/postgresql/postgresql_config.sql                               |   16
-b/doc/appdocsxml.xslt                                                             |    6
-b/funcs/func_cdr.c                                                                |    3
-b/funcs/func_pjsip_aor.c                                                          |    2
-b/include/asterisk/ari.h                                                          |    5
-b/include/asterisk/bridge.h                                                       |    2
-b/include/asterisk/bridge_channel_internal.h                                      |   40
-b/include/asterisk/manager.h                                                      |    2
-b/include/asterisk/module.h                                                       |   37
-b/include/asterisk/pbx.h                                                          |   16
-b/include/asterisk/res_pjsip.h                                                    |   58
-b/include/asterisk/res_pjsip_presence_xml.h                                       |    9
-b/include/asterisk/res_pjsip_session.h                                            |    4
-b/include/asterisk/rtp_engine.h                                                   |   32
-b/include/asterisk/slin.h                                                         |    4
-b/include/asterisk/sorcery.h                                                      |   20
-b/include/asterisk/stasis.h                                                       |   11
-b/include/asterisk/stasis_endpoints.h                                             |    6
-b/include/asterisk/strings.h                                                      |   54
-b/include/asterisk/test.h                                                         |   13
-b/include/asterisk/threadpool.h                                                   |   69
-b/main/.gitignore                                                                 |    1
-b/main/Makefile                                                                   |    2
-b/main/astfd.c                                                                    |   57
-b/main/astobj2_hash.c                                                             |   11
-b/main/audiohook.c                                                                |   25
-b/main/bridge.c                                                                   |   63
-b/main/bridge_channel.c                                                           |   45
-b/main/cdr.c                                                                      |   10
-b/main/channel.c                                                                  |    6
-b/main/channel_internal_api.c                                                     |   11
-b/main/cli.c                                                                      |   18
-b/main/config.c                                                                   |    1
-b/main/core_unreal.c                                                              |   12
-b/main/devicestate.c                                                              |    9
-b/main/format_cap.c                                                               |   19
-b/main/loader.c                                                                   |   54
-b/main/manager_channels.c                                                         |   39
-b/main/manager_endpoints.c                                                        |    1
-b/main/pbx.c                                                                      |   46
-b/main/presencestate.c                                                            |   15
-b/main/rtp_engine.c                                                               |   28
-b/main/sched.c                                                                    |   12
-b/main/sorcery.c                                                                  |   60
-b/main/stasis.c                                                                   |    4
-b/main/stasis_channels.c                                                          |   10
-b/main/stasis_endpoints.c                                                         |   71
-b/main/taskprocessor.c                                                            |    1
-b/main/test.c                                                                     |   36
-b/main/threadpool.c                                                               |  148
-b/main/utils.c                                                                    |  130
-b/menuselect/configure                                                            |    8
-b/pbx/Makefile                                                                    |    2
-b/pbx/pbx_config.c                                                                |   15
-b/res/Makefile                                                                    |    8
-b/res/ari/ari_model_validators.c                                                  |  156
-b/res/ari/ari_model_validators.h                                                  |   45
-b/res/ari/resource_asterisk.c                                                     |  487 +
-b/res/ari/resource_asterisk.h                                                     |  127
-b/res/ari/resource_events.c                                                       |   39
-b/res/ari/resource_events.h                                                       |   15
-b/res/parking/parking_applications.c                                              |   12
-b/res/parking/parking_manager.c                                                   |   16
-b/res/res_ari.c                                                                   |    7
-b/res/res_ari_asterisk.c                                                          |  584 ++
-b/res/res_ari_events.c                                                            |  108
-b/res/res_corosync.c                                                              |    4
-b/res/res_hep_rtcp.c                                                              |    2
-b/res/res_http_websocket.c                                                        |   23
-b/res/res_musiconhold.c                                                           |    2
-b/res/res_mwi_external_ami.c                                                      |    6
-b/res/res_pjsip.c                                                                 |  468 +
-b/res/res_pjsip/location.c                                                        |   12
-b/res/res_pjsip/pjsip_configuration.c                                             |  126
-b/res/res_pjsip/pjsip_distributor.c                                               |  105
-b/res/res_pjsip/pjsip_options.c                                                   |    7
-b/res/res_pjsip_dialog_info_body_generator.c                                      |    9
-b/res/res_pjsip_dtmf_info.c                                                       |    8
-b/res/res_pjsip_exten_state.c                                                     |    2
-b/res/res_pjsip_mwi.c                                                             |  262 -
-b/res/res_pjsip_nat.c                                                             |   90
-b/res/res_pjsip_outbound_registration.c                                           |  454 +
-b/res/res_pjsip_pidf_body_generator.c                                             |   11
-b/res/res_pjsip_pubsub.c                                                          |    5
-b/res/res_pjsip_refer.c                                                           |   46
-b/res/res_pjsip_registrar.c                                                       |    2
-b/res/res_pjsip_sdp_rtp.c                                                         |  114
-b/res/res_pjsip_session.c                                                         |  256
-b/res/res_pjsip_t38.c                                                             |   22
-b/res/res_pjsip_transport_websocket.c                                             |   99
-b/res/res_pjsip_xpidf_body_generator.c                                            |    9
-b/res/res_rtp_asterisk.c                                                          |  215
-b/res/res_security_log.c                                                          |    2
-b/res/res_sorcery_astdb.c                                                         |    1
-b/res/res_sorcery_config.c                                                        |   11
-b/res/res_sorcery_memory_cache.c                                                  | 2572 ++++++++++
-b/res/res_sorcery_realtime.c                                                      |    2
-b/res/res_stasis.c                                                                |    6
-b/res/res_stasis_device_state.c                                                   |    2
-b/res/res_timing_kqueue.c                                                         |    4
-b/res/res_timing_timerfd.c                                                        |    5
-b/res/res_xmpp.c                                                                  |    4
-b/res/stasis/app.c                                                                |    5
-b/res/stasis/control.c                                                            |    4
-b/rest-api-templates/ari_resource.h.mustache                                      |   19
-b/rest-api-templates/res_ari_resource.c.mustache                                  |   70
-b/rest-api/api-docs/applications.json                                             |    2
-b/rest-api/api-docs/asterisk.json                                                 |  307 +
-b/rest-api/api-docs/bridges.json                                                  |    2
-b/rest-api/api-docs/channels.json                                                 |    2
-b/rest-api/api-docs/deviceStates.json                                             |    2
-b/rest-api/api-docs/endpoints.json                                                |    2
-b/rest-api/api-docs/events.json                                                   |    2
-b/rest-api/api-docs/mailboxes.json                                                |    2
-b/rest-api/api-docs/playbacks.json                                                |    2
-b/rest-api/api-docs/recordings.json                                               |    2
-b/rest-api/api-docs/sounds.json                                                   |    2
-b/rest-api/resources.json                                                         |    2
-b/tests/test_cdr.c                                                                |   46
-b/tests/test_cel.c                                                                |   50
-b/tests/test_channel_feature_hooks.c                                              |    4
-b/tests/test_devicestate.c                                                        |  432 +
-b/tests/test_expr.c                                                               |    2
-b/tests/test_format_cap.c                                                         |    2
-b/tests/test_gosub.c                                                              |   10
-b/tests/test_message.c                                                            |   18
-b/tests/test_pbx.c                                                                |    9
-b/tests/test_poll.c                                                               |    2
-b/tests/test_sorcery_memory_cache_thrash.c                                        |  618 ++
-b/tests/test_sorcery_realtime.c                                                   |    2
-b/tests/test_stasis.c                                                             |    4
-b/tests/test_strings.c                                                            |   70
-b/tests/test_threadpool.c                                                         |    4
-169 files changed, 11351 insertions(+), 1237 deletions(-)</pre><br></html>
\ No newline at end of file
diff --git a/asterisk-13.5.0-summary.txt b/asterisk-13.5.0-summary.txt
deleted file mode 100644
index 5c49255..0000000
--- a/asterisk-13.5.0-summary.txt
+++ /dev/null
@@ -1,1141 +0,0 @@
-                                Release Summary
-
-                                asterisk-13.5.0
-
-                                Date: 2015-08-07
-
-                           <asteriskteam at digium.com>
-
-     ----------------------------------------------------------------------
-
-                               Table of Contents
-
-    1. Summary
-    2. Contributors
-    3. Closed Issues
-    4. Open Issues
-    5. Other Changes
-    6. Diffstat
-
-     ----------------------------------------------------------------------
-
-                                    Summary
-
-                                 [Back to Top]
-
-   This release is a point release of an existing major version. The changes
-   included were made to address problems that have been identified in this
-   release series, or are minor, backwards compatible new features or
-   improvements. Users should be able to safely upgrade to this version if
-   this release series is already in use. Users considering upgrading from a
-   previous version 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-13.4.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 affected by commits that went into
-   this release.
-
-   Coders                           Testers            Reporters              
-   33 Matt Jordan                   3 gtjoseph         13 Matt Jordan         
-   33 Richard Mudgett               1 Damian Ivereigh  8 Corey Farrell        
-   15 Joshua Colp                                      7 Kevin Harwell        
-   11 Mark Michelson                                   6 Rusty Newton         
-   6 gtjoseph                                          6 Kevin Harwell        
-   6 Benjamin Ford                                     6 Joshua Colp          
-   5 Walter Doekes                                     5 Richard Mudgett      
-   5 Corey Farrell                                     5 Mark Michelson       
-   4 Kevin Harwell                                     5 Mark Michelson       
-   4 Ivan Poddubny                                     4 Walter Doekes        
-   2 ibercom                                           4 Richard Mudgett      
-   1 Yousf Ateya                                       3 George Joseph        
-   1 Patric Marschall                                  3 John Bigelow         
-   1 Damian Ivereigh                                   3 Badalian Vyacheslav  
-   1 demon-ru                                          3 Carl Fortin          
-   1 Scott Griepentrog                                 3 Carl Fortin          
-   1 Michael Cargile                                   3 Dmitriy Serov        
-   1 Rusty Newton                                      2 Etienne Lessard      
-   1 David M. Lee                                      2 gtjoseph             
-   1 Alexander Traud (License 6520)                    2 warren smith         
-                                                       2 Rusty Newton         
-                                                       2 Joshua Colp          
-                                                       2 Etienne Lessard      
-                                                       2 John Bigelow         
-                                                       1 Barry Chern          
-                                                       1 Vitezslav Novy       
-                                                       1 Scott Griepentrog    
-                                                       1 Y Ateya              
-                                                       1 Dmitriy Serov        
-                                                       1 Chet Stevens         
-                                                       1 cloos                
-                                                       1 Josh Kitchens        
-                                                       1 Alexander Traud      
-                                                       1 Mark Petersen        
-                                                       1 John Hardin          
-                                                       1 Ilya Trikoz          
-                                                       1 Dmitry Burilov       
-                                                       1 Damian Ivereigh      
-                                                       1 Barry Chern          
-                                                       1 Patric Marschall     
-                                                       1 Damian Ivereigh      
-                                                       1 Patric Marschall     
-                                                       1 Chet Stevens         
-                                                       1 Andrey Biglari       
-                                                       1 PSDK                 
-                                                       1 hristo               
-                                                       1 Arveno Santoro       
-                                                       1 Vitezslav Novy       
-                                                       1 Stefan EngstrAP:m    
-                                                       1 Janusz Karolak       
-                                                       1 Badalian Vyacheslav  
-                                                       1 Ivan Poddubny        
-                                                       1 Y Ateya              
-                                                       1 ibercom              
-                                                       1 warren smith         
-                                                       1 cervajs              
-                                                       1 Ilya Trikoz          
-                                                       1 Osaulenko Alexander  
-                                                       1 Steve Pitts          
-                                                       1 Alexander Traud      
-                                                       1 Dade Brandon         
-                                                       1 ibercom              
-                                                       1 Mark Petersen        
-                                                       1 Josh Kitchens        
-
-     ----------------------------------------------------------------------
-
-                                 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.
-
-  Improvement
-
-    Category: Core/General
-
-   ASTERISK-25256: [patch]Post AMI VarSet to empty string events when
-   Asterisk deletes a dialplan variable.
-   Reported by: Richard Mudgett
-     * [875aee4c09] Richard Mudgett -- pbx.c: Post AMI VarSet event if delete
-       a non-empty dialplan variable.
-
-    Category: Core/PBX
-
-   ASTERISK-25040: pbx: Improve performance of reloads by making hint
-   destruction more performant
-   Reported by: Matt Jordan
-     * [399cd8bcd9] Matt Jordan -- main/pbx: Resolve case sensitivity
-       regression in PBX hints
-
-    Category: Core/Sorcery
-
-   ASTERISK-25067: Sorcery Caching: Implement a new caching module
-   Reported by: Matt Jordan
-     * [b74b071369] Joshua Colp -- res_sorcery_memory_cache: Backport to 13
-
-    Category: Resources/res_pjsip
-
-   ASTERISK-25114: res_pjsip: Add AMI events for chan_pjsip contact lifecycle
-   changes
-   Reported by: George Joseph
-     * [262d590819] gtjoseph -- res_pjsip: Add AMI events for chan_pjsip
-       contact lifecycle changes
-
-    Category: Resources/res_pjsip_outbound_registration
-
-   ASTERISK-25072: res_pjsip_outbound_registration: line functionality.
-   Additional check for using the request URI
-   Reported by: Dmitriy Serov
-     * [42476e6633] demon-ru -- res_pjsip_outbound_registration: Check
-       request URI for line.
-
-  Bug
-
-    Category: Applications/app_chanspy
-
-   ASTERISK-25247: choppy audio when spying on a g722 channel, chan_sip or
-   chan_pjsip
-   Reported by: hristo
-     * [f1493f900e] Joshua Colp -- audiohook: Read the correct number of
-       samples based on audiohook format.
-
-    Category: Applications/app_confbridge
-
-   ASTERISK-25253: confbridge volume options and other volume controls such
-   as func_volume don't work
-   Reported by: Dmitriy Serov
-     * [f509730cb9] Joshua Colp -- audiohook: Use manipulated frame instead
-       of dropping it.
-
-    Category: Applications/app_dial
-
-   ASTERISK-25212: [patch]Segfault when using DEBUG_FD_LEAKS
-   Reported by: Walter Doekes
-     * [6551e16e03] Walter Doekes -- astfd: Fix buffer overflow in
-       DEBUG_FD_LEAKS.
-
-    Category: Applications/app_directory
-
-   ASTERISK-25087: Asterisk segfault when using Directory application with
-   alias option and specific mailbox configuration
-   Reported by: Chet Stevens
-     * [a2f4d03c87] Richard Mudgett -- app_directory: Fix crash when using
-       the alias option 'a'.
-
-    Category: Bridges/bridge_native_rtp
-
-   ASTERISK-25240: bridge_native_rtp: Direct media wrongfully started when
-   completing attended transfer
-   Reported by: Joshua Colp
-     * [d558b00c85] Joshua Colp -- bridge_native_rtp.c: Don't start native
-       RTP bridging after attended transfer.
-   ASTERISK-25171: Early completion of feature code attended transfer results
-   in intermittent one-way audio, "ghost ringing" and robotic sound.
-   Reported by: Rusty Newton
-     * [e4a2ef9e4e] Joshua Colp -- channel: Remove ignore of answer on
-       non-outgoing channels.
-
-    Category: CDR/General
-
-   ASTERISK-24344: CDR_PROP(disable) disables CDR only for first dialed party
-   Reported by: Janusz Karolak
-     * [de8c7f46ed] Matt Jordan -- main/cdr: Carry over the disable flag when
-       'disable all' is specified
-   ASTERISK-24443: CDR fields (dst, dcontext) empty in transfer call started
-   from Macro
-   Reported by: Arveno Santoro
-     * [78ea356e78] Matt Jordan -- main/cdr: Copy context/exten on chained
-       CDRs for parallel dials in subroutines
-
-    Category: Channels/chan_dahdi
-
-   ASTERISK-25257: [patch]channels/sig_pri.h -> sig_pri_span ->
-   force_restart_unavailable_chans in wrong scope
-   Reported by: Patric Marschall
-     * [abb14ac5b8] Patric Marschall -- sig_pri.h:
-       force_restart_unavailable_chans in wrong scope
-
-    Category: Channels/chan_iax2
-
-   ASTERISK-24983: IAX deadlock between hangup and scheduled actions (ex.
-   largrq)
-   Reported by: Y Ateya
-     * [cf98c744d5] Yousf Ateya -- chan_iax2: Prevent deadlock between hangup
-       and sending lagrq/ping
-
-    Category: Channels/chan_local
-
-   ASTERISK-25250: chan_sip - Despite the channel being answered, caller on a
-   call established via Local channel continues to hear ringback
-   Reported by: Etienne Lessard
-     * [f635520527] Mark Michelson -- Local channels: Alternate solution to
-       ringback problem.
-     * [54b25c80c8] Mark Michelson -- Local channels: Do not block control -1
-       payloads.
-
-    Category: Channels/chan_mgcp
-
-   ASTERISK-25220: [patch]Closing of fd -1 in chan_mgcp.c
-   Reported by: Walter Doekes
-     * [a5a262be78] Walter Doekes -- chan_mgcp: Don't call close on fd -1.
-
-    Category: Channels/chan_pjsip
-
-   ASTERISK-25258: chan_pjsip: Incorrect format switch on received RTP packet
-   Reported by: Joshua Colp
-     * [2c626ceb64] Joshua Colp -- chan_pjsip: Don't change formats when
-       frame of unsupported format is received.
-   ASTERISK-25183: PJSIP: Crash on NULL channel in
-   chan_pjsip_incoming_response despite previous checks for NULL channel
-   Reported by: Matt Jordan
-     * [653f2087e0] Richard Mudgett -- res_pjsip_session.c: Fix crash on call
-       disconnect.
-     * [ada7346792] Richard Mudgett -- res_pjsip: Need to use the same
-       serializer for a pjproject SIP transaction.
-   ASTERISK-25091: Asterisk REST API - bridge.addChannel crash asterisk when
-   calling channel hangup while adding to bridge
-   Reported by: Ilya Trikoz
-     * [9015bb4c8c] Mark Michelson -- Resolve race conditions involving
-       Stasis bridges.
-   ASTERISK-25156: chan_pjsipa**s CHAN_START cel event lacks the correct
-   context and exten
-   Reported by: cloos
-     * [30a0f2d9ac] Matt Jordan -- chan_pjsip: Set the context and extension
-       on the channel when created
-
-    Category: Channels/chan_sip/CodecHandling
-
-   ASTERISK-25182: [patch] on CLI sip reload, new codecs get appended only
-   Reported by: Alexander Traud
-     * [a419c69def] Alexander Traud -- chan_sip: Reload peer without its old
-       capabilities.
-
-    Category: Channels/chan_sip/General
-
-   ASTERISK-25250: chan_sip - Despite the channel being answered, caller on a
-   call established via Local channel continues to hear ringback
-   Reported by: Etienne Lessard
-     * [f635520527] Mark Michelson -- Local channels: Alternate solution to
-       ringback problem.
-     * [54b25c80c8] Mark Michelson -- Local channels: Do not block control -1
-       payloads.
-   ASTERISK-22805: res_rtp_asterisk: Crash when calling BIO_ctrl_pending in
-   dtls_srtp_check_pending when dialed by JSSIP
-   Reported by: Dmitry Burilov
-     * [05e8e14982] Joshua Colp -- res_rtp_asterisk: Prevent simultaneous
-       access to DTLS SSL context.
-   ASTERISK-25212: [patch]Segfault when using DEBUG_FD_LEAKS
-   Reported by: Walter Doekes
-     * [6551e16e03] Walter Doekes -- astfd: Fix buffer overflow in
-       DEBUG_FD_LEAKS.
-   ASTERISK-25202: Hints extension state broken between 13.3.2 and 13.4
-   Reported by: cervajs
-     * [399cd8bcd9] Matt Jordan -- main/pbx: Resolve case sensitivity
-       regression in PBX hints
-   ASTERISK-25171: Early completion of feature code attended transfer results
-   in intermittent one-way audio, "ghost ringing" and robotic sound.
-   Reported by: Rusty Newton
-     * [e4a2ef9e4e] Joshua Colp -- channel: Remove ignore of answer on
-       non-outgoing channels.
-   ASTERISK-25163: Deadlock in chan_sip between reload of sip peer container
-   and MWI Stasis callback
-   Reported by: Dmitriy Serov
-     * [74616ae43d] Joshua Colp -- chan_sip: Destroy peers without holding
-       peers container lock.
-
-    Category: Channels/chan_sip/IPv6
-
-   ASTERISK-25100: asterisk coredump if host has an IPv6 address that end
-   with ::80
-   Reported by: Mark Petersen
-     * [97a6ce1717] Ivan Poddubny -- Astobj2: Correctly treat hash_fn
-       returning INT_MIN
-
-    Category: Channels/chan_sip/Interoperability
-
-   ASTERISK-25154: [patch]fromtag may need to be updated after successful
-   call dialog match
-   Reported by: Damian Ivereigh
-     * [3f57f3f8ec] Damian Ivereigh -- chan_sip.c: Update dialog fromtag
-       after request with auth
-
-    Category: Channels/chan_sip/SRTP
-
-   ASTERISK-24550: res_rtp_asterisk: Crash in ast_rtp_on_ice_complete during
-   DTLS handshake
-   Reported by: Osaulenko Alexander
-     * [05e8e14982] Joshua Colp -- res_rtp_asterisk: Prevent simultaneous
-       access to DTLS SSL context.
-
-    Category: Channels/chan_sip/Transfers
-
-   ASTERISK-25226: chan_sip: Channel leak in branch 13 on early replaces call
-   pickup
-   Reported by: Walter Doekes
-     * [e0f565663b] Walter Doekes -- chan_sip: Fix early call pickup channel
-       leak.
-
-    Category: Codecs/codec_adpcm
-
-   ASTERISK-24717: ASAN: global-buffer-overflow codec_{ilbc | gsm | adpcm |
-   ipc10}
-   Reported by: Badalian Vyacheslav
-     * [888bb49618] Ivan Poddubny -- Fix buffer overflow in slin sample
-       frames generation.
-
-    Category: Codecs/codec_gsm
-
-   ASTERISK-24717: ASAN: global-buffer-overflow codec_{ilbc | gsm | adpcm |
-   ipc10}
-   Reported by: Badalian Vyacheslav
-     * [888bb49618] Ivan Poddubny -- Fix buffer overflow in slin sample
-       frames generation.
-
-    Category: Codecs/codec_ilbc
-
-   ASTERISK-24717: ASAN: global-buffer-overflow codec_{ilbc | gsm | adpcm |
-   ipc10}
-   Reported by: Badalian Vyacheslav
-     * [888bb49618] Ivan Poddubny -- Fix buffer overflow in slin sample
-       frames generation.
-
-    Category: Codecs/codec_lpc10
-
-   ASTERISK-24717: ASAN: global-buffer-overflow codec_{ilbc | gsm | adpcm |
-   ipc10}
-   Reported by: Badalian Vyacheslav
-     * [888bb49618] Ivan Poddubny -- Fix buffer overflow in slin sample
-       frames generation.
-
-    Category: Core/Bridging
-
-   ASTERISK-25250: chan_sip - Despite the channel being answered, caller on a
-   call established via Local channel continues to hear ringback
-   Reported by: Etienne Lessard
-     * [f635520527] Mark Michelson -- Local channels: Alternate solution to
-       ringback problem.
-     * [54b25c80c8] Mark Michelson -- Local channels: Do not block control -1
-       payloads.
-   ASTERISK-24782: StasisEnd event not present for channel that was swapped
-   out for another after completing attended transfer
-   Reported by: John Bigelow
-     * [97ee0ee6c6] Kevin Harwell -- bridge.c: Fixed race condition during
-       attended transfer
-     * [35a99b6394] Kevin Harwell -- bridge.c: Hangup attended transfer
-       target if bridged
-   ASTERISK-25157: bridging: Performing a blonde transfer does not result in
-   connected line updates
-   Reported by: Joshua Colp
-     * [dbb067279e] Joshua Colp -- bridge: When performing a blonde transfer
-       update connected line information.
-
-    Category: Core/CodecInterface
-
-   ASTERISK-25172: Crash in channels/sip/sip blind transfer/caller_refer_only
-   test in ast_format_cap_append_from_cap during ast_request
-   Reported by: Matt Jordan
-     * [e99e654d75] Joshua Colp -- app_dial: Hold reference to calling
-       channel formats when dialing outbound.
-
-    Category: Core/General
-
-   ASTERISK-25255: Missing AMI VarSet events when setting to an empty string.
-   Reported by: Richard Mudgett
-     * [e31cb6b248] Richard Mudgett -- strings.h: Fix issues with escape
-       string functions.
-   ASTERISK-25201: Crash in PJSIP distributor on already free'd threadpool
-   Reported by: Matt Jordan
-     * [653f2087e0] Richard Mudgett -- res_pjsip_session.c: Fix crash on call
-       disconnect.
-   ASTERISK-25212: [patch]Segfault when using DEBUG_FD_LEAKS
-   Reported by: Walter Doekes
-     * [6551e16e03] Walter Doekes -- astfd: Fix buffer overflow in
-       DEBUG_FD_LEAKS.
-   ASTERISK-22559: gcc 4.6 and higher supports weakref attribute but asterisk
-   doesn't detect it.
-   Reported by: ibercom
-     * [3046bc17ed] ibercom -- weakref attribute detection broken with gcc
-       4.6 and higher
-
-    Category: Core/ManagerInterface
-
-   ASTERISK-24934: [patch]Asterisk manager output does not escape control
-   characters
-   Reported by: warren smith
-     * [e31cb6b248] Richard Mudgett -- strings.h: Fix issues with escape
-       string functions.
-     * [f5d5aa67dc] Kevin Harwell -- AMI: Escape string values.
-   ASTERISK-24900: Manager event ParkedCallSwap is not documented
-   Reported by: Rusty Newton
-     * [723a9d4225] Mark Michelson -- Parking: Add documentation for AMI
-       ParkedCallSwap event.
-
-    Category: Core/ManagerInterface/NewFeature
-
-   ASTERISK-25189: AMI: Add Linkedid header to standard channel snapshot
-   information.
-   Reported by: Richard Mudgett
-     * [890c923786] Richard Mudgett -- AMI: Add Linkedid to the standard
-       channel snapshot AMI event headers.
-
-    Category: Core/PBX
-
-   ASTERISK-25094: PBX core: Investigate thread safety issues
-   Reported by: Corey Farrell
-     * [55c8daf88b] Corey Farrell -- Fix unsafe uses of ast_context pointers.
-
-    Category: Core/RTP
-
-   ASTERISK-25219: [patch]Source and destination overlap in memcpy in
-   rtp_engine.c
-   Reported by: Walter Doekes
-     * [b835312b4c] Walter Doekes -- rtp_engine: Skip useless self-assignment
-       in ast_rtp_engine_unload_format.
-
-    Category: Core/Sorcery
-
-   ASTERISK-25165: Testsuite - Sorcery memory cache leaks
-   Reported by: Corey Farrell
-     * [156395e743] Mark Michelson -- res_sorcery_realtime: Fix leak of
-       sorcery object type.
-
-    Category: Core/Stasis
-
-   ASTERISK-25137: endpoint stasis messages are delivered twice
-   Reported by: Vitezslav Novy
-     * [35c699086a] gtjoseph -- endpoint/stasis: Eliminate duplicate events
-       on endpoint status change
-   ASTERISK-25121: Stasis: Fix unsafe use of stasis_unsubscribe in modules.
-   Reported by: Corey Farrell
-     * [0d266cbe02] Corey Farrell -- Stasis: Fix unsafe use of
-       stasis_unsubscribe in modules.
-
-    Category: Documentation
-
-   ASTERISK-24867: Docs for 'e' option in ResetCDR say to use CDR_PROP
-   instead, CDR_PROP docs are unclear
-   Reported by: Rusty Newton
-     * [62c64c3bd1] Rusty Newton -- Documentation: A couple of trivial fixes
-       in sip.conf.sample and func_cdr.c
-   ASTERISK-24853: Documentation claims chan_sip outbound registrations
-   support WS or WSS as valid transports (not true)
-   Reported by: PSDK
-     * [62c64c3bd1] Rusty Newton -- Documentation: A couple of trivial fixes
-       in sip.conf.sample and func_cdr.c
-
-    Category: Functions/func_talkdetect
-
-   ASTERISK-24988: func_talkdetect: Test is bouncing sporadically
-   Reported by: Joshua Colp
-     * [5ac65ddfb4] Matt Jordan -- res/ari: Register Stasis application on
-       WebSocket attempt
-
-    Category: Resources/res_ari
-
-   ASTERISK-25091: Asterisk REST API - bridge.addChannel crash asterisk when
-   calling channel hangup while adding to bridge
-   Reported by: Ilya Trikoz
-     * [9015bb4c8c] Mark Michelson -- Resolve race conditions involving
-       Stasis bridges.
-
-    Category: Resources/res_ari_bridges
-
-   ASTERISK-25091: Asterisk REST API - bridge.addChannel crash asterisk when
-   calling channel hangup while adding to bridge
-   Reported by: Ilya Trikoz
-     * [9015bb4c8c] Mark Michelson -- Resolve race conditions involving
-       Stasis bridges.
-
-    Category: Resources/res_crypto
-
-   ASTERISK-24550: res_rtp_asterisk: Crash in ast_rtp_on_ice_complete during
-   DTLS handshake
-   Reported by: Osaulenko Alexander
-     * [05e8e14982] Joshua Colp -- res_rtp_asterisk: Prevent simultaneous
-       access to DTLS SSL context.
-
-    Category: Resources/res_http_websocket
-
-   ASTERISK-24963: ASAN: heap-use-after-free with PJSIP and WSS
-   Reported by: Badalian Vyacheslav
-     * [8af6c9cf6b] Ivan Poddubny -- res_pjsip_transport_websocket: Fix
-       use-after-free bugs.
-
-    Category: Resources/res_mwi_external_ami
-
-   ASTERISK-25117: res_mwi_external_ami: Fix manager action registrations.
-   Reported by: Corey Farrell
-     * [e7edb59db6] Corey Farrell -- res_mwi_external_ami: Use module version
-       of AMI registration.
-
-    Category: Resources/res_parking
-
-   ASTERISK-25254: Crash if dialplan sets ATTENDEDTRANSFER to an empty string
-   before Park.
-   Reported by: Richard Mudgett
-     * [c782320c68] Richard Mudgett -- res_parking: Fix crash if
-       ATTENDEDTRANSFER set empty before Park.
-
-    Category: Resources/res_pjsip
-
-   ASTERISK-25201: Crash in PJSIP distributor on already free'd threadpool
-   Reported by: Matt Jordan
-     * [653f2087e0] Richard Mudgett -- res_pjsip_session.c: Fix crash on call
-       disconnect.
-   ASTERISK-25168: Random Core Dumps on Asterisk 13.4 PJSIP, in
-   ast_channel_name at channel_internal_api.c
-   Reported by: Carl Fortin
-     * [0d67e04359] Richard Mudgett -- res_pjsip_mwi.c: Fix MWI subscription
-       memory corruption crash.
-     * [0422433f47] Richard Mudgett -- PJSIP XML, XPIDF: Fix buffer size
-       overwrite memory corruption error.
-     * [8ea214aed7] Richard Mudgett -- PJSIP FAX: Fix T.38 automatic reject
-       timer NULL channel pointer dereferences.
-   ASTERISK-25115: Crash related to func sip_resolve_invoke_user_callback of
-   res_pjsip/pjsip_resolver.c
-   Reported by: John Bigelow
-     * [ada7346792] Richard Mudgett -- res_pjsip: Need to use the same
-       serializer for a pjproject SIP transaction.
-   ASTERISK-25171: Early completion of feature code attended transfer results
-   in intermittent one-way audio, "ghost ringing" and robotic sound.
-   Reported by: Rusty Newton
-     * [e4a2ef9e4e] Joshua Colp -- channel: Remove ignore of answer on
-       non-outgoing channels.
-   ASTERISK-25158: res_pjsip: Add option to use AAL2 packing when negotiating
-   g.726
-   Reported by: Kevin Harwell
-     * [31c77b157b] Kevin Harwell -- res_pjsip: Add option to force G.726 to
-       be treated as AAL2 packed.
-   ASTERISK-25096: [patch]Segfault when registering over websockets with
-   PJSIP (in ast_sockaddr_isnull at /include/asterisk/netsock2.h)
-   Reported by: Josh Kitchens
-     * [8af6c9cf6b] Ivan Poddubny -- res_pjsip_transport_websocket: Fix
-       use-after-free bugs.
-   ASTERISK-25116: res_pjsip: Two PeerStatus AMI messages are sent for every
-   status change
-   Reported by: George Joseph
-     * [35c699086a] gtjoseph -- endpoint/stasis: Eliminate duplicate events
-       on endpoint status change
-   ASTERISK-25131: chan_pjsip: In-dialog authentication not handled.
-   Reported by: Richard Mudgett
-     * [fe21f2e52f] Richard Mudgett -- res_pjsip_session: Fix in-dialog
-       authentication.
-   ASTERISK-25105: res_pjsip: Possible incompatibility between
-   qualify_timeout and pjproject-2.4
-   Reported by: George Joseph
-     * [60e2fbfe62] gtjoseph -- res_pjsip: Refactor endpt_send_transaction
-       (qualify_timeout)
-
-    Category: Resources/res_pjsip_mwi
-
-   ASTERISK-25180: res_pjsip_mwi: Unsolicited MWI requires reload
-   Reported by: Joshua Colp
-     * [80e82dc97f] Joshua Colp -- res_pjsip_mwi: Set up unsolicited MWI upon
-       registration.
-
-    Category: Resources/res_pjsip_nat
-
-   ASTERISK-25196: res_pjsip_nat: rewrite_contact should not be applied to
-   Contact header when Record-Route headers are present
-   Reported by: Mark Michelson
-     * [24eec5a10b] Mark Michelson -- res_pjsip_nat: Adjust when contact
-       should be rewritten.
-     * [028fa54620] Mark Michelson -- res_pjsip_nat: Rewrite route set when
-       required.
-
-    Category: Resources/res_pjsip_outbound_registration
-
-   ASTERISK-24907: res_pjsip_outbound_registration: crash during unload if
-   registration attempts are still occuring
-   Reported by: Kevin Harwell
-     * [0ec461a637] Richard Mudgett -- res_pjsip_outbound_registration.c: Add
-       a serializer shutdown group.
-     * [84c12f9e0c] Richard Mudgett -- threadpool, res_pjsip: Add serializer
-       group shutdown API calls.
-     * [602c4b74b5] Richard Mudgett -- res_pjsip_outbound_registration.c: Fix
-       handle_client_state_destruction() refs
-     * [8c6a95a9ac] Richard Mudgett -- res_pjsip_outbound_registration.c: Use
-       ast_sorcery_object_unregister() API
-     * [20f3d77ab9] Richard Mudgett -- sorcery: Add
-       ast_sorcery_object_unregister() API call.
-     * [4313f32969] Richard Mudgett -- res_pjsip_outbound_registration.c:
-       Reorder load_module() and unload_module().
-
-    Category: Resources/res_pjsip_refer
-
-   ASTERISK-25204: res_pjsip_refer: Duplicated Referred-By or Replaces
-   headers on outbound INVITEs.
-   Reported by: Mark Michelson
-     * [05a2cc1293] Mark Michelson -- res_pjsip_refer: Prevent sending
-       duplicate headers.
-
-    Category: Resources/res_pjsip_session
-
-   ASTERISK-25131: chan_pjsip: In-dialog authentication not handled.
-   Reported by: Richard Mudgett
-     * [fe21f2e52f] Richard Mudgett -- res_pjsip_session: Fix in-dialog
-       authentication.
-
-    Category: Resources/res_pjsip_transport_websocket
-
-   ASTERISK-25122: Large SIP packet received via pjsip over websocket crashes
-   Asterisk
-   Reported by: Ivan Poddubny
-     * [554bd1e39c] Ivan Poddubny -- res_pjsip_transport_websocket: Fix crash
-       on receiving large SIP packets
-
-    Category: Resources/res_rtp_asterisk
-
-   ASTERISK-25103: Roundup - investigate Asterisk DTLS crashes
-   Reported by: Rusty Newton
-     * [7ff1ac8797] Joshua Colp -- res_rtp_asterisk: Ensure DTLS timeout
-       timer is -1 if DTLS is not used.
-     * [05e8e14982] Joshua Colp -- res_rtp_asterisk: Prevent simultaneous
-       access to DTLS SSL context.
-     * [55137c3d12] Joshua Colp -- res/res_http_websocket: Don't send HTTP
-       response fragmented.
-   ASTERISK-22805: res_rtp_asterisk: Crash when calling BIO_ctrl_pending in
-   dtls_srtp_check_pending when dialed by JSSIP
-   Reported by: Dmitry Burilov
-     * [05e8e14982] Joshua Colp -- res_rtp_asterisk: Prevent simultaneous
-       access to DTLS SSL context.
-   ASTERISK-24651: [patch] Fix race condition in DTLS
-   Reported by: Badalian Vyacheslav
-     * [05e8e14982] Joshua Colp -- res_rtp_asterisk: Prevent simultaneous
-       access to DTLS SSL context.
-   ASTERISK-24832: [patch]DTLS-crashes within openssl
-   Reported by: Stefan EngstrAP:m
-     * [05e8e14982] Joshua Colp -- res_rtp_asterisk: Prevent simultaneous
-       access to DTLS SSL context.
-   ASTERISK-25127: DTLS crashes following "Unable to cancel schedule ID" in
-   dtls_srtp_check_pending
-   Reported by: Dade Brandon
-     * [05e8e14982] Joshua Colp -- res_rtp_asterisk: Prevent simultaneous
-       access to DTLS SSL context.
-
-    Category: Resources/res_srtp
-
-   ASTERISK-24550: res_rtp_asterisk: Crash in ast_rtp_on_ice_complete during
-   DTLS handshake
-   Reported by: Osaulenko Alexander
-     * [05e8e14982] Joshua Colp -- res_rtp_asterisk: Prevent simultaneous
-       access to DTLS SSL context.
-
-    Category: Resources/res_stasis
-
-   ASTERISK-24782: StasisEnd event not present for channel that was swapped
-   out for another after completing attended transfer
-   Reported by: John Bigelow
-     * [97ee0ee6c6] Kevin Harwell -- bridge.c: Fixed race condition during
-       attended transfer
-     * [35a99b6394] Kevin Harwell -- bridge.c: Hangup attended transfer
-       target if bridged
-
-    Category: Resources/res_timing_kqueue
-
-   ASTERISK-19277: [patch]endlessly repeating error: "poll failed: Bad file
-   descriptor"
-   Reported by: Barry Chern
-     * [f4dd9560cf] Walter Doekes -- res_timing: Don't close FD 0 when out of
-       open files.
-
-    Category: Resources/res_timing_timerfd
-
-   ASTERISK-19277: [patch]endlessly repeating error: "poll failed: Bad file
-   descriptor"
-   Reported by: Barry Chern
-     * [f4dd9560cf] Walter Doekes -- res_timing: Don't close FD 0 when out of
-       open files.
-
-    Category: Tests/testsuite
-
-   ASTERISK-25165: Testsuite - Sorcery memory cache leaks
-   Reported by: Corey Farrell
-     * [156395e743] Mark Michelson -- res_sorcery_realtime: Fix leak of
-       sorcery object type.
-   ASTERISK-25172: Crash in channels/sip/sip blind transfer/caller_refer_only
-   test in ast_format_cap_append_from_cap during ast_request
-   Reported by: Matt Jordan
-     * [e99e654d75] Joshua Colp -- app_dial: Hold reference to calling
-       channel formats when dialing outbound.
-
-    Category: pjproject/pjsip
-
-   ASTERISK-24963: ASAN: heap-use-after-free with PJSIP and WSS
-   Reported by: Badalian Vyacheslav
-     * [8af6c9cf6b] Ivan Poddubny -- res_pjsip_transport_websocket: Fix
-       use-after-free bugs.
-
-  New Feature
-
-    Category: Channels/chan_pjsip
-
-   ASTERISK-25259: chan_pjsip: Add rtptimeout support
-   Reported by: Joshua Colp
-     * [2749721791] Joshua Colp -- pjsip: Add rtp_timeout and
-       rtp_timeout_hold endpoint options.
-
-    Category: Resources/res_ari
-
-   ASTERISK-25238: ARI: Support push configuration
-   Reported by: Matt Jordan
-     * [8bcf6d2801] Matt Jordan -- ARI: Add support for push configuration of
-       dynamic object
-     * [bb76b88baf] Matt Jordan -- main/sorcery: Don't fail object set
-       creation from JSON if field fails
-     * [5f13c2226a] Matt Jordan -- main/format_cap: Parse capabilities
-       generated by ast_format_cap_get_names
-   ASTERISK-25173: ARI: Add the ability to load/reload/unload an Asterisk
-   module
-   Reported by: Matt Jordan
-     * [3384e64ef6] Benjamin Ford -- ARI: Fixed unload mode for unload
-       module.
-     * [1aafadf814] Benjamin Ford -- ARI: Added new functionality to reload a
-       single module.
-     * [9dcae23cfc] Benjamin Ford -- ARI: Added new functionality to unload a
-       single module.
-     * [c219a98d2b] Benjamin Ford -- ARI: Added new functionality to load a
-       single module.
-     * [73e35d20de] Benjamin Ford -- ARI: Added new functionality to get
-       information on a single module.
-
-    Category: Resources/res_pjsip_sdp_rtp
-
-   ASTERISK-25259: chan_pjsip: Add rtptimeout support
-   Reported by: Joshua Colp
-     * [2749721791] Joshua Colp -- pjsip: Add rtp_timeout and
-       rtp_timeout_hold endpoint options.
-
-     ----------------------------------------------------------------------
-
-                                  Open Issues
-
-                                 [Back to Top]
-
-   This is a list of all open issues from the issue tracker that were
-   referenced by changes that went into this release.
-
-  Bug
-
-    Category: Core/Sorcery
-
-   ASTERISK-25141: pjsip_options: Contact reference leak
-   Reported by: Corey Farrell
-     * [5dc9fb4198] gtjoseph -- res_pjsip/location: Fix ref leak in
-       contact_apply_handler
-     * [9e7827e3ac] Corey Farrell -- pjsip_configuration: Fix leak in
-       persistent_endpoint_update_state.
-     * [857166b5e5] gtjoseph -- res_pjsip/location: Fix memory leak in
-       permanent_uri_handler
-
-     ----------------------------------------------------------------------
-
-                      Commits Not Associated with an Issue
-
-                                 [Back to Top]
-
-   This is a list of all changes that went into this release that did not
-   reference a JIRA issue.
-
-   +------------------------------------------------------------------------+
-   | Revision   | Author    | Summary                                       |
-   |------------+-----------+-----------------------------------------------|
-   | 96ec40eb70 | Matt      | Release summaries: Remove previous versions   |
-   |            | Jordan    |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | 3e526f11c3 | Matt      | .version: Update for 13.5.0                   |
-   |            | Jordan    |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | 68823f7438 | Matt      | .lastclean: Update for 13.5.0                 |
-   |            | Jordan    |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | d3526317bc | Matt      | realtime: Add database scripts for 13.5.0     |
-   |            | Jordan    |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | 59b6e5db76 | Matt      | ChangeLog: Updated for 13.5.0-rc1             |
-   |            | Jordan    |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | a4b527393b | Matt      | Release summaries: Add summaries for          |
-   |            | Jordan    | 13.5.0-rc1                                    |
-   |------------+-----------+-----------------------------------------------|
-   | 158b0b8ebf | Matt      | .version: Update for 13.5.0-rc1               |
-   |            | Jordan    |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | a0a7650e34 | Matt      | .lastclean: Update for 13.5.0-rc1             |
-   |            | Jordan    |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | 4d238af086 | Matt      | realtime: Add database scripts for 13.5.0-rc1 |
-   |            | Jordan    |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | f78a4b52b8 | Matt      | Bump the ARI version to 1.8.0                 |
-   |            | Jordan    |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | b4e19e414a | Mark      | res_pjsip: Add rtp_keepalive to sample config |
-   |            | Michelson | file.                                         |
-   |------------+-----------+-----------------------------------------------|
-   | a23adcca3d | Michael   | res/res_musiconhold: Add a warning when MOH   |
-   |            | Cargile   | does not exist                                |
-   |------------+-----------+-----------------------------------------------|
-   | 03064daeb2 | Matt      | res/res_sorcery_config: Prevent crash from    |
-   |            | Jordan    | misconfigured sorcery.conf                    |
-   |------------+-----------+-----------------------------------------------|
-   | 243c0d1609 | Richard   | parking_applications.c: Fix ast_verb() line   |
-   |            | Mudgett   | terminator.                                   |
-   |------------+-----------+-----------------------------------------------|
-   | 2735dd5b2d | Richard   | res_pjsip_session.c: Extract                  |
-   |            | Mudgett   | sip_session_defer_termination_stop_timer().   |
-   |------------+-----------+-----------------------------------------------|
-   | 3d0ca343ca | Richard   | res_pjsip_session.c: Add some helpful         |
-   |            | Mudgett   | comments and minor tweaks.                    |
-   |------------+-----------+-----------------------------------------------|
-   | 8d08bb179c | Richard   | res_pjsip_session.c: Fix off nominal crash    |
-   |            | Mudgett   | potential in debug message.                   |
-   |------------+-----------+-----------------------------------------------|
-   | 0a1a550593 | Matt      | apps/app_dictate: Fix typo in attribution     |
-   |            | Jordan    |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | 0b6ff77afb | Matt      | res/res_sorcery_astdb: Add a debugging        |
-   |            | Jordan    | message for when retrieval by ID fails        |
-   |------------+-----------+-----------------------------------------------|
-   | 2f0d6d346c | Matt      | res/res_pjsip_outbound_registration: Fix      |
-   |            | Jordan    | WARNING message                               |
-   |------------+-----------+-----------------------------------------------|
-   | cd2213f1ae | Matt      | res_pjsip/configuration: Fix a variety of     |
-   |            | Jordan    | default value problems                        |
-   |------------+-----------+-----------------------------------------------|
-   | 2e4bdbd78a | Matt      | main/sorcery: Provide log messages when a     |
-   |            | Jordan    | wizard does not support an operation          |
-   |------------+-----------+-----------------------------------------------|
-   | 2325b106fd | Matt      | tests/test_devicestate: Add additional tests  |
-   |            | Jordan    | for the device state API                      |
-   |------------+-----------+-----------------------------------------------|
-   | 328f0be806 | Matt      | main/devicestate: Prevent duplicate           |
-   |            | Jordan    | registration of device state providers        |
-   |------------+-----------+-----------------------------------------------|
-   | bee41eec62 | Matt      | res/res_sorcery_memory_cache: Fix test        |
-   |            | Jordan    | registration issues                           |
-   |------------+-----------+-----------------------------------------------|
-   | 4d738e9026 | Matt      | tests/test_sorcery_memory_cache_thrash: Fix   |
-   |            | Jordan    | test loading problems                         |
-   |------------+-----------+-----------------------------------------------|
-   | 47ea312b24 | Benjamin  | ARI: Added new functionality to get all       |
-   |            | Ford      | module information.                           |
-   |------------+-----------+-----------------------------------------------|
-   | 38bace4fbb | Richard   | res_pjsip_t38.c: Fix always false if test.    |
-   |            | Mudgett   |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | 2f7688c788 | Richard   | res_pjsip_mwi.c: Use safer loop coding in     |
-   |            | Mudgett   | mwi_subscription_mailboxes_str().             |
-   |------------+-----------+-----------------------------------------------|
-   | 74be3a50d7 | Richard   | res_pjsip_mwi.c: Eliminate a simple RAII_VAR. |
-   |            | Mudgett   |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | 589e93617a | Richard   | res_pjsip_mwi.c: Fix mid-line log message     |
-   |            | Mudgett   | line breaks.                                  |
-   |------------+-----------+-----------------------------------------------|
-   | 49f81ddb85 | Matt      | Makefile: Remove coverage files on 'make      |
-   |            | Jordan    | clean'                                        |
-   |------------+-----------+-----------------------------------------------|
-   | 78a1f4aa46 | Richard   | chan_vpb.cc: Fix compiler warning Jenkins     |
-   |            | Mudgett   | found.                                        |
-   |------------+-----------+-----------------------------------------------|
-   | 8e07ab145d | Matt      | sorcery/realtime: Add a bit of debug and      |
-   |            | Jordan    | warning messages for bad configs              |
-   |------------+-----------+-----------------------------------------------|
-   | a5e9c4e9b2 | Matt      | res/res_corosync: Always decline module load, |
-   |            | Jordan    | instead of failing                            |
-   |------------+-----------+-----------------------------------------------|
-   | 2602a7484b | Richard   | test.c: Add unit test registration checks for |
-   |            | Mudgett   | summary and description.                      |
-   |------------+-----------+-----------------------------------------------|
-   | 2b0482d699 | Richard   | Unit tests: Fix unit test description         |
-   |            | Mudgett   | strings.                                      |
-   |------------+-----------+-----------------------------------------------|
-   | 036bc0012f | Richard   | res_pjsip_outbound_registration.c: Add        |
-   |            | Mudgett   | missing line endings to CLI commands          |
-   |------------+-----------+-----------------------------------------------|
-   | bec7435945 | Richard   | res_pjsip_outbound_registration.c: Eliminate  |
-   |            | Mudgett   | simple RAII_VAR() usage.                      |
-   |------------+-----------+-----------------------------------------------|
-   | c2519fdf1c | Richard   | res_pjsip_outbound_registration.c: Misc code  |
-   |            | Mudgett   | cleanups.                                     |
-   |------------+-----------+-----------------------------------------------|
-   | a2b718f4f6 | Richard   | res_pjsip.h: Fix some doxygen comments.       |
-   |            | Mudgett   |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | 32ddf6d86b | Richard   | taskprocessor.c: Remove extra unref from      |
-   |            | Mudgett   | off-nominal path.                             |
-   |------------+-----------+-----------------------------------------------|
-   | e0090216db | ibercom   | CLI: Cosmetic issue - core show uptime        |
-   |------------+-----------+-----------------------------------------------|
-   | d908272b7e | David M.  | Fixes for OS X                                |
-   |            | Lee       |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | 1558a89129 | gtjoseph  | Revert "endpoint/stasis: Eliminate duplicate  |
-   |            |           | events on endpoint status change"             |
-   |------------+-----------+-----------------------------------------------|
-   | 5a42397018 | Joshua    | sorcery: Fix cache creation callback.         |
-   |            | Colp      |                                               |
-   |------------+-----------+-----------------------------------------------|
-   | 51ffed5e61 | Matt      | res/res_pjsip_pubsub: Note that 'dialog' is   |
-   |            | Jordan    | also a valid event type for RLS               |
-   |------------+-----------+-----------------------------------------------|
-   | 7950b65e4f | Matt      | res/res_pjsip_exten_state: Fix confusing      |
-   |            | Jordan    | NOTICE message                                |
-   +------------------------------------------------------------------------+
-
-     ----------------------------------------------------------------------
-
-                                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.
-
- asterisk-13.4.0-summary.html                                                      |   18
- asterisk-13.4.0-summary.txt                                                       |   87
- b/.version                                                                        |    2
- b/CHANGES                                                                         |   41
- b/ChangeLog                                                                       | 2194 ++++++++
- b/Makefile                                                                        |    4
- b/Makefile.moddir_rules                                                           |    1
- b/UPGRADE.txt                                                                     |   11
- b/apps/Makefile                                                                   |    2
- b/apps/app_dial.c                                                                 |   20
- b/apps/app_dictate.c                                                              |    2
- b/apps/app_directory.c                                                            |   48
- b/apps/app_meetme.c                                                               |   18
- b/autoconf/ast_gcc_attribute.m4                                                   |    2
- b/bridges/bridge_native_rtp.c                                                     |   28
- b/channels/Makefile                                                               |    8
- b/channels/chan_dahdi.c                                                           |   14
- b/channels/chan_iax2.c                                                            |  144
- b/channels/chan_mgcp.c                                                            |   18
- b/channels/chan_pjsip.c                                                           |   17
- b/channels/chan_sip.c                                                             |   45
- b/channels/chan_skinny.c                                                          |   10
- b/channels/chan_vpb.cc                                                            |    5
- b/channels/misdn/Makefile                                                         |    2
- b/channels/sig_pri.c                                                              |    2
- b/channels/sig_pri.h                                                              |    2
- b/codecs/gsm/Makefile                                                             |    2
- b/configs/samples/pjsip.conf.sample                                               |   14
- b/configs/samples/sip.conf.sample                                                 |    2
- b/configure                                                                       |   22
- b/contrib/ast-db-manage/config/versions/26f10cadc157_add_pjsip_timeout_options.py |   24
- b/contrib/ast-db-manage/config/versions/28b8e71e541f_add_g726_non_standard.py     |   30
- b/contrib/ast-db-manage/config/versions/498357a710ae_add_rtp_keepalive.py         |   22
- b/contrib/realtime/mssql/mssql_config.sql                                         |   28
- b/contrib/realtime/mysql/mysql_config.sql                                         |   20
- b/contrib/realtime/oracle/oracle_config.sql                                       |   28
- b/contrib/realtime/postgresql/postgresql_config.sql                               |   16
- b/doc/appdocsxml.xslt                                                             |    6
- b/funcs/func_cdr.c                                                                |    3
- b/funcs/func_pjsip_aor.c                                                          |    2
- b/include/asterisk/ari.h                                                          |    5
- b/include/asterisk/bridge.h                                                       |    2
- b/include/asterisk/bridge_channel_internal.h                                      |   40
- b/include/asterisk/manager.h                                                      |    2
- b/include/asterisk/module.h                                                       |   37
- b/include/asterisk/pbx.h                                                          |   16
- b/include/asterisk/res_pjsip.h                                                    |   58
- b/include/asterisk/res_pjsip_presence_xml.h                                       |    9
- b/include/asterisk/res_pjsip_session.h                                            |    4
- b/include/asterisk/rtp_engine.h                                                   |   32
- b/include/asterisk/slin.h                                                         |    4
- b/include/asterisk/sorcery.h                                                      |   20
- b/include/asterisk/stasis.h                                                       |   11
- b/include/asterisk/stasis_endpoints.h                                             |    6
- b/include/asterisk/strings.h                                                      |   54
- b/include/asterisk/test.h                                                         |   13
- b/include/asterisk/threadpool.h                                                   |   69
- b/main/.gitignore                                                                 |    1
- b/main/Makefile                                                                   |    2
- b/main/astfd.c                                                                    |   57
- b/main/astobj2_hash.c                                                             |   11
- b/main/audiohook.c                                                                |   25
- b/main/bridge.c                                                                   |   63
- b/main/bridge_channel.c                                                           |   45
- b/main/cdr.c                                                                      |   10
- b/main/channel.c                                                                  |    6
- b/main/channel_internal_api.c                                                     |   11
- b/main/cli.c                                                                      |   18
- b/main/config.c                                                                   |    1
- b/main/core_unreal.c                                                              |   12
- b/main/devicestate.c                                                              |    9
- b/main/format_cap.c                                                               |   19
- b/main/loader.c                                                                   |   54
- b/main/manager_channels.c                                                         |   39
- b/main/manager_endpoints.c                                                        |    1
- b/main/pbx.c                                                                      |   46
- b/main/presencestate.c                                                            |   15
- b/main/rtp_engine.c                                                               |   28
- b/main/sched.c                                                                    |   12
- b/main/sorcery.c                                                                  |   60
- b/main/stasis.c                                                                   |    4
- b/main/stasis_channels.c                                                          |   10
- b/main/stasis_endpoints.c                                                         |   71
- b/main/taskprocessor.c                                                            |    1
- b/main/test.c                                                                     |   36
- b/main/threadpool.c                                                               |  148
- b/main/utils.c                                                                    |  130
- b/menuselect/configure                                                            |    8
- b/pbx/Makefile                                                                    |    2
- b/pbx/pbx_config.c                                                                |   15
- b/res/Makefile                                                                    |    8
- b/res/ari/ari_model_validators.c                                                  |  156
- b/res/ari/ari_model_validators.h                                                  |   45
- b/res/ari/resource_asterisk.c                                                     |  487 +
- b/res/ari/resource_asterisk.h                                                     |  127
- b/res/ari/resource_events.c                                                       |   39
- b/res/ari/resource_events.h                                                       |   15
- b/res/parking/parking_applications.c                                              |   12
- b/res/parking/parking_manager.c                                                   |   16
- b/res/res_ari.c                                                                   |    7
- b/res/res_ari_asterisk.c                                                          |  584 ++
- b/res/res_ari_events.c                                                            |  108
- b/res/res_corosync.c                                                              |    4
- b/res/res_hep_rtcp.c                                                              |    2
- b/res/res_http_websocket.c                                                        |   23
- b/res/res_musiconhold.c                                                           |    2
- b/res/res_mwi_external_ami.c                                                      |    6
- b/res/res_pjsip.c                                                                 |  468 +
- b/res/res_pjsip/location.c                                                        |   12
- b/res/res_pjsip/pjsip_configuration.c                                             |  126
- b/res/res_pjsip/pjsip_distributor.c                                               |  105
- b/res/res_pjsip/pjsip_options.c                                                   |    7
- b/res/res_pjsip_dialog_info_body_generator.c                                      |    9
- b/res/res_pjsip_dtmf_info.c                                                       |    8
- b/res/res_pjsip_exten_state.c                                                     |    2
- b/res/res_pjsip_mwi.c                                                             |  262 -
- b/res/res_pjsip_nat.c                                                             |   90
- b/res/res_pjsip_outbound_registration.c                                           |  454 +
- b/res/res_pjsip_pidf_body_generator.c                                             |   11
- b/res/res_pjsip_pubsub.c                                                          |    5
- b/res/res_pjsip_refer.c                                                           |   46
- b/res/res_pjsip_registrar.c                                                       |    2
- b/res/res_pjsip_sdp_rtp.c                                                         |  114
- b/res/res_pjsip_session.c                                                         |  256
- b/res/res_pjsip_t38.c                                                             |   22
- b/res/res_pjsip_transport_websocket.c                                             |   99
- b/res/res_pjsip_xpidf_body_generator.c                                            |    9
- b/res/res_rtp_asterisk.c                                                          |  215
- b/res/res_security_log.c                                                          |    2
- b/res/res_sorcery_astdb.c                                                         |    1
- b/res/res_sorcery_config.c                                                        |   11
- b/res/res_sorcery_memory_cache.c                                                  | 2572 ++++++++++
- b/res/res_sorcery_realtime.c                                                      |    2
- b/res/res_stasis.c                                                                |    6
- b/res/res_stasis_device_state.c                                                   |    2
- b/res/res_timing_kqueue.c                                                         |    4
- b/res/res_timing_timerfd.c                                                        |    5
- b/res/res_xmpp.c                                                                  |    4
- b/res/stasis/app.c                                                                |    5
- b/res/stasis/control.c                                                            |    4
- b/rest-api-templates/ari_resource.h.mustache                                      |   19
- b/rest-api-templates/res_ari_resource.c.mustache                                  |   70
- b/rest-api/api-docs/applications.json                                             |    2
- b/rest-api/api-docs/asterisk.json                                                 |  307 +
- b/rest-api/api-docs/bridges.json                                                  |    2
- b/rest-api/api-docs/channels.json                                                 |    2
- b/rest-api/api-docs/deviceStates.json                                             |    2
- b/rest-api/api-docs/endpoints.json                                                |    2
- b/rest-api/api-docs/events.json                                                   |    2
- b/rest-api/api-docs/mailboxes.json                                                |    2
- b/rest-api/api-docs/playbacks.json                                                |    2
- b/rest-api/api-docs/recordings.json                                               |    2
- b/rest-api/api-docs/sounds.json                                                   |    2
- b/rest-api/resources.json                                                         |    2
- b/tests/test_cdr.c                                                                |   46
- b/tests/test_cel.c                                                                |   50
- b/tests/test_channel_feature_hooks.c                                              |    4
- b/tests/test_devicestate.c                                                        |  432 +
- b/tests/test_expr.c                                                               |    2
- b/tests/test_format_cap.c                                                         |    2
- b/tests/test_gosub.c                                                              |   10
- b/tests/test_message.c                                                            |   18
- b/tests/test_pbx.c                                                                |    9
- b/tests/test_poll.c                                                               |    2
- b/tests/test_sorcery_memory_cache_thrash.c                                        |  618 ++
- b/tests/test_sorcery_realtime.c                                                   |    2
- b/tests/test_stasis.c                                                             |    4
- b/tests/test_strings.c                                                            |   70
- b/tests/test_threadpool.c                                                         |    4
- 169 files changed, 11351 insertions(+), 1237 deletions(-)
diff --git a/asterisk-13.6.0-summary.html b/asterisk-13.6.0-summary.html
new file mode 100644
index 0000000..5213c19
--- /dev/null
+++ b/asterisk-13.6.0-summary.html
@@ -0,0 +1,322 @@
+<!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"><title>Release Summary - asterisk-13.6.0</title><h1 align="center"><a name="top">Release Summary</a></h1><h3 align="center">asterisk-13.6.0</h3><h3 align="center">Date: 2015-10-09</h3><h3 align="center"><asteriskteam at 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="#closed_issues">Closed Issues</a></li>
+<li><a href="#open_issues">Open 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><p>This release is a point release of an existing major version. The changes included were made to address problems that have been identified in this release series, or are minor, backwards compatible new features or improvements. Users should be able to safely upgrade to this version if this release series is already in use. Users considering upgrading from a previous version a [...]
+<tr><th width="33%">Coders</th><th width="33%">Testers</th><th width="33%">Reporters</th></tr>
+<tr valign="top"><td width="33%">40 Richard Mudgett <rmudgett at digium.com><br/>18 Kevin Harwell <kharwell at lunkwill><br/>16 Joshua Colp <jcolp at digium.com><br/>15 Mark Michelson <mmichelson at digium.com><br/>13 Matt Jordan <mjordan at digium.com><br/>9 Scott Griepentrog <scott at griepentrog.com><br/>8 Kevin Harwell <kharwell at lunkwill.digium.internal><br/>3 Scott Emidy <jemidy at digium.com><br/>3 David M. Lee <dlee at respoke.io><br/>2 Alexander Traud <pabstraud at compuserve.com><br/>2 Alexander Anikin <m [...]
+</table><hr><a name="closed_issues"><h2 align="center">Closed Issues</h2></a><center><a href="#top">[Back to Top]</a></center><p>This is a list of all issues from the issue tracker that were closed by changes that went into this release.</p><h3>New Feature</h3><h4>Category: Resources/res_ari</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25252">ASTERISK-25252</a>: ARI: Add the ability to manipulate log channels<br/>Reported by: Matt Jordan<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=df9ce3636695781be6ab2479f90766a56747dbd7">[df9ce36366]</a> Scott Emidy -- ARI: Retrieve existing log channels</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e9f1bc08cbda7759707c30b8883b266555d0fefc">[e9f1bc08cb]</a> Scott Emidy -- ARI: Creating log channels</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=78364132ce94d9ded24ae6e6ab44b97d256b506d">[78364132ce]</a> Scott Emidy -- ARI: Deleting log channels</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=1ae762634c317fbcbd98a8c34d2474f7d4b654ed">[1ae762634c]</a> Benjamin Ford -- ARI: Rotate log channels.</li>
+</ul><br><h4>Category: Resources/res_pjsip</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25377">ASTERISK-25377</a>: res_pjsip: Change default "From user" from UUID to something more palatable<br/>Reported by: Mark Michelson<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=ac62928d6b7333a0d502be2eba99c238549ae1a3">[ac62928d6b]</a> Mark Michelson -- res_pjsip: Change default from user value.</li>
+</ul><br><h3>Bug</h3><h4>Category: Addons/chan_ooh323</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25227">ASTERISK-25227</a>: No audio at in-band announcements in ooh323 channel<br/>Reported by: Alexandr Dranchuk<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=71408df2b82c932329d250a6077475e4f51a2b0d">[71408df2b8]</a> Alexander Anikin -- chan_ooh323: Add ProgressIndicator IE with inband info available</li>
+</ul><br><h4>Category: Applications/app_dial</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25423">ASTERISK-25423</a>: Caller gets no Connected line update during call pickup.<br/>Reported by: Richard Mudgett<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=6b1e7583c150cc9bafcb567c789b6c23c60e2c71">[6b1e7583c1]</a> Richard Mudgett -- app_queue.c: Force COLP update if outgoing channel name changed.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=6bf304bf251e31ab7c7a4d89508445b84fb5d551">[6bf304bf25]</a> Richard Mudgett -- app_queue.c: Factor out a connected line update routine.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e36b5f1e8e1fd1e805184fca015bb0808b5e7fb8">[e36b5f1e8e]</a> Richard Mudgett -- app_dial.c: Make 'A' option pass COLP updates.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=747bfac895c4d51f55ce687322aa6a95c52be4e2">[747bfac895]</a> Richard Mudgett -- app_dial.c: Force COLP update if outgoing channel name changed.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=14481d9aa0365682ace22c97d5c115166be5429d">[14481d9aa0]</a> Richard Mudgett -- app_dial.c: Factor out a connected line update routine.</li>
+</ul><br><h4>Category: Applications/app_mixmonitor</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25322">ASTERISK-25322</a>: Crash occurs when using MixMonitor with t() or r() options.<br/>Reported by: Richard Mudgett<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=b3a56bee83c01dbb538620a11947d420b17cf458">[b3a56bee83]</a> Richard Mudgett -- audiohook.c: Fix MixMonitor crash when using the r() or t() options.</li>
+</ul><br><h4>Category: Applications/app_page</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25384">ASTERISK-25384</a>: Regular Asterisk crashes when using Page application. "user_data is NULL"<br/>Reported by: Chet Stevens<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=5f15cd93f0b2cb622d54061515b815e3ebbe76b1">[5f15cd93f0]</a> Richard Mudgett -- app_page.c: Fix crash when forwarding with a predial handler.</li>
+</ul><br><h4>Category: Applications/app_queue</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25423">ASTERISK-25423</a>: Caller gets no Connected line update during call pickup.<br/>Reported by: Richard Mudgett<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=6b1e7583c150cc9bafcb567c789b6c23c60e2c71">[6b1e7583c1]</a> Richard Mudgett -- app_queue.c: Force COLP update if outgoing channel name changed.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=6bf304bf251e31ab7c7a4d89508445b84fb5d551">[6bf304bf25]</a> Richard Mudgett -- app_queue.c: Factor out a connected line update routine.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e36b5f1e8e1fd1e805184fca015bb0808b5e7fb8">[e36b5f1e8e]</a> Richard Mudgett -- app_dial.c: Make 'A' option pass COLP updates.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=747bfac895c4d51f55ce687322aa6a95c52be4e2">[747bfac895]</a> Richard Mudgett -- app_dial.c: Force COLP update if outgoing channel name changed.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=14481d9aa0365682ace22c97d5c115166be5429d">[14481d9aa0]</a> Richard Mudgett -- app_dial.c: Factor out a connected line update routine.</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25399">ASTERISK-25399</a>: app_queue: AgentComplete event has wrong reason<br/>Reported by: Kevin Harwell<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=4fb95bbc4e4928dd3403a20d401c285a568f0d09">[4fb95bbc4e]</a> Kevin Harwell -- app_queue: AgentComplete event has wrong reason</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25185">ASTERISK-25185</a>: Segfault in app_queue on transfer scenarios<br/>Reported by: Etienne Lessard<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=6409e7b11a2310196a9978b30a6b79e2760be592">[6409e7b11a]</a> Kevin Harwell -- app_queue: Crash when transferring</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25215">ASTERISK-25215</a>: Differences in queue.log between Set QUEUE_MEMBER and using PauseQueueMember<br/>Reported by: Lorne Gaetz<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e5f5b9f384eef0389a7e35d40c91d3586869a125">[e5f5b9f384]</a> Richard Mudgett -- app_queue.c: Fix setting QUEUE_MEMBER 'paused' and 'ringinuse'.</li>
+</ul><br><h4>Category: Applications/app_record</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25410">ASTERISK-25410</a>: app_record: RECORDED_FILE variable not being populated<br/>Reported by: Kevin Harwell<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=aeddee39fb492ea5ec873bdf02ea3858c5282601">[aeddee39fb]</a> Kevin Harwell -- app_record: RECORDED_FILE variable not being populated</li>
+</ul><br><h4>Category: Bridges/bridge_holding</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25271">ASTERISK-25271</a>: Parking & blind transfer: Transferer channel not hung up if no MOH<br/>Reported by: Kevin Harwell<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8458b8d441c2f4143ff135163ff3da4f88fe14c8">[8458b8d441]</a> Jonathan Rose -- holding_bridge: ensure moh participants get frames</li>
+</ul><br><h4>Category: Channels/chan_dahdi</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25315">ASTERISK-25315</a>: DAHDI channels send shortened duration DTMF tones.<br/>Reported by: Richard Mudgett<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=256bc52b6684141b100c5018dbf0ad3ce6111585">[256bc52b66]</a> Richard Mudgett -- chan_dahdi.c: Flush the DAHDI write buffer after starting DTMF.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=800e0ea48de88c016e1f477edf7db7b9aadc4b54">[800e0ea48d]</a> Richard Mudgett -- chan_dahdi.c: Lock private struct for ast_write().</li>
+</ul><br><h4>Category: Channels/chan_sip/CodecHandling</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25309">ASTERISK-25309</a>: [patch] iLBC 20 advertised<br/>Reported by: Alexander Traud<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f68c995bc97c9b6cb4887043b344087d82aeef10">[f68c995bc9]</a> Alexander Traud -- chan_sip: Fix negotiation of iLBC 30.</li>
+</ul><br><h4>Category: Channels/chan_sip/General</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25346">ASTERISK-25346</a>: chan_sip: Overwriting answered elsewhere hangup cause on call pickup<br/>Reported by: Joshua Colp<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=c01111223f9dbd383a4dd1cf786b63eff214f238">[c01111223f]</a> Joshua Colp -- chan_sip: Allow call pickup to set the hangup cause.</li>
+</ul><br><h4>Category: Channels/chan_sip/Interoperability</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25396">ASTERISK-25396</a>: chan_sip: Extremely long callerid name causes invalid SIP<br/>Reported by: Walter Doekes<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=b59c4d82b58a7a10e1791f9ed5759af8ac637df2">[b59c4d82b5]</a> Walter Doekes -- chan_sip: Fix From header truncation for extremely long CALLERID(name).</li>
+</ul><br><h4>Category: Channels/chan_sip/Security Framework</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25320">ASTERISK-25320</a>: chan_sip.c: sip_report_security_event searches for wrong or non existent peer on invite<br/>Reported by: Kevin Harwell<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=25af2d71c863062868b8bda6cf83515a1935d27e">[25af2d71c8]</a> Kevin Harwell -- chan_sip.c: wrong peer searched in sip_report_security_event</li>
+</ul><br><h4>Category: Channels/chan_skinny</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25296">ASTERISK-25296</a>: RTP performance issue with several channel drivers.<br/>Reported by: Richard Mudgett<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=aeeb170fc4fe4e681a96b87f8e81ade717aa2426">[aeeb170fc4]</a> Richard Mudgett -- rtp_engine.c: Fix performance issue with several channel drivers that use RTP.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=84262749d2a1f59f669e801d5f796b016b223960">[84262749d2]</a> Richard Mudgett -- res_rtp_asterisk.c: Fix off-nominal crash potential.</li>
+</ul><br><h4>Category: Channels/chan_unistim</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25296">ASTERISK-25296</a>: RTP performance issue with several channel drivers.<br/>Reported by: Richard Mudgett<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=aeeb170fc4fe4e681a96b87f8e81ade717aa2426">[aeeb170fc4]</a> Richard Mudgett -- rtp_engine.c: Fix performance issue with several channel drivers that use RTP.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=84262749d2a1f59f669e801d5f796b016b223960">[84262749d2]</a> Richard Mudgett -- res_rtp_asterisk.c: Fix off-nominal crash potential.</li>
+</ul><br><h4>Category: Codecs/General</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25353">ASTERISK-25353</a>: [patch] Transcoding while different in Frame size = Frames lost<br/>Reported by: Alexander Traud<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=b88c54fa4bd537bde46519abb95e30a5f96673ac">[b88c54fa4b]</a> Alexander Traud -- translate: Fix transcoding while different in frame size.</li>
+</ul><br><h4>Category: Core/Bridging</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25341">ASTERISK-25341</a>: bridge: Hangups may get lost when executing actions<br/>Reported by: Joshua Colp<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=6c2dab1e888e59cb429ed61219815bd00eee66c0">[6c2dab1e88]</a> Joshua Colp -- bridge: Kick channel from bridge if hung up during action.</li>
+</ul><br><h4>Category: Core/BuildSystem</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25383">ASTERISK-25383</a>: Core dumps on startup and shutdown with MALLOC_DEBUG enabled<br/>Reported by: yaron nahum<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=028033e5a8dcf2b6d9c454786736825fe0288141">[028033e5a8]</a> Richard Mudgett -- res/ari/config.c: Fix conf_alloc() object init.</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25265">ASTERISK-25265</a>: [patch]DTLS Failure when calling WebRTC-peer on Firefox 39 - add ECDH support and fallback to prime256v1<br/>Reported by: Stefan Engström<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=9a12804e592b97d74ff7b909e0d0022f1ca72386">[9a12804e59]</a> Joshua Colp -- res_rtp_asterisk: Don't leak temporary key when enabling PFS.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=aed068844c1c9748da9c67b74ea4d90622be8f46">[aed068844c]</a> Mark Duncan -- res/res_rtp_asterisk: Add ECDH support</li>
+</ul><br><h4>Category: Core/General</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25449">ASTERISK-25449</a>: main/sched: Regression introduced by 5c713fdf18f causes erroneous duplicate RTCP messages; other potential scheduling issues in chan_sip/chan_skinny<br/>Reported by: Matt Jordan<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=10e790f81ad3be322193cf948e0334f9af09b00f">[10e790f81a]</a> Matt Jordan -- res/res_rtp_asterisk: Fix assignment after ao2 decrement</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=754daeca0a48e5c9365cc7fa4c5a3da6c61ae7f6">[754daeca0a]</a> Matt Jordan -- Fix improper usage of scheduler exposed by 5c713fdf18f</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25383">ASTERISK-25383</a>: Core dumps on startup and shutdown with MALLOC_DEBUG enabled<br/>Reported by: yaron nahum<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=028033e5a8dcf2b6d9c454786736825fe0288141">[028033e5a8]</a> Richard Mudgett -- res/ari/config.c: Fix conf_alloc() object init.</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25418">ASTERISK-25418</a>: On-hold channels redirected out of a bridge appear to still be on hold<br/>Reported by: Mark Michelson<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=629458d34930e5aca56f749bc05562baf95d13f7">[629458d349]</a> Mark Michelson -- Do not swallow frames on channels leaving bridges.</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25355">ASTERISK-25355</a>: sched: ast_sched_del may return prematurely due to spurious wakeup<br/>Reported by: Joshua Colp<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=85e1cb51b21c2d194647e16b81b5a1344d2ff911">[85e1cb51b2]</a> Joshua Colp -- sched: ast_sched_del may return prematurely due to spurious wakeup</li>
+</ul><br><h4>Category: Core/Logging</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25305">ASTERISK-25305</a>: Dynamic logger channels can be added multiple times<br/>Reported by: Mark Michelson<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f050fa76eb8535a2b8a3b047527a42ea369d8792">[f050fa76eb]</a> Mark Michelson -- logger: Prevent duplicate dynamic channels from being added.</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25407">ASTERISK-25407</a>: Asterisk fails to log to multiple syslog destinations<br/>Reported by: Elazar Broad<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=ec514ad64dbc0014525008977c8c74c2856c9d3a">[ec514ad64d]</a> Elazar Broad -- core/logging: Fix logging to more than one syslog channel</li>
+</ul><br><h4>Category: Core/PBX</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25394">ASTERISK-25394</a>: pbx: Incorrect device and presence state when changing hint details<br/>Reported by: Joshua Colp<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=2bd27d12223fe33b58c453965ed5c6ed3af7c4f5">[2bd27d1222]</a> Joshua Colp -- pbx: Update device and presence state when changing a hint extension.</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25367">ASTERISK-25367</a>: pbx: Long pattern match hints may cause "core show hints" to crash<br/>Reported by: Joshua Colp<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=cc1363209e7a5b6c67bf96c593e3beb0884c1fb0">[cc1363209e]</a> Joshua Colp -- pbx: Fix crash when issuing "core show hints" with long pattern match.</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25362">ASTERISK-25362</a>: Deadlock due to presence state callback<br/>Reported by: Mark Michelson<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=03fe79f29eae42be24589b323a5ef3fa9259158d">[03fe79f29e]</a> Mark Michelson -- Fix deadlock on presence state changes.</li>
+</ul><br><h4>Category: Core/RTP</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25296">ASTERISK-25296</a>: RTP performance issue with several channel drivers.<br/>Reported by: Richard Mudgett<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=aeeb170fc4fe4e681a96b87f8e81ade717aa2426">[aeeb170fc4]</a> Richard Mudgett -- rtp_engine.c: Fix performance issue with several channel drivers that use RTP.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=84262749d2a1f59f669e801d5f796b016b223960">[84262749d2]</a> Richard Mudgett -- res_rtp_asterisk.c: Fix off-nominal crash potential.</li>
+</ul><br><h4>Category: Resources/res_ari</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25325">ASTERISK-25325</a>: ARI PUT reload chan_sip HTTP response 404<br/>Reported by: Rodrigo Ramirez Norambuena<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=865377fc38134234f17def6634c47a989cf0e77a">[865377fc38]</a> Rodrigo Ramírez Norambuena -- chan_sip.c: Validation on module reload</li>
+</ul><br><h4>Category: Resources/res_http_websocket</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25312">ASTERISK-25312</a>: res_http_websocket: Terminate connection on fatal cases<br/>Reported by: Joshua Colp<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=b4e9416138339274176cb87b26db905723e553ba">[b4e9416138]</a> Joshua Colp -- res_http_websocket: Forcefully terminate on write errors.</li>
+</ul><br><h4>Category: Resources/res_parking</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25369">ASTERISK-25369</a>: res_parking: ParkAndAnnounce - Inheritable variables aren't applied to the announcer channel<br/>Reported by: Jonathan Rose<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=fbf720db91ae8942e9c2ba092179ab2352d44b06">[fbf720db91]</a> Jonathan Rose -- ParkAndAnnounce: Add variable inheritance</li>
+</ul><br><h4>Category: Resources/res_pjsip</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25295">ASTERISK-25295</a>: res_pjsip crash - pjsip_uri_get_uri at /usr/include/pjsip/sip_uri.h<br/>Reported by: Dmitriy Serov<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=5469caa9ddf002d2e75b5fe5dec0c4dbebea1d1e">[5469caa9dd]</a> Joshua Colp -- res_pjsip: Use hash for contact object identity instead of Contact URI.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a676ba2aad5525926ae31b8317b95ae52cbbabbb">[a676ba2aad]</a> Joshua Colp -- taskprocessor: Fix race condition between unreferencing and finding.</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25381">ASTERISK-25381</a>: res_pjsip: AoRs deleted via ARI (or other mechanism) do not destroy their related contacts<br/>Reported by: Matt Jordan<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=c3e6debdb95a5895894ed2b58b600fcdf17927b9">[c3e6debdb9]</a> Matt Jordan -- res/res_pjsip: Purge contacts when an AoR is deleted</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25339">ASTERISK-25339</a>: res_pjsip: Empty "auth" sections from non-config backgrounds are interpreted as valid<br/>Reported by: Matt Jordan<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=bc6fe07f5c114bdeaef4a3b83a11faaa9d1046eb">[bc6fe07f5c]</a> Matt Jordan -- res_pjsip/pjsip_configuration: Disregard empty auth values</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25304">ASTERISK-25304</a>: res_pjsip: XML sanitization may write past buffer<br/>Reported by: Joshua Colp<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8521a86367ac6090210a89878c8fee6d19c43642">[8521a86367]</a> Joshua Colp -- res_pjsip: Ensure sanitized XML is NULL terminated.</li>
+</ul><br><h4>Category: Resources/res_pjsip_nat</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25387">ASTERISK-25387</a>: res_pjsip_nat: Malformed REGISTER request causes NAT'd Contact header to not be rewritten<br/>Reported by: Matt Jordan<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=1dd0e220bf98ca93b825d7b5af4160f7718eab38">[1dd0e220bf]</a> Matt Jordan -- res/res_pjsip_nat: Ignore REGISTER requests when looking for a Record-Route</li>
+</ul><br><h4>Category: Resources/res_pjsip_pubsub</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25306">ASTERISK-25306</a>: Persistent subscriptions can save multiple SIP messages at once, leading to potential crashes.<br/>Reported by: Mark Michelson<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=c126afe18f9073f3ee74e45f574da421131b9fa2">[c126afe18f]</a> Richard Mudgett -- res_pjsip.c: Fix crash from corrupt saved SUBSCRIBE message.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e25569ef95c6de6e9267df4673bd1d774b82a000">[e25569ef95]</a> Mark Michelson -- res_pjsip_pubsub: More accurately persist packet.</li>
+</ul><br><h4>Category: Resources/res_pjsip_sdp_rtp</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25356">ASTERISK-25356</a>: res_pjsip_sdp_rtp: Multiple keepalive scheduled items may exist<br/>Reported by: Joshua Colp<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=1b1561f4c854c37691bd24227b8f722d1dac4291">[1b1561f4c8]</a> Joshua Colp -- res_pjsip_sdp_rtp: Fix multiple keepalive scheduled items.</li>
+</ul><br><h4>Category: Resources/res_pjsip_session</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25297">ASTERISK-25297</a>: Crashes running channels/pjsip/resolver/srv/failover/in_dialog testsuite tests<br/>Reported by: Richard Mudgett<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=13eb491e35ae6a99164dec6a62d7f05784c75c11">[13eb491e35]</a> Richard Mudgett -- res_pjsip_session.c: Fix crashes seen when call cancelled.</li>
+</ul><br><h4>Category: Resources/res_rtp_asterisk</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25438">ASTERISK-25438</a>: res_rtp_asterisk: ICE role message even when ICE is not enabled<br/>Reported by: Joshua Colp<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=9913d47697716040917b49c0c60ae2d98493d516">[9913d47697]</a> Joshua Colp -- res_rtp_asterisk: Move "Set role" warning to be debug.</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25265">ASTERISK-25265</a>: [patch]DTLS Failure when calling WebRTC-peer on Firefox 39 - add ECDH support and fallback to prime256v1<br/>Reported by: Stefan Engström<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=9a12804e592b97d74ff7b909e0d0022f1ca72386">[9a12804e59]</a> Joshua Colp -- res_rtp_asterisk: Don't leak temporary key when enabling PFS.</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=aed068844c1c9748da9c67b74ea4d90622be8f46">[aed068844c]</a> Mark Duncan -- res/res_rtp_asterisk: Add ECDH support</li>
+</ul><br><h4>Category: Tests/testsuite</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25318">ASTERISK-25318</a>: tests/rest_api/applications/subscribe-endpoint/nominal/resource: Sporadically failing<br/>Reported by: Joshua Colp<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=c2c73190825bf4c9cedb1031327199767a4a3ca8">[c2c7319082]</a> Joshua Colp -- res_pjsip_session: Don't invoke session supplements twice for BYE requests.</li>
+</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25292">ASTERISK-25292</a>: Testuite: tests/apps/bridge/bridge_wait/bridge_wait_e_options fails<br/>Reported by: Kevin Harwell<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=10ba72a9279c591e800ad2656d367b881f73203d">[10ba72a927]</a> Mark Michelson -- Add a test event for inband ringing.</li>
+</ul><br><h3>Improvement</h3><h4>Category: Core/General</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25310">ASTERISK-25310</a>: [patch]on FreeBSD also pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED<br/>Reported by: Guido Falsi<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=4ed9c9a280c08a17fce602c15d2b01de199ca736">[4ed9c9a280]</a> Guido Falsi -- Core/General: Add #ifdef needed on FreeBSD.</li>
+</ul><br><h4>Category: Resources/res_ari_applications</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24870">ASTERISK-24870</a>: ARI: Subscriptions to bridges generally not super useful<br/>Reported by: Matt Jordan<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=90165e306d958293bae47dd901e2c672dca95006">[90165e306d]</a> Matt Jordan -- res/res_stasis: Fix accidental subscription to 'all' bridge topic</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=b50e372394bf0950ebbc96793d9594de97282749">[b50e372394]</a> Matt Jordan -- ARI: Add events for Contact and Peer Status changes</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=3502c0431db52d00eb16dc1cc2462be7a509ba5e">[3502c0431d]</a> Matt Jordan -- res/res_stasis_device_state: Allow for subscribing to 'all' device state</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=4c9f613309d66ae6a8e5454cd53276459bcd2674">[4c9f613309]</a> Matt Jordan -- ARI: Add the ability to subscribe to all events</li>
+</ul><br><h4>Category: Resources/res_ari_bridges</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24870">ASTERISK-24870</a>: ARI: Subscriptions to bridges generally not super useful<br/>Reported by: Matt Jordan<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=90165e306d958293bae47dd901e2c672dca95006">[90165e306d]</a> Matt Jordan -- res/res_stasis: Fix accidental subscription to 'all' bridge topic</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=b50e372394bf0950ebbc96793d9594de97282749">[b50e372394]</a> Matt Jordan -- ARI: Add events for Contact and Peer Status changes</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=3502c0431db52d00eb16dc1cc2462be7a509ba5e">[3502c0431d]</a> Matt Jordan -- res/res_stasis_device_state: Allow for subscribing to 'all' device state</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=4c9f613309d66ae6a8e5454cd53276459bcd2674">[4c9f613309]</a> Matt Jordan -- ARI: Add the ability to subscribe to all events</li>
+</ul><br><hr><a name="open_issues"><h2 align="center">Open Issues</h2></a><center><a href="#top">[Back to Top]</a></center><p>This is a list of all open issues from the issue tracker that were referenced by changes that went into this release.</p><h3>Bug</h3><h4>Category: Addons/chan_ooh323</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25299">ASTERISK-25299</a>: RTP port leaks with incoming OOH323 calls<br/>Reported by: Alexandr Dranchuk<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=480c443e2691272a7227e0949244e80e53bc31b2">[480c443e26]</a> Alexander Anikin -- chan_ooh323: call ast_rtp_instance_stop on ooh323_destroy</li>
+</ul><br><h4>Category: General</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25323">ASTERISK-25323</a>: Asterisk: ongoing segfaults uncovered by CHAOS_DEBUG<br/>Reported by: Scott Griepentrog<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=c94f46080f60435fffd197d14441ccf9d963521b">[c94f46080f]</a> Scott Griepentrog -- CHAOS: avoid crash if string create fails</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=4cc59533b903b3d55e8b388f28385287e712ae62">[4cc59533b9]</a> Richard Mudgett -- CHAOS: res_pjsip_diversion avoid crash if allocation fails</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=fb6b5c684b8772ba008339a417725a208f72409e">[fb6b5c684b]</a> Scott Griepentrog -- PJSIP: avoid crash when getting rtp peer</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f72f9ceefca52002c45f5910219dbcb0f9437a79">[f72f9ceefc]</a> Scott Griepentrog -- pjsip: avoid possible crash req_caps allocation failure</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=6862c2a167f4ed2cb8511bb1ae94a13582afa25b">[6862c2a167]</a> Scott Griepentrog -- Chaos: handle failed allocation in get_media_encryption_type</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f1cd6366588c66dce5be66541ceb7f828fde3773">[f1cd636658]</a> Scott Griepentrog -- Chaos: make hangup NULL tolerant</li>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=ab373f2ceffcad3a497663027199f4f4a81f644b">[ab373f2cef]</a> Scott Griepentrog -- CHAOS: prevent sorcery object with null id</li>
+</ul><br><h4>Category: Resources/res_hep_rtcp</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-25352">ASTERISK-25352</a>: res_hep_rtcp correlation_id is different then res_hep<br/>Reported by: Kevin Scott Adams<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=78d0b9d97ecf034468e252440217dd4bc371ef71">[78d0b9d97e]</a> Matt Jordan -- channels/pjsip/dialplan_functions: Add an option for extracting the SIP call-id</li>
+</ul><br><h4>Category: pjproject/pjsip</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-24602">ASTERISK-24602</a>: Unable to call WebRTC client via wss on chan_pjsip<br/>Reported by: Oleg Kozlov<ul>
+<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=d32e516c7cd48979db092a82b97a7ac4a743f526">[d32e516c7c]</a> Martin Tomec -- res/pjsip: Mark WSS transport as secure</li>
+</ul><br><h3>Improvement</h3><hr><a name="commits"><h2 align="center">Commits Not Associated with an Issue</h2></a><center><a href="#top">[Back to Top]</a></center><p>This is a list of all changes that went into this release that did not reference a JIRA issue.</p><table width="100%" border="1">
+<tr><th>Revision</th><th>Author</th><th>Summary</th></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=cc0eff5651e792d9f97a433fbbac99992c20cb46">cc0eff5651</a></td><td>Kevin Harwell</td><td>Release summaries: Remove previous versions</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8cd191b885c5410faa11e28b52d37fea9d5c5197">8cd191b885</a></td><td>Kevin Harwell</td><td>.version: Update for 13.6.0</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a3777c24fd93fe757ce8c68daf9c2749938eea8f">a3777c24fd</a></td><td>Kevin Harwell</td><td>.lastclean: Update for 13.6.0</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=68121cef21b3753a28248b493d211a6d3176e67a">68121cef21</a></td><td>Kevin Harwell</td><td>realtime: Add database scripts for 13.6.0</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=d72dab4f402c06b304e339f4e8fd801b502cb003">d72dab4f40</a></td><td>Kevin Harwell</td><td>ChangeLog: Updated for 13.6.0-rc3</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=9da83dbd1524aa1c74907066ec6480e9d56651f9">9da83dbd15</a></td><td>Kevin Harwell</td><td>Release summaries: Add summaries for 13.6.0-rc3</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8c60f9326ce609061316f4bc3b1522caa7282482">8c60f9326c</a></td><td>Kevin Harwell</td><td>Release summaries: Remove previous versions</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=316d47755b0d6239cb5bbd674d7596046ad4cddd">316d47755b</a></td><td>Kevin Harwell</td><td>.version: Update for 13.6.0-rc3</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=74a86d0a72c9858dc965e8e2b59ae4a1e0294033">74a86d0a72</a></td><td>Kevin Harwell</td><td>.lastclean: Update for 13.6.0-rc3</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=4c39bea6f00560dd6bc52d9d793e1ae7ebf130b7">4c39bea6f0</a></td><td>Kevin Harwell</td><td>realtime: Add database scripts for 13.6.0-rc3</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=c3521e9469f95b962e52edbbb6e0cdef6d3ceab4">c3521e9469</a></td><td>Kevin Harwell</td><td>ChangeLog: Updated for 13.6.0-rc2</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a44f6aa046c988f3c1ce9defba5038f83255a4c4">a44f6aa046</a></td><td>Kevin Harwell</td><td>Release summaries: Add summaries for 13.6.0-rc2</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=dd74af7e460083df8ca774db2793791ff6413c6e">dd74af7e46</a></td><td>Kevin Harwell</td><td>Release summaries: Remove previous versions</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a11a78ca34fae7ef2069d0a9ae6a5cf1fd2856d7">a11a78ca34</a></td><td>Kevin Harwell</td><td>.version: Update for 13.6.0-rc2</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=570329ec8a05c27675721734e2da3c42c707f0f7">570329ec8a</a></td><td>Kevin Harwell</td><td>.lastclean: Update for 13.6.0-rc2</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=51c9ff47f6bab1aed30f95a8601e0ddf253b657e">51c9ff47f6</a></td><td>Kevin Harwell</td><td>realtime: Add database scripts for 13.6.0-rc2</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a0fb436eda914dca26e96d304d3c9daca2be54de">a0fb436eda</a></td><td>Kevin Harwell</td><td>ChangeLog: Updated for 13.6.0-rc1</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=bba1c4066be4d752f106266a7c084ba2340c2777">bba1c4066b</a></td><td>Kevin Harwell</td><td>Release summaries: Add summaries for 13.6.0-rc1</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=82c4aecdbb4466843a41e0591ed0e7c16c1902a6">82c4aecdbb</a></td><td>Kevin Harwell</td><td>.version: Update for 13.6.0-rc1</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=bc18db73884513e5636fc4af8d1b8bf2ba355c3a">bc18db7388</a></td><td>Kevin Harwell</td><td>.lastclean: Update for 13.6.0-rc1</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=b9c53f95e38e7e9e47c9843bcbb0e8836cafed1b">b9c53f95e3</a></td><td>Kevin Harwell</td><td>realtime: Add database scripts for 13.6.0-rc1</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=d30939b6e84f18eb1fa3eb9819951fe8a1c764f4">d30939b6e8</a></td><td>Kevin Harwell</td><td>ARI: Changed version from 1.8.0 to 1.9.0</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=5f19c9baded56a5adb419a7bcb1ac00fbe09f404">5f19c9bade</a></td><td>Richard Mudgett</td><td>res/ari/config.c: Fix user sort compare function.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=3a8576403968bd1f49c8bef67735c04d05fb6983">3a85764039</a></td><td>Richard Mudgett</td><td>res/ari/config.c: Optimize conf_alloc() object init.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=bbeda190c3f05e95a82c7d9609c66dcf3ce35bd3">bbeda190c3</a></td><td>Richard Mudgett</td><td>app_dial.c: Remove some no-op code.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=fe5077b1f8caed2df419e1bd7b872657b7def726">fe5077b1f8</a></td><td>Mark Michelson</td><td>res_pjsip_pubsub: Eliminate race during initial NOTIFY.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=5c713fdf18ffa934e0cac8ddb29e4ad95a68200b">5c713fdf18</a></td><td>Mark Michelson</td><td>scheduler: Use queue for allocating sched IDs.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e75aff53e6ee68833595db101e43329adf9a4459">e75aff53e6</a></td><td>Richard Mudgett</td><td>res_pjsip_pubsub.c: Mark ast_sip_create_subscription() as not used.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=4d91d01df180a712485aa60d14fda2aa9e5063d2">4d91d01df1</a></td><td>Richard Mudgett</td><td>res_pjsip_pubsub.c: Add some notification comments.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f36a9d122171781dd8a99d32792a0c19103b1f15">f36a9d1221</a></td><td>Richard Mudgett</td><td>res_pjsip_pubsub.c: Set dlg_status code instead of sending SIP response.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=94582f8fabb926d197ce0f3a01208b385975ec09">94582f8fab</a></td><td>Richard Mudgett</td><td>res_pjsip_pubsub.c: Fix off-nominal memory leak.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8b3ed52239b24546b1ee12156dadccb70db7403e">8b3ed52239</a></td><td>Richard Mudgett</td><td>res_pjsip_pubsub.c: Fix one byte buffer overrun error.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=4329bd1e4c059e714122465901ea2c46dd924b71">4329bd1e4c</a></td><td>Richard Mudgett</td><td>res_pjsip_pubsub.c: Use ast_alloca() instead of alloca().</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a456a20ecf835bcf70ebc2a279e230df402bec08">a456a20ecf</a></td><td>Richard Mudgett</td><td>res_pjsip_pubsub.c: Add missing error return in load_module().</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=f58f4c6e2762e5ad7eccf7065e63b345f4cda7f6">f58f4c6e27</a></td><td>Richard Mudgett</td><td>res_pjsip/location.c: Use the builtin ao2_callback() match function instead.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=4eedd9ef9d7c000cd8d67cbeb1789ac6d71860aa">4eedd9ef9d</a></td><td>Matt Jordan</td><td>main/config_options: Check for existance of internal object before derefing</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=695f26cbb759f8ecc18c6b1d6cf84b3105b2f007">695f26cbb7</a></td><td>David M. Lee</td><td>res_rtp_asterisk: Add more ICE debugging</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=61c6c6aa6c60636207567a49c6320946c1840e99">61c6c6aa6c</a></td><td>David M. Lee</td><td>Fix when remote candidates exceed PJ_ICE_MAX_CAND</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=ad9cb6c2ce6dbe9c985c6891daf53cc4160e3a13">ad9cb6c2ce</a></td><td>Mark Michelson</td><td>res_pjsip: Fix contact refleak on stateful responses.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=7c4d0c3506374b89502bd6c1bda89c3f241b6708">7c4d0c3506</a></td><td>Joshua Colp</td><td>res_pjsip_pubsub: On recreated notify fail deleted sub_tree is referenced</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=0582776f7fe55e72acda586fb32185ad7879aeab">0582776f7f</a></td><td>Richard Mudgett</td><td>ari/ari_websockets.c: Fix ast_debug parameter type mismatch.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=77518d54344945d7d3bfc1ebfe61d97704fa5dfa">77518d5434</a></td><td>Richard Mudgett</td><td>res_http_websocket.c: Fix some off nominal path cleanup.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=c61547fee6fdc1e132d359311da48e87d98d25b1">c61547fee6</a></td><td>Richard Mudgett</td><td>res_ari.c: Add missing off nominal unlock and remove a RAII_VAR().</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=bd867cd0787b124984caf2604478212651ea4c03">bd867cd078</a></td><td>Richard Mudgett</td><td>app_queue.c: Extract some functions for simpler code.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=ded51e3d77a13eed059a85a083d0ab0324a77db7">ded51e3d77</a></td><td>Richard Mudgett</td><td>app_queue.c: Fix error checking in QUEUE_MEMBER() read.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=b719f56c72c9cc66879eeef11de2ef4498cba648">b719f56c72</a></td><td>Mark Michelson</td><td>res_pjsip_sdp_rtp: Restore removed NULL check.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=cea5dc7b8afd0e8cbde4c5d253bac3219125b168">cea5dc7b8a</a></td><td>Richard Mudgett</td><td>audiohook.c: Simplify variable usage in audiohook_read_frame_both().</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e18c300550453df06507e32c4bc78ef91d369f27">e18c300550</a></td><td>Joshua Colp</td><td>res_http_websocket: When shutting down a session don't close closed socket</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8e194047acb3ba846356041c1a6222caefc65a2e">8e194047ac</a></td><td>Matt Jordan</td><td>res/res_format_attr_silk: Expose format attributes to other modules</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a0f451c35ed56b08353c4c3150bf847867f74fe7">a0f451c35e</a></td><td>Matt Jordan</td><td>main/format: Add an API call for retrieving format attributes</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=26f0559a94519b735396ed4ce90e23c1d9d5b332">26f0559a94</a></td><td>David M. Lee</td><td>Replace htobe64 with htonll</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=27dc2094e98b59b8a50b059ddd6048285a42e6b9">27dc2094e9</a></td><td>Mark Michelson</td><td>res_http_websocket: Debug write lengths.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=39cc28f6ea2140ad6d561fd4c9e9a66f065cecee">39cc28f6ea</a></td><td>Mark Michelson</td><td>res_http_websocket: Avoid passing strlen() to ast_websocket_write().</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=1519eb44a796911c7c438bbe4e31bb89be244387">1519eb44a7</a></td><td>Richard Mudgett</td><td>rtp_engine.c: Must protect mime_types_len with mime_types_lock.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=a93b7a927c5975c0a8889dc66868f81e4eef8aa3">a93b7a927c</a></td><td>Richard Mudgett</td><td>res_pjsip_sdp_rtp.c: Fix processing wrong SDP media list.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=741fa0d26d38f7a9ed98c595ee1bb6b6ce8a9923">741fa0d26d</a></td><td>Richard Mudgett</td><td>res_pjsip_sdp_rtp.c: Fixup some whitespace.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=89b21fd9a38bcd89402249440c1670ce48781f30">89b21fd9a3</a></td><td>Richard Mudgett</td><td>rtp_engine.h: No sense allowing payload types larger than RFC allows.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=7427c7f13b1d0c9095e83a3ea38394f521d3a75e">7427c7f13b</a></td><td>Richard Mudgett</td><td>rtp_engine.c: Minor tweaks.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=e20f435b6093c2c72e678b9fad1ed037c3191b88">e20f435b60</a></td><td>Richard Mudgett</td><td>rtp_engine.h: Misc comment fixes.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=bc5d7f9c37fe8a4ff5744ab8620898ccae6a7d2a">bc5d7f9c37</a></td><td>Richard Mudgett</td><td>chan_sip.c: Tweak glue->update_peer() parameter nil value.</td></tr>
+<tr><td><a href="https://code.asterisk.org/code/changelog/asterisk?cs=48698a5e21d7307f61b5fb2bd39fd593bc1423ca">48698a5e21</a></td><td>Mark Michelson</td><td>res_http_websocket: Properly encode 64 bit payload</td></tr>
+</table><hr><a name="diffstat"><h2 align="center">Diffstat Results</h2></a><center><a href="#top">[Back to Top]</a></center><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>asterisk-13.5.0-summary.html                                                  |  441 --
+asterisk-13.5.0-summary.txt                                                   | 1141 ------
+b/.version                                                                    |    2
+b/CHANGES                                                                     |   35
+b/ChangeLog                                                                   | 1884 +++++++++-
+b/Makefile                                                                    |    1
+b/UPGRADE.txt                                                                 |    6
+b/addons/chan_ooh323.c                                                        |    1
+b/addons/ooh323c/src/ooq931.c                                                 |    6
+b/apps/app_dial.c                                                             |  156
+b/apps/app_page.c                                                             |   28
+b/apps/app_queue.c                                                            |  412 +-
+b/apps/app_record.c                                                           |    3
+b/bridges/bridge_holding.c                                                    |    6
+b/channels/chan_dahdi.c                                                       |   55
+b/channels/chan_pjsip.c                                                       |   18
+b/channels/chan_sip.c                                                         |   78
+b/channels/chan_skinny.c                                                      |   26
+b/channels/pjsip/dialplan_functions.c                                         |    5
+b/channels/sip/include/security_events.h                                      |    3
+b/channels/sip/security_events.c                                              |    5
+b/codecs/codec_gsm.c                                                          |   29
+b/codecs/codec_ilbc.c                                                         |   28
+b/codecs/codec_lpc10.c                                                        |   41
+b/codecs/codec_speex.c                                                        |   60
+b/configure                                                                   |   63
+b/configure.ac                                                                |    6
+b/contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py |   22
+b/contrib/realtime/mssql/mssql_config.sql                                     |    8
+b/contrib/realtime/mysql/mysql_config.sql                                     |    6
+b/contrib/realtime/oracle/oracle_config.sql                                   |    8
+b/contrib/realtime/postgresql/postgresql_config.sql                           |    6
+b/contrib/scripts/astversion                                                  |  536 ++
+b/contrib/scripts/install_prereq                                              |    2
+b/include/asterisk/autoconfig.h.in                                            |    3
+b/include/asterisk/format.h                                                   |   23
+b/include/asterisk/logger.h                                                   |   44
+b/include/asterisk/res_pjsip.h                                                |   40
+b/include/asterisk/res_pjsip_session.h                                        |    6
+b/include/asterisk/rtp_engine.h                                               |   18
+b/include/asterisk/stasis_app.h                                               |   15
+b/main/audiohook.c                                                            |   43
+b/main/bridge_channel.c                                                       |    7
+b/main/channel.c                                                              |    9
+b/main/config_options.c                                                       |    4
+b/main/dial.c                                                                 |   25
+b/main/endpoints.c                                                            |    3
+b/main/format.c                                                               |   11
+b/main/logger.c                                                               |  272 +
+b/main/pbx.c                                                                  |  146
+b/main/rtp_engine.c                                                           |  153
+b/main/sched.c                                                                |  143
+b/main/sorcery.c                                                              |    4
+b/main/stasis_endpoints.c                                                     |   78
+b/main/taskprocessor.c                                                        |   12
+b/main/translate.c                                                            |   55
+b/main/utils.c                                                                |    4
+b/res/ari/ari_model_validators.c                                              |  445 ++
+b/res/ari/ari_model_validators.h                                              |  118
+b/res/ari/ari_websockets.c                                                    |    9
+b/res/ari/config.c                                                            |   72
+b/res/ari/resource_asterisk.c                                                 |  127
+b/res/ari/resource_asterisk.h                                                 |   63
+b/res/ari/resource_events.c                                                   |   24
+b/res/ari/resource_events.h                                                   |    2
+b/res/parking/parking_applications.c                                          |   65
+b/res/res_ari.c                                                               |   19
+b/res/res_ari_asterisk.c                                                      |  300 +
+b/res/res_ari_events.c                                                        |    6
+b/res/res_config_sqlite.c                                                     |    8
+b/res/res_format_attr_silk.c                                                  |   24
+b/res/res_http_websocket.c                                                    |   80
+b/res/res_pjsip.c                                                             |  131
+b/res/res_pjsip/config_global.c                                               |   18
+b/res/res_pjsip/location.c                                                    |   51
+b/res/res_pjsip/pjsip_configuration.c                                         |    4
+b/res/res_pjsip/presence_xml.c                                                |   31
+b/res/res_pjsip_diversion.c                                                   |    4
+b/res/res_pjsip_multihomed.c                                                  |   23
+b/res/res_pjsip_nat.c                                                         |    2
+b/res/res_pjsip_pidf_digium_body_supplement.c                                 |    2
+b/res/res_pjsip_pubsub.c                                                      |   80
+b/res/res_pjsip_sdp_rtp.c                                                     |   70
+b/res/res_pjsip_session.c                                                     |   37
+b/res/res_pjsip_t38.c                                                         |   15
+b/res/res_pjsip_transport_websocket.c                                         |    5
+b/res/res_rtp_asterisk.c                                                      |   79
+b/res/res_stasis.c                                                            |   45
+b/res/res_stasis_device_state.c                                               |   54
+b/res/stasis/app.c                                                            |  335 +
+b/res/stasis/app.h                                                            |   15
+b/res/stasis/messaging.c                                                      |   44
+b/rest-api-templates/ari_model_validators.c.mustache                          |    2
+b/rest-api/api-docs/applications.json                                         |    2
+b/rest-api/api-docs/asterisk.json                                             |  130
+b/rest-api/api-docs/bridges.json                                              |    2
+b/rest-api/api-docs/channels.json                                             |    2
+b/rest-api/api-docs/deviceStates.json                                         |    2
+b/rest-api/api-docs/endpoints.json                                            |    2
+b/rest-api/api-docs/events.json                                               |  109
+b/rest-api/api-docs/mailboxes.json                                            |    2
+b/rest-api/api-docs/playbacks.json                                            |    2
+b/rest-api/api-docs/recordings.json                                           |    2
+b/rest-api/api-docs/sounds.json                                               |    2
+b/rest-api/resources.json                                                     |    2
+b/tests/test_core_format.c                                                    |   57
+106 files changed, 6435 insertions(+), 2535 deletions(-)</pre><br></html>
\ No newline at end of file
diff --git a/asterisk-13.6.0-summary.txt b/asterisk-13.6.0-summary.txt
new file mode 100644
index 0000000..c9c5590
--- /dev/null
+++ b/asterisk-13.6.0-summary.txt
@@ -0,0 +1,839 @@
+                                Release Summary
+
+                                asterisk-13.6.0
+
+                                Date: 2015-10-09
+
+                           <asteriskteam at digium.com>
+
+     ----------------------------------------------------------------------
+
+                               Table of Contents
+
+    1. Summary
+    2. Contributors
+    3. Closed Issues
+    4. Open Issues
+    5. Other Changes
+    6. Diffstat
+
+     ----------------------------------------------------------------------
+
+                                    Summary
+
+                                 [Back to Top]
+
+   This release is a point release of an existing major version. The changes
+   included were made to address problems that have been identified in this
+   release series, or are minor, backwards compatible new features or
+   improvements. Users should be able to safely upgrade to this version if
+   this release series is already in use. Users considering upgrading from a
+   previous version 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-13.5.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 affected by commits that went into
+   this release.
+
+   Coders                       Testers          Reporters                    
+   40 Richard Mudgett           1 Elazar Broad   13 Matt Jordan               
+   18 Kevin Harwell                              11 Joshua Colp               
+   16 Joshua Colp                                11 Richard Mudgett           
+   15 Mark Michelson                             10 Scott Griepentrog         
+   13 Matt Jordan                                8 Mark Michelson             
+   9 Scott Griepentrog                           8 Mark Michelson             
+   8 Kevin Harwell                               7 John Hardin                
+   3 Scott Emidy                                 5 Kevin Harwell              
+   3 David M. Lee                                4 Scott Griepentrog          
+   2 Alexander Traud                             3 Richard Mudgett            
+   2 Alexander Anikin                            2 Kevin Harwell              
+   2 Jonathan Rose                               2 Alexander Traud            
+   1 Martin Tomec                                2 Alexandr Dranchuk          
+   1 Elazar Broad                                2 Dmitriy Serov              
+   1 Walter Doekes                               2 Stefan EngstrAP:m          
+   1 Rodrigo RamArez Norambuena                  1 Oleg Kozlov                
+   1 Mark Duncan                                 1 Walter Doekes              
+   1 Benjamin Ford                               1 Etienne Lessard            
+   1 Guido Falsi                                 1 Lorne Gaetz                
+                                                 1 Chet Stevens               
+                                                 1 Rodrigo Ramirez Norambuena 
+                                                 1 Ashley Sanders             
+                                                 1 Guido Falsi                
+                                                 1 Lorne Gaetz                
+                                                 1 Chet Stevens               
+                                                 1 Kevin Scott Adams          
+                                                 1 Elazar Broad               
+                                                 1 Sean Pimental              
+                                                 1 Jonathan Rose              
+                                                 1 Etienne Lessard            
+                                                 1 Alexandr Dranchuk          
+                                                 1 yaron nahum                
+                                                 1 Elazar Broad               
+                                                 1 yaron nahum                
+                                                 1 Guido Falsi                
+
+     ----------------------------------------------------------------------
+
+                                 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.
+
+  New Feature
+
+    Category: Resources/res_ari
+
+   ASTERISK-25252: ARI: Add the ability to manipulate log channels
+   Reported by: Matt Jordan
+     * [df9ce36366] Scott Emidy -- ARI: Retrieve existing log channels
+     * [e9f1bc08cb] Scott Emidy -- ARI: Creating log channels
+     * [78364132ce] Scott Emidy -- ARI: Deleting log channels
+     * [1ae762634c] Benjamin Ford -- ARI: Rotate log channels.
+
+    Category: Resources/res_pjsip
+
+   ASTERISK-25377: res_pjsip: Change default "From user" from UUID to
+   something more palatable
+   Reported by: Mark Michelson
+     * [ac62928d6b] Mark Michelson -- res_pjsip: Change default from user
+       value.
+
+  Bug
+
+    Category: Addons/chan_ooh323
+
+   ASTERISK-25227: No audio at in-band announcements in ooh323 channel
+   Reported by: Alexandr Dranchuk
+     * [71408df2b8] Alexander Anikin -- chan_ooh323: Add ProgressIndicator IE
+       with inband info available
+
+    Category: Applications/app_dial
+
+   ASTERISK-25423: Caller gets no Connected line update during call pickup.
+   Reported by: Richard Mudgett
+     * [6b1e7583c1] Richard Mudgett -- app_queue.c: Force COLP update if
+       outgoing channel name changed.
+     * [6bf304bf25] Richard Mudgett -- app_queue.c: Factor out a connected
+       line update routine.
+     * [e36b5f1e8e] Richard Mudgett -- app_dial.c: Make 'A' option pass COLP
+       updates.
+     * [747bfac895] Richard Mudgett -- app_dial.c: Force COLP update if
+       outgoing channel name changed.
+     * [14481d9aa0] Richard Mudgett -- app_dial.c: Factor out a connected
+       line update routine.
+
+    Category: Applications/app_mixmonitor
+
+   ASTERISK-25322: Crash occurs when using MixMonitor with t() or r()
+   options.
+   Reported by: Richard Mudgett
+     * [b3a56bee83] Richard Mudgett -- audiohook.c: Fix MixMonitor crash when
+       using the r() or t() options.
+
+    Category: Applications/app_page
+
+   ASTERISK-25384: Regular Asterisk crashes when using Page application.
+   "user_data is NULL"
+   Reported by: Chet Stevens
+     * [5f15cd93f0] Richard Mudgett -- app_page.c: Fix crash when forwarding
+       with a predial handler.
+
+    Category: Applications/app_queue
+
+   ASTERISK-25423: Caller gets no Connected line update during call pickup.
+   Reported by: Richard Mudgett
+     * [6b1e7583c1] Richard Mudgett -- app_queue.c: Force COLP update if
+       outgoing channel name changed.
+     * [6bf304bf25] Richard Mudgett -- app_queue.c: Factor out a connected
+       line update routine.
+     * [e36b5f1e8e] Richard Mudgett -- app_dial.c: Make 'A' option pass COLP
+       updates.
+     * [747bfac895] Richard Mudgett -- app_dial.c: Force COLP update if
+       outgoing channel name changed.
+     * [14481d9aa0] Richard Mudgett -- app_dial.c: Factor out a connected
+       line update routine.
+   ASTERISK-25399: app_queue: AgentComplete event has wrong reason
+   Reported by: Kevin Harwell
+     * [4fb95bbc4e] Kevin Harwell -- app_queue: AgentComplete event has wrong
+       reason
+   ASTERISK-25185: Segfault in app_queue on transfer scenarios
+   Reported by: Etienne Lessard
+     * [6409e7b11a] Kevin Harwell -- app_queue: Crash when transferring
+   ASTERISK-25215: Differences in queue.log between Set QUEUE_MEMBER and
+   using PauseQueueMember
+   Reported by: Lorne Gaetz
+     * [e5f5b9f384] Richard Mudgett -- app_queue.c: Fix setting QUEUE_MEMBER
+       'paused' and 'ringinuse'.
+
+    Category: Applications/app_record
+
+   ASTERISK-25410: app_record: RECORDED_FILE variable not being populated
+   Reported by: Kevin Harwell
+     * [aeddee39fb] Kevin Harwell -- app_record: RECORDED_FILE variable not
+       being populated
+
+    Category: Bridges/bridge_holding
+
+   ASTERISK-25271: Parking & blind transfer: Transferer channel not hung up
+   if no MOH
+   Reported by: Kevin Harwell
+     * [8458b8d441] Jonathan Rose -- holding_bridge: ensure moh participants
+       get frames
+
+    Category: Channels/chan_dahdi
+
+   ASTERISK-25315: DAHDI channels send shortened duration DTMF tones.
+   Reported by: Richard Mudgett
+     * [256bc52b66] Richard Mudgett -- chan_dahdi.c: Flush the DAHDI write
+       buffer after starting DTMF.
+     * [800e0ea48d] Richard Mudgett -- chan_dahdi.c: Lock private struct for
+       ast_write().
+
+    Category: Channels/chan_sip/CodecHandling
+
+   ASTERISK-25309: [patch] iLBC 20 advertised
+   Reported by: Alexander Traud
+     * [f68c995bc9] Alexander Traud -- chan_sip: Fix negotiation of iLBC 30.
+
+    Category: Channels/chan_sip/General
+
+   ASTERISK-25346: chan_sip: Overwriting answered elsewhere hangup cause on
+   call pickup
+   Reported by: Joshua Colp
+     * [c01111223f] Joshua Colp -- chan_sip: Allow call pickup to set the
+       hangup cause.
+
+    Category: Channels/chan_sip/Interoperability
+
+   ASTERISK-25396: chan_sip: Extremely long callerid name causes invalid SIP
+   Reported by: Walter Doekes
+     * [b59c4d82b5] Walter Doekes -- chan_sip: Fix From header truncation for
+       extremely long CALLERID(name).
+
+    Category: Channels/chan_sip/Security Framework
+
+   ASTERISK-25320: chan_sip.c: sip_report_security_event searches for wrong
+   or non existent peer on invite
+   Reported by: Kevin Harwell
+     * [25af2d71c8] Kevin Harwell -- chan_sip.c: wrong peer searched in
+       sip_report_security_event
+
+    Category: Channels/chan_skinny
+
+   ASTERISK-25296: RTP performance issue with several channel drivers.
+   Reported by: Richard Mudgett
+     * [aeeb170fc4] Richard Mudgett -- rtp_engine.c: Fix performance issue
+       with several channel drivers that use RTP.
+     * [84262749d2] Richard Mudgett -- res_rtp_asterisk.c: Fix off-nominal
+       crash potential.
+
+    Category: Channels/chan_unistim
+
+   ASTERISK-25296: RTP performance issue with several channel drivers.
+   Reported by: Richard Mudgett
+     * [aeeb170fc4] Richard Mudgett -- rtp_engine.c: Fix performance issue
+       with several channel drivers that use RTP.
+     * [84262749d2] Richard Mudgett -- res_rtp_asterisk.c: Fix off-nominal
+       crash potential.
+
+    Category: Codecs/General
+
+   ASTERISK-25353: [patch] Transcoding while different in Frame size = Frames
+   lost
+   Reported by: Alexander Traud
+     * [b88c54fa4b] Alexander Traud -- translate: Fix transcoding while
+       different in frame size.
+
+    Category: Core/Bridging
+
+   ASTERISK-25341: bridge: Hangups may get lost when executing actions
+   Reported by: Joshua Colp
+     * [6c2dab1e88] Joshua Colp -- bridge: Kick channel from bridge if hung
+       up during action.
+
+    Category: Core/BuildSystem
+
+   ASTERISK-25383: Core dumps on startup and shutdown with MALLOC_DEBUG
+   enabled
+   Reported by: yaron nahum
+     * [028033e5a8] Richard Mudgett -- res/ari/config.c: Fix conf_alloc()
+       object init.
+   ASTERISK-25265: [patch]DTLS Failure when calling WebRTC-peer on Firefox 39
+   - add ECDH support and fallback to prime256v1
+   Reported by: Stefan EngstrAP:m
+     * [9a12804e59] Joshua Colp -- res_rtp_asterisk: Don't leak temporary key
+       when enabling PFS.
+     * [aed068844c] Mark Duncan -- res/res_rtp_asterisk: Add ECDH support
+
+    Category: Core/General
+
+   ASTERISK-25449: main/sched: Regression introduced by 5c713fdf18f causes
+   erroneous duplicate RTCP messages; other potential scheduling issues in
+   chan_sip/chan_skinny
+   Reported by: Matt Jordan
+     * [10e790f81a] Matt Jordan -- res/res_rtp_asterisk: Fix assignment after
+       ao2 decrement
+     * [754daeca0a] Matt Jordan -- Fix improper usage of scheduler exposed by
+       5c713fdf18f
+   ASTERISK-25383: Core dumps on startup and shutdown with MALLOC_DEBUG
+   enabled
+   Reported by: yaron nahum
+     * [028033e5a8] Richard Mudgett -- res/ari/config.c: Fix conf_alloc()
+       object init.
+   ASTERISK-25418: On-hold channels redirected out of a bridge appear to
+   still be on hold
+   Reported by: Mark Michelson
+     * [629458d349] Mark Michelson -- Do not swallow frames on channels
+       leaving bridges.
+   ASTERISK-25355: sched: ast_sched_del may return prematurely due to
+   spurious wakeup
+   Reported by: Joshua Colp
+     * [85e1cb51b2] Joshua Colp -- sched: ast_sched_del may return
+       prematurely due to spurious wakeup
+
+    Category: Core/Logging
+
+   ASTERISK-25305: Dynamic logger channels can be added multiple times
+   Reported by: Mark Michelson
+     * [f050fa76eb] Mark Michelson -- logger: Prevent duplicate dynamic
+       channels from being added.
+   ASTERISK-25407: Asterisk fails to log to multiple syslog destinations
+   Reported by: Elazar Broad
+     * [ec514ad64d] Elazar Broad -- core/logging: Fix logging to more than
+       one syslog channel
+
+    Category: Core/PBX
+
+   ASTERISK-25394: pbx: Incorrect device and presence state when changing
+   hint details
+   Reported by: Joshua Colp
+     * [2bd27d1222] Joshua Colp -- pbx: Update device and presence state when
+       changing a hint extension.
+   ASTERISK-25367: pbx: Long pattern match hints may cause "core show hints"
+   to crash
+   Reported by: Joshua Colp
+     * [cc1363209e] Joshua Colp -- pbx: Fix crash when issuing "core show
+       hints" with long pattern match.
+   ASTERISK-25362: Deadlock due to presence state callback
+   Reported by: Mark Michelson
+     * [03fe79f29e] Mark Michelson -- Fix deadlock on presence state changes.
+
+    Category: Core/RTP
+
+   ASTERISK-25296: RTP performance issue with several channel drivers.
+   Reported by: Richard Mudgett
+     * [aeeb170fc4] Richard Mudgett -- rtp_engine.c: Fix performance issue
+       with several channel drivers that use RTP.
+     * [84262749d2] Richard Mudgett -- res_rtp_asterisk.c: Fix off-nominal
+       crash potential.
+
+    Category: Resources/res_ari
+
+   ASTERISK-25325: ARI PUT reload chan_sip HTTP response 404
+   Reported by: Rodrigo Ramirez Norambuena
+     * [865377fc38] Rodrigo RamArez Norambuena -- chan_sip.c: Validation on
+       module reload
+
+    Category: Resources/res_http_websocket
+
+   ASTERISK-25312: res_http_websocket: Terminate connection on fatal cases
+   Reported by: Joshua Colp
+     * [b4e9416138] Joshua Colp -- res_http_websocket: Forcefully terminate
+       on write errors.
+
+    Category: Resources/res_parking
+
+   ASTERISK-25369: res_parking: ParkAndAnnounce - Inheritable variables
+   aren't applied to the announcer channel
+   Reported by: Jonathan Rose
+     * [fbf720db91] Jonathan Rose -- ParkAndAnnounce: Add variable
+       inheritance
+
+    Category: Resources/res_pjsip
+
+   ASTERISK-25295: res_pjsip crash - pjsip_uri_get_uri at
+   /usr/include/pjsip/sip_uri.h
+   Reported by: Dmitriy Serov
+     * [5469caa9dd] Joshua Colp -- res_pjsip: Use hash for contact object
+       identity instead of Contact URI.
+     * [a676ba2aad] Joshua Colp -- taskprocessor: Fix race condition between
+       unreferencing and finding.
+   ASTERISK-25381: res_pjsip: AoRs deleted via ARI (or other mechanism) do
+   not destroy their related contacts
+   Reported by: Matt Jordan
+     * [c3e6debdb9] Matt Jordan -- res/res_pjsip: Purge contacts when an AoR
+       is deleted
+   ASTERISK-25339: res_pjsip: Empty "auth" sections from non-config
+   backgrounds are interpreted as valid
+   Reported by: Matt Jordan
+     * [bc6fe07f5c] Matt Jordan -- res_pjsip/pjsip_configuration: Disregard
+       empty auth values
+   ASTERISK-25304: res_pjsip: XML sanitization may write past buffer
+   Reported by: Joshua Colp
+     * [8521a86367] Joshua Colp -- res_pjsip: Ensure sanitized XML is NULL
+       terminated.
+
+    Category: Resources/res_pjsip_nat
+
+   ASTERISK-25387: res_pjsip_nat: Malformed REGISTER request causes NAT'd
+   Contact header to not be rewritten
+   Reported by: Matt Jordan
+     * [1dd0e220bf] Matt Jordan -- res/res_pjsip_nat: Ignore REGISTER
+       requests when looking for a Record-Route
+
+    Category: Resources/res_pjsip_pubsub
+
+   ASTERISK-25306: Persistent subscriptions can save multiple SIP messages at
+   once, leading to potential crashes.
+   Reported by: Mark Michelson
+     * [c126afe18f] Richard Mudgett -- res_pjsip.c: Fix crash from corrupt
+       saved SUBSCRIBE message.
+     * [e25569ef95] Mark Michelson -- res_pjsip_pubsub: More accurately
+       persist packet.
+
+    Category: Resources/res_pjsip_sdp_rtp
+
+   ASTERISK-25356: res_pjsip_sdp_rtp: Multiple keepalive scheduled items may
+   exist
+   Reported by: Joshua Colp
+     * [1b1561f4c8] Joshua Colp -- res_pjsip_sdp_rtp: Fix multiple keepalive
+       scheduled items.
+
+    Category: Resources/res_pjsip_session
+
+   ASTERISK-25297: Crashes running
+   channels/pjsip/resolver/srv/failover/in_dialog testsuite tests
+   Reported by: Richard Mudgett
+     * [13eb491e35] Richard Mudgett -- res_pjsip_session.c: Fix crashes seen
+       when call cancelled.
+
+    Category: Resources/res_rtp_asterisk
+
+   ASTERISK-25438: res_rtp_asterisk: ICE role message even when ICE is not
+   enabled
+   Reported by: Joshua Colp
+     * [9913d47697] Joshua Colp -- res_rtp_asterisk: Move "Set role" warning
+       to be debug.
+   ASTERISK-25265: [patch]DTLS Failure when calling WebRTC-peer on Firefox 39
+   - add ECDH support and fallback to prime256v1
+   Reported by: Stefan EngstrAP:m
+     * [9a12804e59] Joshua Colp -- res_rtp_asterisk: Don't leak temporary key
+       when enabling PFS.
+     * [aed068844c] Mark Duncan -- res/res_rtp_asterisk: Add ECDH support
+
+    Category: Tests/testsuite
+
+   ASTERISK-25318:
+   tests/rest_api/applications/subscribe-endpoint/nominal/resource:
+   Sporadically failing
+   Reported by: Joshua Colp
+     * [c2c7319082] Joshua Colp -- res_pjsip_session: Don't invoke session
+       supplements twice for BYE requests.
+   ASTERISK-25292: Testuite:
+   tests/apps/bridge/bridge_wait/bridge_wait_e_options fails
+   Reported by: Kevin Harwell
+     * [10ba72a927] Mark Michelson -- Add a test event for inband ringing.
+
+  Improvement
+
+    Category: Core/General
+
+   ASTERISK-25310: [patch]on FreeBSD also pthread_attr_init() defaults to
+   PTHREAD_EXPLICIT_SCHED
+   Reported by: Guido Falsi
+     * [4ed9c9a280] Guido Falsi -- Core/General: Add #ifdef needed on
+       FreeBSD.
+
+    Category: Resources/res_ari_applications
+
+   ASTERISK-24870: ARI: Subscriptions to bridges generally not super useful
+   Reported by: Matt Jordan
+     * [90165e306d] Matt Jordan -- res/res_stasis: Fix accidental
+       subscription to 'all' bridge topic
+     * [b50e372394] Matt Jordan -- ARI: Add events for Contact and Peer
+       Status changes
+     * [3502c0431d] Matt Jordan -- res/res_stasis_device_state: Allow for
+       subscribing to 'all' device state
+     * [4c9f613309] Matt Jordan -- ARI: Add the ability to subscribe to all
+       events
+
+    Category: Resources/res_ari_bridges
+
+   ASTERISK-24870: ARI: Subscriptions to bridges generally not super useful
+   Reported by: Matt Jordan
+     * [90165e306d] Matt Jordan -- res/res_stasis: Fix accidental
+       subscription to 'all' bridge topic
+     * [b50e372394] Matt Jordan -- ARI: Add events for Contact and Peer
+       Status changes
+     * [3502c0431d] Matt Jordan -- res/res_stasis_device_state: Allow for
+       subscribing to 'all' device state
+     * [4c9f613309] Matt Jordan -- ARI: Add the ability to subscribe to all
+       events
+
+     ----------------------------------------------------------------------
+
+                                  Open Issues
+
+                                 [Back to Top]
+
+   This is a list of all open issues from the issue tracker that were
+   referenced by changes that went into this release.
+
+  Bug
+
+    Category: Addons/chan_ooh323
+
+   ASTERISK-25299: RTP port leaks with incoming OOH323 calls
+   Reported by: Alexandr Dranchuk
+     * [480c443e26] Alexander Anikin -- chan_ooh323: call
+       ast_rtp_instance_stop on ooh323_destroy
+
+    Category: General
+
+   ASTERISK-25323: Asterisk: ongoing segfaults uncovered by CHAOS_DEBUG
+   Reported by: Scott Griepentrog
+     * [c94f46080f] Scott Griepentrog -- CHAOS: avoid crash if string create
+       fails
+     * [4cc59533b9] Richard Mudgett -- CHAOS: res_pjsip_diversion avoid crash
+       if allocation fails
+     * [fb6b5c684b] Scott Griepentrog -- PJSIP: avoid crash when getting rtp
+       peer
+     * [f72f9ceefc] Scott Griepentrog -- pjsip: avoid possible crash req_caps
+       allocation failure
+     * [6862c2a167] Scott Griepentrog -- Chaos: handle failed allocation in
+       get_media_encryption_type
+     * [f1cd636658] Scott Griepentrog -- Chaos: make hangup NULL tolerant
+     * [ab373f2cef] Scott Griepentrog -- CHAOS: prevent sorcery object with
+       null id
+
+    Category: Resources/res_hep_rtcp
+
+   ASTERISK-25352: res_hep_rtcp correlation_id is different then res_hep
+   Reported by: Kevin Scott Adams
+     * [78d0b9d97e] Matt Jordan -- channels/pjsip/dialplan_functions: Add an
+       option for extracting the SIP call-id
+
+    Category: pjproject/pjsip
+
+   ASTERISK-24602: Unable to call WebRTC client via wss on chan_pjsip
+   Reported by: Oleg Kozlov
+     * [d32e516c7c] Martin Tomec -- res/pjsip: Mark WSS transport as secure
+
+  Improvement
+
+     ----------------------------------------------------------------------
+
+                      Commits Not Associated with an Issue
+
+                                 [Back to Top]
+
+   This is a list of all changes that went into this release that did not
+   reference a JIRA issue.
+
+   +------------------------------------------------------------------------+
+   | Revision   | Author          | Summary                                 |
+   |------------+-----------------+-----------------------------------------|
+   | cc0eff5651 | Kevin Harwell   | Release summaries: Remove previous      |
+   |            |                 | versions                                |
+   |------------+-----------------+-----------------------------------------|
+   | 8cd191b885 | Kevin Harwell   | .version: Update for 13.6.0             |
+   |------------+-----------------+-----------------------------------------|
+   | a3777c24fd | Kevin Harwell   | .lastclean: Update for 13.6.0           |
+   |------------+-----------------+-----------------------------------------|
+   | 68121cef21 | Kevin Harwell   | realtime: Add database scripts for      |
+   |            |                 | 13.6.0                                  |
+   |------------+-----------------+-----------------------------------------|
+   | d72dab4f40 | Kevin Harwell   | ChangeLog: Updated for 13.6.0-rc3       |
+   |------------+-----------------+-----------------------------------------|
+   | 9da83dbd15 | Kevin Harwell   | Release summaries: Add summaries for    |
+   |            |                 | 13.6.0-rc3                              |
+   |------------+-----------------+-----------------------------------------|
+   | 8c60f9326c | Kevin Harwell   | Release summaries: Remove previous      |
+   |            |                 | versions                                |
+   |------------+-----------------+-----------------------------------------|
+   | 316d47755b | Kevin Harwell   | .version: Update for 13.6.0-rc3         |
+   |------------+-----------------+-----------------------------------------|
+   | 74a86d0a72 | Kevin Harwell   | .lastclean: Update for 13.6.0-rc3       |
+   |------------+-----------------+-----------------------------------------|
+   | 4c39bea6f0 | Kevin Harwell   | realtime: Add database scripts for      |
+   |            |                 | 13.6.0-rc3                              |
+   |------------+-----------------+-----------------------------------------|
+   | c3521e9469 | Kevin Harwell   | ChangeLog: Updated for 13.6.0-rc2       |
+   |------------+-----------------+-----------------------------------------|
+   | a44f6aa046 | Kevin Harwell   | Release summaries: Add summaries for    |
+   |            |                 | 13.6.0-rc2                              |
+   |------------+-----------------+-----------------------------------------|
+   | dd74af7e46 | Kevin Harwell   | Release summaries: Remove previous      |
+   |            |                 | versions                                |
+   |------------+-----------------+-----------------------------------------|
+   | a11a78ca34 | Kevin Harwell   | .version: Update for 13.6.0-rc2         |
+   |------------+-----------------+-----------------------------------------|
+   | 570329ec8a | Kevin Harwell   | .lastclean: Update for 13.6.0-rc2       |
+   |------------+-----------------+-----------------------------------------|
+   | 51c9ff47f6 | Kevin Harwell   | realtime: Add database scripts for      |
+   |            |                 | 13.6.0-rc2                              |
+   |------------+-----------------+-----------------------------------------|
+   | a0fb436eda | Kevin Harwell   | ChangeLog: Updated for 13.6.0-rc1       |
+   |------------+-----------------+-----------------------------------------|
+   | bba1c4066b | Kevin Harwell   | Release summaries: Add summaries for    |
+   |            |                 | 13.6.0-rc1                              |
+   |------------+-----------------+-----------------------------------------|
+   | 82c4aecdbb | Kevin Harwell   | .version: Update for 13.6.0-rc1         |
+   |------------+-----------------+-----------------------------------------|
+   | bc18db7388 | Kevin Harwell   | .lastclean: Update for 13.6.0-rc1       |
+   |------------+-----------------+-----------------------------------------|
+   | b9c53f95e3 | Kevin Harwell   | realtime: Add database scripts for      |
+   |            |                 | 13.6.0-rc1                              |
+   |------------+-----------------+-----------------------------------------|
+   | d30939b6e8 | Kevin Harwell   | ARI: Changed version from 1.8.0 to      |
+   |            |                 | 1.9.0                                   |
+   |------------+-----------------+-----------------------------------------|
+   | 5f19c9bade | Richard Mudgett | res/ari/config.c: Fix user sort compare |
+   |            |                 | function.                               |
+   |------------+-----------------+-----------------------------------------|
+   | 3a85764039 | Richard Mudgett | res/ari/config.c: Optimize conf_alloc() |
+   |            |                 | object init.                            |
+   |------------+-----------------+-----------------------------------------|
+   | bbeda190c3 | Richard Mudgett | app_dial.c: Remove some no-op code.     |
+   |------------+-----------------+-----------------------------------------|
+   | fe5077b1f8 | Mark Michelson  | res_pjsip_pubsub: Eliminate race during |
+   |            |                 | initial NOTIFY.                         |
+   |------------+-----------------+-----------------------------------------|
+   | 5c713fdf18 | Mark Michelson  | scheduler: Use queue for allocating     |
+   |            |                 | sched IDs.                              |
+   |------------+-----------------+-----------------------------------------|
+   |            |                 | res_pjsip_pubsub.c: Mark                |
+   | e75aff53e6 | Richard Mudgett | ast_sip_create_subscription() as not    |
+   |            |                 | used.                                   |
+   |------------+-----------------+-----------------------------------------|
+   | 4d91d01df1 | Richard Mudgett | res_pjsip_pubsub.c: Add some            |
+   |            |                 | notification comments.                  |
+   |------------+-----------------+-----------------------------------------|
+   | f36a9d1221 | Richard Mudgett | res_pjsip_pubsub.c: Set dlg_status code |
+   |            |                 | instead of sending SIP response.        |
+   |------------+-----------------+-----------------------------------------|
+   | 94582f8fab | Richard Mudgett | res_pjsip_pubsub.c: Fix off-nominal     |
+   |            |                 | memory leak.                            |
+   |------------+-----------------+-----------------------------------------|
+   | 8b3ed52239 | Richard Mudgett | res_pjsip_pubsub.c: Fix one byte buffer |
+   |            |                 | overrun error.                          |
+   |------------+-----------------+-----------------------------------------|
+   | 4329bd1e4c | Richard Mudgett | res_pjsip_pubsub.c: Use ast_alloca()    |
+   |            |                 | instead of alloca().                    |
+   |------------+-----------------+-----------------------------------------|
+   | a456a20ecf | Richard Mudgett | res_pjsip_pubsub.c: Add missing error   |
+   |            |                 | return in load_module().                |
+   |------------+-----------------+-----------------------------------------|
+   | f58f4c6e27 | Richard Mudgett | res_pjsip/location.c: Use the builtin   |
+   |            |                 | ao2_callback() match function instead.  |
+   |------------+-----------------+-----------------------------------------|
+   |            |                 | main/config_options: Check for          |
+   | 4eedd9ef9d | Matt Jordan     | existance of internal object before     |
+   |            |                 | derefing                                |
+   |------------+-----------------+-----------------------------------------|
+   | 695f26cbb7 | David M. Lee    | res_rtp_asterisk: Add more ICE          |
+   |            |                 | debugging                               |
+   |------------+-----------------+-----------------------------------------|
+   | 61c6c6aa6c | David M. Lee    | Fix when remote candidates exceed       |
+   |            |                 | PJ_ICE_MAX_CAND                         |
+   |------------+-----------------+-----------------------------------------|
+   | ad9cb6c2ce | Mark Michelson  | res_pjsip: Fix contact refleak on       |
+   |            |                 | stateful responses.                     |
+   |------------+-----------------+-----------------------------------------|
+   | 7c4d0c3506 | Joshua Colp     | res_pjsip_pubsub: On recreated notify   |
+   |            |                 | fail deleted sub_tree is referenced     |
+   |------------+-----------------+-----------------------------------------|
+   | 0582776f7f | Richard Mudgett | ari/ari_websockets.c: Fix ast_debug     |
+   |            |                 | parameter type mismatch.                |
+   |------------+-----------------+-----------------------------------------|
+   | 77518d5434 | Richard Mudgett | res_http_websocket.c: Fix some off      |
+   |            |                 | nominal path cleanup.                   |
+   |------------+-----------------+-----------------------------------------|
+   | c61547fee6 | Richard Mudgett | res_ari.c: Add missing off nominal      |
+   |            |                 | unlock and remove a RAII_VAR().         |
+   |------------+-----------------+-----------------------------------------|
+   | bd867cd078 | Richard Mudgett | app_queue.c: Extract some functions for |
+   |            |                 | simpler code.                           |
+   |------------+-----------------+-----------------------------------------|
+   | ded51e3d77 | Richard Mudgett | app_queue.c: Fix error checking in      |
+   |            |                 | QUEUE_MEMBER() read.                    |
+   |------------+-----------------+-----------------------------------------|
+   | b719f56c72 | Mark Michelson  | res_pjsip_sdp_rtp: Restore removed NULL |
+   |            |                 | check.                                  |
+   |------------+-----------------+-----------------------------------------|
+   | cea5dc7b8a | Richard Mudgett | audiohook.c: Simplify variable usage in |
+   |            |                 | audiohook_read_frame_both().            |
+   |------------+-----------------+-----------------------------------------|
+   | e18c300550 | Joshua Colp     | res_http_websocket: When shutting down  |
+   |            |                 | a session don't close closed socket     |
+   |------------+-----------------+-----------------------------------------|
+   | 8e194047ac | Matt Jordan     | res/res_format_attr_silk: Expose format |
+   |            |                 | attributes to other modules             |
+   |------------+-----------------+-----------------------------------------|
+   | a0f451c35e | Matt Jordan     | main/format: Add an API call for        |
+   |            |                 | retrieving format attributes            |
+   |------------+-----------------+-----------------------------------------|
+   | 26f0559a94 | David M. Lee    | Replace htobe64 with htonll             |
+   |------------+-----------------+-----------------------------------------|
+   | 27dc2094e9 | Mark Michelson  | res_http_websocket: Debug write         |
+   |            |                 | lengths.                                |
+   |------------+-----------------+-----------------------------------------|
+   | 39cc28f6ea | Mark Michelson  | res_http_websocket: Avoid passing       |
+   |            |                 | strlen() to ast_websocket_write().      |
+   |------------+-----------------+-----------------------------------------|
+   | 1519eb44a7 | Richard Mudgett | rtp_engine.c: Must protect              |
+   |            |                 | mime_types_len with mime_types_lock.    |
+   |------------+-----------------+-----------------------------------------|
+   | a93b7a927c | Richard Mudgett | res_pjsip_sdp_rtp.c: Fix processing     |
+   |            |                 | wrong SDP media list.                   |
+   |------------+-----------------+-----------------------------------------|
+   | 741fa0d26d | Richard Mudgett | res_pjsip_sdp_rtp.c: Fixup some         |
+   |            |                 | whitespace.                             |
+   |------------+-----------------+-----------------------------------------|
+   | 89b21fd9a3 | Richard Mudgett | rtp_engine.h: No sense allowing payload |
+   |            |                 | types larger than RFC allows.           |
+   |------------+-----------------+-----------------------------------------|
+   | 7427c7f13b | Richard Mudgett | rtp_engine.c: Minor tweaks.             |
+   |------------+-----------------+-----------------------------------------|
+   | e20f435b60 | Richard Mudgett | rtp_engine.h: Misc comment fixes.       |
+   |------------+-----------------+-----------------------------------------|
+   | bc5d7f9c37 | Richard Mudgett | chan_sip.c: Tweak glue->update_peer()   |
+   |            |                 | parameter nil value.                    |
+   |------------+-----------------+-----------------------------------------|
+   | 48698a5e21 | Mark Michelson  | res_http_websocket: Properly encode 64  |
+   |            |                 | bit payload                             |
+   +------------------------------------------------------------------------+
+
+     ----------------------------------------------------------------------
+
+                                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.
+
+ asterisk-13.5.0-summary.html                                                  |  441 --
+ asterisk-13.5.0-summary.txt                                                   | 1141 ------
+ b/.version                                                                    |    2
+ b/CHANGES                                                                     |   35
+ b/ChangeLog                                                                   | 1884 +++++++++-
+ b/Makefile                                                                    |    1
+ b/UPGRADE.txt                                                                 |    6
+ b/addons/chan_ooh323.c                                                        |    1
+ b/addons/ooh323c/src/ooq931.c                                                 |    6
+ b/apps/app_dial.c                                                             |  156
+ b/apps/app_page.c                                                             |   28
+ b/apps/app_queue.c                                                            |  412 +-
+ b/apps/app_record.c                                                           |    3
+ b/bridges/bridge_holding.c                                                    |    6
+ b/channels/chan_dahdi.c                                                       |   55
+ b/channels/chan_pjsip.c                                                       |   18
+ b/channels/chan_sip.c                                                         |   78
+ b/channels/chan_skinny.c                                                      |   26
+ b/channels/pjsip/dialplan_functions.c                                         |    5
+ b/channels/sip/include/security_events.h                                      |    3
+ b/channels/sip/security_events.c                                              |    5
+ b/codecs/codec_gsm.c                                                          |   29
+ b/codecs/codec_ilbc.c                                                         |   28
+ b/codecs/codec_lpc10.c                                                        |   41
+ b/codecs/codec_speex.c                                                        |   60
+ b/configure                                                                   |   63
+ b/configure.ac                                                                |    6
+ b/contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py |   22
+ b/contrib/realtime/mssql/mssql_config.sql                                     |    8
+ b/contrib/realtime/mysql/mysql_config.sql                                     |    6
+ b/contrib/realtime/oracle/oracle_config.sql                                   |    8
+ b/contrib/realtime/postgresql/postgresql_config.sql                           |    6
+ b/contrib/scripts/astversion                                                  |  536 ++
+ b/contrib/scripts/install_prereq                                              |    2
+ b/include/asterisk/autoconfig.h.in                                            |    3
+ b/include/asterisk/format.h                                                   |   23
+ b/include/asterisk/logger.h                                                   |   44
+ b/include/asterisk/res_pjsip.h                                                |   40
+ b/include/asterisk/res_pjsip_session.h                                        |    6
+ b/include/asterisk/rtp_engine.h                                               |   18
+ b/include/asterisk/stasis_app.h                                               |   15
+ b/main/audiohook.c                                                            |   43
+ b/main/bridge_channel.c                                                       |    7
+ b/main/channel.c                                                              |    9
+ b/main/config_options.c                                                       |    4
+ b/main/dial.c                                                                 |   25
+ b/main/endpoints.c                                                            |    3
+ b/main/format.c                                                               |   11
+ b/main/logger.c                                                               |  272 +
+ b/main/pbx.c                                                                  |  146
+ b/main/rtp_engine.c                                                           |  153
+ b/main/sched.c                                                                |  143
+ b/main/sorcery.c                                                              |    4
+ b/main/stasis_endpoints.c                                                     |   78
+ b/main/taskprocessor.c                                                        |   12
+ b/main/translate.c                                                            |   55
+ b/main/utils.c                                                                |    4
+ b/res/ari/ari_model_validators.c                                              |  445 ++
+ b/res/ari/ari_model_validators.h                                              |  118
+ b/res/ari/ari_websockets.c                                                    |    9
+ b/res/ari/config.c                                                            |   72
+ b/res/ari/resource_asterisk.c                                                 |  127
+ b/res/ari/resource_asterisk.h                                                 |   63
+ b/res/ari/resource_events.c                                                   |   24
+ b/res/ari/resource_events.h                                                   |    2
+ b/res/parking/parking_applications.c                                          |   65
+ b/res/res_ari.c                                                               |   19
+ b/res/res_ari_asterisk.c                                                      |  300 +
+ b/res/res_ari_events.c                                                        |    6
+ b/res/res_config_sqlite.c                                                     |    8
+ b/res/res_format_attr_silk.c                                                  |   24
+ b/res/res_http_websocket.c                                                    |   80
+ b/res/res_pjsip.c                                                             |  131
+ b/res/res_pjsip/config_global.c                                               |   18
+ b/res/res_pjsip/location.c                                                    |   51
+ b/res/res_pjsip/pjsip_configuration.c                                         |    4
+ b/res/res_pjsip/presence_xml.c                                                |   31
+ b/res/res_pjsip_diversion.c                                                   |    4
+ b/res/res_pjsip_multihomed.c                                                  |   23
+ b/res/res_pjsip_nat.c                                                         |    2
+ b/res/res_pjsip_pidf_digium_body_supplement.c                                 |    2
+ b/res/res_pjsip_pubsub.c                                                      |   80
+ b/res/res_pjsip_sdp_rtp.c                                                     |   70
+ b/res/res_pjsip_session.c                                                     |   37
+ b/res/res_pjsip_t38.c                                                         |   15
+ b/res/res_pjsip_transport_websocket.c                                         |    5
+ b/res/res_rtp_asterisk.c                                                      |   79
+ b/res/res_stasis.c                                                            |   45
+ b/res/res_stasis_device_state.c                                               |   54
+ b/res/stasis/app.c                                                            |  335 +
+ b/res/stasis/app.h                                                            |   15
+ b/res/stasis/messaging.c                                                      |   44
+ b/rest-api-templates/ari_model_validators.c.mustache                          |    2
+ b/rest-api/api-docs/applications.json                                         |    2
+ b/rest-api/api-docs/asterisk.json                                             |  130
+ b/rest-api/api-docs/bridges.json                                              |    2
+ b/rest-api/api-docs/channels.json                                             |    2
+ b/rest-api/api-docs/deviceStates.json                                         |    2
+ b/rest-api/api-docs/endpoints.json                                            |    2
+ b/rest-api/api-docs/events.json                                               |  109
+ b/rest-api/api-docs/mailboxes.json                                            |    2
+ b/rest-api/api-docs/playbacks.json                                            |    2
+ b/rest-api/api-docs/recordings.json                                           |    2
+ b/rest-api/api-docs/sounds.json                                               |    2
+ b/rest-api/resources.json                                                     |    2
+ b/tests/test_core_format.c                                                    |   57
+ 106 files changed, 6435 insertions(+), 2535 deletions(-)
diff --git a/bridges/bridge_holding.c b/bridges/bridge_holding.c
index 2fd79d0..0ef5601 100644
--- a/bridges/bridge_holding.c
+++ b/bridges/bridge_holding.c
@@ -205,7 +205,11 @@ static void participant_entertainment_start(struct ast_bridge_channel *bridge_ch
 	switch(hc->idle_mode) {
 	case IDLE_MODE_MOH:
 		moh_class = ast_bridge_channel_get_role_option(bridge_channel, "holding_participant", "moh_class");
-		ast_moh_start(bridge_channel->chan, moh_class, NULL);
+		if (ast_moh_start(bridge_channel->chan, moh_class, NULL)) {
+			ast_log(LOG_WARNING, "Failed to start moh, starting silence generator instead\n");
+			hc->idle_mode = IDLE_MODE_SILENCE;
+			hc->silence_generator = ast_channel_start_silence_generator(bridge_channel->chan);
+		}
 		break;
 	case IDLE_MODE_RINGING:
 		ast_indicate(bridge_channel->chan, AST_CONTROL_RINGING);
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 953561c..248a7fd 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -4199,7 +4199,7 @@ static int dahdi_digit_begin(struct ast_channel *chan, char digit)
 {
 	struct dahdi_pvt *pvt;
 	int idx;
-	int dtmf = -1;
+	int dtmf;
 	int res;
 
 	pvt = ast_channel_tech_pvt(chan);
@@ -4222,8 +4222,11 @@ static int dahdi_digit_begin(struct ast_channel *chan, char digit)
 		break;
 	}
 #endif
-	if ((dtmf = digit_to_dtmfindex(digit)) == -1)
+	dtmf = digit_to_dtmfindex(digit);
+	if (dtmf == -1) {
+		/* Not a valid DTMF digit */
 		goto out;
+	}
 
 	if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) {
 		char dial_str[] = { 'T', digit, '\0' };
@@ -4233,10 +4236,19 @@ static int dahdi_digit_begin(struct ast_channel *chan, char digit)
 			pvt->dialing = 1;
 		}
 	} else {
-		ast_debug(1, "Channel %s started VLDTMF digit '%c'\n",
-			ast_channel_name(chan), digit);
 		pvt->dialing = 1;
 		pvt->begindigit = digit;
+
+		/* Flush the write buffer in DAHDI to start sending the digit immediately. */
+		dtmf = DAHDI_FLUSH_WRITE;
+		res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &dtmf);
+		if (res) {
+			ast_log(LOG_WARNING, "Unable to flush the DAHDI write buffer to send DTMF on channel %d: %s\n",
+				pvt->channel, strerror(errno));
+		}
+
+		ast_debug(1, "Channel %s started VLDTMF digit '%c'\n",
+			ast_channel_name(chan), digit);
 	}
 
 out:
@@ -8773,39 +8785,52 @@ static int my_dahdi_write(struct dahdi_pvt *p, unsigned char *buf, int len, int
 
 static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
 {
-	struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
+	struct dahdi_pvt *p;
 	int res;
 	int idx;
+
+	/* Write a frame of (presumably voice) data */
+	if (frame->frametype != AST_FRAME_VOICE) {
+		if (frame->frametype != AST_FRAME_IMAGE) {
+			ast_log(LOG_WARNING, "Don't know what to do with frame type '%u'\n",
+				frame->frametype);
+		}
+		return 0;
+	}
+
+	/* Return if it's not valid data */
+	if (!frame->data.ptr || !frame->datalen) {
+		return 0;
+	}
+
+	p = ast_channel_tech_pvt(ast);
+	ast_mutex_lock(&p->lock);
+
 	idx = dahdi_get_index(ast, p, 0);
 	if (idx < 0) {
+		ast_mutex_unlock(&p->lock);
 		ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast_channel_name(ast));
 		return -1;
 	}
 
-	/* Write a frame of (presumably voice) data */
-	if (frame->frametype != AST_FRAME_VOICE) {
-		if (frame->frametype != AST_FRAME_IMAGE)
-			ast_log(LOG_WARNING, "Don't know what to do with frame type '%u'\n", frame->frametype);
-		return 0;
-	}
 	if (p->dialing) {
+		ast_mutex_unlock(&p->lock);
 		ast_debug(5, "Dropping frame since I'm still dialing on %s...\n",
 			ast_channel_name(ast));
 		return 0;
 	}
 	if (!p->owner) {
+		ast_mutex_unlock(&p->lock);
 		ast_debug(5, "Dropping frame since there is no active owner on %s...\n",
 			ast_channel_name(ast));
 		return 0;
 	}
 	if (p->cidspill) {
+		ast_mutex_unlock(&p->lock);
 		ast_debug(5, "Dropping frame since I've still got a callerid spill on %s...\n",
 			ast_channel_name(ast));
 		return 0;
 	}
-	/* Return if it's not valid data */
-	if (!frame->data.ptr || !frame->datalen)
-		return 0;
 
 	if (ast_format_cmp(frame->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
 		if (!p->subs[idx].linear) {
@@ -8826,10 +8851,12 @@ static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
 		}
 		res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 0);
 	} else {
+		ast_mutex_unlock(&p->lock);
 		ast_log(LOG_WARNING, "Cannot handle frames in %s format\n",
 			ast_format_get_name(frame->subclass.format));
 		return -1;
 	}
+	ast_mutex_unlock(&p->lock);
 	if (res < 0) {
 		ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
 		return -1;
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index bb79e84..d7e291d 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -160,10 +160,10 @@ static struct ast_sip_session_supplement chan_pjsip_ack_supplement = {
 static enum ast_rtp_glue_result chan_pjsip_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
 {
 	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
-	struct chan_pjsip_pvt *pvt = channel->pvt;
+	struct chan_pjsip_pvt *pvt;
 	struct ast_sip_endpoint *endpoint;
 
-	if (!pvt || !channel->session || !pvt->media[SIP_MEDIA_AUDIO]->rtp) {
+	if (!channel || !channel->session || !(pvt = channel->pvt) || !pvt->media[SIP_MEDIA_AUDIO]->rtp) {
 		return AST_RTP_GLUE_RESULT_FORBID;
 	}
 
@@ -1762,9 +1762,17 @@ static int hangup(void *data)
 static int chan_pjsip_hangup(struct ast_channel *ast)
 {
 	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
-	struct chan_pjsip_pvt *pvt = channel->pvt;
-	int cause = hangup_cause2sip(ast_channel_hangupcause(channel->session->channel));
-	struct hangup_data *h_data = hangup_data_alloc(cause, ast);
+	struct chan_pjsip_pvt *pvt;
+	int cause;
+	struct hangup_data *h_data;
+
+	if (!channel || !channel->session) {
+		return -1;
+	}
+
+	pvt = channel->pvt;
+	cause = hangup_cause2sip(ast_channel_hangupcause(channel->session->channel));
+	h_data = hangup_data_alloc(cause, ast);
 
 	if (!h_data) {
 		goto failure;
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 1838bda..384e843 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -3717,7 +3717,7 @@ static int __sip_xmit(struct sip_pvt *p, struct ast_str *data)
 	} else if (p->socket.tcptls_session) {
 		res = sip_tcptls_write(p->socket.tcptls_session, ast_str_buffer(data), ast_str_strlen(data));
 	} else if (p->socket.ws_session) {
-		if (!(res = ast_websocket_write(p->socket.ws_session, AST_WEBSOCKET_OPCODE_TEXT, ast_str_buffer(data), ast_str_strlen(data)))) {
+		if (!(res = ast_websocket_write_string(p->socket.ws_session, ast_str_buffer(data)))) {
 			/* The WebSocket API just returns 0 on success and -1 on failure, while this code expects the payload length to be returned */
 			res = ast_str_strlen(data);
 		}
@@ -4318,7 +4318,7 @@ void sip_scheddestroy(struct sip_pvt *p, int ms)
 	}
 	p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p, "setting ref as passing into ast_sched_add for __sip_autodestruct"));
 
-	if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0) {
+	if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > -1) {
 		stop_session_timer(p);
 	}
 }
@@ -7350,7 +7350,7 @@ static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
 		   redirect of both channels). Note that a channel can not be masqueraded *into*
 		   a native bridge. So there is no danger that this breaks a native bridge that
 		   should stay up. */
-		sip_set_rtp_peer(newchan, NULL, NULL, 0, 0, 0);
+		sip_set_rtp_peer(newchan, NULL, NULL, NULL, NULL, 0);
 		ret = 0;
 	}
 	ast_debug(3, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, ast_channel_name(p->owner), ast_channel_name(oldchan));
@@ -12811,9 +12811,6 @@ static void add_codec_to_sdp(const struct sip_pvt *p,
 	} else if (ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) {
 		/* Indicate that we don't support VAD (G.723.1 annex A) */
 		ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code);
-	} else if (ast_format_cmp(format, ast_format_ilbc) == AST_FORMAT_CMP_EQUAL) {
-		/* Add information about us using only 20/30 ms packetization */
-		ast_str_append(a_buf, 0, "a=fmtp:%d mode=%u\r\n", rtp_code, framing);
 	} else if (ast_format_cmp(format, ast_format_siren7) == AST_FORMAT_CMP_EQUAL) {
 		/* Indicate that we only expect 32Kbps */
 		ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=32000\r\n", rtp_code);
@@ -13943,6 +13940,7 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
 	int cid_has_name = 1;
 	int cid_has_num = 1;
 	struct ast_party_id connected_id;
+	int ret;
 
 	if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
 	 	const char *s = p->username;	/* being a string field, cannot be NULL */
@@ -14027,26 +14025,41 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
 
 	ast_copy_string(tmp_l, l, sizeof(tmp_l));
 	if (sip_cfg.pedanticsipchecking) {
-		ast_escape_quoted(n, tmp_n, sizeof(tmp_n));
-		n = tmp_n;
 		ast_uri_encode(l, tmp_l, sizeof(tmp_l), ast_uri_sip_user);
 	}
 
 	ourport = (p->fromdomainport && (p->fromdomainport != STANDARD_SIP_PORT)) ? p->fromdomainport : ast_sockaddr_port(&p->ourip);
 
-	/* If a caller id name was specified, add a display name. */
-	if (cid_has_name || !cid_has_num) {
-		snprintf(from, sizeof(from), "\"%s\" ", n);
+	if (!sip_standard_port(p->socket.type, ourport)) {
+		ret = snprintf(from, sizeof(from), "<sip:%s@%s:%d>;tag=%s", tmp_l, d, ourport, p->tag);
 	} else {
-		from[0] = '\0';
+		ret = snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", tmp_l, d, p->tag);
+	}
+	if (ret < 0 || ret >= sizeof(from)) { /* a return value of size or more means that the output was truncated */
+		/* We don't have an escape path from here... */
+		ast_log(LOG_ERROR, "The From header was truncated in call '%s'. This call setup will fail.\n", p->callid);
 	}
 
-	if (!sip_standard_port(p->socket.type, ourport)) {
-		size_t offset = strlen(from);
-		snprintf(&from[offset], sizeof(from) - offset, "<sip:%s@%s:%d>;tag=%s", tmp_l, d, ourport, p->tag);
-	} else {
-		size_t offset = strlen(from);
-		snprintf(&from[offset], sizeof(from) - offset, "<sip:%s@%s>;tag=%s", tmp_l, d, p->tag);
+	/* If a caller id name was specified, prefix a display name, if there is enough room. */
+	if (cid_has_name || !cid_has_num) {
+		size_t written = strlen(from);
+		ssize_t left = sizeof(from) - written - 4; /* '"" \0' */
+		if (left > 0) {
+			size_t name_len;
+			if (sip_cfg.pedanticsipchecking) {
+				ast_escape_quoted(n, tmp_n, MIN(left + 1, sizeof(tmp_n)));
+				n = tmp_n;
+			}
+			name_len = strlen(n);
+			if (left < name_len) {
+				name_len = left;
+			}
+			memmove(from + name_len + 3, from, written + 1);
+			from[0] = '"';
+			memcpy(from + 1, n, name_len);
+			from[name_len + 1] = '"';
+			from[name_len + 2] = ' ';
+		}
 	}
 
 	if (!ast_strlen_zero(explicit_uri)) {
@@ -14088,21 +14101,25 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
  		/*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */
  		if (!strchr(p->todnid, '@')) {
  			/* We have no domain in the dnid */
- 			snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
+			ret = snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
  		} else {
- 			snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
+			ret = snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
  		}
  	} else {
  		if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) {
  			/* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
-			snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag);
+			ret = snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag);
  		} else if (p->options && p->options->vxml_url) {
  			/* If there is a VXML URL append it to the SIP URL */
- 			snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
+			ret = snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
  		} else {
- 			snprintf(to, sizeof(to), "<%s>", p->uri);
+			ret = snprintf(to, sizeof(to), "<%s>", p->uri);
 		}
  	}
+	if (ret < 0 || ret >= sizeof(to)) { /* a return value of size or more means that the output was truncated */
+		/* We don't have an escape path from here... */
+		ast_log(LOG_ERROR, "The To header was truncated in call '%s'. This call setup will fail.\n", p->callid);
+	}
 
 	init_req(req, sipmethod, p->uri);
 	/* now tmp_n is available so reuse it to build the CSeq */
@@ -22722,7 +22739,7 @@ static void check_pendings(struct sip_pvt *p)
 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 	} else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
 		/* if we can't REINVITE, hold it for later */
-		if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
+		if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > -1) {
 			ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
 		} else {
 			ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid);
@@ -24525,10 +24542,9 @@ static void *sip_pickup_thread(void *stuff)
 	struct ast_channel *chan;
 	chan = stuff;
 
+	ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL_CLEARING);
 	if (ast_pickup_call(chan)) {
 		ast_channel_hangupcause_set(chan, AST_CAUSE_CALL_REJECTED);
-	} else {
-		ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL_CLEARING);
 	}
 	ast_hangup(chan);
 	ast_channel_unref(chan);
@@ -28110,7 +28126,7 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct as
 		res = handle_request_invite(p, req, addr, seqno, recount, e, nounlock);
 
 		if (res < 9) {
-			sip_report_security_event(p, req, res);
+			sip_report_security_event(NULL, &p->recv, p, req, res);
 		}
 
 		switch (res) {
@@ -28149,7 +28165,7 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct as
 		break;
 	case SIP_REGISTER:
 		res = handle_request_register(p, req, addr, e);
-		sip_report_security_event(p, req, res);
+		sip_report_security_event(p->exten, NULL, p, req, res);
 		break;
 	case SIP_INFO:
 		if (req->debug)
@@ -33135,10 +33151,8 @@ static char *sip_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a
 /*! \brief  Part of Asterisk module interface */
 static int reload(void)
 {
-	if (sip_reload(0, 0, NULL)) {
-		return 0;
-	}
-	return 1;
+	sip_reload(0, 0, NULL);
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 /*! \brief  Return the first entry from ast_sockaddr_resolve filtered by address family
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 3d2d2e8..23a4835 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -4863,7 +4863,7 @@ static int skinny_dialer_cb(const void *data)
 {
 	struct skinny_subchannel *sub = (struct skinny_subchannel *)data;
 	SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %u - Dialer called from SCHED %d\n", sub->callid, sub->dialer_sched);
-	sub->dialer_sched = 0;
+	sub->dialer_sched = -1;
 	skinny_dialer(sub, 1);
 	return 0;
 }
@@ -4872,7 +4872,7 @@ static int skinny_autoanswer_cb(const void *data)
 {
 	struct skinny_subchannel *sub = (struct skinny_subchannel *)data;
 	skinny_locksub(sub);
-	sub->aa_sched = 0;
+	sub->aa_sched = -1;
 	setsubstate(sub, SKINNY_CONNECTED);
 	skinny_unlocksub(sub);
 	return 0;
@@ -4882,7 +4882,7 @@ static int skinny_cfwd_cb(const void *data)
 {
 	struct skinny_subchannel *sub = (struct skinny_subchannel *)data;
 	struct skinny_line *l = sub->line;
-	sub->cfwd_sched = 0;
+	sub->cfwd_sched = -1;
 	SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %u - CFWDNOANS to %s.\n", sub->callid, l->call_forward_noanswer);
 	ast_channel_call_forward_set(sub->owner, l->call_forward_noanswer);
 	ast_queue_control(sub->owner, AST_CONTROL_REDIRECTING);
@@ -4924,7 +4924,7 @@ static int skinny_call(struct ast_channel *ast, const char *dest, int timeout)
 	skinny_locksub(sub);
 	AST_LIST_TRAVERSE(ast_channel_varshead(ast), current, entries) {
 		if (!(strcmp(ast_var_name(current), "SKINNY_AUTOANSWER"))) {
-			if (d->hookstate == SKINNY_ONHOOK && !sub->aa_sched) {
+			if (d->hookstate == SKINNY_ONHOOK && sub->aa_sched < 0) {
 				char buf[24];
 				int aatime;
 				char *stringp = buf, *curstr;
@@ -5389,9 +5389,9 @@ static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subli
 			sub->xferor = 0;
 			sub->related = NULL;
 			sub->calldirection = direction;
-			sub->aa_sched = 0;
-			sub->dialer_sched = 0;
-			sub->cfwd_sched = 0;
+			sub->aa_sched = -1;
+			sub->dialer_sched = -1;
+			sub->cfwd_sched = -1;
 			sub->dialType = DIALTYPE_NORMAL;
 			sub->getforward = 0;
 
@@ -5550,17 +5550,17 @@ static void setsubstate(struct skinny_subchannel *sub, int state)
 
 	if (sub->dialer_sched) {
 		skinny_sched_del(sub->dialer_sched, sub);
-		sub->dialer_sched = 0;
+		sub->dialer_sched = -1;
 	}
 
 	if (state != SUBSTATE_RINGIN && sub->aa_sched) {
 		skinny_sched_del(sub->aa_sched, sub);
-		sub->aa_sched = 0;
+		sub->aa_sched = -1;
 		sub->aa_beep = 0;
 		sub->aa_mute = 0;
 	}
 
-	if (sub->cfwd_sched) {
+	if (sub->cfwd_sched > -1) {
 		if (state == SUBSTATE_CONNECTED) {
 			if (skinny_sched_del(sub->cfwd_sched, sub)) {
 				SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %u - trying to change state from %s to %s, but already forwarded because no answer.\n",
@@ -5568,7 +5568,7 @@ static void setsubstate(struct skinny_subchannel *sub, int state)
 				skinny_unlocksub(sub);
 				return;
 			}
-			sub->cfwd_sched = 0;
+			sub->cfwd_sched = -1;
 		} else if (state == SUBSTATE_ONHOOK) {
 			skinny_sched_del(sub->cfwd_sched, sub);
 		}
@@ -6240,7 +6240,7 @@ static int handle_keypad_button_message(struct skinny_req *req, struct skinnyses
 	if ((sub->owner && ast_channel_state(sub->owner) <  AST_STATE_UP)) {
 		if (sub->dialer_sched && !skinny_sched_del(sub->dialer_sched, sub)) {
 			SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %u - Got a digit and not timed out, so try dialing\n", sub->callid);
-			sub->dialer_sched = 0;
+			sub->dialer_sched = -1;
 			len = strlen(sub->exten);
 			if (len == 0) {
 				transmit_stop_tone(d, l->instance, sub->callid);
@@ -7077,7 +7077,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
 			d->name, instance, callreference);
 		if (sub->dialer_sched && !skinny_sched_del(sub->dialer_sched, sub)) {
 			size_t len;
-			sub->dialer_sched = 0;
+			sub->dialer_sched = -1;
 			len = strlen(sub->exten);
 			if (len > 0) {
 				sub->exten[len-1] = '\0';
diff --git a/channels/pjsip/dialplan_functions.c b/channels/pjsip/dialplan_functions.c
index 9c52456..eb6def6 100644
--- a/channels/pjsip/dialplan_functions.c
+++ b/channels/pjsip/dialplan_functions.c
@@ -318,6 +318,9 @@
 				<literal>type</literal> parameter must be provided. It specifies
 				which signalling parameter to read.</para>
 				<enumlist>
+					<enum name="call-id">
+						<para>The SIP call-id.</para>
+					</enum>
 					<enum name="secure">
 						<para>Whether or not the signalling uses a secure transport.</para>
 						<enumlist>
@@ -594,6 +597,8 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const
 	if (ast_strlen_zero(type)) {
 		ast_log(LOG_WARNING, "You must supply a type field for 'pjsip' information\n");
 		return -1;
+	} else if (!strcmp(type, "call-id")) {
+		snprintf(buf, buflen, "%.*s", (int) pj_strlen(&dlg->call_id->id), pj_strbuf(&dlg->call_id->id));
 	} else if (!strcmp(type, "secure")) {
 #ifdef HAVE_PJSIP_GET_DEST_INFO
 		pjsip_host_info dest;
diff --git a/channels/sip/include/security_events.h b/channels/sip/include/security_events.h
index cee2fa7..1d0f58b 100644
--- a/channels/sip/include/security_events.h
+++ b/channels/sip/include/security_events.h
@@ -38,6 +38,7 @@ void sip_report_failed_challenge_response(const struct sip_pvt *p, const char *r
 void sip_report_chal_sent(const struct sip_pvt *p);
 void sip_report_inval_transport(const struct sip_pvt *p, const char *transport);
 void sip_digest_parser(char *c, struct digestkeys *keys);
-int sip_report_security_event(const struct sip_pvt *p, const struct sip_request *req, const int res);
+int sip_report_security_event(const char *peer, struct ast_sockaddr *addr, const struct sip_pvt *p,
+			      const struct sip_request *req, const int res);
 
 #endif
diff --git a/channels/sip/security_events.c b/channels/sip/security_events.c
index 691c5bd..9f5d94f 100644
--- a/channels/sip/security_events.c
+++ b/channels/sip/security_events.c
@@ -270,7 +270,8 @@ void sip_report_inval_transport(const struct sip_pvt *p, const char *transport)
         ast_security_event_report(AST_SEC_EVT(&inval_transport));
 }
 
-int sip_report_security_event(const struct sip_pvt *p, const struct sip_request *req, const int res) {
+int sip_report_security_event(const char *peer, struct ast_sockaddr *addr, const struct sip_pvt *p,
+			      const struct sip_request *req, const int res) {
 
 	struct sip_peer *peer_report;
 	enum check_auth_result res_report = res;
@@ -288,7 +289,7 @@ int sip_report_security_event(const struct sip_pvt *p, const struct sip_request
 		[K_LAST]  = { NULL, NULL}
 	};
 
-	peer_report = sip_find_peer(p->exten, NULL, TRUE, FINDPEERS, FALSE, 0);
+	peer_report = sip_find_peer(peer, addr, TRUE, FINDPEERS, FALSE, p->socket.type);
 
 	switch(res_report) {
 	case AUTH_DONT_KNOW:
diff --git a/codecs/codec_gsm.c b/codecs/codec_gsm.c
index 8cb4943..a18dc0a 100644
--- a/codecs/codec_gsm.c
+++ b/codecs/codec_gsm.c
@@ -39,6 +39,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/config.h"
 #include "asterisk/module.h"
 #include "asterisk/utils.h"
+#include "asterisk/linkedlists.h"
 
 #ifdef HAVE_GSM_HEADER
 #include "gsm.h"
@@ -139,25 +140,35 @@ static int lintogsm_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 static struct ast_frame *lintogsm_frameout(struct ast_trans_pvt *pvt)
 {
 	struct gsm_translator_pvt *tmp = pvt->pvt;
-	int datalen = 0;
-	int samples = 0;
+	struct ast_frame *result = NULL;
+	struct ast_frame *last = NULL;
+	int samples = 0; /* output samples */
 
-	/* We can't work on anything less than a frame in size */
-	if (pvt->samples < GSM_SAMPLES)
-		return NULL;
 	while (pvt->samples >= GSM_SAMPLES) {
+		struct ast_frame *current;
+
 		/* Encode a frame of data */
-		gsm_encode(tmp->gsm, tmp->buf + samples, (gsm_byte *) pvt->outbuf.c + datalen);
-		datalen += GSM_FRAME_LEN;
+		gsm_encode(tmp->gsm, tmp->buf + samples, (gsm_byte *) pvt->outbuf.c);
 		samples += GSM_SAMPLES;
 		pvt->samples -= GSM_SAMPLES;
+
+		current = ast_trans_frameout(pvt, GSM_FRAME_LEN, GSM_SAMPLES);
+		if (!current) {
+			continue;
+		} else if (last) {
+			AST_LIST_NEXT(last, frame_list) = current;
+		} else {
+			result = current;
+		}
+		last = current;
 	}
 
 	/* Move the data at the end of the buffer to the front */
-	if (pvt->samples)
+	if (samples) {
 		memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
+	}
 
-	return ast_trans_frameout(pvt, datalen, samples);
+	return result;
 }
 
 static void gsm_destroy_stuff(struct ast_trans_pvt *pvt)
diff --git a/codecs/codec_ilbc.c b/codecs/codec_ilbc.c
index af23b90..2646f49 100644
--- a/codecs/codec_ilbc.c
+++ b/codecs/codec_ilbc.c
@@ -37,6 +37,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/translate.h"
 #include "asterisk/module.h"
 #include "asterisk/utils.h"
+#include "asterisk/linkedlists.h"
 
 #ifdef ILBC_WEBRTC
 #include <ilbc.h>
@@ -150,31 +151,40 @@ static int lintoilbc_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 static struct ast_frame *lintoilbc_frameout(struct ast_trans_pvt *pvt)
 {
 	struct ilbc_coder_pvt *tmp = pvt->pvt;
-	int datalen = 0;
-	int samples = 0;
+	struct ast_frame *result = NULL;
+	struct ast_frame *last = NULL;
+	int samples = 0; /* output samples */
 
-	/* We can't work on anything less than a frame in size */
-	if (pvt->samples < ILBC_SAMPLES)
-		return NULL;
 	while (pvt->samples >= ILBC_SAMPLES) {
+		struct ast_frame *current;
 		ilbc_block tmpf[ILBC_SAMPLES];
 		int i;
 
 		/* Encode a frame of data */
 		for (i = 0 ; i < ILBC_SAMPLES ; i++)
 			tmpf[i] = tmp->buf[samples + i];
-		iLBC_encode( (ilbc_bytes*)pvt->outbuf.BUF_TYPE + datalen, tmpf, &tmp->enc);
+		iLBC_encode((ilbc_bytes *) pvt->outbuf.BUF_TYPE, tmpf, &tmp->enc);
 
-		datalen += ILBC_FRAME_LEN;
 		samples += ILBC_SAMPLES;
 		pvt->samples -= ILBC_SAMPLES;
+
+		current = ast_trans_frameout(pvt, ILBC_FRAME_LEN, ILBC_SAMPLES);
+		if (!current) {
+			continue;
+		} else if (last) {
+			AST_LIST_NEXT(last, frame_list) = current;
+		} else {
+			result = current;
+		}
+		last = current;
 	}
 
 	/* Move the data at the end of the buffer to the front */
-	if (pvt->samples)
+	if (samples) {
 		memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
+	}
 
-	return ast_trans_frameout(pvt, datalen, samples);
+	return result;
 }
 
 static struct ast_translator ilbctolin = {
diff --git a/codecs/codec_lpc10.c b/codecs/codec_lpc10.c
index ca2eb8e..a62eed3 100644
--- a/codecs/codec_lpc10.c
+++ b/codecs/codec_lpc10.c
@@ -39,6 +39,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/config.h"
 #include "asterisk/module.h"
 #include "asterisk/utils.h"
+#include "asterisk/linkedlists.h"
 
 #include "lpc10/lpc10.h"
 
@@ -160,31 +161,45 @@ static int lintolpc10_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 static struct ast_frame *lintolpc10_frameout(struct ast_trans_pvt *pvt)
 {
 	struct lpc10_coder_pvt *tmp = pvt->pvt;
-	int x;
-	int datalen = 0;	/* output frame */
-	int samples = 0;	/* output samples */
-	float tmpbuf[LPC10_SAMPLES_PER_FRAME];
-	INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];	/* XXX what ??? */
-	/* We can't work on anything less than a frame in size */
-	if (pvt->samples < LPC10_SAMPLES_PER_FRAME)
-		return NULL;
-	while (pvt->samples >=  LPC10_SAMPLES_PER_FRAME) {
+	struct ast_frame *result = NULL;
+	struct ast_frame *last = NULL;
+	int samples = 0; /* output samples */
+
+	while (pvt->samples >= LPC10_SAMPLES_PER_FRAME) {
+		struct ast_frame *current;
+		float tmpbuf[LPC10_SAMPLES_PER_FRAME];
+		INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];	/* XXX what ??? */
+		int x;
+
 		/* Encode a frame of data */
 		for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++)
 			tmpbuf[x] = (float)tmp->buf[x + samples] / 32768.0;
 		lpc10_encode(tmpbuf, bits, tmp->lpc10.enc);
-		build_bits(pvt->outbuf.uc + datalen, bits);
-		datalen += LPC10_BYTES_IN_COMPRESSED_FRAME;
+		build_bits(pvt->outbuf.uc, bits);
+
 		samples += LPC10_SAMPLES_PER_FRAME;
 		pvt->samples -= LPC10_SAMPLES_PER_FRAME;
 		/* Use one of the two left over bits to record if this is a 22 or 23 ms frame...
 		   important for IAX use */
 		tmp->longer = 1 - tmp->longer;
+
+		current = ast_trans_frameout(pvt, LPC10_BYTES_IN_COMPRESSED_FRAME, LPC10_SAMPLES_PER_FRAME);
+		if (!current) {
+			continue;
+		} else if (last) {
+			AST_LIST_NEXT(last, frame_list) = current;
+		} else {
+			result = current;
+		}
+		last = current;
 	}
+
 	/* Move the data at the end of the buffer to the front */
-	if (pvt->samples)
+	if (samples) {
 		memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
-	return ast_trans_frameout(pvt, datalen, samples);
+	}
+
+	return result;
 }
 
 
diff --git a/codecs/codec_speex.c b/codecs/codec_speex.c
index c91070d..c9adceb 100644
--- a/codecs/codec_speex.c
+++ b/codecs/codec_speex.c
@@ -54,6 +54,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/module.h"
 #include "asterisk/config.h"
 #include "asterisk/utils.h"
+#include "asterisk/frame.h"
+#include "asterisk/linkedlists.h"
 
 /* codec variables */
 static int quality = 3;
@@ -259,15 +261,16 @@ static int lintospeex_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 static struct ast_frame *lintospeex_frameout(struct ast_trans_pvt *pvt)
 {
 	struct speex_coder_pvt *tmp = pvt->pvt;
-	int is_speech=1;
-	int datalen = 0;	/* output bytes */
-	int samples = 0;	/* output samples */
+	struct ast_frame *result = NULL;
+	struct ast_frame *last = NULL;
+	int samples = 0; /* output samples */
 
-	/* We can't work on anything less than a frame in size */
-	if (pvt->samples < tmp->framesize)
-		return NULL;
-	speex_bits_reset(&tmp->bits);
 	while (pvt->samples >= tmp->framesize) {
+		struct ast_frame *current;
+		int is_speech = 1;
+
+		speex_bits_reset(&tmp->bits);
+
 #ifdef _SPEEX_TYPES_H
 		/* Preprocess audio */
 		if (preproc)
@@ -293,18 +296,18 @@ static struct ast_frame *lintospeex_frameout(struct ast_trans_pvt *pvt)
 #endif
 		samples += tmp->framesize;
 		pvt->samples -= tmp->framesize;
-	}
 
-	/* Move the data at the end of the buffer to the front */
-	if (pvt->samples)
-		memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
-
-	/* Use AST_FRAME_CNG to signify the start of any silence period */
-	if (is_speech) {
-		tmp->silent_state = 0;
-	} else {
-		if (tmp->silent_state) {
-			return NULL;
+		/* Use AST_FRAME_CNG to signify the start of any silence period */
+		if (is_speech) {
+			int datalen = 0; /* output bytes */
+
+			tmp->silent_state = 0;
+			/* Terminate bit stream */
+			speex_bits_pack(&tmp->bits, 15, 5);
+			datalen = speex_bits_write(&tmp->bits, pvt->outbuf.c, pvt->t->buf_size);
+			current = ast_trans_frameout(pvt, datalen, tmp->framesize);
+		} else if (tmp->silent_state) {
+			current = NULL;
 		} else {
 			struct ast_frame frm = {
 				.frametype = AST_FRAME_CNG,
@@ -320,14 +323,25 @@ static struct ast_frame *lintospeex_frameout(struct ast_trans_pvt *pvt)
 			tmp->silent_state = 1;
 
 			/* XXX what now ? format etc... */
-			return ast_frisolate(&frm);
+			current = ast_frisolate(&frm);
 		}
+
+		if (!current) {
+			continue;
+		} else if (last) {
+			AST_LIST_NEXT(last, frame_list) = current;
+		} else {
+			result = current;
+		}
+		last = current;
+	}
+
+	/* Move the data at the end of the buffer to the front */
+	if (samples) {
+		memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
 	}
 
-	/* Terminate bit stream */
-	speex_bits_pack(&tmp->bits, 15, 5);
-	datalen = speex_bits_write(&tmp->bits, pvt->outbuf.c, pvt->t->buf_size);
-	return ast_trans_frameout(pvt, datalen, samples);
+	return result;
 }
 
 static void speextolin_destroy(struct ast_trans_pvt *arg)
diff --git a/configure b/configure
index e2cf9c9..a0468b9 100755
--- a/configure
+++ b/configure
@@ -1089,6 +1089,10 @@ PBX_DAHDI
 DAHDI_DIR
 DAHDI_INCLUDE
 DAHDI_LIB
+PBX_OPENSSL_ECDH_AUTO
+OPENSSL_ECDH_AUTO_DIR
+OPENSSL_ECDH_AUTO_INCLUDE
+OPENSSL_ECDH_AUTO_LIB
 PBX_OPENSSL_EC
 OPENSSL_EC_DIR
 OPENSSL_EC_INCLUDE
@@ -8696,6 +8700,18 @@ PBX_OPENSSL_EC=0
 
 
 
+OPENSSL_ECDH_AUTO_DESCRIP="OpenSSL Auto ECDH Support"
+OPENSSL_ECDH_AUTO_OPTION=crypto
+OPENSSL_ECDH_AUTO_DIR=${CRYPTO_DIR}
+
+PBX_OPENSSL_ECDH_AUTO=0
+
+
+
+
+
+
+
     DAHDI_DESCRIP="DAHDI"
     DAHDI_OPTION="dahdi"
     PBX_DAHDI=0
@@ -30266,6 +30282,53 @@ fi
 
 fi
 
+if test "$PBX_OPENSSL" = "1";
+then
+
+    if test "x${PBX_OPENSSL_ECDH_AUTO}" != "x1" -a "${USE_OPENSSL_ECDH_AUTO}" != "no"; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_CTX_set_ecdh_auto declared in openssl/ssl.h" >&5
+$as_echo_n "checking for SSL_CTX_set_ecdh_auto declared in openssl/ssl.h... " >&6; }
+        saved_cppflags="${CPPFLAGS}"
+        if test "x${OPENSSL_ECDH_AUTO_DIR}" != "x"; then
+            OPENSSL_ECDH_AUTO_INCLUDE="-I${OPENSSL_ECDH_AUTO_DIR}/include"
+        fi
+        CPPFLAGS="${CPPFLAGS} ${OPENSSL_ECDH_AUTO_INCLUDE}"
+
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+ #include <openssl/ssl.h>
+int
+main ()
+{
+#if !defined(SSL_CTX_set_ecdh_auto)
+                                    (void) SSL_CTX_set_ecdh_auto;
+                                #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+                PBX_OPENSSL_ECDH_AUTO=1
+
+$as_echo "#define HAVE_OPENSSL_ECDH_AUTO 1" >>confdefs.h
+
+
+
+else
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+        CPPFLAGS="${saved_cppflags}"
+    fi
+
+fi
+
 
 if test "x${PBX_SRTP}" != "x1" -a "${USE_SRTP}" != "no"; then
    pbxlibdir=""
diff --git a/configure.ac b/configure.ac
index 971f9bf..3292809 100644
--- a/configure.ac
+++ b/configure.ac
@@ -414,6 +414,7 @@ AST_EXT_LIB_SETUP([CRYPT], [password and data encryption], [crypt])
 AST_EXT_LIB_SETUP([CRYPTO], [OpenSSL Cryptography], [crypto])
 AST_EXT_LIB_SETUP_OPTIONAL([OPENSSL_SRTP], [OpenSSL SRTP Extension Support], [CRYPTO], [crypto])
 AST_EXT_LIB_SETUP_OPTIONAL([OPENSSL_EC], [OpenSSL Elliptic Curve Support], [CRYPTO], [crypto])
+AST_EXT_LIB_SETUP_OPTIONAL([OPENSSL_ECDH_AUTO], [OpenSSL Auto ECDH Support], [CRYPTO], [crypto])
 AST_EXT_LIB_SETUP([DAHDI], [DAHDI], [dahdi])
 AST_EXT_LIB_SETUP([FFMPEG], [Ffmpeg and avcodec], [avcodec])
 AST_EXT_LIB_SETUP([GSM], [External GSM], [gsm], [, use 'internal' GSM otherwise])
@@ -2283,6 +2284,11 @@ then
 	AST_EXT_LIB_CHECK([OPENSSL_EC], [ssl], [EC_KEY_new_by_curve_name], [openssl/ec.h], [-lcrypto])
 fi
 
+if test "$PBX_OPENSSL" = "1";
+then
+        AST_C_DECLARE_CHECK([OPENSSL_ECDH_AUTO], [SSL_CTX_set_ecdh_auto], [openssl/ssl.h])
+fi
+
 AST_EXT_LIB_CHECK([SRTP], [srtp], [srtp_init], [srtp/srtp.h])
 
 if test "$PBX_SRTP" = "1";
diff --git a/contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py b/contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py
new file mode 100644
index 0000000..7e6cf99
--- /dev/null
+++ b/contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py
@@ -0,0 +1,22 @@
+"""add default_from_user
+
+Revision ID: 154177371065
+Revises: 26f10cadc157
+Create Date: 2015-09-04 14:13:59.195013
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '154177371065'
+down_revision = '26f10cadc157'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+    op.add_column('ps_globals', sa.Column('default_from_user', sa.String(80)))
+
+
+def downgrade():
+    op.drop_column('ps_globals', 'default_from_user')
diff --git a/contrib/realtime/mssql/mssql_config.sql b/contrib/realtime/mssql/mssql_config.sql
index 9e80689..cd632c1 100644
--- a/contrib/realtime/mssql/mssql_config.sql
+++ b/contrib/realtime/mssql/mssql_config.sql
@@ -1064,7 +1064,13 @@ ALTER TABLE ps_endpoints ADD rtp_timeout_hold INTEGER NULL;
 
 GO
 
-INSERT INTO alembic_version (version_num) VALUES ('26f10cadc157');
+-- Running upgrade 26f10cadc157 -> 154177371065
+
+ALTER TABLE ps_globals ADD default_from_user VARCHAR(80) NULL;
+
+GO
+
+INSERT INTO alembic_version (version_num) VALUES ('154177371065');
 
 GO
 
diff --git a/contrib/realtime/mysql/mysql_config.sql b/contrib/realtime/mysql/mysql_config.sql
index 2ca8baf..95b0fb4 100644
--- a/contrib/realtime/mysql/mysql_config.sql
+++ b/contrib/realtime/mysql/mysql_config.sql
@@ -761,3 +761,9 @@ ALTER TABLE ps_endpoints ADD COLUMN rtp_timeout_hold INTEGER;
 
 UPDATE alembic_version SET version_num='26f10cadc157';
 
+-- Running upgrade 26f10cadc157 -> 154177371065
+
+ALTER TABLE ps_globals ADD COLUMN default_from_user VARCHAR(80);
+
+UPDATE alembic_version SET version_num='154177371065';
+
diff --git a/contrib/realtime/oracle/oracle_config.sql b/contrib/realtime/oracle/oracle_config.sql
index 34e07c0..be195d8 100644
--- a/contrib/realtime/oracle/oracle_config.sql
+++ b/contrib/realtime/oracle/oracle_config.sql
@@ -1066,7 +1066,13 @@ ALTER TABLE ps_endpoints ADD rtp_timeout_hold INTEGER
 
 /
 
-INSERT INTO alembic_version (version_num) VALUES ('26f10cadc157')
+-- Running upgrade 26f10cadc157 -> 154177371065
+
+ALTER TABLE ps_globals ADD default_from_user VARCHAR2(80 CHAR)
+
+/
+
+INSERT INTO alembic_version (version_num) VALUES ('154177371065')
 
 /
 
diff --git a/contrib/realtime/postgresql/postgresql_config.sql b/contrib/realtime/postgresql/postgresql_config.sql
index 3e1f9ed..11eed62 100644
--- a/contrib/realtime/postgresql/postgresql_config.sql
+++ b/contrib/realtime/postgresql/postgresql_config.sql
@@ -777,7 +777,11 @@ ALTER TABLE ps_endpoints ADD COLUMN rtp_timeout INTEGER;
 
 ALTER TABLE ps_endpoints ADD COLUMN rtp_timeout_hold INTEGER;
 
-INSERT INTO alembic_version (version_num) VALUES ('26f10cadc157');
+-- Running upgrade 26f10cadc157 -> 154177371065
+
+ALTER TABLE ps_globals ADD COLUMN default_from_user VARCHAR(80);
+
+INSERT INTO alembic_version (version_num) VALUES ('154177371065');
 
 COMMIT;
 
diff --git a/contrib/scripts/astversion b/contrib/scripts/astversion
new file mode 100755
index 0000000..a17c696
--- /dev/null
+++ b/contrib/scripts/astversion
@@ -0,0 +1,536 @@
+#!/bin/bash
+#
+# astversion - determine version/source of components
+#
+# use: astverion {options}
+#
+# options:
+#         --prefix=PATH  - specify prefix from build
+#         --exec=PATH    - specify asterisk executable
+#         --lib=PATH     - specify asterisk library path
+#         --src=PATH     - specify source path to search
+#
+# Copyright (c) 2015, Digium, Inc.
+#
+# Written by Scott Griepentrog <sgriepentrog at digium.com>
+#
+# Distributed under the terms of the GNU General Public License
+
+# condense list of files when more than X in a set
+CONDENSE=3
+
+# libraries to provide the source/version of
+LIBRARIES=(
+	libasteriskssl.so.1
+	libspandsp.so.2
+	libpjsip.so.2
+	libpri.so.1.4
+)
+
+# possible library locations
+LIB_PATHS=(
+	/usr/lib
+	/usr/lib64
+	/lib
+	/lib64
+	/usr/local/lib
+	/usr/local/lib64
+	/opt/lib
+	/opt/lib64
+)
+
+# collection of files to search for
+FILES=()
+
+# source directories to search
+SRC_DIRS=()
+
+main()
+{
+	TMPFILE="/tmp/astversion.$$"
+
+	sanity_check
+	locate_files "$@"
+	locate_libraries
+	locate_modules
+
+	echo "Checking Asterisk versions on $HOSTNAME at $(date)"
+	check_asterisk_version
+	check_dahdi_version
+
+	gather_packages
+	if [ ! -z "$DISTRO" ]
+	then
+		search_packages
+	else
+		echo "WARNING: Unable to determine distro, skipping package search"
+	fi
+	search_source
+	show_unknown_files
+
+	rm -f $TMPFILE
+}
+
+sanity_check()
+{
+	# insure that needed tools are present
+	TOOLS=(uname basename fgrep cut head readlink find)
+	# making assumption that rpm and dpkg always exist on their platforms
+
+	for TOOL in ${TOOLS[@]}
+	do
+		if ! which $TOOL > /dev/null
+		then
+			echo "ERROR: please install package for $TOOL"
+			exit 1
+		fi
+	done
+}
+
+locate_files()
+{
+	# guess prefix from executable path
+	SCRIPT_PREFIX="$(readlink -f ${0%/sbin/astversion} 2>/dev/null)"
+	if [ -x $SCRIPT_PREFIX/sbin/asterisk ]
+	then
+		PREFIX=$SCRIPT_PREFIX
+		ASTERISK_PATH=$SCRIPT_PREFIX/sbin/asterisk
+	fi
+	if [ -z "$ASTERISK_PATH" ]
+	then
+		ASTERISK_PATH=$(readlink -f $(which asterisk 2>/dev/null) 2>/dev/null)
+		PREFIX=${ASTERISK_PATH%/sbin/asterisk}
+	fi
+
+	# parse user supplied information
+	USER_PREFIX=""
+	USER_EXEC=""
+	for opt in "$@"
+	do
+		case "$opt" in
+		-h|--help)
+			echo "Use: astversion {--prefix=PATH} {--exec=PATH} {--lib=PATH}"
+			exit 0
+			;;
+		--prefix=*)
+			USER_PREFIX=${opt:9}
+			;;
+		--exec=*)
+			USER_EXEC=${opt:7}
+			;;
+		--lib=*)
+			LIBDIR=${opt:6}
+			;;
+		--src=*)
+			SRC_DIRS+=${opt:6}
+			;;
+		*)
+			echo "ERROR: Unknown option: $opt"
+			exit 1
+			;;
+		esac
+	done
+
+	# apply user supplied values
+	if [ ! -z "$USER_PREFIX" ]
+	then
+		PREFIX="$USER_PREFIX"
+		ASTERISK_PATH=""
+	fi
+	if [ ! -z "$USER_EXEC" ]
+	then
+		ASTERISK_PATH="$USER_EXEC"
+	fi
+
+	# locate asterisk executable
+	if [ -z "$ASTERISK_PATH" ]
+	then
+		ASTERISK_PATH="$PREFIX/sbin/asterisk"
+	fi
+	if [ ! -x "$ASTERISK_PATH" ]
+	then
+		echo "ERROR: the Asterisk executable is not found or not executable at $ASTERISK_PATH"
+		exit 1
+	fi
+	FILES+=($ASTERISK_PATH)
+
+	# locate dahdi_cfg executable
+	DAHDI_CFG_PATH=$(readlink -f $(which dahdi_cfg 2>/dev/null) 2>/dev/null)
+	if [ ! -z "$DAHDI_CFG_PATH" ]
+	then
+		FILES+=($DAHDI_CFG_PATH)
+	fi
+
+	# locate asterisk libdir
+	if [ -z "$LIBDIR" ]
+	then
+		LIBDIR="$PREFIX/lib"
+		if [ `uname -m` = "x86_64" -a -d "$PREFIX/lib64" ]
+		then
+			LIBDIR="$PREFIX/lib64"
+		fi
+	fi
+
+	if [ ! -d "$LIBDIR/asterisk/modules" ]
+	then
+		echo "ERROR: asterisk module directory not found at $LIBDIR"
+		exit 1
+	fi
+}
+
+locate_libraries()
+{
+	# LIBDIR should contain libasteriskssl, but others may be elsewhere
+
+	# add LIBDIR to path list
+	if ! [[ " ${LIB_PATHS[@]} " =~ " $LIBDIR " ]]
+	then
+		LIB_PATHS+=($LIBDIR)
+	fi
+
+	for LIBRARY in ${LIBRARIES[@]}
+	do
+		FOUND_LIB=()
+		for LIB_PATH in ${LIB_PATHS[@]}
+		do
+			FULL_PATH="$LIB_PATH/$LIBRARY"
+			if [ ! -L $LIB_PATH -a -f $FULL_PATH ]
+			then
+				FOUND_LIB+=($FULL_PATH)
+				FILES+=($FULL_PATH)
+			fi
+		done
+
+		if [ ${#FOUND_LIB[@]} -gt 1 ]
+		then
+			echo "### WARNING: duplicate libraries found: ${FOUND_LIB[@]}"
+		fi
+	done
+}
+
+check_asterisk_version()
+{
+	# get the version that the executable says it is
+	echo "Using Asterisk executable: $ASTERISK_PATH"
+	AST_EXEC_VER=$($ASTERISK_PATH -V)
+	if [ -z "$AST_EXEC_VER" ]
+	then
+		echo "### ERROR: Unable to find Asterisk version from executable"
+		exit 1
+	fi
+	if [ "${AST_EXEC_VER:0:9}" != "Asterisk " ]
+	then
+		echo "### ERROR: Unexpected version from executable: $AST_EXEC_VER"
+		exit 1
+	fi
+
+	# compare with the version that is running
+	if ! $ASTERISK_PATH -rx "core show version" > $TMPFILE 2>/dev/null
+	then
+		echo "Installed version: $AST_EXEC_VER"
+		echo "Asterisk is not running - more details are available when running."
+		AST_RUN_VER=""
+	else
+		AST_RUN_VER=$(grep '^Asterisk [^e][^n][^d]' < $TMPFILE)
+		if [ -z "$AST_RUN_VER" ]
+		then
+			echo "### ERROR: Unable to find Asterisk version from running instance"
+			exit 1
+		fi
+
+		# is it running the same version? (note: space is significant!)
+		if ! fgrep "$AST_EXEC_VER " < $TMPFILE > /dev/null
+		then
+			echo "Installed version: $AST_EXEC_VER"
+			echo "### WARNING: Asterisk is running different version:"
+		fi
+		echo "$AST_RUN_VER"
+	fi
+}
+
+check_dahdi_version()
+{
+	if [ ! -f /sys/module/dahdi/version ]
+	then
+		echo "Dahdi kernel module is not installed"
+	else
+		DAHDI_KERNEL=$(cat /sys/module/dahdi/version)
+		echo "Dahdi kernel module version: $DAHDI_KERNEL"
+	fi
+
+	if ! which dahdi_cfg >&/dev/null
+	then
+		echo "Dahdi tools are not installed"
+	else
+		DAHDI_TOOLS=$(dahdi_cfg -v |& head -1)
+		echo "$DAHDI_TOOLS"
+	fi
+
+	if $ASTERISK_PATH -rx "dahdi show version" > $TMPFILE 2>/dev/null
+	then
+		DAHDI_CLI=$(grep ^DAHDI $TMPFILE)
+		# may be empty if dahdi not installed
+		if [ ! -z "$DAHDI_CLI" ]
+		then
+			echo "Asterisk reports: $DAHDI_CLI"
+		else
+			echo "Asterisk reports that Dahdi is not available"
+		fi
+	fi
+}
+
+scan_package_redhat()
+{
+	PKGNAME="$1"
+
+	if ! rpm -q $PKGNAME > /tmp/astversion-$PKGNAME-version
+	then
+		rm -f /tmp/astversion-$PKGNAME-version
+		return 2
+	fi
+
+	rpm -ql $PKGNAME > /tmp/astversion-$PKGNAME-files
+	rpm -V $PKGNAME > /tmp/astversion-$PKGNAME-verify
+	return 0
+}
+
+scan_package_debian()
+{
+	PKGNAME="$1"
+
+	if ! dpkg -s $PKGNAME > $TMPFILE
+	then
+		rm -f /tmp/astversion-$PKGNAME-version
+		return 2
+	fi
+
+	# prefix the version with the package name to mimic rpm
+	echo -n "$PKGNAME " > /tmp/astversion-$PKGNAME-version
+	cat $TMPFILE | fgrep Version |cut -d ' ' -f2 >> /tmp/astversion-$PKGNAME-version
+
+	dpkg -L $PKGNAME > /tmp/astversion-$PKGNAME-files
+	dpkg -V $PKGNAME > /tmp/astversion-$PKGNAME-verify
+}
+
+package_has_file()
+{
+	PKGNAME="$1"
+	PKGFILE="$2"
+
+	if [ ! -f /tmp/astversion-$PKGNAME-version ]
+	then
+		return 1
+	fi
+
+	if [ ! -f /tmp/astversion-$PKGNAME-files ]
+	then
+		return 2
+	fi
+
+	if ! fgrep "$PKGFILE" /tmp/astversion-$PKGNAME-files >/dev/null
+	then
+		# package doesn't have that file
+		return 3
+	fi
+
+	if fgrep "$PKGFILE" /tmp/astversion-$PKGNAME-verify >/dev/null
+	then
+		# file does not match package
+		return 4
+	fi
+
+	return 0
+}
+
+
+gather_packages()
+{
+	# build a list of installed packages that are likely to contain files of interest
+	PACKAGES=()
+	SEARCH=(asterisk dahdi libpri pjproject spandsp)
+	DISTRO=""
+
+	if [ -f /etc/redhat-release ]
+	then
+		DISTRO="redhat"
+		for NAME in ${SEARCH[@]}
+		do
+			PACKAGES+=($(rpm -qa |fgrep $NAME))
+		done
+	fi
+
+	if [ -f /etc/debian_version ]
+	then
+		DISTRO="debian"
+		for NAME in ${SEARCH[@]}
+		do
+			PACKAGES+=($(dpkg --get-selections |cut -f1 |fgrep $NAME))
+		done
+	fi
+}
+
+locate_modules()
+{
+	# build a list of files that need to be located
+	MODULES=($LIBDIR/asterisk/modules/*.so)
+
+	# add libraries and binaries that exist to the files list
+	for MODULE in ${MODULES[@]}
+	do
+		FILES+=($MODULE)
+	done
+}
+
+search_packages()
+{
+	# search each package and report files that match
+	for PACKAGE in ${PACKAGES[@]}
+	do
+		scan_package_$DISTRO "$PACKAGE"
+		PKGVERSION=$(cat /tmp/astversion-$PKGNAME-version)
+
+		FOUND=()
+		for FILE in ${FILES[@]}
+		do
+			if package_has_file "$PACKAGE" "$FILE"
+			then
+				FOUND+=($FILE)
+				FILES=(${FILES[@]/$FILE/})
+			fi
+		done
+
+		if [ ! -z "$FOUND" ]
+		then
+			if [ ${#FOUND[@]} -le $CONDENSE ]
+			then
+				for FILEFOUND in ${FOUND[@]}
+				do
+					echo "Matched $FILEFOUND to package $PKGVERSION"
+				done
+			else
+				echo "Matched ${#FOUND[@]} files to package $PKGVERSION"
+			fi
+		fi
+
+		rm -f /tmp/astversion-$PKGNAME-version
+		rm -f /tmp/astversion-$PKGNAME-files
+		rm -f /tmp/astversion-$PKGNAME-verify
+	done
+}
+
+search_source()
+{
+	# look for source path locally (compiled on this machine)
+	# - scan elfs for compilation directory
+	# - compare the file to confirm match
+	if [ -z "$FILES" ]
+	then
+		return
+	fi
+
+	# skip this check when without readelf tool (fedora 22)
+	if ! which readelf >& /dev/null
+	then
+		echo "Warning: skipping source detection because readelf utility is not available"
+		return
+	fi
+
+	# build a list of source paths
+	DIRS=()
+	for FILE in ${FILES[@]}
+	do
+		DEBUG_ELF=$(readelf -wi $FILE |fgrep DW_AT_comp_dir |head -1)
+		COMP_DIR=${DEBUG_ELF##* }
+		DIR=${COMP_DIR//[[:space:]]/}
+		if [ -d $DIR ]
+		then
+			if ! [[ " ${DIRS[@]} " =~ " $DIR " ]]
+			then
+				DIRS+=($DIR)
+			fi
+		fi
+	done
+
+	# add in user specified directories last
+	for DIR in ${SRC_DIRS[@]}
+	do
+		if ! [[ " ${DIRS[@]} " =~ " $DIR " ]]
+		then
+			DIRS+=($DIR)
+		fi
+	done
+
+	# for each source path, look for target file
+	for DIR in ${DIRS[@]}
+	do
+		FOUND=()
+		for FILE in ${FILES[@]}
+		do
+			BINARY_FILE=$(basename $FILE)
+			BINARY_PATH="$DIR/$BINARY_FILE"
+			if [ ! -f "$BINARY_PATH" ]
+			then
+				# it may be hiding somewhere
+				FIND_BINARY=$(find $DIR -name $BINARY_FILE |head -1)
+				if [ ! -z "$FIND_BINARY" ]
+				then
+					BINARY_PATH=$FIND_BINARY
+				fi
+			fi
+			if [ -f "$BINARY_PATH" ]
+			then
+				if cmp $BINARY_PATH $FILE >/dev/null
+				then
+					FOUND+=($FILE)
+					FILES=(${FILES[@]/$FILE/})
+				fi
+			fi
+		done
+
+		if [ ! -z "$FOUND" ]
+		then
+			if [ ${#FOUND[@]} -le $CONDENSE ]
+			then
+				for FILEFOUND in ${FOUND[@]}
+				do
+					echo "Located $FILEFOUND compiled from $DIR"
+				done
+			else
+				echo "Located ${#FOUND[@]} files compiled from $DIR"
+			fi
+		fi
+	done
+}
+
+show_unknown_files()
+{
+	# show a warning for any remaining files unaccounted for
+	if [ -z "$FILES" ]
+	then
+		echo "Success: all files accounted for."
+	else
+		echo ""
+		echo "WARNING: source of the following files was not found:"
+		if ! which readelf >& /dev/null
+		then
+			for FILE in ${FILES[@]}
+			do
+				echo "     ### $FILE"
+			done
+		else
+			for FILE in ${FILES[@]}
+			do
+				DEBUG_ELF=$(readelf -wi $FILE |fgrep DW_AT_comp_dir |head -1)
+				if [ -z "$DEBUG_ELF" ]
+				then
+					COMP_DIR="(no debug info)"
+				else
+					COMP_DIR=${DEBUG_ELF##* }
+				fi
+				echo "     ### $FILE - $COMP_DIR"
+			done
+		fi
+	fi
+}
+
+main "$@"
diff --git a/contrib/scripts/install_prereq b/contrib/scripts/install_prereq
index 58ef05c..4639478 100755
--- a/contrib/scripts/install_prereq
+++ b/contrib/scripts/install_prereq
@@ -31,7 +31,7 @@ PACKAGES_DEBIAN="$PACKAGES_DEBIAN libresample-dev libc-client-dev binutils-dev l
 PACKAGES_DEBIAN="$PACKAGES_DEBIAN subversion git libxslt1-dev"
 PACKAGES_RH="automake gcc gcc-c++ ncurses-devel openssl-devel libxml2-devel unixODBC-devel libcurl-devel libogg-devel libvorbis-devel speex-devel"
 PACKAGES_RH="$PACKAGES_RH spandsp-devel freetds-devel net-snmp-devel iksemel-devel corosynclib-devel newt-devel popt-devel libtool-ltdl-devel lua-devel"
-PACKAGES_RH="$PACKAGES_RH libsqlite3x-devel radiusclient-ng-devel portaudio-devel postgresql-devel libresample-devel neon-devel libical-devel"
+PACKAGES_RH="$PACKAGES_RH sqlite-devel libsqlite3x-devel radiusclient-ng-devel portaudio-devel postgresql-devel libresample-devel neon-devel libical-devel"
 PACKAGES_RH="$PACKAGES_RH openldap-devel gmime22-devel sqlite2-devel mysql-devel bluez-libs-devel jack-audio-connection-kit-devel gsm-devel libedit-devel libuuid-devel"
 PACKAGES_RH="$PACKAGES_RH jansson-devel libsrtp-devel pjproject-devel subversion git libxslt-devel"
 
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index 4efff1f..542f5d2 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -548,6 +548,9 @@
 /* Define to 1 if CRYPTO has the OpenSSL Elliptic Curve Support feature. */
 #undef HAVE_OPENSSL_EC
 
+/* Define if your system has SSL_CTX_set_ecdh_auto declared. */
+#undef HAVE_OPENSSL_ECDH_AUTO
+
 /* Define to 1 if CRYPTO has the OpenSSL SRTP Extension Support feature. */
 #undef HAVE_OPENSSL_SRTP
 
diff --git a/include/asterisk/format.h b/include/asterisk/format.h
index 3da2d82..2ce1b97 100644
--- a/include/asterisk/format.h
+++ b/include/asterisk/format.h
@@ -120,6 +120,18 @@ struct ast_format_interface {
 	 */
 	void (* const format_generate_sdp_fmtp)(const struct ast_format *format, unsigned int payload,
 		struct ast_str **str);
+
+	/*!
+	 * \since 13.6.0
+	 * \brief Retrieve a particular format attribute setting
+	 *
+	 * \param format The format containing attributes
+	 * \param name The name of the attribute to retrieve
+	 *
+	 * \retval NULL if the parameter is not set on the format
+	 * \retval non-NULL the format attribute value
+	 */
+	const void *(* const format_attribute_get)(const struct ast_format *format, const char *name);
 };
 
 /*!
@@ -204,6 +216,17 @@ struct ast_format *ast_format_attribute_set(const struct ast_format *format, con
 	const char *value);
 
 /*!
+ * \since 13.6.0
+ *
+ * \param format The format to retrieve the attribute from
+ * \param name Attribute name
+ *
+ * \retval non-NULL the attribute value
+ * \retval NULL the attribute does not exist or is unset
+ */
+const void *ast_format_attribute_get(const struct ast_format *format, const char *name);
+
+/*!
  * \brief This function is used to have a media format aware module parse and interpret
  * SDP attribute information. Once interpreted this information is stored on the format
  * itself using Asterisk format attributes.
diff --git a/include/asterisk/logger.h b/include/asterisk/logger.h
index 2215115..d06aecf 100644
--- a/include/asterisk/logger.h
+++ b/include/asterisk/logger.h
@@ -45,6 +45,13 @@ extern "C" {
 
 #define AST_CALLID_BUFFER_LENGTH 13
 
+enum ast_logger_results {
+	AST_LOGGER_SUCCESS = 0, /*!< Log channel was created or deleted successfully*/
+	AST_LOGGER_FAILURE = 1, /*!< Log channel already exists for create or doesn't exist for deletion of log channel */
+	AST_LOGGER_DECLINE = -1, /*!< Log channel request was not accepted */
+	AST_LOGGER_ALLOC_ERROR = -2 /*!< filename allocation error */
+};
+
 /*! \brief Used for sending a log message
 	This is the standard logger function.  Probably the only way you will invoke it would be something like this:
 	ast_log(AST_LOG_WHATEVER, "Problem with the %s Captain.  We should get some more.  Will %d be enough?\n", "flux capacitor", 10);
@@ -92,6 +99,36 @@ void ast_log_callid(int level, const char *file, int line, const char *function,
 	__attribute__((format(printf, 6, 7)));
 
 /*!
+ * \brief Retrieve the existing log channels
+ * \param logentry A callback to an updater function
+ * \param data Data passed into the callback for manipulation
+ *
+ * For each of the logging channels, logentry will be executed with the
+ * channel file name, log type, status of the log, and configuration levels.
+ *
+ * \retval 0 on success
+ * \retval 1 on failure
+ * \retval -2 on allocation error
+ */
+int ast_logger_get_channels(int (*logentry)(const char *channel, const char *type,
+	const char *status, const char *configuration, void *data), void *data);
+
+/*!
+ * \brief Create a log channel
+ *
+ * \param log_channel Log channel to create
+ * \param components Logging config levels to add to the log channel
+ */
+int ast_logger_create_channel(const char *log_channel, const char *components);
+
+/*!
+ * \brief Delete the specified log channel
+ *
+ * \param log_channel The log channel to delete
+ */
+int ast_logger_remove_channel(const char *log_channel);
+
+/*!
  * \brief Log a backtrace of the current thread's execution stack to the Asterisk log
  */
 void ast_log_backtrace(void);
@@ -102,6 +139,13 @@ int logger_reload(void);
 /*! \brief Reload logger while rotating log files */
 int ast_logger_rotate(void);
 
+/*!
+ * \brief Rotate the specified log channel.
+ *
+ * \param log_channel The log channel to rotate
+ */
+int ast_logger_rotate_channel(const char *log_channel);
+
 void __attribute__((format(printf, 5, 6))) ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...);
 
 /*!
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 7c7b058..a36935d 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -2039,6 +2039,19 @@ char *ast_sip_get_debug(void);
  */
 char *ast_sip_get_endpoint_identifier_order(void);
 
+/*!
+ * \brief Retrieve the global default from user.
+ *
+ * This is the value placed in outbound requests' From header if there
+ * is no better option (such as an endpoint-configured from_user or
+ * caller ID number).
+ *
+ * \param[out] from_user The default from user
+ * \param size The buffer size of from_user
+ * \return nothing
+ */
+void ast_sip_get_default_from_user(char *from_user, size_t size);
+
 /*! \brief Determines whether the res_pjsip module is loaded */
 #define CHECK_PJSIP_MODULE_LOADED()				\
 	do {							\
@@ -2071,4 +2084,31 @@ unsigned int ast_sip_get_max_initial_qualify_time(void);
 const char *ast_sip_get_contact_status_label(const enum ast_sip_contact_status_type status);
 const char *ast_sip_get_contact_short_status_label(const enum ast_sip_contact_status_type status);
 
+/*!
+ * \brief Retrieve the local host address in IP form
+ *
+ * \param af The address family to retrieve
+ * \param addr A place to store the local host address
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ *
+ * \since 13.6.0
+ */
+int ast_sip_get_host_ip(int af, pj_sockaddr *addr);
+
+/*!
+ * \brief Retrieve the local host address in string form
+ *
+ * \param af The address family to retrieve
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ *
+ * \since 13.6.0
+ *
+ * \note An empty string may be returned if the address family is valid but no local address exists
+ */
+const char *ast_sip_get_host_ip_string(int af);
+
 #endif /* _RES_PJSIP_H */
diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h
index 2893f66..ddc87b0 100644
--- a/include/asterisk/res_pjsip_session.h
+++ b/include/asterisk/res_pjsip_session.h
@@ -355,6 +355,12 @@ struct ast_sip_session_sdp_handler {
 	int (*apply_negotiated_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream,
 		const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream);
 	/*!
+	 * \brief Stop a session_media created by this handler but do not destroy resources
+	 * \param session The session for which media is being stopped
+	 * \param session_media The media to destroy
+	 */
+	void (*stream_stop)(struct ast_sip_session_media *session_media);
+	/*!
 	 * \brief Destroy a session_media created by this handler
 	 * \param session The session for which media is being destroyed
 	 * \param session_media The media to destroy
diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h
index b7ac2a1..80183ed 100644
--- a/include/asterisk/rtp_engine.h
+++ b/include/asterisk/rtp_engine.h
@@ -1,4 +1,4 @@
- /*
+/*
  * Asterisk -- An open source telephony toolkit.
  *
  * Copyright (C) 1999 - 2009, Digium, Inc.
@@ -78,14 +78,13 @@ extern "C" {
 #include "asterisk/stasis.h"
 #include "asterisk/vector.h"
 
-/* Maximum number of payloads supported */
-#if defined(LOW_MEMORY)
+/*! Maximum number of payload types RTP can support. */
 #define AST_RTP_MAX_PT 128
-#else
-#define AST_RTP_MAX_PT 196
-#endif
 
-/* Maximum number of generations */
+/*! First dynamic RTP payload type */
+#define AST_RTP_PT_FIRST_DYNAMIC 96
+
+/*! Maximum number of generations */
 #define AST_RED_MAX_GENERATION 5
 
 /*!
@@ -625,7 +624,7 @@ struct ast_rtp_glue {
 	enum ast_rtp_glue_result (*get_trtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance);
 	/*! Callback for updating the destination that the remote side should send RTP to */
 	int (*update_peer)(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, const struct ast_format_cap *cap, int nat_active);
-	/*! Callback for retrieving codecs that the channel can do.  Result returned in result_cap*/
+	/*! Callback for retrieving codecs that the channel can do.  Result returned in result_cap. */
 	void (*get_codec)(struct ast_channel *chan, struct ast_format_cap *result_cap);
 	/*! Linked list information */
 	AST_RWLIST_ENTRY(ast_rtp_glue) entry;
@@ -1418,7 +1417,7 @@ unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, struct ast_format
  * \code
  * struct ast_format_cap *astformats = ast_format_cap_alloc_nolock()
  * int nonastformats;
- * ast_rtp_codecs_payload_formats(&codecs, &astformats, &nonastformats);
+ * ast_rtp_codecs_payload_formats(&codecs, astformats, &nonastformats);
  * \endcode
  *
  * This retrieves all the formats known about in the codecs structure and puts the Asterisk ones in the integer
@@ -1449,6 +1448,7 @@ void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, struct ast_fo
  * \since 1.8
  */
 int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code);
+
 /*!
  * \brief Search for a payload code in the ast_rtp_codecs structure
  *
diff --git a/include/asterisk/stasis_app.h b/include/asterisk/stasis_app.h
index 567670b..f2b07e0 100644
--- a/include/asterisk/stasis_app.h
+++ b/include/asterisk/stasis_app.h
@@ -92,6 +92,21 @@ struct ao2_container *stasis_app_get_all(void);
 int stasis_app_register(const char *app_name, stasis_app_cb handler, void *data);
 
 /*!
+ * \brief Register a new Stasis application that receives all Asterisk events.
+ *
+ * If an application is already registered with the given name, the old
+ * application is sent a 'replaced' message and unregistered.
+ *
+ * \param app_name Name of this application.
+ * \param handler Callback for application messages.
+ * \param data Data blob to pass to the callback. Must be AO2 managed.
+ *
+ * \return 0 for success
+ * \return -1 for error.
+ */
+int stasis_app_register_all(const char *app_name, stasis_app_cb handler, void *data);
+
+/*!
  * \brief Unregister a Stasis application.
  * \param app_name Name of the application to unregister.
  */
diff --git a/main/audiohook.c b/main/audiohook.c
index 5595e88..93d3521 100644
--- a/main/audiohook.c
+++ b/main/audiohook.c
@@ -253,11 +253,16 @@ static struct ast_frame *audiohook_read_frame_single(struct ast_audiohook *audio
 
 static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audiohook, size_t samples, struct ast_frame **read_reference, struct ast_frame **write_reference)
 {
-	int i = 0, usable_read, usable_write;
-	short buf1[samples], buf2[samples], *read_buf = NULL, *write_buf = NULL, *final_buf = NULL, *data1 = NULL, *data2 = NULL;
+	int count;
+	int usable_read;
+	int usable_write;
+	short adjust_value;
+	short buf1[samples];
+	short buf2[samples];
+	short *read_buf = NULL;
+	short *write_buf = NULL;
 	struct ast_frame frame = {
 		.frametype = AST_FRAME_VOICE,
-		.data.ptr = NULL,
 		.datalen = sizeof(buf1),
 		.samples = samples,
 	};
@@ -290,8 +295,7 @@ static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audioho
 			read_buf = buf1;
 			/* Adjust read volume if need be */
 			if (audiohook->options.read_volume) {
-				int count = 0;
-				short adjust_value = abs(audiohook->options.read_volume);
+				adjust_value = abs(audiohook->options.read_volume);
 				for (count = 0; count < samples; count++) {
 					if (audiohook->options.read_volume > 0) {
 						ast_slinear_saturated_multiply(&buf1[count], &adjust_value);
@@ -311,8 +315,7 @@ static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audioho
 			write_buf = buf2;
 			/* Adjust write volume if need be */
 			if (audiohook->options.write_volume) {
-				int count = 0;
-				short adjust_value = abs(audiohook->options.write_volume);
+				adjust_value = abs(audiohook->options.write_volume);
 				for (count = 0; count < samples; count++) {
 					if (audiohook->options.write_volume > 0) {
 						ast_slinear_saturated_multiply(&buf2[count], &adjust_value);
@@ -326,34 +329,32 @@ static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audioho
 		ast_debug(1, "Failed to get %d samples from write factory %p\n", (int)samples, &audiohook->write_factory);
 	}
 
+	frame.subclass.format = ast_format_cache_get_slin_by_rate(audiohook->hook_internal_samp_rate);
+
 	/* Basically we figure out which buffer to use... and if mixing can be done here */
 	if (read_buf && read_reference) {
-		frame.data.ptr = buf1;
+		frame.data.ptr = read_buf;
 		*read_reference = ast_frdup(&frame);
 	}
 	if (write_buf && write_reference) {
-		frame.data.ptr = buf2;
+		frame.data.ptr = write_buf;
 		*write_reference = ast_frdup(&frame);
 	}
 
-	if (read_buf && write_buf) {
-		for (i = 0, data1 = read_buf, data2 = write_buf; i < samples; i++, data1++, data2++) {
-			ast_slinear_saturated_add(data1, data2);
+	/* Make the correct buffer part of the built frame, so it gets duplicated. */
+	if (read_buf) {
+		frame.data.ptr = read_buf;
+		if (write_buf) {
+			for (count = 0; count < samples; count++) {
+				ast_slinear_saturated_add(read_buf++, write_buf++);
+			}
 		}
-		final_buf = buf1;
-	} else if (read_buf) {
-		final_buf = buf1;
 	} else if (write_buf) {
-		final_buf = buf2;
+		frame.data.ptr = write_buf;
 	} else {
 		return NULL;
 	}
 
-	/* Make the final buffer part of the frame, so it gets duplicated fine */
-	frame.data.ptr = final_buf;
-
-	frame.subclass.format = ast_format_cache_get_slin_by_rate(audiohook->hook_internal_samp_rate);
-
 	/* Yahoo, a combined copy of the audio! */
 	return ast_frdup(&frame);
 }
diff --git a/main/bridge_channel.c b/main/bridge_channel.c
index 3ee04db..8ce0220 100644
--- a/main/bridge_channel.c
+++ b/main/bridge_channel.c
@@ -1914,6 +1914,13 @@ static void bridge_channel_handle_action(struct ast_bridge_channel *bridge_chann
 	default:
 		break;
 	}
+
+	/* While invoking an action it is possible for the channel to be hung up. So
+	 * that the bridge respects this we check here and if hung up kick it out.
+	 */
+	if (bridge_channel->chan && ast_check_hangup_locked(bridge_channel->chan)) {
+		ast_bridge_channel_kick(bridge_channel, 0);
+	}
 }
 
 /*!
diff --git a/main/channel.c b/main/channel.c
index 57523d7..9aeae5f 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -4487,7 +4487,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
 
 	/* Don't bother if the channel is about to go away, anyway. */
 	if ((ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)
-			|| ast_check_hangup(chan))
+			|| (ast_check_hangup(chan) && !ast_channel_is_leaving_bridge(chan)))
 		&& condition != AST_CONTROL_MASQUERADE_NOTIFY) {
 		res = -1;
 		goto indicate_cleanup;
@@ -4656,6 +4656,11 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
 		/* We have a tone to play, yay. */
 		ast_debug(1, "Driver for channel '%s' does not support indication %u, emulating it\n", ast_channel_name(chan), condition);
 		res = ast_playtones_start(chan, 0, ts->data, 1);
+		if (!res) {
+			ast_test_suite_event_notify("RINGING_INBAND",
+					"Channel: %s\r\n",
+					ast_channel_name(chan));
+		}
 		ts = ast_tone_zone_sound_unref(ts);
 	}
 
@@ -7404,7 +7409,7 @@ int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *inte
 
 	ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"));
 
-	return 0;
+	return -1;
 }
 
 void ast_moh_stop(struct ast_channel *chan)
diff --git a/main/config_options.c b/main/config_options.c
index 0cc2dda..0c706ac 100644
--- a/main/config_options.c
+++ b/main/config_options.c
@@ -837,6 +837,10 @@ int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
 	struct aco_option *opt;
 	struct ao2_iterator iter;
 
+	if (!type->internal) {
+		return -1;
+	}
+
 	iter = ao2_iterator_init(type->internal->opts, 0);
 
 	while ((opt = ao2_iterator_next(&iter))) {
diff --git a/main/dial.c b/main/dial.c
index ca85cd3..97942b8 100644
--- a/main/dial.c
+++ b/main/dial.c
@@ -378,14 +378,13 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
 	ast_channel_unlock(channel->owner);
 
 	if (!ast_strlen_zero(predial_string)) {
-		const char *predial_callee = ast_app_expand_sub_args(chan, predial_string);
-		if (!predial_callee) {
-			ast_log(LOG_ERROR, "Could not expand subroutine arguments in predial request '%s'\n", predial_string);
+		if (chan) {
+			ast_autoservice_start(chan);
+		}
+		ast_pre_call(channel->owner, predial_string);
+		if (chan) {
+			ast_autoservice_stop(chan);
 		}
-		ast_autoservice_start(chan);
-		ast_pre_call(channel->owner, predial_callee);
-		ast_autoservice_stop(chan);
-		ast_free((char *) predial_callee);
 	}
 
 	return 0;
@@ -397,10 +396,6 @@ int ast_dial_prerun(struct ast_dial *dial, struct ast_channel *chan, struct ast_
 	int res = -1;
 	char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
 
-	if (!ast_strlen_zero(predial_string)) {
-		ast_replace_subargument_delimiter(predial_string);
-	}
-
 	AST_LIST_LOCK(&dial->channels);
 	AST_LIST_TRAVERSE(&dial->channels, channel, list) {
 		if ((res = begin_dial_prerun(channel, chan, cap, predial_string))) {
@@ -450,10 +445,6 @@ static int begin_dial(struct ast_dial *dial, struct ast_channel *chan, int async
 	int success = 0;
 	char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
 
-	if (!ast_strlen_zero(predial_string)) {
-		ast_replace_subargument_delimiter(predial_string);
-	}
-
 	/* Iterate through channel list, requesting and calling each one */
 	AST_LIST_LOCK(&dial->channels);
 	AST_LIST_TRAVERSE(&dial->channels, channel, list) {
@@ -473,10 +464,6 @@ static int handle_call_forward(struct ast_dial *dial, struct ast_dial_channel *c
 	char *tech = "Local", *device = tmp, *stuff;
 	char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
 
-	if (!ast_strlen_zero(predial_string)) {
-		ast_replace_subargument_delimiter(predial_string);
-	}
-
 	/* If call forwarding is disabled just drop the original channel and don't attempt to dial the new one */
 	if (FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_DISABLE_CALL_FORWARDING)) {
 		ast_hangup(original);
diff --git a/main/endpoints.c b/main/endpoints.c
index ce0ab02..0155adf 100644
--- a/main/endpoints.c
+++ b/main/endpoints.c
@@ -464,7 +464,7 @@ static void endpoint_snapshot_dtor(void *obj)
 struct ast_endpoint_snapshot *ast_endpoint_snapshot_create(
 	struct ast_endpoint *endpoint)
 {
-	RAII_VAR(struct ast_endpoint_snapshot *, snapshot, NULL, ao2_cleanup);
+	struct ast_endpoint_snapshot *snapshot;
 	int channel_count;
 	struct ao2_iterator i;
 	void *obj;
@@ -500,7 +500,6 @@ struct ast_endpoint_snapshot *ast_endpoint_snapshot_create(
 	}
 	ao2_iterator_destroy(&i);
 
-	ao2_ref(snapshot, +1);
 	return snapshot;
 }
 
diff --git a/main/format.c b/main/format.c
index 148c77f..8ac82f0 100644
--- a/main/format.c
+++ b/main/format.c
@@ -298,6 +298,17 @@ struct ast_format *ast_format_attribute_set(const struct ast_format *format, con
 	return interface->format_attribute_set(format, name, value);
 }
 
+const void *ast_format_attribute_get(const struct ast_format *format, const char *name)
+{
+	const struct ast_format_interface *interface = format->interface;
+
+	if (!interface || !interface->format_attribute_get) {
+		return NULL;
+	}
+
+	return interface->format_attribute_get(format, name);
+}
+
 struct ast_format *ast_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
 {
 	const struct ast_format_interface *interface = format->interface;
diff --git a/main/logger.c b/main/logger.c
index f84221f..fb9e8ed 100644
--- a/main/logger.c
+++ b/main/logger.c
@@ -286,6 +286,70 @@ static void make_components(struct logchannel *chan)
 	chan->logmask = logmask;
 }
 
+/*!
+ * \brief create the filename that will be used for a logger channel.
+ *
+ * \param channel The name of the logger channel
+ * \param[out] filename The filename for the logger channel
+ * \param size The size of the filename buffer
+ */
+static void make_filename(const char *channel, char *filename, size_t size)
+{
+	const char *log_dir_prefix = "";
+	const char *log_dir_separator = "";
+
+	*filename = '\0';
+
+	if (!strcasecmp(channel, "console")) {
+		return;
+	}
+
+	if (!strncasecmp(channel, "syslog", 6)) {
+		ast_copy_string(filename, channel, size);
+		return;
+	}
+
+	/* It's a filename */
+
+	if (channel[0] != '/') {
+		log_dir_prefix = ast_config_AST_LOG_DIR;
+		log_dir_separator = "/";
+	}
+
+	if (!ast_strlen_zero(hostname)) {
+		snprintf(filename, size, "%s%s%s.%s",
+			log_dir_prefix, log_dir_separator, channel, hostname);
+	} else {
+		snprintf(filename, size, "%s%s%s",
+			log_dir_prefix, log_dir_separator, channel);
+	}
+}
+
+/*!
+ * \brief Find a particular logger channel by name
+ *
+ * \pre logchannels list is locked
+ *
+ * \param channel The name of the logger channel to find
+ * \retval non-NULL The corresponding logger channel
+ * \retval NULL Unable to find a logger channel with that particular name
+ */
+static struct logchannel *find_logchannel(const char *channel)
+{
+	char filename[PATH_MAX];
+	struct logchannel *chan;
+
+	make_filename(channel, filename, sizeof(filename));
+
+	AST_RWLIST_TRAVERSE(&logchannels, chan, list) {
+		if (!strcmp(chan->filename, filename)) {
+			return chan;
+		}
+	}
+
+	return NULL;
+}
+
 static struct logchannel *make_logchannel(const char *channel, const char *components, int lineno, int dynamic)
 {
 	struct logchannel *chan;
@@ -301,6 +365,8 @@ static struct logchannel *make_logchannel(const char *channel, const char *compo
 	chan->lineno = lineno;
 	chan->dynamic = dynamic;
 
+	make_filename(channel, chan->filename, sizeof(chan->filename));
+
 	if (!strcasecmp(channel, "console")) {
 		chan->type = LOGTYPE_CONSOLE;
 	} else if (!strncasecmp(channel, "syslog", 6)) {
@@ -322,25 +388,7 @@ static struct logchannel *make_logchannel(const char *channel, const char *compo
 		}
 
 		chan->type = LOGTYPE_SYSLOG;
-		ast_copy_string(chan->filename, channel, sizeof(chan->filename));
-		openlog("asterisk", LOG_PID, chan->facility);
 	} else {
-		const char *log_dir_prefix = "";
-		const char *log_dir_separator = "";
-
-		if (channel[0] != '/') {
-			log_dir_prefix = ast_config_AST_LOG_DIR;
-			log_dir_separator = "/";
-		}
-
-		if (!ast_strlen_zero(hostname)) {
-			snprintf(chan->filename, sizeof(chan->filename), "%s%s%s.%s",
-				log_dir_prefix, log_dir_separator, channel, hostname);
-		} else {
-			snprintf(chan->filename, sizeof(chan->filename), "%s%s%s",
-				log_dir_prefix, log_dir_separator, channel);
-		}
-
 		if (!(chan->fileptr = fopen(chan->filename, "a"))) {
 			/* Can't do real logging here since we're called with a lock
 			 * so log to any attached consoles */
@@ -933,6 +981,41 @@ int ast_logger_rotate()
 	return reload_logger(1, NULL);
 }
 
+int ast_logger_rotate_channel(const char *log_channel)
+{
+	struct logchannel *f;
+	int success = AST_LOGGER_FAILURE;
+	char filename[PATH_MAX];
+
+	make_filename(log_channel, filename, sizeof(filename));
+
+	AST_RWLIST_WRLOCK(&logchannels);
+
+	ast_mkdir(ast_config_AST_LOG_DIR, 0644);
+
+	AST_RWLIST_TRAVERSE(&logchannels, f, list) {
+		if (f->disabled) {
+			f->disabled = 0;	/* Re-enable logging at reload */
+			manager_event(EVENT_FLAG_SYSTEM, "LogChannel", "Channel: %s\r\nEnabled: Yes\r\n",
+				f->filename);
+		}
+		if (f->fileptr && (f->fileptr != stdout) && (f->fileptr != stderr)) {
+			fclose(f->fileptr);	/* Close file */
+			f->fileptr = NULL;
+			if (strcmp(filename, f->filename) == 0) {
+				rotate_file(f->filename);
+				success = AST_LOGGER_SUCCESS;
+			}
+		}
+	}
+
+	init_logger_chain(1 /* locked */, NULL);
+
+	AST_RWLIST_UNLOCK(&logchannels);
+
+	return success;
+}
+
 static char *handle_logger_set_level(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	int x;
@@ -975,6 +1058,48 @@ static char *handle_logger_set_level(struct ast_cli_entry *e, int cmd, struct as
 	return CLI_SUCCESS;
 }
 
+int ast_logger_get_channels(int (*logentry)(const char *channel, const char *type,
+	const char *status, const char *configuration, void *data), void *data)
+{
+	struct logchannel *chan;
+	struct ast_str *configs = ast_str_create(64);
+	int res = AST_LOGGER_SUCCESS;
+
+	if (!configs) {
+		return AST_LOGGER_ALLOC_ERROR;
+	}
+
+	AST_RWLIST_RDLOCK(&logchannels);
+	AST_RWLIST_TRAVERSE(&logchannels, chan, list) {
+		unsigned int level;
+
+		ast_str_reset(configs);
+
+		for (level = 0; level < ARRAY_LEN(levels); level++) {
+			if ((chan->logmask & (1 << level)) && levels[level]) {
+				ast_str_append(&configs, 0, "%s ", levels[level]);
+			}
+		}
+
+		res = logentry(chan->filename, chan->type == LOGTYPE_CONSOLE ? "Console" :
+			(chan->type == LOGTYPE_SYSLOG ? "Syslog" : "File"), chan->disabled ?
+			"Disabled" : "Enabled", ast_str_buffer(configs), data);
+
+		if (res) {
+			AST_RWLIST_UNLOCK(&logchannels);
+			ast_free(configs);
+			configs = NULL;
+			return AST_LOGGER_FAILURE;
+		}
+	}
+	AST_RWLIST_UNLOCK(&logchannels);
+
+	ast_free(configs);
+	configs = NULL;
+
+	return AST_LOGGER_SUCCESS;
+}
+
 /*! \brief CLI command to show logging system configuration */
 static char *handle_logger_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
@@ -1014,10 +1139,38 @@ static char *handle_logger_show_channels(struct ast_cli_entry *e, int cmd, struc
 	return CLI_SUCCESS;
 }
 
-static char *handle_logger_add_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+int ast_logger_create_channel(const char *log_channel, const char *components)
 {
 	struct logchannel *chan;
 
+	if (ast_strlen_zero(components)) {
+		return AST_LOGGER_DECLINE;
+	}
+
+	AST_RWLIST_WRLOCK(&logchannels);
+
+	chan = find_logchannel(log_channel);
+	if (chan) {
+		AST_RWLIST_UNLOCK(&logchannels);
+		return AST_LOGGER_FAILURE;
+	}
+
+	chan = make_logchannel(log_channel, components, 0, 1);
+	if (!chan) {
+		AST_RWLIST_UNLOCK(&logchannels);
+		return AST_LOGGER_ALLOC_ERROR;
+	}
+
+	AST_RWLIST_INSERT_HEAD(&logchannels, chan, list);
+	global_logmask |= chan->logmask;
+
+	AST_RWLIST_UNLOCK(&logchannels);
+
+	return AST_LOGGER_SUCCESS;
+}
+
+static char *handle_logger_add_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
 	switch (cmd) {
 	case CLI_INIT:
 		e->command = "logger add channel";
@@ -1036,31 +1189,43 @@ static char *handle_logger_add_channel(struct ast_cli_entry *e, int cmd, struct
 		return CLI_SHOWUSAGE;
 	}
 
-	AST_RWLIST_WRLOCK(&logchannels);
-	AST_RWLIST_TRAVERSE(&logchannels, chan, list) {
-		if (!strcmp(chan->filename, a->argv[3])) {
-			break;
-		}
-	}
-
-	if (chan) {
-		AST_RWLIST_UNLOCK(&logchannels);
+	switch (ast_logger_create_channel(a->argv[3], a->argv[4])) {
+	case AST_LOGGER_SUCCESS:
+		return CLI_SUCCESS;
+	case AST_LOGGER_FAILURE:
 		ast_cli(a->fd, "Logger channel '%s' already exists\n", a->argv[3]);
 		return CLI_SUCCESS;
+	case AST_LOGGER_DECLINE:
+	case AST_LOGGER_ALLOC_ERROR:
+	default:
+		ast_cli(a->fd, "ERROR: Unable to create log channel '%s'\n", a->argv[3]);
+		return CLI_FAILURE;
 	}
+}
 
-	chan = make_logchannel(a->argv[3], a->argv[4], 0, 1);
-	if (chan) {
-		AST_RWLIST_INSERT_HEAD(&logchannels, chan, list);
-		global_logmask |= chan->logmask;
+int ast_logger_remove_channel(const char *log_channel)
+{
+	struct logchannel *chan;
+
+	AST_RWLIST_WRLOCK(&logchannels);
+
+	chan = find_logchannel(log_channel);
+	if (chan && chan->dynamic) {
+		AST_RWLIST_REMOVE(&logchannels, chan, list);
+	} else {
 		AST_RWLIST_UNLOCK(&logchannels);
-		return CLI_SUCCESS;
+		return AST_LOGGER_FAILURE;
 	}
-
 	AST_RWLIST_UNLOCK(&logchannels);
-	ast_cli(a->fd, "ERROR: Unable to create log channel '%s'\n", a->argv[3]);
 
-	return CLI_FAILURE;
+	if (chan->fileptr) {
+		fclose(chan->fileptr);
+		chan->fileptr = NULL;
+	}
+	ast_free(chan);
+	chan = NULL;
+
+	return AST_LOGGER_SUCCESS;
 }
 
 static char *handle_logger_remove_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
@@ -1099,30 +1264,17 @@ static char *handle_logger_remove_channel(struct ast_cli_entry *e, int cmd, stru
 		return CLI_SHOWUSAGE;
 	}
 
-	AST_RWLIST_WRLOCK(&logchannels);
-	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&logchannels, chan, list) {
-		if (chan->dynamic && !strcmp(chan->filename, a->argv[3])) {
-			AST_RWLIST_REMOVE_CURRENT(list);
-			break;
-		}
-	}
-	AST_RWLIST_TRAVERSE_SAFE_END;
-	AST_RWLIST_UNLOCK(&logchannels);
-
-	if (!chan) {
+	switch (ast_logger_remove_channel(a->argv[3])) {
+	case AST_LOGGER_SUCCESS:
+		ast_cli(a->fd, "Removed dynamic logger channel '%s'\n", a->argv[3]);
+		return CLI_SUCCESS;
+	case AST_LOGGER_FAILURE:
 		ast_cli(a->fd, "Unable to find dynamic logger channel '%s'\n", a->argv[3]);
 		return CLI_SUCCESS;
+	default:
+		ast_cli(a->fd, "Internal failure attempting to delete dynamic logger channel '%s'\n", a->argv[3]);
+		return CLI_FAILURE;
 	}
-
-	ast_cli(a->fd, "Removed dynamic logger channel '%s'\n", chan->filename);
-	if (chan->fileptr) {
-		fclose(chan->fileptr);
-		chan->fileptr = NULL;
-	}
-	ast_free(chan);
-	chan = NULL;
-
-	return CLI_SUCCESS;
 }
 
 struct verb {
@@ -1152,7 +1304,7 @@ static struct sigaction handle_SIGXFSZ = {
 	.sa_flags = SA_RESTART,
 };
 
-static void ast_log_vsyslog(struct logmsg *msg)
+static void ast_log_vsyslog(struct logmsg *msg, int facility)
 {
 	char buf[BUFSIZ];
 	int syslog_level = ast_syslog_priority_from_loglevel(msg->level);
@@ -1170,6 +1322,8 @@ static void ast_log_vsyslog(struct logmsg *msg)
 		return;
 	}
 
+	syslog_level = LOG_MAKEPRI(facility, syslog_level);
+
 	snprintf(buf, sizeof(buf), "%s[%d]%s: %s:%d in %s: %s",
 		 levels[msg->level], msg->lwp, call_identifier_str, msg->file, msg->line, msg->function, msg->message);
 
@@ -1255,7 +1409,7 @@ static void logger_print_normal(struct logmsg *logmsg)
 
 			/* Check syslog channels */
 			if (chan->type == LOGTYPE_SYSLOG && (chan->logmask & (1 << logmsg->level))) {
-				ast_log_vsyslog(logmsg);
+				ast_log_vsyslog(logmsg, chan->facility);
 			/* Console channels */
 			} else if (chan->type == LOGTYPE_CONSOLE && (chan->logmask & (1 << logmsg->level))) {
 				char linestr[128];
diff --git a/main/pbx.c b/main/pbx.c
index f23dff7..be00328 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -5926,12 +5926,28 @@ static int ast_add_hint(struct ast_exten *e)
 /*! \brief Change hint for an extension */
 static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
 {
+	struct ast_str *hint_app;
 	struct ast_hint *hint;
+	int previous_device_state;
+	char *previous_message = NULL;
+	char *message = NULL;
+	char *previous_subtype = NULL;
+	char *subtype = NULL;
+	int previous_presence_state;
+	int presence_state;
+	int presence_state_changed = 0;
 
 	if (!oe || !ne) {
 		return -1;
 	}
 
+	hint_app = ast_str_create(1024);
+	if (!hint_app) {
+		return -1;
+	}
+
+	ast_mutex_lock(&context_merge_lock); /* Hold off ast_merge_contexts_and_delete and state changes */
+
 	ao2_lock(hints);/* Locked to hold off others while we move the hint around. */
 
 	/*
@@ -5941,6 +5957,8 @@ static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
 	hint = ao2_find(hints, oe, OBJ_UNLINK);
 	if (!hint) {
 		ao2_unlock(hints);
+		ast_mutex_unlock(&context_merge_lock);
+		ast_free(hint_app);
 		return -1;
 	}
 
@@ -5949,7 +5967,28 @@ static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
 	/* Update the hint and put it back in the hints container. */
 	ao2_lock(hint);
 	hint->exten = ne;
+
+	/* Store the previous states so we know whether we need to notify state callbacks */
+	previous_device_state = hint->laststate;
+	previous_presence_state = hint->last_presence_state;
+	previous_message = hint->last_presence_message;
+	previous_subtype = hint->last_presence_subtype;
+
+	/* Update the saved device and presence state with the new extension */
+	hint->laststate = ast_extension_state2(ne, NULL);
+	hint->last_presence_state = AST_PRESENCE_INVALID;
+	hint->last_presence_subtype = NULL;
+	hint->last_presence_message = NULL;
+
+	presence_state = extension_presence_state_helper(ne, &subtype, &message);
+	if (presence_state > 0) {
+		hint->last_presence_state = presence_state;
+		hint->last_presence_subtype = subtype;
+		hint->last_presence_message = message;
+	}
+
 	ao2_unlock(hint);
+
 	ao2_link(hints, hint);
 	if (add_hintdevice(hint, ast_get_extension_app(ne))) {
 		ast_log(LOG_WARNING, "Could not add devices for hint: %s@%s.\n",
@@ -5958,8 +5997,98 @@ static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
 	}
 
 	ao2_unlock(hints);
+
+	/* Locking for state callbacks is respected here and only the context_merge_lock lock is
+	 * held during the state callback invocation. This will stop the normal state callback
+	 * thread from being able to handle incoming state changes if they occur.
+	 */
+
+	/* Determine if presence state has changed due to the change of the hint extension */
+	if ((hint->last_presence_state != previous_presence_state) ||
+		strcmp(S_OR(hint->last_presence_subtype, ""), S_OR(previous_subtype, "")) ||
+		strcmp(S_OR(hint->last_presence_message, ""), S_OR(previous_message, ""))) {
+		presence_state_changed = 1;
+	}
+
+	/* Notify any existing state callbacks if the device or presence state has changed */
+	if ((hint->laststate != previous_device_state) || presence_state_changed) {
+		struct ao2_iterator cb_iter;
+		struct ast_state_cb *state_cb;
+		struct ao2_container *device_state_info;
+		int first_extended_cb_call = 1;
+
+		/* For general callbacks */
+		cb_iter = ao2_iterator_init(statecbs, 0);
+		for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
+			/* Unlike the normal state callbacks since something has explicitly provided us this extension
+			 * it will remain valid and unchanged for the lifetime of this function invocation.
+			 */
+			if (hint->laststate != previous_device_state) {
+				execute_state_callback(state_cb->change_cb,
+					ast_get_context_name(ast_get_extension_context(ne)),
+					ast_get_extension_name(ne),
+					state_cb->data,
+					AST_HINT_UPDATE_DEVICE,
+					hint,
+					NULL);
+			}
+			if (presence_state_changed) {
+				execute_state_callback(state_cb->change_cb,
+					ast_get_context_name(ast_get_extension_context(ne)),
+					ast_get_extension_name(ne),
+					state_cb->data,
+					AST_HINT_UPDATE_PRESENCE,
+					hint,
+					NULL);
+			}
+		}
+		ao2_iterator_destroy(&cb_iter);
+
+		ast_str_set(&hint_app, 0, "%s", ast_get_extension_app(ne));
+
+		device_state_info = alloc_device_state_info();
+		ast_extension_state3(hint_app, device_state_info);
+
+		/* For extension callbacks */
+		cb_iter = ao2_iterator_init(hint->callbacks, 0);
+		for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
+			if (hint->laststate != previous_device_state) {
+				if (state_cb->extended && first_extended_cb_call) {
+				/* Fill detailed device_state_info now that we know it is used by extd. callback */
+					first_extended_cb_call = 0;
+					get_device_state_causing_channels(device_state_info);
+				}
+				execute_state_callback(state_cb->change_cb,
+					ast_get_context_name(ast_get_extension_context(ne)),
+					ast_get_extension_name(ne),
+					state_cb->data,
+					AST_HINT_UPDATE_DEVICE,
+					hint,
+					state_cb->extended ? device_state_info : NULL);
+			}
+			if (presence_state_changed) {
+				execute_state_callback(state_cb->change_cb,
+					ast_get_context_name(ast_get_extension_context(ne)),
+					ast_get_extension_name(ne),
+					state_cb->data,
+					AST_HINT_UPDATE_PRESENCE,
+					hint,
+					NULL);
+			}
+		}
+		ao2_iterator_destroy(&cb_iter);
+
+		ao2_cleanup(device_state_info);
+	}
+
 	ao2_ref(hint, -1);
 
+	ast_mutex_unlock(&context_merge_lock);
+
+	ast_free(hint_app);
+	ast_free(previous_message);
+	ast_free(previous_subtype);
+
 	return 0;
 }
 
@@ -7524,7 +7653,7 @@ static char *handle_show_hints(struct ast_cli_entry *e, int cmd, struct ast_cli_
 			continue;
 		}
 		watchers = ao2_container_count(hint->callbacks);
-		sprintf(buf, "%s@%s",
+		snprintf(buf, sizeof(buf), "%s@%s",
 			ast_get_extension_name(hint->exten),
 			ast_get_context_name(ast_get_extension_context(hint->exten)));
 
@@ -11978,10 +12107,11 @@ static void presence_state_cb(void *unused, struct stasis_subscription *sub, str
 		struct ast_state_cb *state_cb;
 		const char *app;
 		char *parse;
-		SCOPED_AO2LOCK(lock, hint);
+		ao2_lock(hint);
 
 		if (!hint->exten) {
 			/* The extension has already been destroyed */
+			ao2_unlock(hint);
 			continue;
 		}
 
@@ -11989,16 +12119,19 @@ static void presence_state_cb(void *unused, struct stasis_subscription *sub, str
 		app = ast_get_extension_app(hint->exten);
 		if (ast_strlen_zero(app)) {
 			/* The hint does not monitor presence at all. */
+			ao2_unlock(hint);
 			continue;
 		}
 
 		ast_str_set(&hint_app, 0, "%s", app);
 		parse = parse_hint_presence(hint_app);
 		if (ast_strlen_zero(parse)) {
+			ao2_unlock(hint);
 			continue;
 		}
 		if (strcasecmp(parse, presence_state->provider)) {
 			/* The hint does not monitor the presence provider. */
+			ao2_unlock(hint);
 			continue;
 		}
 
@@ -12019,6 +12152,7 @@ static void presence_state_cb(void *unused, struct stasis_subscription *sub, str
 			((hint->last_presence_message && presence_state->message && !strcmp(hint->last_presence_message, presence_state->message)) || (!hint->last_presence_message && !presence_state->message))) {
 
 			/* this update is the same as the last, do nothing */
+			ao2_unlock(hint);
 			continue;
 		}
 
@@ -12028,6 +12162,14 @@ static void presence_state_cb(void *unused, struct stasis_subscription *sub, str
 		hint->last_presence_state = presence_state->state;
 		hint->last_presence_subtype = presence_state->subtype ? ast_strdup(presence_state->subtype) : NULL;
 		hint->last_presence_message = presence_state->message ? ast_strdup(presence_state->message) : NULL;
+		/*
+		 * (Copied from device_state_cb)
+		 *
+		 * NOTE: We cannot hold any locks while notifying
+		 * the watchers without causing a deadlock.
+		 * (conlock, hints, and hint)
+		 */
+		ao2_unlock(hint);
 
 		/* For general callbacks */
 		cb_iter = ao2_iterator_init(statecbs, 0);
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 0fca0dd..8ad3d9e 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -229,14 +229,17 @@ static int mime_types_len = 0;
  * See http://www.iana.org/assignments/rtp-parameters for a list of
  * assigned values
  */
-static struct ast_rtp_payload_type static_RTP_PT[AST_RTP_MAX_PT];
+static struct ast_rtp_payload_type *static_RTP_PT[AST_RTP_MAX_PT];
 static ast_rwlock_t static_RTP_PT_lock;
 
 /*! \brief \ref stasis topic for RTP related messages */
 static struct stasis_topic *rtp_topic;
 
 
-/*! \internal \brief Destructor for \c ast_rtp_payload_type */
+/*!
+ * \internal
+ * \brief Destructor for \c ast_rtp_payload_type
+ */
 static void rtp_payload_type_dtor(void *obj)
 {
 	struct ast_rtp_payload_type *payload = obj;
@@ -248,7 +251,8 @@ struct ast_rtp_payload_type *ast_rtp_engine_alloc_payload_type(void)
 {
 	struct ast_rtp_payload_type *payload;
 
-	payload = ao2_alloc(sizeof(*payload), rtp_payload_type_dtor);
+	payload = ao2_alloc_options(sizeof(*payload), rtp_payload_type_dtor,
+		AO2_ALLOC_OPT_LOCK_NOLOCK);
 
 	return payload;
 }
@@ -599,6 +603,7 @@ void ast_rtp_codecs_payloads_destroy(struct ast_rtp_codecs *codecs)
 void ast_rtp_codecs_payloads_clear(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance)
 {
 	ast_rtp_codecs_payloads_destroy(codecs);
+	ast_rtp_codecs_payloads_initialize(codecs);
 
 	if (instance && instance->engine && instance->engine->payload_set) {
 		int i;
@@ -606,8 +611,6 @@ void ast_rtp_codecs_payloads_clear(struct ast_rtp_codecs *codecs, struct ast_rtp
 			instance->engine->payload_set(instance, i, 0, NULL, 0);
 		}
 	}
-
-	ast_rtp_codecs_payloads_initialize(codecs);
 }
 
 void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
@@ -644,28 +647,27 @@ void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct as
 {
 	struct ast_rtp_payload_type *new_type;
 
-	new_type = ast_rtp_engine_alloc_payload_type();
-	if (!new_type) {
+	if (payload < 0 || payload >= AST_RTP_MAX_PT) {
 		return;
 	}
 
 	ast_rwlock_rdlock(&static_RTP_PT_lock);
-	if (payload < 0 || payload >= AST_RTP_MAX_PT) {
-		ast_rwlock_unlock(&static_RTP_PT_lock);
+	new_type = ao2_bump(static_RTP_PT[payload]);
+	ast_rwlock_unlock(&static_RTP_PT_lock);
+	if (!new_type) {
+		ast_debug(1, "Don't have a default tx payload type %d format for m type on %p\n",
+			payload, codecs);
 		return;
 	}
 
+	ast_debug(1, "Setting tx payload type %d based on m type on %p\n",
+		payload, codecs);
+
 	ast_rwlock_wrlock(&codecs->codecs_lock);
+
 	if (payload < AST_VECTOR_SIZE(&codecs->payloads)) {
 		ao2_t_cleanup(AST_VECTOR_GET(&codecs->payloads, payload), "cleaning up replaced payload type");
 	}
-
-	new_type->asterisk_format = static_RTP_PT[payload].asterisk_format;
-	new_type->rtp_code = static_RTP_PT[payload].rtp_code;
-	new_type->payload = payload;
-	new_type->format = ao2_bump(static_RTP_PT[payload].format);
-
-	ast_debug(1, "Setting payload %d (%p) based on m type on %p\n", payload, new_type, codecs);
 	AST_VECTOR_REPLACE(&codecs->payloads, payload, new_type);
 
 	if (instance && instance->engine && instance->engine->payload_set) {
@@ -673,7 +675,6 @@ void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct as
 	}
 
 	ast_rwlock_unlock(&codecs->codecs_lock);
-	ast_rwlock_unlock(&static_RTP_PT_lock);
 }
 
 int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int pt,
@@ -684,12 +685,11 @@ int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs,
 	unsigned int i;
 	int found = 0;
 
-	ast_rwlock_rdlock(&mime_types_lock);
 	if (pt < 0 || pt >= AST_RTP_MAX_PT) {
-		ast_rwlock_unlock(&mime_types_lock);
 		return -1; /* bogus payload type */
 	}
 
+	ast_rwlock_rdlock(&mime_types_lock);
 	ast_rwlock_wrlock(&codecs->codecs_lock);
 	for (i = 0; i < mime_types_len; ++i) {
 		const struct ast_rtp_mime_type *t = &ast_rtp_mime_types[i];
@@ -790,15 +790,8 @@ struct ast_rtp_payload_type *ast_rtp_codecs_get_payload(struct ast_rtp_codecs *c
 	ast_rwlock_unlock(&codecs->codecs_lock);
 
 	if (!type) {
-		type = ast_rtp_engine_alloc_payload_type();
-		if (!type) {
-			return NULL;
-		}
 		ast_rwlock_rdlock(&static_RTP_PT_lock);
-		type->asterisk_format = static_RTP_PT[payload].asterisk_format;
-		type->rtp_code = static_RTP_PT[payload].rtp_code;
-		type->payload = payload;
-		type->format = ao2_bump(static_RTP_PT[payload].format);
+		type = ao2_bump(static_RTP_PT[payload]);
 		ast_rwlock_unlock(&static_RTP_PT_lock);
 	}
 
@@ -809,17 +802,24 @@ int ast_rtp_codecs_payload_replace_format(struct ast_rtp_codecs *codecs, int pay
 {
 	struct ast_rtp_payload_type *type;
 
-	if (payload < 0 || payload >= AST_RTP_MAX_PT) {
+	if (payload < 0 || payload >= AST_RTP_MAX_PT || !format) {
 		return -1;
 	}
 
+	type = ast_rtp_engine_alloc_payload_type();
+	if (!type) {
+		return -1;
+	}
+	ao2_ref(format, +1);
+	type->format = format;
+	type->asterisk_format = 1;
+	type->payload = payload;
+
 	ast_rwlock_wrlock(&codecs->codecs_lock);
 	if (payload < AST_VECTOR_SIZE(&codecs->payloads)) {
-		type = AST_VECTOR_GET(&codecs->payloads, payload);
-		if (type && type->asterisk_format) {
-			ao2_replace(type->format, format);
-		}
+		ao2_cleanup(AST_VECTOR_GET(&codecs->payloads, payload));
 	}
+	AST_VECTOR_REPLACE(&codecs->payloads, payload, type);
 	ast_rwlock_unlock(&codecs->codecs_lock);
 
 	return 0;
@@ -922,12 +922,15 @@ int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_form
 	if (payload < 0) {
 		ast_rwlock_rdlock(&static_RTP_PT_lock);
 		for (i = 0; i < AST_RTP_MAX_PT; i++) {
-			if (static_RTP_PT[i].asterisk_format && asterisk_format && format &&
-				(ast_format_cmp(format, static_RTP_PT[i].format) != AST_FORMAT_CMP_NOT_EQUAL)) {
+			if (!static_RTP_PT[i]) {
+				continue;
+			}
+			if (static_RTP_PT[i]->asterisk_format && asterisk_format && format &&
+				(ast_format_cmp(format, static_RTP_PT[i]->format) != AST_FORMAT_CMP_NOT_EQUAL)) {
 				payload = i;
 				break;
-			} else if (!static_RTP_PT[i].asterisk_format && !asterisk_format &&
-				(static_RTP_PT[i].rtp_code == code)) {
+			} else if (!static_RTP_PT[i]->asterisk_format && !asterisk_format &&
+				(static_RTP_PT[i]->rtp_code == code)) {
 				payload = i;
 				break;
 			}
@@ -1694,16 +1697,6 @@ void ast_rtp_dtls_cfg_free(struct ast_rtp_dtls_cfg *dtls_cfg)
 
 /*! \internal
  * \brief Small helper routine that cleans up entry i in
- * \c static_RTP_PT.
- */
-static void rtp_engine_static_RTP_PT_cleanup(int i)
-{
-	ao2_cleanup(static_RTP_PT[i].format);
-	memset(&static_RTP_PT[i], 0, sizeof(struct ast_rtp_payload_type));
-}
-
-/*! \internal
- * \brief Small helper routine that cleans up entry i in
  * \c ast_rtp_mime_types.
  */
 static void rtp_engine_mime_type_cleanup(int i)
@@ -1714,12 +1707,16 @@ static void rtp_engine_mime_type_cleanup(int i)
 
 static void set_next_mime_type(struct ast_format *format, int rtp_code, const char *type, const char *subtype, unsigned int sample_rate)
 {
-	int x = mime_types_len;
-	if (ARRAY_LEN(ast_rtp_mime_types) == mime_types_len) {
+	int x;
+
+	ast_rwlock_wrlock(&mime_types_lock);
+
+	x = mime_types_len;
+	if (ARRAY_LEN(ast_rtp_mime_types) <= x) {
+		ast_rwlock_unlock(&mime_types_lock);
 		return;
 	}
 
-	ast_rwlock_wrlock(&mime_types_lock);
 	/* Make sure any previous value in ast_rtp_mime_types is cleaned up */
 	memset(&ast_rtp_mime_types[x], 0, sizeof(struct ast_rtp_mime_type));	
 	if (format) {
@@ -1732,35 +1729,51 @@ static void set_next_mime_type(struct ast_format *format, int rtp_code, const ch
 	ast_copy_string(ast_rtp_mime_types[x].subtype, subtype, sizeof(ast_rtp_mime_types[x].subtype));
 	ast_rtp_mime_types[x].sample_rate = sample_rate;
 	mime_types_len++;
+
 	ast_rwlock_unlock(&mime_types_lock);
 }
 
 static void add_static_payload(int map, struct ast_format *format, int rtp_code)
 {
 	int x;
+	struct ast_rtp_payload_type *type;
+
+	ast_assert(map < ARRAY_LEN(static_RTP_PT));
+
 	ast_rwlock_wrlock(&static_RTP_PT_lock);
 	if (map < 0) {
 		/* find next available dynamic payload slot */
-		for (x = 96; x < 127; x++) {
-			if (!static_RTP_PT[x].asterisk_format && !static_RTP_PT[x].rtp_code) {
+		for (x = AST_RTP_PT_FIRST_DYNAMIC; x < AST_RTP_MAX_PT; ++x) {
+			if (!static_RTP_PT[x]) {
 				map = x;
 				break;
 			}
 		}
+		if (map < 0) {
+			if (format) {
+				ast_log(LOG_WARNING, "No Dynamic RTP mapping available for format %s\n",
+					ast_format_get_name(format));
+			} else {
+				ast_log(LOG_WARNING, "No Dynamic RTP mapping available for RTP code %d\n",
+					rtp_code);
+			}
+			ast_rwlock_unlock(&static_RTP_PT_lock);
+			return;
+		}
 	}
 
-	if (map < 0) {
-		ast_log(LOG_WARNING, "No Dynamic RTP mapping available for format %s\n",
-			ast_format_get_name(format));
-		ast_rwlock_unlock(&static_RTP_PT_lock);
-		return;
-	}
-
-	if (format) {
-		static_RTP_PT[map].asterisk_format = 1;
-		static_RTP_PT[map].format = ao2_bump(format);
-	} else {
-		static_RTP_PT[map].rtp_code = rtp_code;
+	type = ast_rtp_engine_alloc_payload_type();
+	if (type) {
+		if (format) {
+			ao2_ref(format, +1);
+			type->format = format;
+			type->asterisk_format = 1;
+		} else {
+			type->rtp_code = rtp_code;
+		}
+		type->payload = map;
+		ao2_cleanup(static_RTP_PT[map]);
+		static_RTP_PT[map] = type;
 	}
 	ast_rwlock_unlock(&static_RTP_PT_lock);
 }
@@ -1789,8 +1802,10 @@ int ast_rtp_engine_unload_format(struct ast_format *format)
 	ast_rwlock_wrlock(&static_RTP_PT_lock);
 	/* remove everything pertaining to this format id from the lists */
 	for (x = 0; x < AST_RTP_MAX_PT; x++) {
-		if (ast_format_cmp(static_RTP_PT[x].format, format) == AST_FORMAT_CMP_EQUAL) {
-			rtp_engine_static_RTP_PT_cleanup(x);
+		if (static_RTP_PT[x]
+			&& ast_format_cmp(static_RTP_PT[x]->format, format) == AST_FORMAT_CMP_EQUAL) {
+			ao2_ref(static_RTP_PT[x], -1);
+			static_RTP_PT[x] = NULL;
 		}
 	}
 	ast_rwlock_unlock(&static_RTP_PT_lock);
@@ -2079,9 +2094,8 @@ static void rtp_engine_shutdown(void)
 
 	ast_rwlock_wrlock(&static_RTP_PT_lock);
 	for (x = 0; x < AST_RTP_MAX_PT; x++) {
-		if (static_RTP_PT[x].format) {
-			rtp_engine_static_RTP_PT_cleanup(x);
-		}
+		ao2_cleanup(static_RTP_PT[x]);
+		static_RTP_PT[x] = NULL;
 	}
 	ast_rwlock_unlock(&static_RTP_PT_lock);
 
@@ -2091,10 +2105,11 @@ static void rtp_engine_shutdown(void)
 			rtp_engine_mime_type_cleanup(x);
 		}
 	}
+	mime_types_len = 0;
 	ast_rwlock_unlock(&mime_types_lock);
 }
 
-int ast_rtp_engine_init()
+int ast_rtp_engine_init(void)
 {
 	ast_rwlock_init(&mime_types_lock);
 	ast_rwlock_init(&static_RTP_PT_lock);
diff --git a/main/sched.c b/main/sched.c
index 4443497..89ef9ae 100644
--- a/main/sched.c
+++ b/main/sched.c
@@ -62,9 +62,26 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 AST_THREADSTORAGE(last_del_id);
 
+/*!
+ * \brief Scheduler ID holder
+ *
+ * These form a queue on a scheduler context. When a new
+ * scheduled item is created, a sched_id is popped off the
+ * queue and its id is assigned to the new scheduled item.
+ * When the scheduled task is complete, the sched_id on that
+ * task is then pushed to the back of the queue to be re-used
+ * on some future scheduled item.
+ */
+struct sched_id {
+	/*! Immutable ID number that is copied onto the scheduled task */
+	int id;
+	AST_LIST_ENTRY(sched_id) list;
+};
+
 struct sched {
 	AST_LIST_ENTRY(sched) list;
-	int id;                       /*!< ID number of event */
+	/*! The ID that has been popped off the scheduler context's queue */
+	struct sched_id *sched_id;
 	struct timeval when;          /*!< Absolute time event should take place */
 	int resched;                  /*!< When to reschedule */
 	int variable;                 /*!< Use return value from callback to reschedule */
@@ -99,6 +116,10 @@ struct ast_sched_context {
 	AST_LIST_HEAD_NOLOCK(, sched) schedc;   /*!< Cache of unused schedule structures and how many */
 	unsigned int schedccnt;
 #endif
+	/*! Queue of scheduler task IDs to assign */
+	AST_LIST_HEAD_NOLOCK(, sched_id) id_queue;
+	/*! The number of IDs in the id_queue */
+	int id_queue_size;
 };
 
 static void *sched_run(void *data)
@@ -208,6 +229,8 @@ struct ast_sched_context *ast_sched_context_create(void)
 	ast_mutex_init(&tmp->lock);
 	tmp->eventcnt = 1;
 
+	AST_LIST_HEAD_INIT_NOLOCK(&tmp->id_queue);
+
 	if (!(tmp->sched_heap = ast_heap_create(8, sched_time_cmp,
 			offsetof(struct sched, __heap_index)))) {
 		ast_sched_context_destroy(tmp);
@@ -219,6 +242,11 @@ struct ast_sched_context *ast_sched_context_create(void)
 
 static void sched_free(struct sched *task)
 {
+	/* task->sched_id will be NULL most of the time, but when the
+	 * scheduler context shuts down, it will free all scheduled
+	 * tasks, and in that case, the task->sched_id will be non-NULL
+	 */
+	ast_free(task->sched_id);
 	ast_cond_destroy(&task->cond);
 	ast_free(task);
 }
@@ -226,6 +254,7 @@ static void sched_free(struct sched *task)
 void ast_sched_context_destroy(struct ast_sched_context *con)
 {
 	struct sched *s;
+	struct sched_id *sid;
 
 	sched_thread_destroy(con);
 	con->sched_thread = NULL;
@@ -246,40 +275,75 @@ void ast_sched_context_destroy(struct ast_sched_context *con)
 		con->sched_heap = NULL;
 	}
 
+	while ((sid = AST_LIST_REMOVE_HEAD(&con->id_queue, list))) {
+		ast_free(sid);
+	}
+
 	ast_mutex_unlock(&con->lock);
 	ast_mutex_destroy(&con->lock);
 
 	ast_free(con);
 }
 
-static struct sched *sched_alloc(struct ast_sched_context *con)
-{
-	struct sched *tmp;
+#define ID_QUEUE_INCREMENT 16
 
-	/*
-	 * We keep a small cache of schedule entries
-	 * to minimize the number of necessary malloc()'s
+/*!
+ * \brief Add new scheduler IDs to the queue.
+ *
+ * \retval The number of IDs added to the queue
+ */
+static int add_ids(struct ast_sched_context *con)
+{
+	int new_size;
+	int original_size;
+	int i;
+
+	original_size = con->id_queue_size;
+	/* So we don't go overboard with the mallocs here, we'll just up
+	 * the size of the list by a fixed amount each time instead of
+	 * multiplying the size by any particular factor
 	 */
-#ifdef SCHED_MAX_CACHE
-	if ((tmp = AST_LIST_REMOVE_HEAD(&con->schedc, list))) {
-		con->schedccnt--;
-	} else 
-#endif
-	{
-		tmp = ast_calloc(1, sizeof(*tmp));
-		ast_cond_init(&tmp->cond, NULL);
+	new_size = original_size + ID_QUEUE_INCREMENT;
+	if (new_size < 0) {
+		/* Overflow. Cap it at INT_MAX. */
+		new_size = INT_MAX;
 	}
+	for (i = original_size; i < new_size; ++i) {
+		struct sched_id *new_id;
 
-	return tmp;
+		new_id = ast_calloc(1, sizeof(*new_id));
+		if (!new_id) {
+			break;
+		}
+		new_id->id = i;
+		AST_LIST_INSERT_TAIL(&con->id_queue, new_id, list);
+		++con->id_queue_size;
+	}
+
+	return con->id_queue_size - original_size;
+}
+
+static int set_sched_id(struct ast_sched_context *con, struct sched *new_sched)
+{
+	if (AST_LIST_EMPTY(&con->id_queue) && (add_ids(con) == 0)) {
+		return -1;
+	}
+
+	new_sched->sched_id = AST_LIST_REMOVE_HEAD(&con->id_queue, list);
+	return 0;
 }
 
 static void sched_release(struct ast_sched_context *con, struct sched *tmp)
 {
+	if (tmp->sched_id) {
+		AST_LIST_INSERT_TAIL(&con->id_queue, tmp->sched_id, list);
+		tmp->sched_id = NULL;
+	}
+
 	/*
 	 * Add to the cache, or just free() if we
 	 * already have too many cache entries
 	 */
-
 #ifdef SCHED_MAX_CACHE
 	if (con->schedccnt < SCHED_MAX_CACHE) {
 		AST_LIST_INSERT_HEAD(&con->schedc, tmp, list);
@@ -289,6 +353,35 @@ static void sched_release(struct ast_sched_context *con, struct sched *tmp)
 		sched_free(tmp);
 }
 
+static struct sched *sched_alloc(struct ast_sched_context *con)
+{
+	struct sched *tmp;
+
+	/*
+	 * We keep a small cache of schedule entries
+	 * to minimize the number of necessary malloc()'s
+	 */
+#ifdef SCHED_MAX_CACHE
+	if ((tmp = AST_LIST_REMOVE_HEAD(&con->schedc, list))) {
+		con->schedccnt--;
+	} else
+#endif
+	{
+		tmp = ast_calloc(1, sizeof(*tmp));
+		if (!tmp) {
+			return NULL;
+		}
+		ast_cond_init(&tmp->cond, NULL);
+	}
+
+	if (set_sched_id(con, tmp)) {
+		sched_release(con, tmp);
+		return NULL;
+	}
+
+	return tmp;
+}
+
 void ast_sched_clean_by_callback(struct ast_sched_context *con, ast_sched_cb match, ast_sched_cb cleanup_cb)
 {
 	int i = 1;
@@ -388,7 +481,7 @@ int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb
 
 	ast_mutex_lock(&con->lock);
 	if ((tmp = sched_alloc(con))) {
-		tmp->id = con->eventcnt++;
+		con->eventcnt++;
 		tmp->callback = callback;
 		tmp->data = data;
 		tmp->resched = when;
@@ -399,7 +492,7 @@ int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb
 			sched_release(con, tmp);
 		} else {
 			schedule(con, tmp);
-			res = tmp->id;
+			res = tmp->sched_id->id;
 		}
 	}
 #ifdef DUMP_SCHEDULER
@@ -437,7 +530,7 @@ static struct sched *sched_find(struct ast_sched_context *con, int id)
 	for (x = 1; x <= heap_size; x++) {
 		struct sched *cur = ast_heap_peek(con->sched_heap, x);
 
-		if (cur->id == id) {
+		if (cur->sched_id->id == id) {
 			return cur;
 		}
 	}
@@ -488,16 +581,18 @@ int _ast_sched_del(struct ast_sched_context *con, int id, const char *file, int
 	s = sched_find(con, id);
 	if (s) {
 		if (!ast_heap_remove(con->sched_heap, s)) {
-			ast_log(LOG_WARNING,"sched entry %d not in the sched heap?\n", s->id);
+			ast_log(LOG_WARNING,"sched entry %d not in the sched heap?\n", s->sched_id->id);
 		}
 		sched_release(con, s);
-	} else if (con->currently_executing && (id == con->currently_executing->id)) {
+	} else if (con->currently_executing && (id == con->currently_executing->sched_id->id)) {
 		s = con->currently_executing;
 		s->deleted = 1;
 		/* Wait for executing task to complete so that caller of ast_sched_del() does not
 		 * free memory out from under the task.
 		 */
-		ast_cond_wait(&s->cond, &con->lock);
+		while (con->currently_executing && (id == con->currently_executing->sched_id->id)) {
+			ast_cond_wait(&s->cond, &con->lock);
+		}
 		/* Do not sched_release() here because ast_sched_runq() will do it */
 	}
 
@@ -584,7 +679,7 @@ void ast_sched_dump(struct ast_sched_context *con)
 		q = ast_heap_peek(con->sched_heap, x);
 		delta = ast_tvsub(q->when, when);
 		ast_debug(1, "|%.4d | %-15p | %-15p | %.6ld : %.6ld |\n",
-			q->id,
+			q->sched_id->id,
 			q->callback,
 			q->data,
 			(long)delta.tv_sec,
diff --git a/main/sorcery.c b/main/sorcery.c
index 2f45196..43a395a 100644
--- a/main/sorcery.c
+++ b/main/sorcery.c
@@ -1736,6 +1736,10 @@ void *ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, con
 	} else {
 		details->object->id = ast_strdup(id);
 	}
+	if (!details->object->id) {
+		ao2_ref(details, -1);
+		return NULL;
+	}
 
 	ast_copy_string(details->object->type, type, sizeof(details->object->type));
 
diff --git a/main/stasis_endpoints.c b/main/stasis_endpoints.c
index e0d0878..157f98c 100644
--- a/main/stasis_endpoints.c
+++ b/main/stasis_endpoints.c
@@ -124,12 +124,7 @@ struct stasis_topic *ast_endpoint_topic_all_cached(void)
 	return stasis_cp_all_topic_cached(endpoint_cache_all);
 }
 
-static struct ast_manager_event_blob *peerstatus_to_ami(struct stasis_message *msg);
-
 STASIS_MESSAGE_TYPE_DEFN(ast_endpoint_snapshot_type);
-STASIS_MESSAGE_TYPE_DEFN(ast_endpoint_state_type,
-	.to_ami = peerstatus_to_ami,
-);
 
 static struct ast_manager_event_blob *peerstatus_to_ami(struct stasis_message *msg)
 {
@@ -166,10 +161,44 @@ static struct ast_manager_event_blob *peerstatus_to_ami(struct stasis_message *m
 		ast_str_buffer(peerstatus_event_string));
 }
 
-static struct ast_manager_event_blob *contactstatus_to_ami(struct stasis_message *msg);
+static struct ast_json *peerstatus_to_json(struct stasis_message *msg, const struct stasis_message_sanitizer *sanitize)
+{
+	struct ast_endpoint_blob *obj = stasis_message_data(msg);
+	struct ast_json *json_endpoint;
+	struct ast_json *json_peer;
+	struct ast_json *json_final;
+	const struct timeval *tv = stasis_message_timestamp(msg);
 
-STASIS_MESSAGE_TYPE_DEFN(ast_endpoint_contact_state_type,
-	.to_ami = contactstatus_to_ami,
+	json_endpoint = ast_endpoint_snapshot_to_json(obj->snapshot, NULL);
+	if (!json_endpoint) {
+		return NULL;
+	}
+
+	json_peer = ast_json_object_create();
+	if (!json_peer) {
+		ast_json_unref(json_endpoint);
+		return NULL;
+	}
+
+	/* Copy all fields from the blob */
+	ast_json_object_update(json_peer, obj->blob);
+
+	json_final = ast_json_pack("{s: s, s: o, s: o, s: o }",
+		"type", "PeerStatusChange",
+		"timestamp", ast_json_timeval(*tv, NULL),
+		"endpoint", json_endpoint,
+		"peer", json_peer);
+	if (!json_final) {
+		ast_json_unref(json_endpoint);
+		ast_json_unref(json_peer);
+	}
+
+	return json_final;
+}
+
+STASIS_MESSAGE_TYPE_DEFN(ast_endpoint_state_type,
+	.to_ami = peerstatus_to_ami,
+	.to_json = peerstatus_to_json,
 );
 
 static struct ast_manager_event_blob *contactstatus_to_ami(struct stasis_message *msg)
@@ -206,6 +235,39 @@ static struct ast_manager_event_blob *contactstatus_to_ami(struct stasis_message
 		"%s", ast_str_buffer(contactstatus_event_string));
 }
 
+static struct ast_json *contactstatus_to_json(struct stasis_message *msg, const struct stasis_message_sanitizer *sanitize)
+{
+	struct ast_endpoint_blob *obj = stasis_message_data(msg);
+	struct ast_json *json_endpoint;
+	struct ast_json *json_final;
+	const struct timeval *tv = stasis_message_timestamp(msg);
+
+	json_endpoint = ast_endpoint_snapshot_to_json(obj->snapshot, NULL);
+	if (!json_endpoint) {
+		return NULL;
+	}
+
+	json_final = ast_json_pack("{s: s, s: o, s: o, s: { s: s, s: s, s: s } } ",
+		"type", "ContactStatusChange",
+		"timestamp", ast_json_timeval(*tv, NULL),
+		"endpoint", json_endpoint,
+		"contact_info",
+		"uri", ast_json_string_get(ast_json_object_get(obj->blob, "uri")),
+		"contact_status", ast_json_string_get(ast_json_object_get(obj->blob, "contact_status")),
+		"aor", ast_json_string_get(ast_json_object_get(obj->blob, "aor")),
+		"roundtrip_usec", ast_json_string_get(ast_json_object_get(obj->blob, "roundtrip_usec")));
+	if (!json_final) {
+		ast_json_unref(json_endpoint);
+	}
+
+	return json_final;
+}
+
+STASIS_MESSAGE_TYPE_DEFN(ast_endpoint_contact_state_type,
+	.to_ami = contactstatus_to_ami,
+	.to_json = contactstatus_to_json
+);
+
 static void endpoint_blob_dtor(void *obj)
 {
 	struct ast_endpoint_blob *event = obj;
diff --git a/main/taskprocessor.c b/main/taskprocessor.c
index 20a42fa..e8dc8f5 100644
--- a/main/taskprocessor.c
+++ b/main/taskprocessor.c
@@ -691,15 +691,25 @@ void *ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
 		return NULL;
 	}
 
+	/* To prevent another thread from finding and getting a reference to this
+	 * taskprocessor we hold the singletons lock. If we didn't do this then
+	 * they may acquire it and find that the listener has been shut down.
+	 */
+	ao2_lock(tps_singletons);
+
 	if (ao2_ref(tps, -1) > 3) {
+		ao2_unlock(tps_singletons);
 		return NULL;
 	}
+
 	/* If we're down to 3 references, then those must be:
 	 * 1. The reference we just got rid of
 	 * 2. The container
 	 * 3. The listener
 	 */
-	ao2_unlink(tps_singletons, tps);
+	ao2_unlink_flags(tps_singletons, tps, OBJ_NOLOCK);
+	ao2_unlock(tps_singletons);
+
 	listener_shutdown(tps->listener);
 	return NULL;
 }
diff --git a/main/translate.c b/main/translate.c
index 2b11d7b..6d92777 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -44,6 +44,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/cli.h"
 #include "asterisk/term.h"
 #include "asterisk/format.h"
+#include "asterisk/linkedlists.h"
 
 /*! \todo
  * TODO: sample frames for each supported input format.
@@ -547,7 +548,12 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
 	}
 	delivery = f->delivery;
 	for (out = f; out && p ; p = p->next) {
-		framein(p, out);
+		struct ast_frame *current = out;
+
+		do {
+			framein(p, current);
+			current = AST_LIST_NEXT(current, frame_list);
+		} while (current);
 		if (out != f) {
 			ast_frfree(out);
 		}
@@ -556,22 +562,33 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
 	if (out) {
 		/* we have a frame, play with times */
 		if (!ast_tvzero(delivery)) {
-			/* Regenerate prediction after a discontinuity */
-			if (ast_tvzero(path->nextout)) {
-				path->nextout = ast_tvnow();
-			}
+			struct ast_frame *current = out;
 
-			/* Use next predicted outgoing timestamp */
-			out->delivery = path->nextout;
+			do {
+				/* Regenerate prediction after a discontinuity */
+				if (ast_tvzero(path->nextout)) {
+					path->nextout = ast_tvnow();
+				}
 
-			/* Predict next outgoing timestamp from samples in this
-			   frame. */
-			path->nextout = ast_tvadd(path->nextout, ast_samp2tv(
-				 out->samples, ast_format_get_sample_rate(out->subclass.format)));
-			if (f->samples != out->samples && ast_test_flag(out, AST_FRFLAG_HAS_TIMING_INFO)) {
-				ast_debug(4, "Sample size different %d vs %d\n", f->samples, out->samples);
-				ast_clear_flag(out, AST_FRFLAG_HAS_TIMING_INFO);
-			}
+				/* Use next predicted outgoing timestamp */
+				current->delivery = path->nextout;
+
+				/* Invalidate prediction if we're entering a silence period */
+				if (current->frametype == AST_FRAME_CNG) {
+					path->nextout = ast_tv(0, 0);
+				/* Predict next outgoing timestamp from samples in this
+				   frame. */
+				} else {
+					path->nextout = ast_tvadd(path->nextout, ast_samp2tv(
+						current->samples, ast_format_get_sample_rate(current->subclass.format)));
+				}
+
+				if (f->samples != current->samples && ast_test_flag(current, AST_FRFLAG_HAS_TIMING_INFO)) {
+					ast_debug(4, "Sample size different %d vs %d\n", f->samples, current->samples);
+					ast_clear_flag(current, AST_FRFLAG_HAS_TIMING_INFO);
+				}
+				current = AST_LIST_NEXT(current, frame_list);
+			} while (current);
 		} else {
 			out->delivery = ast_tv(0, 0);
 			ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
@@ -580,10 +597,10 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
 				out->len = len;
 				out->seqno = seqno;
 			}
-		}
-		/* Invalidate prediction if we're entering a silence period */
-		if (out->frametype == AST_FRAME_CNG) {
-			path->nextout = ast_tv(0, 0);
+			/* Invalidate prediction if we're entering a silence period */
+			if (out->frametype == AST_FRAME_CNG) {
+				path->nextout = ast_tv(0, 0);
+			}
 		}
 	}
 	if (consume) {
diff --git a/main/utils.c b/main/utils.c
index f9a5be2..ffef3ac 100644
--- a/main/utils.c
+++ b/main/utils.c
@@ -1256,8 +1256,8 @@ int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*st
 		pthread_attr_init(attr);
 	}
 
-#ifdef __linux__
-	/* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
+#if defined(__linux__) || defined(__FreeBSD__)
+	/* On Linux and FreeBSD , pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
 	   which is kind of useless. Change this here to
 	   PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
 	   priority will propagate down to new threads by default.
diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c
index 6675896..389f83b 100644
--- a/res/ari/ari_model_validators.c
+++ b/res/ari/ari_model_validators.c
@@ -362,6 +362,92 @@ ari_validator ast_ari_validate_config_tuple_fn(void)
 	return ast_ari_validate_config_tuple;
 }
 
+int ast_ari_validate_log_channel(struct ast_json *json)
+{
+	int res = 1;
+	struct ast_json_iter *iter;
+	int has_channel = 0;
+	int has_configuration = 0;
+	int has_status = 0;
+	int has_type = 0;
+
+	for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+		if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_channel = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI LogChannel field channel failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("configuration", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_configuration = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI LogChannel field configuration failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("status", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_status = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI LogChannel field status failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_type = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI LogChannel field type failed validation\n");
+				res = 0;
+			}
+		} else
+		{
+			ast_log(LOG_ERROR,
+				"ARI LogChannel has undocumented field %s\n",
+				ast_json_object_iter_key(iter));
+			res = 0;
+		}
+	}
+
+	if (!has_channel) {
+		ast_log(LOG_ERROR, "ARI LogChannel missing required field channel\n");
+		res = 0;
+	}
+
+	if (!has_configuration) {
+		ast_log(LOG_ERROR, "ARI LogChannel missing required field configuration\n");
+		res = 0;
+	}
+
+	if (!has_status) {
+		ast_log(LOG_ERROR, "ARI LogChannel missing required field status\n");
+		res = 0;
+	}
+
+	if (!has_type) {
+		ast_log(LOG_ERROR, "ARI LogChannel missing required field type\n");
+		res = 0;
+	}
+
+	return res;
+}
+
+ari_validator ast_ari_validate_log_channel_fn(void)
+{
+	return ast_ari_validate_log_channel;
+}
+
 int ast_ari_validate_module(struct ast_json *json)
 {
 	int res = 1;
@@ -4094,6 +4180,180 @@ ari_validator ast_ari_validate_channel_varset_fn(void)
 	return ast_ari_validate_channel_varset;
 }
 
+int ast_ari_validate_contact_info(struct ast_json *json)
+{
+	int res = 1;
+	struct ast_json_iter *iter;
+	int has_aor = 0;
+	int has_contact_status = 0;
+	int has_uri = 0;
+
+	for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+		if (strcmp("aor", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_aor = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI ContactInfo field aor failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("contact_status", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_contact_status = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI ContactInfo field contact_status failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("roundtrip_usec", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI ContactInfo field roundtrip_usec failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("uri", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_uri = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI ContactInfo field uri failed validation\n");
+				res = 0;
+			}
+		} else
+		{
+			ast_log(LOG_ERROR,
+				"ARI ContactInfo has undocumented field %s\n",
+				ast_json_object_iter_key(iter));
+			res = 0;
+		}
+	}
+
+	if (!has_aor) {
+		ast_log(LOG_ERROR, "ARI ContactInfo missing required field aor\n");
+		res = 0;
+	}
+
+	if (!has_contact_status) {
+		ast_log(LOG_ERROR, "ARI ContactInfo missing required field contact_status\n");
+		res = 0;
+	}
+
+	if (!has_uri) {
+		ast_log(LOG_ERROR, "ARI ContactInfo missing required field uri\n");
+		res = 0;
+	}
+
+	return res;
+}
+
+ari_validator ast_ari_validate_contact_info_fn(void)
+{
+	return ast_ari_validate_contact_info;
+}
+
+int ast_ari_validate_contact_status_change(struct ast_json *json)
+{
+	int res = 1;
+	struct ast_json_iter *iter;
+	int has_type = 0;
+	int has_application = 0;
+	int has_contact_info = 0;
+	int has_endpoint = 0;
+
+	for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+		if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_type = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI ContactStatusChange field type failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("application", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_application = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI ContactStatusChange field application failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			prop_is_valid = ast_ari_validate_date(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI ContactStatusChange field timestamp failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("contact_info", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_contact_info = 1;
+			prop_is_valid = ast_ari_validate_contact_info(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI ContactStatusChange field contact_info failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("endpoint", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_endpoint = 1;
+			prop_is_valid = ast_ari_validate_endpoint(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI ContactStatusChange field endpoint failed validation\n");
+				res = 0;
+			}
+		} else
+		{
+			ast_log(LOG_ERROR,
+				"ARI ContactStatusChange has undocumented field %s\n",
+				ast_json_object_iter_key(iter));
+			res = 0;
+		}
+	}
+
+	if (!has_type) {
+		ast_log(LOG_ERROR, "ARI ContactStatusChange missing required field type\n");
+		res = 0;
+	}
+
+	if (!has_application) {
+		ast_log(LOG_ERROR, "ARI ContactStatusChange missing required field application\n");
+		res = 0;
+	}
+
+	if (!has_contact_info) {
+		ast_log(LOG_ERROR, "ARI ContactStatusChange missing required field contact_info\n");
+		res = 0;
+	}
+
+	if (!has_endpoint) {
+		ast_log(LOG_ERROR, "ARI ContactStatusChange missing required field endpoint\n");
+		res = 0;
+	}
+
+	return res;
+}
+
+ari_validator ast_ari_validate_contact_status_change_fn(void)
+{
+	return ast_ari_validate_contact_status_change;
+}
+
 int ast_ari_validate_device_state_changed(struct ast_json *json)
 {
 	int res = 1;
@@ -4393,7 +4653,7 @@ int ast_ari_validate_event(struct ast_json *json)
 
 	discriminator = ast_json_string_get(ast_json_object_get(json, "type"));
 	if (!discriminator) {
-		ast_log(LOG_ERROR, "ARI Event missing required field type");
+		ast_log(LOG_ERROR, "ARI Event missing required field type\n");
 		return 0;
 	}
 
@@ -4466,6 +4726,9 @@ int ast_ari_validate_event(struct ast_json *json)
 	if (strcmp("ChannelVarset", discriminator) == 0) {
 		return ast_ari_validate_channel_varset(json);
 	} else
+	if (strcmp("ContactStatusChange", discriminator) == 0) {
+		return ast_ari_validate_contact_status_change(json);
+	} else
 	if (strcmp("DeviceStateChanged", discriminator) == 0) {
 		return ast_ari_validate_device_state_changed(json);
 	} else
@@ -4475,6 +4738,9 @@ int ast_ari_validate_event(struct ast_json *json)
 	if (strcmp("EndpointStateChange", discriminator) == 0) {
 		return ast_ari_validate_endpoint_state_change(json);
 	} else
+	if (strcmp("PeerStatusChange", discriminator) == 0) {
+		return ast_ari_validate_peer_status_change(json);
+	} else
 	if (strcmp("PlaybackFinished", discriminator) == 0) {
 		return ast_ari_validate_playback_finished(json);
 	} else
@@ -4570,7 +4836,7 @@ int ast_ari_validate_message(struct ast_json *json)
 
 	discriminator = ast_json_string_get(ast_json_object_get(json, "type"));
 	if (!discriminator) {
-		ast_log(LOG_ERROR, "ARI Message missing required field type");
+		ast_log(LOG_ERROR, "ARI Message missing required field type\n");
 		return 0;
 	}
 
@@ -4643,6 +4909,9 @@ int ast_ari_validate_message(struct ast_json *json)
 	if (strcmp("ChannelVarset", discriminator) == 0) {
 		return ast_ari_validate_channel_varset(json);
 	} else
+	if (strcmp("ContactStatusChange", discriminator) == 0) {
+		return ast_ari_validate_contact_status_change(json);
+	} else
 	if (strcmp("DeviceStateChanged", discriminator) == 0) {
 		return ast_ari_validate_device_state_changed(json);
 	} else
@@ -4658,6 +4927,9 @@ int ast_ari_validate_message(struct ast_json *json)
 	if (strcmp("MissingParams", discriminator) == 0) {
 		return ast_ari_validate_missing_params(json);
 	} else
+	if (strcmp("PeerStatusChange", discriminator) == 0) {
+		return ast_ari_validate_peer_status_change(json);
+	} else
 	if (strcmp("PlaybackFinished", discriminator) == 0) {
 		return ast_ari_validate_playback_finished(json);
 	} else
@@ -4775,6 +5047,175 @@ ari_validator ast_ari_validate_missing_params_fn(void)
 	return ast_ari_validate_missing_params;
 }
 
+int ast_ari_validate_peer(struct ast_json *json)
+{
+	int res = 1;
+	struct ast_json_iter *iter;
+	int has_peer_status = 0;
+
+	for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+		if (strcmp("address", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI Peer field address failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("cause", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI Peer field cause failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("peer_status", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_peer_status = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI Peer field peer_status failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("port", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI Peer field port failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("time", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI Peer field time failed validation\n");
+				res = 0;
+			}
+		} else
+		{
+			ast_log(LOG_ERROR,
+				"ARI Peer has undocumented field %s\n",
+				ast_json_object_iter_key(iter));
+			res = 0;
+		}
+	}
+
+	if (!has_peer_status) {
+		ast_log(LOG_ERROR, "ARI Peer missing required field peer_status\n");
+		res = 0;
+	}
+
+	return res;
+}
+
+ari_validator ast_ari_validate_peer_fn(void)
+{
+	return ast_ari_validate_peer;
+}
+
+int ast_ari_validate_peer_status_change(struct ast_json *json)
+{
+	int res = 1;
+	struct ast_json_iter *iter;
+	int has_type = 0;
+	int has_application = 0;
+	int has_endpoint = 0;
+	int has_peer = 0;
+
+	for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+		if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_type = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI PeerStatusChange field type failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("application", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_application = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI PeerStatusChange field application failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			prop_is_valid = ast_ari_validate_date(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI PeerStatusChange field timestamp failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("endpoint", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_endpoint = 1;
+			prop_is_valid = ast_ari_validate_endpoint(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI PeerStatusChange field endpoint failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("peer", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_peer = 1;
+			prop_is_valid = ast_ari_validate_peer(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI PeerStatusChange field peer failed validation\n");
+				res = 0;
+			}
+		} else
+		{
+			ast_log(LOG_ERROR,
+				"ARI PeerStatusChange has undocumented field %s\n",
+				ast_json_object_iter_key(iter));
+			res = 0;
+		}
+	}
+
+	if (!has_type) {
+		ast_log(LOG_ERROR, "ARI PeerStatusChange missing required field type\n");
+		res = 0;
+	}
+
+	if (!has_application) {
+		ast_log(LOG_ERROR, "ARI PeerStatusChange missing required field application\n");
+		res = 0;
+	}
+
+	if (!has_endpoint) {
+		ast_log(LOG_ERROR, "ARI PeerStatusChange missing required field endpoint\n");
+		res = 0;
+	}
+
+	if (!has_peer) {
+		ast_log(LOG_ERROR, "ARI PeerStatusChange missing required field peer\n");
+		res = 0;
+	}
+
+	return res;
+}
+
+ari_validator ast_ari_validate_peer_status_change_fn(void)
+{
+	return ast_ari_validate_peer_status_change;
+}
+
 int ast_ari_validate_playback_finished(struct ast_json *json)
 {
 	int res = 1;
diff --git a/res/ari/ari_model_validators.h b/res/ari/ari_model_validators.h
index e122ded..0bcdb0f 100644
--- a/res/ari/ari_model_validators.h
+++ b/res/ari/ari_model_validators.h
@@ -225,6 +225,24 @@ int ast_ari_validate_config_tuple(struct ast_json *json);
 ari_validator ast_ari_validate_config_tuple_fn(void);
 
 /*!
+ * \brief Validator for LogChannel.
+ *
+ * Details of an Asterisk log channel
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_log_channel(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_log_channel().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_log_channel_fn(void);
+
+/*!
  * \brief Validator for Module.
  *
  * Details of an Asterisk module
@@ -989,6 +1007,42 @@ int ast_ari_validate_channel_varset(struct ast_json *json);
 ari_validator ast_ari_validate_channel_varset_fn(void);
 
 /*!
+ * \brief Validator for ContactInfo.
+ *
+ * Detailed information about a contact on an endpoint.
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_contact_info(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_contact_info().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_contact_info_fn(void);
+
+/*!
+ * \brief Validator for ContactStatusChange.
+ *
+ * The state of a contact on an endpoint has changed.
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_contact_status_change(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_contact_status_change().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_contact_status_change_fn(void);
+
+/*!
  * \brief Validator for DeviceStateChanged.
  *
  * Notification that a device state has changed.
@@ -1097,6 +1151,42 @@ int ast_ari_validate_missing_params(struct ast_json *json);
 ari_validator ast_ari_validate_missing_params_fn(void);
 
 /*!
+ * \brief Validator for Peer.
+ *
+ * Detailed information about a remote peer that communicates with Asterisk.
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_peer(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_peer().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_peer_fn(void);
+
+/*!
+ * \brief Validator for PeerStatusChange.
+ *
+ * The state of a peer associated with an endpoint has changed.
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_peer_status_change(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_peer_status_change().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_peer_status_change_fn(void);
+
+/*!
  * \brief Validator for PlaybackFinished.
  *
  * Event showing the completion of a media playback operation.
@@ -1283,6 +1373,11 @@ ari_validator ast_ari_validate_application_fn(void);
  * ConfigTuple
  * - attribute: string (required)
  * - value: string (required)
+ * LogChannel
+ * - channel: string (required)
+ * - configuration: string (required)
+ * - status: string (required)
+ * - type: string (required)
  * Module
  * - description: string (required)
  * - name: string (required)
@@ -1523,6 +1618,17 @@ ari_validator ast_ari_validate_application_fn(void);
  * - channel: Channel
  * - value: string (required)
  * - variable: string (required)
+ * ContactInfo
+ * - aor: string (required)
+ * - contact_status: string (required)
+ * - roundtrip_usec: string
+ * - uri: string (required)
+ * ContactStatusChange
+ * - type: string (required)
+ * - application: string (required)
+ * - timestamp: Date
+ * - contact_info: ContactInfo (required)
+ * - endpoint: Endpoint (required)
  * DeviceStateChanged
  * - type: string (required)
  * - application: string (required)
@@ -1552,6 +1658,18 @@ ari_validator ast_ari_validate_application_fn(void);
  * MissingParams
  * - type: string (required)
  * - params: List[string] (required)
+ * Peer
+ * - address: string
+ * - cause: string
+ * - peer_status: string (required)
+ * - port: string
+ * - time: string
+ * PeerStatusChange
+ * - type: string (required)
+ * - application: string (required)
+ * - timestamp: Date
+ * - endpoint: Endpoint (required)
+ * - peer: Peer (required)
  * PlaybackFinished
  * - type: string (required)
  * - application: string (required)
diff --git a/res/ari/ari_websockets.c b/res/ari/ari_websockets.c
index f3b764b..8e11629 100644
--- a/res/ari/ari_websockets.c
+++ b/res/ari/ari_websockets.c
@@ -163,9 +163,7 @@ int ast_ari_websocket_session_write(struct ast_ari_websocket_session *session,
 #ifdef AST_DEVMODE
 	if (!session->validator(message)) {
 		ast_log(LOG_ERROR, "Outgoing message failed validation\n");
-		return ast_websocket_write(session->ws_session,
-			AST_WEBSOCKET_OPCODE_TEXT, VALIDATION_FAILED,
-			strlen(VALIDATION_FAILED));
+		return ast_websocket_write_string(session->ws_session, VALIDATION_FAILED);
 	}
 #endif
 
@@ -176,9 +174,8 @@ int ast_ari_websocket_session_write(struct ast_ari_websocket_session *session,
 		return -1;
 	}
 
-	ast_debug(3, "Examining ARI event: \n%s\n", str);
-	if (ast_websocket_write(session->ws_session,
-				AST_WEBSOCKET_OPCODE_TEXT, str,	strlen(str))) {
+	ast_debug(3, "Examining ARI event (length %u): \n%s\n", (unsigned int) strlen(str), str);
+	if (ast_websocket_write_string(session->ws_session, str)) {
 		ast_log(LOG_NOTICE, "Problem occurred during websocket write, websocket closed\n");
 		return -1;
 	}
diff --git a/res/ari/config.c b/res/ari/config.c
index 667d91a..2d3a80d 100644
--- a/res/ari/config.c
+++ b/res/ari/config.c
@@ -116,19 +116,31 @@ static void *user_alloc(const char *cat)
 static int user_sort_cmp(const void *obj_left, const void *obj_right, int flags)
 {
 	const struct ast_ari_conf_user *user_left = obj_left;
-
-	if (flags & OBJ_PARTIAL_KEY) {
-		const char *key_right = obj_right;
-		return strncasecmp(user_left->username, key_right,
-			strlen(key_right));
-	} else if (flags & OBJ_KEY) {
-		const char *key_right = obj_right;
-		return strcasecmp(user_left->username, key_right);
-	} else {
-		const struct ast_ari_conf_user *user_right = obj_right;
-		const char *key_right = user_right->username;
-		return strcasecmp(user_left->username, key_right);
+	const struct ast_ari_conf_user *user_right = obj_right;
+	const char *key_right = obj_right;
+	int cmp;
+
+	switch (flags & OBJ_SEARCH_MASK) {
+	case OBJ_SEARCH_OBJECT:
+		key_right = user_right->username;
+		/* Fall through */
+	case OBJ_SEARCH_KEY:
+		cmp = strcasecmp(user_left->username, key_right);
+		break;
+	case OBJ_SEARCH_PARTIAL_KEY:
+		/*
+		 * We could also use a partial key struct containing a length
+		 * so strlen() does not get called for every comparison instead.
+		 */
+		cmp = strncasecmp(user_left->username, key_right, strlen(key_right));
+		break;
+	default:
+		/* Sort can only work on something with a full or partial key. */
+		ast_assert(0);
+		cmp = 0;
+		break;
 	}
+	return cmp;
 }
 
 /*! \brief \ref aco_type item_find function */
@@ -138,7 +150,7 @@ static void *user_find(struct ao2_container *tmp_container, const char *cat)
 		return NULL;
 	}
 
-	return ao2_find(tmp_container, cat, OBJ_KEY);
+	return ao2_find(tmp_container, cat, OBJ_SEARCH_KEY);
 }
 
 static struct aco_type user_option = {
@@ -155,13 +167,18 @@ static struct aco_type user_option = {
 
 static struct aco_type *user[] = ACO_TYPES(&user_option);
 
+static void conf_general_dtor(void *obj)
+{
+	struct ast_ari_conf_general *general = obj;
+
+	ast_string_field_free_memory(general);
+}
+
 /*! \brief \ref ast_ari_conf destructor. */
 static void conf_destructor(void *obj)
 {
 	struct ast_ari_conf *cfg = obj;
 
-	ast_string_field_free_memory(cfg->general);
-
 	ao2_cleanup(cfg->general);
 	ao2_cleanup(cfg->users);
 }
@@ -169,7 +186,7 @@ static void conf_destructor(void *obj)
 /*! \brief Allocate an \ref ast_ari_conf for config parsing */
 static void *conf_alloc(void)
 {
-	RAII_VAR(struct ast_ari_conf *, cfg, NULL, ao2_cleanup);
+	struct ast_ari_conf *cfg;
 
 	cfg = ao2_alloc_options(sizeof(*cfg), conf_destructor,
 		AO2_ALLOC_OPT_LOCK_NOLOCK);
@@ -177,21 +194,20 @@ static void *conf_alloc(void)
 		return NULL;
 	}
 
-	cfg->general = ao2_alloc_options(sizeof(*cfg->general), NULL,
+	cfg->general = ao2_alloc_options(sizeof(*cfg->general), conf_general_dtor,
 		AO2_ALLOC_OPT_LOCK_NOLOCK);
-	if (!cfg->general) {
-		return NULL;
-	}
-	aco_set_defaults(&general_option, "general", cfg->general);
-
-	if (ast_string_field_init(cfg->general, 64)) {
-		return NULL;
-	}
 
 	cfg->users = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_NOLOCK,
 		AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, user_sort_cmp, NULL);
 
-	ao2_ref(cfg, +1);
+	if (!cfg->users
+		|| !cfg->general
+		|| ast_string_field_init(cfg->general, 64)
+		|| aco_set_defaults(&general_option, "general", cfg->general)) {
+		ao2_ref(cfg, -1);
+		return NULL;
+	}
+
 	return cfg;
 }
 
@@ -230,7 +246,7 @@ struct ast_ari_conf_user *ast_ari_config_validate_user(const char *username,
 		return NULL;
 	}
 
-	user = ao2_find(conf->users, username, OBJ_KEY);
+	user = ao2_find(conf->users, username, OBJ_SEARCH_KEY);
 	if (!user) {
 		return NULL;
 	}
@@ -309,6 +325,7 @@ int ast_ari_config_init(void)
 		return -1;
 	}
 
+	/* ARI general category options */
 	aco_option_register(&cfg_info, "enabled", ACO_EXACT, general_options,
 		"yes", OPT_BOOL_T, 1,
 		FLDSET(struct ast_ari_conf_general, enabled));
@@ -325,6 +342,7 @@ int ast_ari_config_init(void)
 		AST_DEFAULT_WEBSOCKET_WRITE_TIMEOUT_STR, OPT_INT_T, PARSE_IN_RANGE,
 		FLDSET(struct ast_ari_conf_general, write_timeout), 1, INT_MAX);
 
+	/* ARI type=user category options */
 	aco_option_register(&cfg_info, "type", ACO_EXACT, user, NULL,
 		OPT_NOOP_T, 0, 0);
 	aco_option_register(&cfg_info, "read_only", ACO_EXACT, user,
diff --git a/res/ari/resource_asterisk.c b/res/ari/resource_asterisk.c
index 2b6b6bc..30684d2 100644
--- a/res/ari/resource_asterisk.c
+++ b/res/ari/resource_asterisk.c
@@ -33,6 +33,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include "asterisk/ast_version.h"
 #include "asterisk/buildinfo.h"
+#include "asterisk/logger.h"
 #include "asterisk/module.h"
 #include "asterisk/paths.h"
 #include "asterisk/pbx.h"
@@ -627,6 +628,132 @@ void ast_ari_asterisk_reload_module(struct ast_variable *headers,
 	ast_ari_response_no_content(response);
 }
 
+/*!
+ * \brief Process logger information and append to a json array
+ * \param channel Resource logger channel name path
+ * \param type Resource log type
+ * \param status Resource log status
+ * \param configuration Resource logger levels
+ * \param log_data_list Resource array
+ *
+ * \retval -1 if no resource exists
+ * \retval 0 if resource exists
+ */
+static int process_log_list(const char *channel, const char *type,
+	const char *status, const char *configuration, void *log_data_list)
+{
+	struct ast_json *logger_info;
+
+	logger_info = ast_json_pack("{s: s, s: s, s: s, s: s}",
+		"channel", channel, "type", type, "status", status, "configuration",
+		configuration);
+
+	if (!logger_info) {
+		return AST_LOGGER_FAILURE;
+	}
+
+	ast_json_array_append(log_data_list, logger_info);
+	return AST_LOGGER_SUCCESS;
+}
+
+void ast_ari_asterisk_list_log_channels(struct ast_variable *headers,
+	struct ast_ari_asterisk_list_log_channels_args *args,
+	struct ast_ari_response *response)
+{
+	struct ast_json *json;
+	int res;
+
+	json = ast_json_array_create();
+	res = ast_logger_get_channels(&process_log_list, json);
+
+	if (res == AST_LOGGER_FAILURE) {
+		ast_ari_response_error(response, 500, "Internal Server Error",
+			"Response body is not valid");
+		return;
+	} else if (res == AST_LOGGER_ALLOC_ERROR) {
+		ast_ari_response_error(response, 500, "Internal Server Error",
+			"Allocation Failed");
+		return;
+	}
+
+	ast_ari_response_ok(response, json);
+}
+
+void ast_ari_asterisk_add_log(struct ast_variable *headers,
+	struct ast_ari_asterisk_add_log_args *args,
+	struct ast_ari_response *response)
+{
+	int res;
+
+	ast_assert(response != NULL);
+
+	res = ast_logger_create_channel(args->log_channel_name, args->configuration);
+
+	if (res == AST_LOGGER_DECLINE) {
+		ast_ari_response_error(response, 400, "Bad Request",
+			"Configuration levels are required");
+		return;
+	} else if (res == AST_LOGGER_FAILURE) {
+		ast_ari_response_error(response, 409, "Conflict",
+			"Log channel already exists");
+		return;
+	} else if (res == AST_LOGGER_ALLOC_ERROR) {
+		ast_ari_response_error(response, 500, "Internal Server Error",
+			"Allocation failed");
+		return;
+	}
+
+	ast_ari_response_no_content(response);
+}
+
+void ast_ari_asterisk_rotate_log(struct ast_variable *headers,
+	struct ast_ari_asterisk_rotate_log_args *args,
+	struct ast_ari_response *response)
+{
+	int res;
+
+	ast_assert(response != NULL);
+
+	res = ast_logger_rotate_channel(args->log_channel_name);
+
+	if (res == AST_LOGGER_FAILURE) {
+		ast_ari_response_error(
+			response, 404, "Not Found",
+			"Log channel does not exist");
+		return;
+	} else if (res == AST_LOGGER_ALLOC_ERROR) {
+		ast_ari_response_error(
+			response, 500, "Internal Server Error",
+			"Allocation failed");
+		return;
+	}
+
+	ast_ari_response_no_content(response);
+}
+
+void ast_ari_asterisk_delete_log(struct ast_variable *headers,
+	struct ast_ari_asterisk_delete_log_args *args,
+	struct ast_ari_response *response)
+{
+	int res;
+
+	ast_assert(response != NULL);
+
+	res = ast_logger_remove_channel(args->log_channel_name);
+
+	if (res == AST_LOGGER_FAILURE) {
+		ast_ari_response_error(response, 404, "Not Found",
+			"Log channel does not exist");
+		return;
+	} else if (res == AST_LOGGER_ALLOC_ERROR) {
+		ast_ari_response_error(response, 500, "Internal Server Error",
+			"Allocation failed");
+		return;
+	}
+
+	ast_ari_response_no_content(response);
+}
+
 void ast_ari_asterisk_get_global_var(struct ast_variable *headers,
 	struct ast_ari_asterisk_get_global_var_args *args,
 	struct ast_ari_response *response)
diff --git a/res/ari/resource_asterisk.h b/res/ari/resource_asterisk.h
index 1afc093..a4a7da0 100644
--- a/res/ari/resource_asterisk.h
+++ b/res/ari/resource_asterisk.h
@@ -194,6 +194,69 @@ struct ast_ari_asterisk_reload_module_args {
  * \param[out] response HTTP response
  */
 void ast_ari_asterisk_reload_module(struct ast_variable *headers, struct ast_ari_asterisk_reload_module_args *args, struct ast_ari_response *response);
+/*! Argument struct for ast_ari_asterisk_list_log_channels() */
+struct ast_ari_asterisk_list_log_channels_args {
+};
+/*!
+ * \brief Gets Asterisk log channel information.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_asterisk_list_log_channels(struct ast_variable *headers, struct ast_ari_asterisk_list_log_channels_args *args, struct ast_ari_response *response);
+/*! Argument struct for ast_ari_asterisk_add_log() */
+struct ast_ari_asterisk_add_log_args {
+	/*! The log channel to add */
+	const char *log_channel_name;
+	/*! levels of the log channel */
+	const char *configuration;
+};
+/*!
+ * \brief Body parsing function for /asterisk/logging/{logChannelName}.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_asterisk_add_log_parse_body(
+	struct ast_json *body,
+	struct ast_ari_asterisk_add_log_args *args);
+
+/*!
+ * \brief Adds a log channel.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_asterisk_add_log(struct ast_variable *headers, struct ast_ari_asterisk_add_log_args *args, struct ast_ari_response *response);
+/*! Argument struct for ast_ari_asterisk_delete_log() */
+struct ast_ari_asterisk_delete_log_args {
+	/*! Log channels name */
+	const char *log_channel_name;
+};
+/*!
+ * \brief Deletes a log channel.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_asterisk_delete_log(struct ast_variable *headers, struct ast_ari_asterisk_delete_log_args *args, struct ast_ari_response *response);
+/*! Argument struct for ast_ari_asterisk_rotate_log() */
+struct ast_ari_asterisk_rotate_log_args {
+	/*! Log channel's name */
+	const char *log_channel_name;
+};
+/*!
+ * \brief Rotates a log channel.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_asterisk_rotate_log(struct ast_variable *headers, struct ast_ari_asterisk_rotate_log_args *args, struct ast_ari_response *response);
 /*! Argument struct for ast_ari_asterisk_get_global_var() */
 struct ast_ari_asterisk_get_global_var_args {
 	/*! The variable to get */
diff --git a/res/ari/resource_events.c b/res/ari/resource_events.c
index 09bcafc..71d54b4 100644
--- a/res/ari/resource_events.c
+++ b/res/ari/resource_events.c
@@ -148,9 +148,11 @@ static void app_handler(void *data, const char *app_name,
  * \brief Register for all of the apps given.
  * \param session Session info struct.
  * \param app_name Name of application to register.
+ * \param register_handler Pointer to the application registration handler
  */
 static int session_register_app(struct event_session *session,
-				 const char *app_name)
+				 const char *app_name,
+				 int (* register_handler)(const char *, stasis_app_cb handler, void *data))
 {
 	SCOPED_AO2LOCK(lock, session);
 
@@ -167,7 +169,7 @@ static int session_register_app(struct event_session *session,
 		return -1;
 	}
 
-	stasis_app_register(app_name, app_handler, session);
+	register_handler(app_name, app_handler, session);
 
 	return 0;
 }
@@ -178,6 +180,7 @@ int ast_ari_websocket_events_event_websocket_attempted(struct ast_tcptls_session
 {
 	int res = 0;
 	size_t i, j;
+	int (* register_handler)(const char *, stasis_app_cb handler, void *data);
 
 	ast_debug(3, "/events WebSocket attempted\n");
 
@@ -186,13 +189,19 @@ int ast_ari_websocket_events_event_websocket_attempted(struct ast_tcptls_session
 		return -1;
 	}
 
+	if (args->subscribe_all) {
+		register_handler = &stasis_app_register_all;
+	} else {
+		register_handler = &stasis_app_register;
+	}
+
 	for (i = 0; i < args->app_count; ++i) {
 		if (ast_strlen_zero(args->app[i])) {
 			res = -1;
 			break;
 		}
 
-		res |= stasis_app_register(args->app[i], app_handler, NULL);
+		res |= register_handler(args->app[i], app_handler, NULL);
 	}
 
 	if (res) {
@@ -213,6 +222,7 @@ void ast_ari_websocket_events_event_websocket_established(struct ast_ari_websock
 	struct ast_json *msg;
 	int res;
 	size_t i;
+	int (* register_handler)(const char *, stasis_app_cb handler, void *data);
 
 	ast_debug(3, "/events WebSocket connection\n");
 
@@ -222,12 +232,18 @@ void ast_ari_websocket_events_event_websocket_established(struct ast_ari_websock
 		return;
 	}
 
+	if (args->subscribe_all) {
+		register_handler = &stasis_app_register_all;
+	} else {
+		register_handler = &stasis_app_register;
+	}
+
 	res = 0;
 	for (i = 0; i < args->app_count; ++i) {
 		if (ast_strlen_zero(args->app[i])) {
 			continue;
 		}
-		res |= session_register_app(session, args->app[i]);
+		res |= session_register_app(session, args->app[i], register_handler);
 	}
 
 	if (ao2_container_count(session->websocket_apps) == 0) {
diff --git a/res/ari/resource_events.h b/res/ari/resource_events.h
index 2b63181..c482699 100644
--- a/res/ari/resource_events.h
+++ b/res/ari/resource_events.h
@@ -47,6 +47,8 @@ struct ast_ari_events_event_websocket_args {
 	size_t app_count;
 	/*! Parsing context for app. */
 	char *app_parse;
+	/*! Subscribe to all Asterisk events. If provided, the applications listed will be subscribed to all events, effectively disabling the application specific subscriptions. Default is 'false'. */
+	int subscribe_all;
 };
 
 /*!
diff --git a/res/parking/parking_applications.c b/res/parking/parking_applications.c
index 733c943..d8cda6f 100644
--- a/res/parking/parking_applications.c
+++ b/res/parking/parking_applications.c
@@ -694,6 +694,68 @@ static struct park_announce_subscription_data *park_announce_subscription_data_c
 	return pa_data;
 }
 
+/*! \internal
+ * \brief Gathers inheritable channel variables from a channel by name.
+ *
+ * \param oh outgoing helper struct we are bestowing inheritable variables to
+ * \param channel_id name or uniqueID of the channel to inherit variables from
+ *
+ * \return Nothing
+ */
+static void inherit_channel_vars_from_id(struct outgoing_helper *oh, const char *channel_id)
+{
+	struct ast_channel *chan = ast_channel_get_by_name(channel_id);
+	struct ast_var_t *current;
+	struct ast_variable *newvar;
+	const char *varname;
+	int vartype;
+
+
+	if (!chan) {
+		/* Already gone */
+		return;
+	}
+
+	ast_channel_lock(chan);
+
+	AST_LIST_TRAVERSE(ast_channel_varshead((struct ast_channel *) chan), current, entries) {
+		varname = ast_var_full_name(current);
+		if (!varname) {
+			continue;
+		}
+
+		vartype = 0;
+		if (varname[0] == '_') {
+			vartype = 1;
+			if (varname[1] == '_') {
+				vartype = 2;
+			}
+		}
+
+		switch (vartype) {
+		case 1:
+			newvar = ast_variable_new(&varname[1], ast_var_value(current), "");
+			break;
+		case 2:
+			newvar = ast_variable_new(varname, ast_var_value(current), "");
+			break;
+		default:
+			continue;
+		}
+		if (newvar) {
+			ast_debug(1, "Inheriting variable %s from %s.\n",
+				newvar->name, ast_channel_name(chan));
+			if (oh->vars) {
+				newvar->next = oh->vars;
+				oh->vars = newvar;
+			}
+		}
+	}
+
+	ast_channel_unlock(chan);
+	ast_channel_cleanup(chan);
+}
+
 static void announce_to_dial(char *dial_string, char *announce_string, int parkingspace, struct ast_channel_snapshot *parkee_snapshot)
 {
 	struct ast_channel *dchan;
@@ -715,6 +777,9 @@ static void announce_to_dial(char *dial_string, char *announce_string, int parki
 
 	snprintf(buf, sizeof(buf), "%d", parkingspace);
 	oh.vars = ast_variable_new("_PARKEDAT", buf, "");
+
+	inherit_channel_vars_from_id(&oh, parkee_snapshot->uniqueid);
+
 	dchan = __ast_request_and_dial(dial_tech, cap_slin, NULL, NULL, dial_string, 30000,
 		&outstate,
 		parkee_snapshot->caller_number,
diff --git a/res/res_ari.c b/res/res_ari.c
index 761c2dd..f39db16 100644
--- a/res/res_ari.c
+++ b/res/res_ari.c
@@ -180,8 +180,7 @@ int ast_ari_add_handler(struct stasis_rest_handlers *handler)
 
 	SCOPED_MUTEX(lock, &root_handler_lock);
 
-	old_size = sizeof(*new_handler) +
-		root_handler->num_children * sizeof(handler);
+	old_size = sizeof(*new_handler) + root_handler->num_children * sizeof(handler);
 	new_size = old_size + sizeof(handler);
 
 	new_handler = ao2_alloc(new_size, NULL);
@@ -200,21 +199,24 @@ int ast_ari_add_handler(struct stasis_rest_handlers *handler)
 
 int ast_ari_remove_handler(struct stasis_rest_handlers *handler)
 {
-	RAII_VAR(struct stasis_rest_handlers *, new_handler, NULL, ao2_cleanup);
-	size_t size, i, j;
+	struct stasis_rest_handlers *new_handler;
+	size_t size;
+	size_t i;
+	size_t j;
 
 	ast_assert(root_handler != NULL);
 
 	ast_mutex_lock(&root_handler_lock);
-	size = sizeof(*new_handler) +
-		root_handler->num_children * sizeof(handler);
+	size = sizeof(*new_handler) + root_handler->num_children * sizeof(handler);
 
 	new_handler = ao2_alloc(size, NULL);
 	if (!new_handler) {
+		ast_mutex_unlock(&root_handler_lock);
 		return -1;
 	}
-	memcpy(new_handler, root_handler, sizeof(*new_handler));
 
+	/* Create replacement root_handler less the handler to remove. */
+	memcpy(new_handler, root_handler, sizeof(*new_handler));
 	for (i = 0, j = 0; i < root_handler->num_children; ++i) {
 		if (root_handler->children[i] == handler) {
 			ast_module_unref(ast_module_info->self);
@@ -224,9 +226,10 @@ int ast_ari_remove_handler(struct stasis_rest_handlers *handler)
 	}
 	new_handler->num_children = j;
 
+	/* Replace the old root_handler with the new. */
 	ao2_cleanup(root_handler);
-	ao2_ref(new_handler, +1);
 	root_handler = new_handler;
+
 	ast_mutex_unlock(&root_handler_lock);
 	return 0;
 }
diff --git a/res/res_ari_asterisk.c b/res/res_ari_asterisk.c
index ea8ddbb..fe6e3d3 100644
--- a/res/res_ari_asterisk.c
+++ b/res/res_ari_asterisk.c
@@ -721,6 +721,273 @@ static void ast_ari_asterisk_reload_module_cb(
 fin: __attribute__((unused))
 	return;
 }
+/*!
+ * \brief Parameter parsing callback for /asterisk/logging.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_asterisk_list_log_channels_cb(
+	struct ast_tcptls_session_instance *ser,
+	struct ast_variable *get_params, struct ast_variable *path_vars,
+	struct ast_variable *headers, struct ast_ari_response *response)
+{
+	struct ast_ari_asterisk_list_log_channels_args args = {};
+	RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+#if defined(AST_DEVMODE)
+	int is_valid;
+	int code;
+#endif /* AST_DEVMODE */
+
+	ast_ari_asterisk_list_log_channels(headers, &args, response);
+#if defined(AST_DEVMODE)
+	code = response->response_code;
+
+	switch (code) {
+	case 0: /* Implementation is still a stub, or the code wasn't set */
+		is_valid = response->message == NULL;
+		break;
+	case 500: /* Internal Server Error */
+	case 501: /* Not Implemented */
+		is_valid = 1;
+		break;
+	default:
+		if (200 <= code && code <= 299) {
+			is_valid = ast_ari_validate_list(response->message,
+				ast_ari_validate_log_channel_fn());
+		} else {
+			ast_log(LOG_ERROR, "Invalid error response %d for /asterisk/logging\n", code);
+			is_valid = 0;
+		}
+	}
+
+	if (!is_valid) {
+		ast_log(LOG_ERROR, "Response validation failed for /asterisk/logging\n");
+		ast_ari_response_error(response, 500,
+			"Internal Server Error", "Response validation failed");
+	}
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+	return;
+}
+int ast_ari_asterisk_add_log_parse_body(
+	struct ast_json *body,
+	struct ast_ari_asterisk_add_log_args *args)
+{
+	struct ast_json *field;
+	/* Parse query parameters out of it */
+	field = ast_json_object_get(body, "configuration");
+	if (field) {
+		args->configuration = ast_json_string_get(field);
+	}
+	return 0;
+}
+
+/*!
+ * \brief Parameter parsing callback for /asterisk/logging/{logChannelName}.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_asterisk_add_log_cb(
+	struct ast_tcptls_session_instance *ser,
+	struct ast_variable *get_params, struct ast_variable *path_vars,
+	struct ast_variable *headers, struct ast_ari_response *response)
+{
+	struct ast_ari_asterisk_add_log_args args = {};
+	struct ast_variable *i;
+	RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+#if defined(AST_DEVMODE)
+	int is_valid;
+	int code;
+#endif /* AST_DEVMODE */
+
+	for (i = get_params; i; i = i->next) {
+		if (strcmp(i->name, "configuration") == 0) {
+			args.configuration = (i->value);
+		} else
+		{}
+	}
+	for (i = path_vars; i; i = i->next) {
+		if (strcmp(i->name, "logChannelName") == 0) {
+			args.log_channel_name = (i->value);
+		} else
+		{}
+	}
+	/* Look for a JSON request entity */
+	body = ast_http_get_json(ser, headers);
+	if (!body) {
+		switch (errno) {
+		case EFBIG:
+			ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+			goto fin;
+		case ENOMEM:
+			ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+			goto fin;
+		case EIO:
+			ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+			goto fin;
+		}
+	}
+	if (ast_ari_asterisk_add_log_parse_body(body, &args)) {
+		ast_ari_response_alloc_failed(response);
+		goto fin;
+	}
+	ast_ari_asterisk_add_log(headers, &args, response);
+#if defined(AST_DEVMODE)
+	code = response->response_code;
+
+	switch (code) {
+	case 0: /* Implementation is still a stub, or the code wasn't set */
+		is_valid = response->message == NULL;
+		break;
+	case 500: /* Internal Server Error */
+	case 501: /* Not Implemented */
+	case 400: /* Bad request body */
+	case 409: /* Log channel could not be created. */
+		is_valid = 1;
+		break;
+	default:
+		if (200 <= code && code <= 299) {
+			is_valid = ast_ari_validate_void(
+				response->message);
+		} else {
+			ast_log(LOG_ERROR, "Invalid error response %d for /asterisk/logging/{logChannelName}\n", code);
+			is_valid = 0;
+		}
+	}
+
+	if (!is_valid) {
+		ast_log(LOG_ERROR, "Response validation failed for /asterisk/logging/{logChannelName}\n");
+		ast_ari_response_error(response, 500,
+			"Internal Server Error", "Response validation failed");
+	}
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+	return;
+}
+/*!
+ * \brief Parameter parsing callback for /asterisk/logging/{logChannelName}.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_asterisk_delete_log_cb(
+	struct ast_tcptls_session_instance *ser,
+	struct ast_variable *get_params, struct ast_variable *path_vars,
+	struct ast_variable *headers, struct ast_ari_response *response)
+{
+	struct ast_ari_asterisk_delete_log_args args = {};
+	struct ast_variable *i;
+	RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+#if defined(AST_DEVMODE)
+	int is_valid;
+	int code;
+#endif /* AST_DEVMODE */
+
+	for (i = path_vars; i; i = i->next) {
+		if (strcmp(i->name, "logChannelName") == 0) {
+			args.log_channel_name = (i->value);
+		} else
+		{}
+	}
+	ast_ari_asterisk_delete_log(headers, &args, response);
+#if defined(AST_DEVMODE)
+	code = response->response_code;
+
+	switch (code) {
+	case 0: /* Implementation is still a stub, or the code wasn't set */
+		is_valid = response->message == NULL;
+		break;
+	case 500: /* Internal Server Error */
+	case 501: /* Not Implemented */
+	case 404: /* Log channel does not exist. */
+		is_valid = 1;
+		break;
+	default:
+		if (200 <= code && code <= 299) {
+			is_valid = ast_ari_validate_void(
+				response->message);
+		} else {
+			ast_log(LOG_ERROR, "Invalid error response %d for /asterisk/logging/{logChannelName}\n", code);
+			is_valid = 0;
+		}
+	}
+
+	if (!is_valid) {
+		ast_log(LOG_ERROR, "Response validation failed for /asterisk/logging/{logChannelName}\n");
+		ast_ari_response_error(response, 500,
+			"Internal Server Error", "Response validation failed");
+	}
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+	return;
+}
+/*!
+ * \brief Parameter parsing callback for /asterisk/logging/{logChannelName}/rotate.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_asterisk_rotate_log_cb(
+	struct ast_tcptls_session_instance *ser,
+	struct ast_variable *get_params, struct ast_variable *path_vars,
+	struct ast_variable *headers, struct ast_ari_response *response)
+{
+	struct ast_ari_asterisk_rotate_log_args args = {};
+	struct ast_variable *i;
+	RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+#if defined(AST_DEVMODE)
+	int is_valid;
+	int code;
+#endif /* AST_DEVMODE */
+
+	for (i = path_vars; i; i = i->next) {
+		if (strcmp(i->name, "logChannelName") == 0) {
+			args.log_channel_name = (i->value);
+		} else
+		{}
+	}
+	ast_ari_asterisk_rotate_log(headers, &args, response);
+#if defined(AST_DEVMODE)
+	code = response->response_code;
+
+	switch (code) {
+	case 0: /* Implementation is still a stub, or the code wasn't set */
+		is_valid = response->message == NULL;
+		break;
+	case 500: /* Internal Server Error */
+	case 501: /* Not Implemented */
+	case 404: /* Log channel does not exist. */
+		is_valid = 1;
+		break;
+	default:
+		if (200 <= code && code <= 299) {
+			is_valid = ast_ari_validate_void(
+				response->message);
+		} else {
+			ast_log(LOG_ERROR, "Invalid error response %d for /asterisk/logging/{logChannelName}/rotate\n", code);
+			is_valid = 0;
+		}
+	}
+
+	if (!is_valid) {
+		ast_log(LOG_ERROR, "Response validation failed for /asterisk/logging/{logChannelName}/rotate\n");
+		ast_ari_response_error(response, 500,
+			"Internal Server Error", "Response validation failed");
+	}
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+	return;
+}
 int ast_ari_asterisk_get_global_var_parse_body(
 	struct ast_json *body,
 	struct ast_ari_asterisk_get_global_var_args *args)
@@ -989,6 +1256,35 @@ static struct stasis_rest_handlers asterisk_modules = {
 	.children = { &asterisk_modules_moduleName, }
 };
 /*! \brief REST handler for /api-docs/asterisk.{format} */
+static struct stasis_rest_handlers asterisk_logging_logChannelName_rotate = {
+	.path_segment = "rotate",
+	.callbacks = {
+		[AST_HTTP_PUT] = ast_ari_asterisk_rotate_log_cb,
+	},
+	.num_children = 0,
+	.children = {  }
+};
+/*! \brief REST handler for /api-docs/asterisk.{format} */
+static struct stasis_rest_handlers asterisk_logging_logChannelName = {
+	.path_segment = "logChannelName",
+	.is_wildcard = 1,
+	.callbacks = {
+		[AST_HTTP_POST] = ast_ari_asterisk_add_log_cb,
+		[AST_HTTP_DELETE] = ast_ari_asterisk_delete_log_cb,
+	},
+	.num_children = 1,
+	.children = { &asterisk_logging_logChannelName_rotate, }
+};
+/*! \brief REST handler for /api-docs/asterisk.{format} */
+static struct stasis_rest_handlers asterisk_logging = {
+	.path_segment = "logging",
+	.callbacks = {
+		[AST_HTTP_GET] = ast_ari_asterisk_list_log_channels_cb,
+	},
+	.num_children = 1,
+	.children = { &asterisk_logging_logChannelName, }
+};
+/*! \brief REST handler for /api-docs/asterisk.{format} */
 static struct stasis_rest_handlers asterisk_variable = {
 	.path_segment = "variable",
 	.callbacks = {
@@ -1003,8 +1299,8 @@ static struct stasis_rest_handlers asterisk = {
 	.path_segment = "asterisk",
 	.callbacks = {
 	},
-	.num_children = 4,
-	.children = { &asterisk_config,&asterisk_info,&asterisk_modules,&asterisk_variable, }
+	.num_children = 5,
+	.children = { &asterisk_config,&asterisk_info,&asterisk_modules,&asterisk_logging,&asterisk_variable, }
 };
 
 static int load_module(void)
diff --git a/res/res_ari_events.c b/res/res_ari_events.c
index 4265385..65bd38d 100644
--- a/res/res_ari_events.c
+++ b/res/res_ari_events.c
@@ -110,6 +110,9 @@ static int ast_ari_events_event_websocket_ws_attempted_cb(struct ast_tcptls_sess
 				args.app[j] = (vals[j]);
 			}
 		} else
+		if (strcmp(i->name, "subscribeAll") == 0) {
+			args.subscribe_all = ast_true(i->value);
+		} else
 		{}
 	}
 
@@ -208,6 +211,9 @@ static void ast_ari_events_event_websocket_ws_established_cb(struct ast_websocke
 				args.app[j] = (vals[j]);
 			}
 		} else
+		if (strcmp(i->name, "subscribeAll") == 0) {
+			args.subscribe_all = ast_true(i->value);
+		} else
 		{}
 	}
 
diff --git a/res/res_config_sqlite.c b/res/res_config_sqlite.c
index fe2fb3c..b97ef7a 100644
--- a/res/res_config_sqlite.c
+++ b/res/res_config_sqlite.c
@@ -781,8 +781,16 @@ static int cdr_handler(struct ast_cdr *cdr)
 	struct ast_str *sql1 = ast_str_create(160), *sql2 = ast_str_create(16);
 	int first = 1;
 
+	if (!sql1 || !sql2) {
+		ast_free(sql1);
+		ast_free(sql2);
+		return -1;
+	}
+
 	if (!tbl) {
 		ast_log(LOG_WARNING, "No such table: %s\n", cdr_table);
+		ast_free(sql1);
+		ast_free(sql2);
 		return -1;
 	}
 
diff --git a/res/res_format_attr_silk.c b/res/res_format_attr_silk.c
index 3a8ca60..dcbbe4c 100644
--- a/res/res_format_attr_silk.c
+++ b/res/res_format_attr_silk.c
@@ -200,12 +200,36 @@ static struct ast_format *silk_set(const struct ast_format *format, const char *
 	return cloned;
 }
 
+static const void *silk_get(const struct ast_format *format, const char *name)
+{
+	struct silk_attr *attr = ast_format_get_attribute_data(format);
+	unsigned int *val;
+
+	if (!strcasecmp(name, "sample_rate")) {
+		val = &attr->samplerate;
+	} else if (!strcasecmp(name, "max_bitrate")) {
+		val = &attr->maxbitrate;
+	} else if (!strcasecmp(name, "dtx")) {
+		val = &attr->dtx;
+	} else if (!strcasecmp(name, "fec")) {
+		val = &attr->fec;
+	} else if (!strcasecmp(name, "packetloss_percentage")) {
+		val = &attr->packetloss_percentage;
+	} else {
+		ast_log(LOG_WARNING, "unknown attribute type %s\n", name);
+		return NULL;
+	}
+
+	return val;
+}
+
 static struct ast_format_interface silk_interface = {
 	.format_destroy = silk_destroy,
 	.format_clone = silk_clone,
 	.format_cmp = silk_cmp,
 	.format_get_joint = silk_getjoint,
 	.format_attribute_set = silk_set,
+	.format_attribute_get = silk_get,
 	.format_parse_sdp_fmtp = silk_parse_sdp_fmtp,
 	.format_generate_sdp_fmtp = silk_generate_sdp_fmtp,
 };
diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c
index 1f1f77c..b6baa3c 100644
--- a/res/res_http_websocket.c
+++ b/res/res_http_websocket.c
@@ -167,9 +167,11 @@ static void session_destroy_fn(void *obj)
 
 	if (session->f) {
 		ast_websocket_close(session, 0);
-		fclose(session->f);
-		ast_verb(2, "WebSocket connection %s '%s' closed\n", session->client ? "to" : "from",
-			ast_sockaddr_stringify(&session->address));
+		if (session->f) {
+			fclose(session->f);
+			ast_verb(2, "WebSocket connection %s '%s' closed\n", session->client ? "to" : "from",
+				ast_sockaddr_stringify(&session->address));
+		}
 	}
 
 	ao2_cleanup(session->client);
@@ -205,7 +207,6 @@ int AST_OPTIONAL_API_NAME(ast_websocket_server_add_protocol)(struct ast_websocke
 
 	protocol = ast_websocket_sub_protocol_alloc(name);
 	if (!protocol) {
-		ao2_unlock(server->protocols);
 		return -1;
 	}
 	protocol->session_established = callback;
@@ -294,10 +295,39 @@ int AST_OPTIONAL_API_NAME(ast_websocket_close)(struct ast_websocket *session, ui
 
 	ao2_lock(session);
 	res = ast_careful_fwrite(session->f, session->fd, frame, 4, session->timeout);
+
+	/* If an error occurred when trying to close this connection explicitly terminate it now.
+	 * Doing so will cause the thread polling on it to wake up and terminate.
+	 */
+	if (res) {
+		fclose(session->f);
+		session->f = NULL;
+		ast_verb(2, "WebSocket connection %s '%s' forcefully closed due to fatal write error\n",
+			session->client ? "to" : "from", ast_sockaddr_stringify(&session->address));
+	}
+
 	ao2_unlock(session);
 	return res;
 }
 
+static const char *opcode_map[] = {
+	[AST_WEBSOCKET_OPCODE_CONTINUATION] = "continuation",
+	[AST_WEBSOCKET_OPCODE_TEXT] = "text",
+	[AST_WEBSOCKET_OPCODE_BINARY] = "binary",
+	[AST_WEBSOCKET_OPCODE_CLOSE] = "close",
+	[AST_WEBSOCKET_OPCODE_PING] = "ping",
+	[AST_WEBSOCKET_OPCODE_PONG] = "pong",
+};
+
+static const char *websocket_opcode2str(enum ast_websocket_opcode opcode)
+{
+	if (opcode < AST_WEBSOCKET_OPCODE_CONTINUATION ||
+			opcode > AST_WEBSOCKET_OPCODE_PONG) {
+		return "<unknown>";
+	} else {
+		return opcode_map[opcode];
+	}
+}
 
 /*! \brief Write function for websocket traffic */
 int AST_OPTIONAL_API_NAME(ast_websocket_write)(struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t actual_length)
@@ -306,6 +336,9 @@ int AST_OPTIONAL_API_NAME(ast_websocket_write)(struct ast_websocket *session, en
 	char *frame;
 	uint64_t length;
 
+	ast_debug(3, "Writing websocket %s frame, length %" PRIu64 "\n",
+			websocket_opcode2str(opcode), actual_length);
+
 	if (actual_length < 126) {
 		length = actual_length;
 	} else if (actual_length < (1 << 16)) {
@@ -328,7 +361,7 @@ int AST_OPTIONAL_API_NAME(ast_websocket_write)(struct ast_websocket *session, en
 	if (length == 126) {
 		put_unaligned_uint16(&frame[2], htons(actual_length));
 	} else if (length == 127) {
-		put_unaligned_uint64(&frame[2], htonl(actual_length));
+		put_unaligned_uint64(&frame[2], htonll(actual_length));
 	}
 
 	ao2_lock(session);
@@ -449,6 +482,13 @@ static inline int ws_safe_read(struct ast_websocket *session, char *buf, int len
 	char *rbuf = buf;
 	int sanity = 10;
 
+	ao2_lock(session);
+	if (!session->f) {
+		ao2_unlock(session);
+		errno = ECONNABORTED;
+		return -1;
+	}
+
 	for (;;) {
 		clearerr(session->f);
 		rlen = fread(rbuf, 1, xlen, session->f);
@@ -457,6 +497,7 @@ static inline int ws_safe_read(struct ast_websocket *session, char *buf, int len
 				ast_log(LOG_WARNING, "Web socket closed abruptly\n");
 				*opcode = AST_WEBSOCKET_OPCODE_CLOSE;
 				session->closing = 1;
+				ao2_unlock(session);
 				return -1;
 			}
 
@@ -464,6 +505,7 @@ static inline int ws_safe_read(struct ast_websocket *session, char *buf, int len
 				ast_log(LOG_ERROR, "Error reading from web socket: %s\n", strerror(errno));
 				*opcode = AST_WEBSOCKET_OPCODE_CLOSE;
 				session->closing = 1;
+				ao2_unlock(session);
 				return -1;
 			}
 
@@ -471,6 +513,7 @@ static inline int ws_safe_read(struct ast_websocket *session, char *buf, int len
 				ast_log(LOG_WARNING, "Websocket seems unresponsive, disconnecting ...\n");
 				*opcode = AST_WEBSOCKET_OPCODE_CLOSE;
 				session->closing = 1;
+				ao2_unlock(session);
 				return -1;
 			}
 		}
@@ -483,9 +526,12 @@ static inline int ws_safe_read(struct ast_websocket *session, char *buf, int len
 			ast_log(LOG_ERROR, "ast_wait_for_input returned err: %s\n", strerror(errno));
 			*opcode = AST_WEBSOCKET_OPCODE_CLOSE;
 			session->closing = 1;
+			ao2_unlock(session);
 			return -1;
 		}
 	}
+
+	ao2_unlock(session);
 	return 0;
 }
 
@@ -502,7 +548,7 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha
 	*fragmented = 0;
 
 	if (ws_safe_read(session, &buf[0], MIN_WS_HDR_SZ, opcode)) {
-		return 0;
+		return -1;
 	}
 	frame_size += MIN_WS_HDR_SZ;
 
@@ -520,7 +566,7 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha
 		if (options_len) {
 			/* read the rest of the header options */
 			if (ws_safe_read(session, &buf[frame_size], options_len, opcode)) {
-				return 0;
+				return -1;
 			}
 			frame_size += options_len;
 		}
@@ -549,7 +595,7 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha
 		}
 
 		if (ws_safe_read(session, *payload, *payload_len, opcode)) {
-			return 0;
+			return -1;
 		}
 		/* If a mask is present unmask the payload */
 		if (mask_present) {
@@ -572,7 +618,7 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha
 					session->payload, session->payload_len, *payload_len);
 				*payload_len = 0;
 				ast_websocket_close(session, 1009);
-				return 0;
+				return -1;
 			}
 
 			session->payload = new_payload;
@@ -609,7 +655,7 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha
 		/* Make the payload available so the user can look at the reason code if they so desire */
 		if ((*payload_len) && (new_payload = ast_realloc(session->payload, *payload_len))) {
 			if (ws_safe_read(session, &buf[frame_size], (*payload_len), opcode)) {
-				return 0;
+				return -1;
 			}
 			session->payload = new_payload;
 			memcpy(session->payload, &buf[frame_size], *payload_len);
@@ -777,6 +823,7 @@ int AST_OPTIONAL_API_NAME(ast_websocket_uri_cb)(struct ast_tcptls_session_instan
 		    && protocol_handler->session_attempted(ser, get_vars, headers)) {
 			ast_debug(3, "WebSocket connection from '%s' rejected by protocol handler '%s'\n",
 				ast_sockaddr_stringify(&ser->remote_address), protocol_handler->name);
+			websocket_bad_request(ser);
 			ao2_ref(protocol_handler, -1);
 			return 0;
 		}
@@ -1354,8 +1401,19 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read_string)
 int AST_OPTIONAL_API_NAME(ast_websocket_write_string)
 	(struct ast_websocket *ws, const char *buf)
 {
+	uint64_t len = strlen(buf);
+
+	ast_debug(3, "Writing websocket string of length %" PRIu64 "\n", len);
+
+	/* We do not pass strlen(buf) to ast_websocket_write() directly because the
+	 * size_t returned by strlen() may not require the same storage size
+	 * as the uint64_t that ast_websocket_write() uses. This normally
+	 * would not cause a problem, but since ast_websocket_write() uses
+	 * the optional API, this function call goes through a series of macros
+	 * that may cause a 32-bit to 64-bit conversion to go awry.
+	 */
 	return ast_websocket_write(ws, AST_WEBSOCKET_OPCODE_TEXT,
-				   (char *)buf, strlen(buf));
+				   (char *)buf, len);
 }
 
 static int load_module(void)
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index 43e3da6..46edd31 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -40,6 +40,8 @@
 #include "asterisk/file.h"
 #include "asterisk/cli.h"
 #include "asterisk/res_pjsip_cli.h"
+#include "asterisk/test.h"
+#include "asterisk/res_pjsip_presence_xml.h"
 
 /*** MODULEINFO
 	<depend>pjproject</depend>
@@ -1281,6 +1283,11 @@
                                         Identifier names are usually derived from and can be found in the endpoint
                                         identifier module itself (res_pjsip_endpoint_identifier_*)</synopsis>
 				</configOption>
+				<configOption name="default_from_user" default="asterisk">
+					<synopsis>When Asterisk generates an outgoing SIP request, the From header username will be
+                                        set to this value if there is no better option (such as CallerID) to be
+                                        used.</synopsis>
+				</configOption>
 			</configObject>
 		</configFile>
 	</configInfo>
@@ -1904,6 +1911,18 @@ static pjsip_endpoint *ast_pjsip_endpoint;
 
 static struct ast_threadpool *sip_threadpool;
 
+/*! Local host address for IPv4 */
+static pj_sockaddr host_ip_ipv4;
+
+/*! Local host address for IPv4 (string form) */
+static char host_ip_ipv4_string[PJ_INET6_ADDRSTRLEN + 2];
+
+/*! Local host address for IPv6 */
+static pj_sockaddr host_ip_ipv6;
+
+/*! Local host address for IPv6 (string form) */
+static char host_ip_ipv6_string[PJ_INET6_ADDRSTRLEN + 2];
+
 static int register_service_noref(void *data)
 {
 	pjsip_module **module = data;
@@ -2323,10 +2342,11 @@ static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *u
 	pjsip_sip_uri *sip_uri;
 	pjsip_transport_type_e type = PJSIP_TRANSPORT_UNSPECIFIED;
 	int local_port;
-	char uuid_str[AST_UUID_STR_LEN];
+	char default_user[PJSIP_MAX_URL_SIZE];
 
 	if (ast_strlen_zero(user)) {
-		user = ast_uuid_generate_str(uuid_str, sizeof(uuid_str));
+		ast_sip_get_default_from_user(default_user, sizeof(default_user));
+		user = default_user;
 	}
 
 	/* Parse the provided target URI so we can determine what transport it will end up using */
@@ -2647,6 +2667,12 @@ int ast_sip_create_rdata(pjsip_rx_data *rdata, char *packet, const char *src_nam
 {
 	pj_str_t tmp;
 
+	/*
+	 * Initialize the error list in case there is a parse error
+	 * in the given packet.
+	 */
+	pj_list_init(&rdata->msg_info.parse_err);
+
 	rdata->tp_info.transport = PJ_POOL_ZALLOC_T(rdata->tp_info.pool, pjsip_transport);
 	if (!rdata->tp_info.transport) {
 		return -1;
@@ -2657,7 +2683,7 @@ int ast_sip_create_rdata(pjsip_rx_data *rdata, char *packet, const char *src_nam
 	rdata->pkt_info.src_port = src_port;
 
 	pjsip_parse_rdata(packet, strlen(packet), rdata);
-	if (!rdata->msg_info.msg) {
+	if (!rdata->msg_info.msg || !pj_list_empty(&rdata->msg_info.parse_err)) {
 		return -1;
 	}
 
@@ -3662,6 +3688,14 @@ int ast_sip_send_stateful_response(pjsip_rx_data *rdata, pjsip_tx_data *tdata, s
 	pjsip_transaction *tsx;
 
 	if (pjsip_tsx_create_uas(NULL, rdata, &tsx) != PJ_SUCCESS) {
+		struct ast_sip_contact *contact;
+
+		/* ast_sip_create_response bumps the refcount of the contact and adds it to the tdata.
+		 * We'll leak that reference if we don't get rid of it here.
+		 */
+		contact = ast_sip_mod_data_get(tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT);
+		ao2_cleanup(contact);
+		ast_sip_mod_data_set(tdata->pool, tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT, NULL);
 		pjsip_tx_data_dec_ref(tdata);
 		return -1;
 	}
@@ -3689,6 +3723,30 @@ int ast_sip_create_response(const pjsip_rx_data *rdata, int st_code,
 	return res;
 }
 
+int ast_sip_get_host_ip(int af, pj_sockaddr *addr)
+{
+	if (af == pj_AF_INET() && !ast_strlen_zero(host_ip_ipv4_string)) {
+		pj_sockaddr_copy_addr(addr, &host_ip_ipv4);
+		return 0;
+	} else if (af == pj_AF_INET6() && !ast_strlen_zero(host_ip_ipv6_string)) {
+		pj_sockaddr_copy_addr(addr, &host_ip_ipv6);
+		return 0;
+	}
+
+	return -1;
+}
+
+const char *ast_sip_get_host_ip_string(int af)
+{
+	if (af == pj_AF_INET()) {
+		return host_ip_ipv4_string;
+	} else if (af == pj_AF_INET6()) {
+		return host_ip_ipv6_string;
+	}
+
+	return NULL;
+}
+
 static void remove_request_headers(pjsip_endpoint *endpt)
 {
 	const pjsip_hdr *request_headers = pjsip_endpt_get_request_headers(endpt);
@@ -3701,6 +3759,57 @@ static void remove_request_headers(pjsip_endpoint *endpt)
 	}
 }
 
+AST_TEST_DEFINE(xml_sanitization_end_null)
+{
+	char sanitized[8];
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "xml_sanitization_end_null";
+		info->category = "/res/res_pjsip/";
+		info->summary = "Ensure XML sanitization works as expected with a long string";
+		info->description = "This test sanitizes a string which exceeds the output\n"
+			"buffer size. Once done the string is confirmed to be NULL terminated.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	ast_sip_sanitize_xml("aaaaaaaaaaaa", sanitized, sizeof(sanitized));
+	if (sanitized[7] != '\0') {
+		ast_test_status_update(test, "Sanitized XML string is not null-terminated when it should be\n");
+		return AST_TEST_FAIL;
+	}
+
+	return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(xml_sanitization_exceeds_buffer)
+{
+	char sanitized[8];
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "xml_sanitization_exceeds_buffer";
+		info->category = "/res/res_pjsip/";
+		info->summary = "Ensure XML sanitization does not exceed buffer when output won't fit";
+		info->description = "This test sanitizes a string which before sanitization would\n"
+			"fit within the output buffer. After sanitization, however, the string would\n"
+			"exceed the buffer. Once done the string is confirmed to be NULL terminated.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	ast_sip_sanitize_xml("<><><>&", sanitized, sizeof(sanitized));
+	if (sanitized[7] != '\0') {
+		ast_test_status_update(test, "Sanitized XML string is not null-terminated when it should be\n");
+		return AST_TEST_FAIL;
+	}
+
+	return AST_TEST_PASS;
+}
+
 /*!
  * \internal
  * \brief Reload configuration within a PJSIP thread
@@ -3752,6 +3861,16 @@ static int load_module(void)
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
+	if (!pj_gethostip(pj_AF_INET(), &host_ip_ipv4)) {
+		pj_sockaddr_print(&host_ip_ipv4, host_ip_ipv4_string, sizeof(host_ip_ipv4_string), 2);
+		ast_verb(3, "Local IPv4 address determined to be: %s\n", host_ip_ipv4_string);
+	}
+
+	if (!pj_gethostip(pj_AF_INET6(), &host_ip_ipv6)) {
+		pj_sockaddr_print(&host_ip_ipv6, host_ip_ipv6_string, sizeof(host_ip_ipv6_string), 2);
+		ast_verb(3, "Local IPv6 address determined to be: %s\n", host_ip_ipv6_string);
+	}
+
 	if (ast_sip_initialize_system()) {
 		ast_log(LOG_ERROR, "Failed to initialize SIP 'system' configuration section. Aborting load\n");
 		pj_pool_release(memory_pool);
@@ -3870,6 +3989,9 @@ static int load_module(void)
 	ast_res_pjsip_init_options_handling(0);
 	ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));
 
+	AST_TEST_REGISTER(xml_sanitization_end_null);
+	AST_TEST_REGISTER(xml_sanitization_exceeds_buffer);
+
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
@@ -3912,6 +4034,9 @@ static int unload_pjsip(void *data)
 
 static int unload_module(void)
 {
+	AST_TEST_UNREGISTER(xml_sanitization_end_null);
+	AST_TEST_UNREGISTER(xml_sanitization_exceeds_buffer);
+
 	/* The thread this is called from cannot call PJSIP/PJLIB functions,
 	 * so we have to push the work to the threadpool to handle
 	 */
diff --git a/res/res_pjsip/config_global.c b/res/res_pjsip/config_global.c
index 42ba234..ef706f0 100644
--- a/res/res_pjsip/config_global.c
+++ b/res/res_pjsip/config_global.c
@@ -34,6 +34,7 @@
 #define DEFAULT_DEBUG "no"
 #define DEFAULT_ENDPOINT_IDENTIFIER_ORDER "ip,username,anonymous"
 #define DEFAULT_MAX_INITIAL_QUALIFY_TIME 0
+#define DEFAULT_FROM_USER "asterisk"
 
 static char default_useragent[256];
 
@@ -46,6 +47,8 @@ struct global_config {
 		AST_STRING_FIELD(debug);
 		/*! Order by which endpoint identifiers are checked (comma separated list) */
 		AST_STRING_FIELD(endpoint_identifier_order);
+		/*! User name to place in From header if there is no better option */
+		AST_STRING_FIELD(default_from_user);
 	);
 	/* Value to put in Max-Forwards header */
 	unsigned int max_forwards;
@@ -179,6 +182,19 @@ unsigned int ast_sip_get_max_initial_qualify_time(void)
 	return time;
 }
 
+void ast_sip_get_default_from_user(char *from_user, size_t size)
+{
+	struct global_config *cfg;
+
+	cfg = get_global_cfg();
+	if (!cfg) {
+		ast_copy_string(from_user, DEFAULT_FROM_USER, size);
+	} else {
+		ast_copy_string(from_user, cfg->default_from_user, size);
+		ao2_ref(cfg, -1);
+	}
+}
+
 /*!
  * \internal
  * \brief Observer to set default global object if none exist.
@@ -292,6 +308,8 @@ int ast_sip_initialize_sorcery_global(void)
 	ast_sorcery_object_field_register(sorcery, "global", "max_initial_qualify_time",
 		__stringify(DEFAULT_MAX_INITIAL_QUALIFY_TIME),
 		OPT_UINT_T, 0, FLDSET(struct global_config, max_initial_qualify_time));
+	ast_sorcery_object_field_register(sorcery, "global", "default_from_user", DEFAULT_FROM_USER,
+		OPT_STRINGFIELD_T, 0, STRFLDSET(struct global_config, default_from_user));
 
 	if (ast_sorcery_instance_observer_add(sorcery, &observer_callbacks_global)) {
 		return -1;
diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c
index d87410d..9625f04 100644
--- a/res/res_pjsip/location.c
+++ b/res/res_pjsip/location.c
@@ -47,6 +47,41 @@ static void *aor_alloc(const char *name)
 	return aor;
 }
 
+/*! \brief Internal callback function which destroys the specified contact */
+static int destroy_contact(void *obj, void *arg, int flags)
+{
+	struct ast_sip_contact *contact = obj;
+
+	ast_sip_location_delete_contact(contact);
+
+	return CMP_MATCH;
+}
+
+static void aor_deleted_observer(const void *object)
+{
+	const char *aor_id = ast_sorcery_object_get_id(object);
+	/* Give enough space for ^ at the beginning and ;@ at the end, since that is our object naming scheme */
+	char regex[strlen(aor_id) + 4];
+	struct ao2_container *contacts;
+
+	snprintf(regex, sizeof(regex), "^%s;@", aor_id);
+
+	if (!(contacts = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "contact", regex))) {
+		return;
+	}
+
+	/* Destroy any contacts that may still exist that were made for this AoR */
+	ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, destroy_contact, NULL);
+
+	ao2_ref(contacts, -1);
+}
+
+/*! \brief Observer for contacts so state can be updated on respective endpoints */
+static const struct ast_sorcery_observer aor_observer = {
+	.deleted = aor_deleted_observer,
+};
+
+
 /*! \brief Destructor for contact */
 static void contact_destroy(void *obj)
 {
@@ -102,12 +137,6 @@ static int contact_link_static(void *obj, void *arg, int flags)
 	return 0;
 }
 
-/*! \brief Simple callback function which returns immediately, used to grab the first contact of an AOR */
-static int contact_find_first(void *obj, void *arg, int flags)
-{
-	return CMP_MATCH | CMP_STOP;
-}
-
 struct ast_sip_contact *ast_sip_location_retrieve_first_aor_contact(const struct ast_sip_aor *aor)
 {
 	RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
@@ -118,7 +147,8 @@ struct ast_sip_contact *ast_sip_location_retrieve_first_aor_contact(const struct
 		return NULL;
 	}
 
-	contact = ao2_callback(contacts, 0, contact_find_first, NULL);
+	/* Get the first AOR contact in the container. */
+	contact = ao2_callback(contacts, 0, NULL, NULL);
 	return contact;
 }
 
@@ -234,8 +264,10 @@ int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri,
 {
 	char name[MAX_OBJECT_FIELD * 2 + 3];
 	RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
+	char hash[33];
 
-	snprintf(name, sizeof(name), "%s;@%s", ast_sorcery_object_get_id(aor), uri);
+	ast_md5_hash(hash, uri);
+	snprintf(name, sizeof(name), "%s;@%s", ast_sorcery_object_get_id(aor), hash);
 
 	if (!(contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", name))) {
 		return -1;
@@ -910,6 +942,8 @@ int ast_sip_initialize_sorcery_location(void)
 		return -1;
 	}
 
+	ast_sorcery_observer_add(sorcery, "aor", &aor_observer);
+
 	ast_sorcery_object_field_register(sorcery, "contact", "type", "", OPT_NOOP_T, 0, 0);
 	ast_sorcery_object_field_register(sorcery, "contact", "uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, uri));
 	ast_sorcery_object_field_register(sorcery, "contact", "path", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, path));
@@ -971,6 +1005,7 @@ int ast_sip_initialize_sorcery_location(void)
 
 int ast_sip_destroy_sorcery_location(void)
 {
+	ast_sorcery_observer_remove(ast_sip_get_sorcery(), "aor", &aor_observer);
 	ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
 	ast_sip_unregister_cli_formatter(contact_formatter);
 	ast_sip_unregister_cli_formatter(aor_formatter);
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index c0c96ad..2fdfc9d 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -402,6 +402,10 @@ int ast_sip_auth_vector_init(struct ast_sip_auth_vector *auths, const char *valu
 	}
 
 	while ((val = strsep(&auth_names, ","))) {
+		if (ast_strlen_zero(val)) {
+			continue;
+		}
+
 		val = ast_strdup(val);
 		if (!val) {
 			goto failure;
diff --git a/res/res_pjsip/presence_xml.c b/res/res_pjsip/presence_xml.c
index 12bfa07..b98ea02 100644
--- a/res/res_pjsip/presence_xml.c
+++ b/res/res_pjsip/presence_xml.c
@@ -30,45 +30,54 @@ void ast_sip_sanitize_xml(const char *input, char *output, size_t len)
 {
 	char *copy = ast_strdupa(input);
 	char *break_point;
+	size_t remaining = len - 1;
 
 	output[0] = '\0';
 
-	while ((break_point = strpbrk(copy, "<>\"&'\n\r"))) {
+	while ((break_point = strpbrk(copy, "<>\"&'\n\r")) && remaining) {
 		char to_escape = *break_point;
 
 		*break_point = '\0';
-		strncat(output, copy, len);
+		strncat(output, copy, remaining);
+
+		/* The strncat function will write remaining+1 if the string length is
+		 * equal to or greater than the size provided to it. We take this into
+		 * account by subtracting 1, which ensures that the NULL byte is written
+		 * inside of the provided buffer.
+		 */
+		remaining = len - strlen(output) - 1;
 
 		switch (to_escape) {
 		case '<':
-			strncat(output, "<", len);
+			strncat(output, "<", remaining);
 			break;
 		case '>':
-			strncat(output, ">", len);
+			strncat(output, ">", remaining);
 			break;
 		case '"':
-			strncat(output, """, len);
+			strncat(output, """, remaining);
 			break;
 		case '&':
-			strncat(output, "&", len);
+			strncat(output, "&", remaining);
 			break;
 		case '\'':
-			strncat(output, "'", len);
+			strncat(output, "'", remaining);
 			break;
 		case '\r':
-			strncat(output, "
", len);
+			strncat(output, "
", remaining);
 			break;
 		case '\n':
-			strncat(output, "
", len);
+			strncat(output, "
", remaining);
 			break;
 		};
 
 		copy = break_point + 1;
+		remaining = len - strlen(output) - 1;
 	}
 
 	/* Be sure to copy everything after the final bracket */
-	if (*copy) {
-		strncat(output, copy, len);
+	if (*copy && remaining) {
+		strncat(output, copy, remaining);
 	}
 }
 
diff --git a/res/res_pjsip_diversion.c b/res/res_pjsip_diversion.c
index 49f7892..4d9aca4 100644
--- a/res/res_pjsip_diversion.c
+++ b/res/res_pjsip_diversion.c
@@ -117,7 +117,9 @@ static void set_redirecting_value(char **dst, const pj_str_t *src)
 {
 	ast_free(*dst);
 	*dst = ast_malloc(pj_strlen(src) + 1);
-	ast_copy_pj_str(*dst, src, pj_strlen(src) + 1);
+	if (*dst) {
+		ast_copy_pj_str(*dst, src, pj_strlen(src) + 1);
+	}
 }
 
 static void set_redirecting_id(pjsip_name_addr *name_addr, struct ast_party_id *data,
diff --git a/res/res_pjsip_multihomed.c b/res/res_pjsip_multihomed.c
index e1abff3..437a1cb 100644
--- a/res/res_pjsip_multihomed.c
+++ b/res/res_pjsip_multihomed.c
@@ -30,12 +30,6 @@
 #include "asterisk/res_pjsip.h"
 #include "asterisk/module.h"
 
-/*! \brief Local host address for IPv4 */
-static char host_ipv4[PJ_INET_ADDRSTRLEN + 2];
-
-/*! \brief Local host address for IPv6 */
-static char host_ipv6[PJ_INET6_ADDRSTRLEN + 2];
-
 /*! \brief Helper function which returns a UDP transport bound to the given address and port */
 static pjsip_transport *multihomed_get_udp_transport(pj_str_t *address, int port)
 {
@@ -75,8 +69,10 @@ static int multihomed_rewrite_sdp(struct pjmedia_sdp_session *sdp)
 	}
 
 	/* If the host address is used in the SDP replace it with the address of what this is going out on */
-	if ((!pj_strcmp2(&sdp->conn->addr_type, "IP4") && !pj_strcmp2(&sdp->conn->addr, host_ipv4)) ||
-		(!pj_strcmp2(&sdp->conn->addr_type, "IP6") && !pj_strcmp2(&sdp->conn->addr, host_ipv6))) {
+	if ((!pj_strcmp2(&sdp->conn->addr_type, "IP4") && !pj_strcmp2(&sdp->conn->addr,
+		ast_sip_get_host_ip_string(pj_AF_INET()))) ||
+		(!pj_strcmp2(&sdp->conn->addr_type, "IP6") && !pj_strcmp2(&sdp->conn->addr,
+		ast_sip_get_host_ip_string(pj_AF_INET6())))) {
 		return 1;
 	}
 
@@ -204,7 +200,6 @@ static int unload_module(void)
 static int load_module(void)
 {
 	char hostname[MAXHOSTNAMELEN] = "";
-	pj_sockaddr addr;
 
 	CHECK_PJSIP_MODULE_LOADED();
 
@@ -213,16 +208,6 @@ static int load_module(void)
 			hostname);
 	}
 
-	if (!pj_gethostip(pj_AF_INET(), &addr)) {
-		pj_sockaddr_print(&addr, host_ipv4, sizeof(host_ipv4), 2);
-		ast_verb(3, "Local IPv4 address determined to be: %s\n", host_ipv4);
-	}
-
-	if (!pj_gethostip(pj_AF_INET6(), &addr)) {
-		pj_sockaddr_print(&addr, host_ipv6, sizeof(host_ipv6), 2);
-		ast_verb(3, "Local IPv6 address determined to be: %s\n", host_ipv6);
-	}
-
 	if (ast_sip_register_service(&multihomed_module)) {
 		ast_log(LOG_ERROR, "Could not register multihomed module for incoming and outgoing requests\n");
 		return AST_MODULE_LOAD_FAILURE;
diff --git a/res/res_pjsip_nat.c b/res/res_pjsip_nat.c
index c32b71d..a2eb6ad 100644
--- a/res/res_pjsip_nat.c
+++ b/res/res_pjsip_nat.c
@@ -56,7 +56,7 @@ static int rewrite_route_set(pjsip_rx_data *rdata, pjsip_dialog *dlg)
 				break;
 			}
 		}
-	} else {
+	} else if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method)) {
 		rr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_RECORD_ROUTE, NULL);
 	}
 
diff --git a/res/res_pjsip_pidf_digium_body_supplement.c b/res/res_pjsip_pidf_digium_body_supplement.c
index 86e673a..4b1a781 100644
--- a/res/res_pjsip_pidf_digium_body_supplement.c
+++ b/res/res_pjsip_pidf_digium_body_supplement.c
@@ -40,7 +40,7 @@ static int pidf_supplement_body(void *body, void *data)
 {
 	struct ast_sip_exten_state_data *state_data = data;
 	pj_xml_node *node;
-	char sanitized[256];
+	char sanitized[1024];
 
 	if (ast_strlen_zero(state_data->user_agent) ||
 	    !strstr(state_data->user_agent, "digium")) {
diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c
index 650f5c5..eb49aaf 100644
--- a/res/res_pjsip_pubsub.c
+++ b/res/res_pjsip_pubsub.c
@@ -561,8 +561,19 @@ static void subscription_persistence_update(struct sip_subscription_tree *sub_tr
 		expires = expires_hdr ? expires_hdr->ivalue : DEFAULT_PUBLISH_EXPIRES;
 		sub_tree->persistence->expires = ast_tvadd(ast_tvnow(), ast_samp2tv(expires, 1));
 
-		ast_copy_string(sub_tree->persistence->packet, rdata->pkt_info.packet,
-				sizeof(sub_tree->persistence->packet));
+		/* When receiving a packet on an streaming transport, it's possible to receive more than one SIP
+		 * message at a time into the rdata->pkt_info.packet buffer. However, the rdata->msg_info.msg_buf
+		 * will always point to the proper SIP message that is to be processed. When updating subscription
+		 * persistence that is pulled from persistent storage, though, the rdata->pkt_info.packet will
+		 * only ever have a single SIP message on it, and so we base persistence on that.
+		 */
+		if (rdata->msg_info.msg_buf) {
+			ast_copy_string(sub_tree->persistence->packet, rdata->msg_info.msg_buf,
+					MIN(sizeof(sub_tree->persistence->packet), rdata->msg_info.len));
+		} else {
+			ast_copy_string(sub_tree->persistence->packet, rdata->pkt_info.packet,
+					sizeof(sub_tree->persistence->packet));
+		}
 		ast_copy_string(sub_tree->persistence->src_name, rdata->pkt_info.src_name,
 				sizeof(sub_tree->persistence->src_name));
 		sub_tree->persistence->src_port = rdata->pkt_info.src_port;
@@ -971,6 +982,7 @@ static int build_resource_tree(struct ast_sip_endpoint *endpoint, const struct a
 
 	tree->root = tree_node_alloc(resource, &visited, list->full_state);
 	if (!tree->root) {
+		AST_VECTOR_FREE(&visited);
 		return 500;
 	}
 
@@ -1159,6 +1171,7 @@ static void shutdown_subscriptions(struct ast_sip_subscription *sub)
 		return;
 	}
 
+	/* We notify subscription shutdown only on the tree leaves. */
 	if (sub->handler->subscription_shutdown) {
 		sub->handler->subscription_shutdown(sub);
 	}
@@ -1251,7 +1264,7 @@ static struct sip_subscription_tree *create_subscription_tree(const struct ast_s
 
 	sub_tree = allocate_subscription_tree(endpoint);
 	if (!sub_tree) {
-		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+		*dlg_status = PJ_ENOMEM;
 		return NULL;
 	}
 	sub_tree->role = AST_SIP_NOTIFIER;
@@ -1293,7 +1306,7 @@ static struct sip_subscription_tree *create_subscription_tree(const struct ast_s
 	return sub_tree;
 }
 
-static int generate_initial_notify(struct ast_sip_subscription *sub);
+static int initial_notify_task(void *obj);
 static int send_notify(struct sip_subscription_tree *sub_tree, unsigned int force_full_state);
 
 /*! \brief Callback function to perform the actual recreation of a subscription */
@@ -1338,9 +1351,16 @@ static int subscription_persistence_recreate(void *obj, void *arg, int flags)
 		return 0;
 	}
 
+	if (rdata.msg_info.msg->type != PJSIP_REQUEST_MSG) {
+		ast_log(LOG_NOTICE, "Endpoint %s persisted a SIP response instead of a subscribe request. Unable to reload subscription.\n",
+				ast_sorcery_object_get_id(endpoint));
+		ast_sorcery_delete(ast_sip_get_sorcery(), persistence);
+		return 0;
+	}
+
 	request_uri = pjsip_uri_get_uri(rdata.msg_info.msg->line.req.uri);
 	resource_size = pj_strlen(&request_uri->user) + 1;
-	resource = alloca(resource_size);
+	resource = ast_alloca(resource_size);
 	ast_copy_pj_str(resource, &request_uri->user, resource_size);
 
 	/* Update the expiration header with the new expiration */
@@ -1384,10 +1404,10 @@ static int subscription_persistence_recreate(void *obj, void *arg, int flags)
 		}
 		sub_tree->persistence = ao2_bump(persistence);
 		subscription_persistence_update(sub_tree, &rdata);
-		if (generate_initial_notify(sub_tree->root)) {
+		if (ast_sip_push_task(sub_tree->serializer, initial_notify_task, ao2_bump(sub_tree))) {
 			pjsip_evsub_terminate(sub_tree->evsub, PJ_TRUE);
+			ao2_ref(sub_tree, -1);
 		}
-		send_notify(sub_tree, 1);
 	} else {
 		ast_sorcery_delete(ast_sip_get_sorcery(), persistence);
 	}
@@ -1507,6 +1527,7 @@ void *ast_sip_subscription_get_header(const struct ast_sip_subscription *sub, co
 	return pjsip_msg_find_hdr_by_name(msg, &name, NULL);
 }
 
+/* XXX This function is not used. */
 struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_subscription_handler *handler,
 		struct ast_sip_endpoint *endpoint, const char *resource)
 {
@@ -2503,6 +2524,7 @@ static int generate_initial_notify(struct ast_sip_subscription *sub)
 		return 0;
 	}
 
+	/* We notify subscription establishment only on the tree leaves. */
 	if (sub->handler->notifier->subscription_established(sub)) {
 		return -1;
 	}
@@ -2522,6 +2544,24 @@ static int generate_initial_notify(struct ast_sip_subscription *sub)
 	return res;
 }
 
+static int initial_notify_task(void * obj)
+{
+	struct sip_subscription_tree *sub_tree;
+
+	sub_tree = obj;
+	if (generate_initial_notify(sub_tree->root)) {
+		pjsip_evsub_terminate(sub_tree->evsub, PJ_TRUE);
+	} else {
+		send_notify(sub_tree, 1);
+		ast_test_suite_event_notify("SUBSCRIPTION_ESTABLISHED",
+			"Resource: %s",
+			sub_tree->root->resource);
+	}
+
+	ao2_ref(sub_tree, -1);
+	return 0;
+}
+
 static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata)
 {
 	pjsip_expires_hdr *expires_header;
@@ -2559,7 +2599,7 @@ static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata)
 
 	request_uri_sip = pjsip_uri_get_uri(request_uri);
 	resource_size = pj_strlen(&request_uri_sip->user) + 1;
-	resource = alloca(resource_size);
+	resource = ast_alloca(resource_size);
 	ast_copy_pj_str(resource, &request_uri_sip->user, resource_size);
 
 	expires_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, rdata->msg_info.msg->hdr.next);
@@ -2609,13 +2649,9 @@ static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata)
 		sub_tree->persistence = subscription_persistence_create(sub_tree);
 		subscription_persistence_update(sub_tree, rdata);
 		sip_subscription_accept(sub_tree, rdata, resp);
-		if (generate_initial_notify(sub_tree->root)) {
+		if (ast_sip_push_task(sub_tree->serializer, initial_notify_task, ao2_bump(sub_tree))) {
 			pjsip_evsub_terminate(sub_tree->evsub, PJ_TRUE);
-		} else {
-			send_notify(sub_tree, 1);
-			ast_test_suite_event_notify("SUBSCRIPTION_ESTABLISHED",
-					"Resource: %s",
-					sub_tree->root->resource);
+			ao2_ref(sub_tree, -1);
 		}
 	}
 
@@ -2776,7 +2812,7 @@ static struct ast_sip_publication *publish_request_initial(struct ast_sip_endpoi
 
 	request_uri_sip = pjsip_uri_get_uri(request_uri);
 	resource_size = pj_strlen(&request_uri_sip->user) + 1;
-	resource_name = alloca(resource_size);
+	resource_name = ast_alloca(resource_size);
 	ast_copy_pj_str(resource_name, &request_uri_sip->user, resource_size);
 
 	resource = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "inbound-publication", resource_name);
@@ -2976,16 +3012,13 @@ int ast_sip_pubsub_register_body_generator(struct ast_sip_pubsub_body_generator
 	AST_LIST_INSERT_HEAD(&body_generators, generator, list);
 	AST_RWLIST_UNLOCK(&body_generators);
 
-	/* Lengths of type and subtype plus space for a slash. pj_str_t is not
-	 * null-terminated, so there is no need to allocate for the extra null
-	 * byte
-	 */
+	/* Lengths of type and subtype plus a slash. */
 	accept_len = strlen(generator->type) + strlen(generator->subtype) + 1;
 
-	accept.ptr = alloca(accept_len);
-	accept.slen = accept_len;
-	/* Safe use of sprintf */
-	sprintf(accept.ptr, "%s/%s", generator->type, generator->subtype);
+	/* Add room for null terminator that sprintf() will set. */
+	pj_strset(&accept, ast_alloca(accept_len + 1), accept_len);
+	sprintf((char *) pj_strbuf(&accept), "%s/%s", generator->type, generator->subtype);/* Safe */
+
 	pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), &pubsub_module,
 			PJSIP_H_ACCEPT, NULL, 1, &accept);
 
@@ -4251,6 +4284,7 @@ static int load_module(void)
 	if (apply_list_configuration(sorcery)) {
 		ast_sip_unregister_service(&pubsub_module);
 		ast_sched_context_destroy(sched);
+		return AST_MODULE_LOAD_FAILURE;
 	}
 
 	ast_sorcery_apply_default(sorcery, "inbound-publication", "config", "pjsip.conf,criteria=type=inbound-publication");
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 4071ad7..df28204 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -115,6 +115,10 @@ static int send_keepalive(const void *data)
 	time_t interval;
 	int send_keepalive;
 
+	if (!rtp) {
+		return 0;
+	}
+
 	keepalive = ast_rtp_instance_get_keepalive(rtp);
 
 	if (!ast_sockaddr_isnull(&session_media->direct_media_addr)) {
@@ -237,13 +241,13 @@ static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp
 		}
 
 		ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
-                if (strcmp(name,"telephone-event") == 0) {
-                        tel_event++;
-                }
+		if (strcmp(name, "telephone-event") == 0) {
+			tel_event++;
+		}
 
 		ast_copy_pj_str(media, (pj_str_t*)&stream->desc.media, sizeof(media));
-		ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]),
-							     media, name, options, rtpmap->clock_rate);
+		ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, NULL,
+			pj_strtoul(&stream->desc.fmt[i]), media, name, options, rtpmap->clock_rate);
 		/* Look for an optional associated fmtp attribute */
 		if (!(attr = pjmedia_sdp_media_find_attr2(stream, "fmtp", &rtpmap->pt))) {
 			continue;
@@ -270,8 +274,8 @@ static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp
 			}
 		}
 	}
-	if ((tel_event==0) && (session->endpoint->dtmf == AST_SIP_DTMF_AUTO)) {
-                ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND);
+	if (!tel_event && (session->endpoint->dtmf == AST_SIP_DTMF_AUTO)) {
+		ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND);
 	}
 	/* Get the packetization, if it exists */
 	if ((attr = pjmedia_sdp_media_find_attr2(stream, "ptime", NULL))) {
@@ -329,7 +333,7 @@ static int set_caps(struct ast_sip_session *session, struct ast_sip_session_medi
 	}
 
 	ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session_media->rtp),
-				     session_media->rtp);
+		session_media->rtp);
 
 	ast_format_cap_append_from_cap(session->req_caps, joint, AST_MEDIA_TYPE_UNKNOWN);
 
@@ -598,6 +602,9 @@ static enum ast_sip_session_media_encryption get_media_encryption_type(pj_str_t
 
 	*optimistic = 0;
 
+	if (!transport_str) {
+		return AST_SIP_MEDIA_TRANSPORT_INVALID;
+	}
 	if (strstr(transport_str, "UDP/TLS")) {
 		return AST_SIP_MEDIA_ENCRYPT_DTLS;
 	} else if (strstr(transport_str, "SAVP")) {
@@ -1019,7 +1026,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
 	static const pj_str_t STR_IP6 = { "IP6", 3};
 	static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
 	pjmedia_sdp_media *media;
-	char hostip[PJ_INET6_ADDRSTRLEN+2];
+	const char *hostip = NULL;
 	struct ast_sockaddr addr;
 	char tmp[512];
 	pj_str_t stmp;
@@ -1067,16 +1074,16 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
 
 	/* Add connection level details */
 	if (direct_media_enabled) {
-		ast_copy_string(hostip, ast_sockaddr_stringify_fmt(&session_media->direct_media_addr, AST_SOCKADDR_STR_ADDR), sizeof(hostip));
+		hostip = ast_sockaddr_stringify_fmt(&session_media->direct_media_addr, AST_SOCKADDR_STR_ADDR);
 	} else if (ast_strlen_zero(session->endpoint->media.address)) {
-		pj_sockaddr localaddr;
-
-		if (pj_gethostip(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr)) {
-			return -1;
-		}
-		pj_sockaddr_print(&localaddr, hostip, sizeof(hostip), 2);
+		hostip = ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET());
 	} else {
-		ast_copy_string(hostip, session->endpoint->media.address, sizeof(hostip));
+		hostip = session->endpoint->media.address;
+	}
+
+	if (ast_strlen_zero(hostip)) {
+		ast_log(LOG_ERROR, "No local host IP available for stream %s\n", session_media->stream_type);
+		return -1;
 	}
 
 	media->conn->net_type = STR_IN;
@@ -1137,8 +1144,12 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
 	/* Add non-codec formats */
 	if (media_type != AST_MEDIA_TYPE_VIDEO) {
 		for (index = 1LL; index <= AST_RTP_MAX; index <<= 1) {
-			if (!(noncodec & index) || (rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp),
-											   0, NULL, index)) == -1) {
+			if (!(noncodec & index)) {
+				continue;
+			}
+			rtp_code = ast_rtp_codecs_payload_code(
+				ast_rtp_instance_get_codecs(session_media->rtp), 0, NULL, index);
+			if (rtp_code == -1) {
 				continue;
 			}
 
@@ -1240,7 +1251,7 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct a
 	/* Apply connection information to the RTP instance */
 	ast_sockaddr_set_port(addrs, remote_stream->desc.port);
 	ast_rtp_instance_set_remote_address(session_media->rtp, addrs);
-	if (set_caps(session, session_media, local_stream)) {
+	if (set_caps(session, session_media, remote_stream)) {
 		return 1;
 	}
 
@@ -1296,6 +1307,7 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct a
 		 * a NAT. This way there won't be an awkward delay before media starts flowing in some
 		 * scenarios.
 		 */
+		AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
 		session_media->keepalive_sched_id = ast_sched_add_variable(sched, 500, send_keepalive,
 			session_media, 1);
 	}
@@ -1347,13 +1359,23 @@ static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struc
 	pj_strdup2(tdata->pool, &stream->conn->addr, transport->external_media_address);
 }
 
+/*! \brief Function which stops the RTP instance */
+static void stream_stop(struct ast_sip_session_media *session_media)
+{
+	if (!session_media->rtp) {
+		return;
+	}
+
+	AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
+	AST_SCHED_DEL(sched, session_media->timeout_sched_id);
+	ast_rtp_instance_stop(session_media->rtp);
+}
+
 /*! \brief Function which destroys the RTP instance when session ends */
 static void stream_destroy(struct ast_sip_session_media *session_media)
 {
 	if (session_media->rtp) {
-		AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
-		AST_SCHED_DEL(sched, session_media->timeout_sched_id);
-		ast_rtp_instance_stop(session_media->rtp);
+		stream_stop(session_media);
 		ast_rtp_instance_destroy(session_media->rtp);
 	}
 	session_media->rtp = NULL;
@@ -1366,6 +1388,7 @@ static struct ast_sip_session_sdp_handler audio_sdp_handler = {
 	.create_outgoing_sdp_stream = create_outgoing_sdp_stream,
 	.apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
 	.change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
+	.stream_stop = stream_stop,
 	.stream_destroy = stream_destroy,
 };
 
@@ -1376,6 +1399,7 @@ static struct ast_sip_session_sdp_handler video_sdp_handler = {
 	.create_outgoing_sdp_stream = create_outgoing_sdp_stream,
 	.apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
 	.change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
+	.stream_stop = stream_stop,
 	.stream_destroy = stream_destroy,
 };
 
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 5eb72b4..6044ceb 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -362,6 +362,13 @@ static int handle_negotiated_sdp_session_media(void *obj, void *arg, int flags)
 			}
 		}
 	}
+
+	if (session_media->handler && session_media->handler->stream_stop) {
+		ast_debug(1, "Stopping SDP media stream '%s' as it is not currently negotiated\n",
+			session_media->stream_type);
+		session_media->handler->stream_stop(session_media);
+	}
+
 	return CMP_MATCH;
 }
 
@@ -1290,6 +1297,11 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
 	session->contact = ao2_bump(contact);
 	session->inv_session = inv_session;
 	session->req_caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+	if (!session->req_caps) {
+		/* Release the ref held by session->inv_session */
+		ao2_ref(session, -1);
+		return NULL;
+	}
 
 	if ((endpoint->dtmf == AST_SIP_DTMF_INBAND) || (endpoint->dtmf == AST_SIP_DTMF_AUTO)) {
 		dsp_features |= DSP_FEATURE_DIGIT_DETECT;
@@ -2390,8 +2402,16 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
 		break;
 	case PJSIP_EVENT_RX_MSG:
 		cb = ast_sip_mod_data_get(tsx->mod_data, session_module.id, MOD_DATA_ON_RESPONSE);
-		handle_incoming(session, e->body.tsx_state.src.rdata, e->type,
-				AST_SIP_SESSION_AFTER_MEDIA);
+		/* As the PJSIP invite session implementation responds with a 200 OK before we have a
+		 * chance to be invoked session supplements for BYE requests actually end up executing
+		 * in the invite session state callback as well. To prevent session supplements from
+		 * running on the BYE request again we explicitly squash invocation of them here.
+		 */
+		if ((e->body.tsx_state.src.rdata->msg_info.msg->type != PJSIP_REQUEST_MSG) ||
+			(tsx->method.id != PJSIP_BYE_METHOD)) {
+			handle_incoming(session, e->body.tsx_state.src.rdata, e->type,
+							AST_SIP_SESSION_AFTER_MEDIA);
+		}
 		if (tsx->method.id == PJSIP_INVITE_METHOD) {
 			if (tsx->role == PJSIP_ROLE_UAC) {
 				if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
@@ -2643,12 +2663,7 @@ static struct pjmedia_sdp_session *create_local_sdp(pjsip_inv_session *inv, stru
 		if (!ast_strlen_zero(session->endpoint->media.address)) {
 			pj_strdup2(inv->pool_prov, &local->origin.addr, session->endpoint->media.address);
 		} else {
-			pj_sockaddr localaddr;
-			char our_ip[PJ_INET6_ADDRSTRLEN];
-
-			pj_gethostip(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr);
-			pj_sockaddr_print(&localaddr, our_ip, sizeof(our_ip), 0);
-			pj_strdup2(inv->pool_prov, &local->origin.addr, our_ip);
+			pj_strdup2(inv->pool_prov, &local->origin.addr, ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET()));
 		}
 	}
 
@@ -2681,8 +2696,10 @@ static void session_inv_on_media_update(pjsip_inv_session *inv, pj_status_t stat
 	struct ast_sip_session *session = inv->mod_data[session_module.id];
 	const pjmedia_sdp_session *local, *remote;
 
-	if (!session->channel) {
-		/* If we don't have a channel. We really don't care about media updates.
+	if (!session || !session->channel) {
+		/*
+		 * If we don't have a session or channel then we really
+		 * don't care about media updates.
 		 * Just ignore
 		 */
 		return;
diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c
index 5a2357d..c867f7f 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -707,7 +707,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
 	static const pj_str_t STR_T38UDPREDUNDANCY = { "t38UDPRedundancy", 16 };
 	struct t38_state *state;
 	pjmedia_sdp_media *media;
-	char hostip[PJ_INET6_ADDRSTRLEN+2];
+	const char *hostip = NULL;
 	struct ast_sockaddr addr;
 	char tmp[512];
 	pj_str_t stmp;
@@ -732,14 +732,13 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
 	media->desc.transport = STR_UDPTL;
 
 	if (ast_strlen_zero(session->endpoint->media.address)) {
-		pj_sockaddr localaddr;
-
-		if (pj_gethostip(session->endpoint->media.t38.ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr)) {
-			return -1;
-		}
-		pj_sockaddr_print(&localaddr, hostip, sizeof(hostip), 2);
+		hostip = ast_sip_get_host_ip_string(session->endpoint->media.t38.ipv6 ? pj_AF_INET6() : pj_AF_INET());
 	} else {
-		ast_copy_string(hostip, session->endpoint->media.address, sizeof(hostip));
+		hostip = session->endpoint->media.address;
+	}
+
+	if (ast_strlen_zero(hostip)) {
+		return -1;
 	}
 
 	media->conn->net_type = STR_IN;
diff --git a/res/res_pjsip_transport_websocket.c b/res/res_pjsip_transport_websocket.c
index be30468..a49eade 100644
--- a/res/res_pjsip_transport_websocket.c
+++ b/res/res_pjsip_transport_websocket.c
@@ -63,8 +63,9 @@ static pj_status_t ws_send_msg(pjsip_transport *transport,
                             pjsip_transport_callback callback)
 {
 	struct ws_transport *wstransport = (struct ws_transport *)transport;
+	uint64_t len = tdata->buf.cur - tdata->buf.start;
 
-	if (ast_websocket_write(wstransport->ws_session, AST_WEBSOCKET_OPCODE_TEXT, tdata->buf.start, (int)(tdata->buf.cur - tdata->buf.start))) {
+	if (ast_websocket_write(wstransport->ws_session, AST_WEBSOCKET_OPCODE_TEXT, tdata->buf.start, len)) {
 		return PJ_EUNKNOWN;
 	}
 
@@ -418,7 +419,7 @@ static int load_module(void)
 	CHECK_PJSIP_MODULE_LOADED();
 
 	pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE, "WS", 5060, &transport_type_ws);
-	pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE, "WSS", 5060, &transport_type_wss);
+	pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE, "WSS", 5060, &transport_type_wss);
 
 	if (ast_sip_register_service(&websocket_module) != PJ_SUCCESS) {
 		return AST_MODULE_LOAD_DECLINE;
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index 5d206c1..390fd08 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -590,12 +590,16 @@ static int ice_reset_session(struct ast_rtp_instance *instance)
 	pj_ice_sess_role role = rtp->ice->role;
 	int res;
 
+	ast_debug(3, "Resetting ICE for RTP instance '%p'\n", instance);
 	if (!rtp->ice->is_nominating && !rtp->ice->is_complete) {
+		ast_debug(3, "Nevermind. ICE isn't ready for a reset\n");
 		return 0;
 	}
 
+	ast_debug(3, "Stopping ICE for RTP instance '%p'\n", instance);
 	ast_rtp_ice_stop(instance);
 
+	ast_debug(3, "Recreating ICE session %s (%d) for RTP instance '%p'\n", ast_sockaddr_stringify(&rtp->ice_original_rtp_addr), rtp->ice_port, instance);
 	res = ice_create(instance, &rtp->ice_original_rtp_addr, rtp->ice_port, 1);
 	if (!res) {
 		/* Preserve the role that the old ICE session used */
@@ -648,6 +652,7 @@ static void ast_rtp_ice_start(struct ast_rtp_instance *instance)
 	/* Check for equivalence in the lists */
 	if (rtp->ice_active_remote_candidates &&
 			!ice_candidates_compare(rtp->ice_proposed_remote_candidates, rtp->ice_active_remote_candidates)) {
+		ast_debug(3, "Proposed == active candidates for RTP instance '%p'\n", instance);
 		ao2_cleanup(rtp->ice_proposed_remote_candidates);
 		rtp->ice_proposed_remote_candidates = NULL;
 		return;
@@ -694,8 +699,10 @@ static void ast_rtp_ice_start(struct ast_rtp_instance *instance)
 		}
 
 		if (candidate->id == AST_RTP_ICE_COMPONENT_RTP && rtp->turn_rtp) {
+			ast_debug(3, "RTP candidate %s (%p)\n", ast_sockaddr_stringify(&candidate->address), instance);
 			pj_turn_sock_set_perm(rtp->turn_rtp, 1, &candidates[cand_cnt].addr, 1);
 		} else if (candidate->id == AST_RTP_ICE_COMPONENT_RTCP && rtp->turn_rtcp) {
+			ast_debug(3, "RTCP candidate %s (%p)\n", ast_sockaddr_stringify(&candidate->address), instance);
 			pj_turn_sock_set_perm(rtp->turn_rtcp, 1, &candidates[cand_cnt].addr, 1);
 		}
 
@@ -705,21 +712,40 @@ static void ast_rtp_ice_start(struct ast_rtp_instance *instance)
 
 	ao2_iterator_destroy(&i);
 
-	if (has_rtp && has_rtcp &&
-	    pj_ice_sess_create_check_list(rtp->ice, &ufrag, &passwd, ao2_container_count(
-						  rtp->ice_active_remote_candidates), &candidates[0]) == PJ_SUCCESS) {
-		ast_test_suite_event_notify("ICECHECKLISTCREATE", "Result: SUCCESS");
-		pj_ice_sess_start_check(rtp->ice);
-		pj_timer_heap_poll(timer_heap, NULL);
-		rtp->strict_rtp_state = STRICT_RTP_OPEN;
-		return;
+	if (cand_cnt < ao2_container_count(rtp->ice_active_remote_candidates)) {
+		ast_log(LOG_WARNING, "Lost %d ICE candidates. Consider increasing PJ_ICE_MAX_CAND in PJSIP (%p)\n",
+			ao2_container_count(rtp->ice_active_remote_candidates) - cand_cnt, instance);
+	}
+
+	if (!has_rtp) {
+		ast_log(LOG_WARNING, "No RTP candidates; skipping ICE checklist (%p)\n", instance);
+	}
+
+	if (!has_rtcp) {
+		ast_log(LOG_WARNING, "No RTCP candidates; skipping ICE checklist (%p)\n", instance);
+	}
+
+	if (has_rtp && has_rtcp) {
+		pj_status_t res = pj_ice_sess_create_check_list(rtp->ice, &ufrag, &passwd, cand_cnt, &candidates[0]);
+		char reason[80];
+
+		if (res == PJ_SUCCESS) {
+			ast_debug(3, "Successfully created ICE checklist (%p)\n", instance);
+			ast_test_suite_event_notify("ICECHECKLISTCREATE", "Result: SUCCESS");
+			pj_ice_sess_start_check(rtp->ice);
+			pj_timer_heap_poll(timer_heap, NULL);
+			rtp->strict_rtp_state = STRICT_RTP_OPEN;
+			return;
+		}
+
+		pj_strerror(res, reason, sizeof(reason));
+		ast_log(LOG_WARNING, "Failed to create ICE session check list: %s (%p)\n", reason, instance);
 	}
 
 	ast_test_suite_event_notify("ICECHECKLISTCREATE", "Result: FAILURE");
 
 	/* even though create check list failed don't stop ice as
 	   it might still work */
-	ast_debug(1, "Failed to create ICE session check list\n");
 	/* however we do need to reset remote candidates since
 	   this function may be re-entered */
 	ao2_ref(rtp->ice_active_remote_candidates, -1);
@@ -769,7 +795,11 @@ static void ast_rtp_ice_set_role(struct ast_rtp_instance *instance, enum ast_rtp
 {
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 
+	ast_debug(3, "Set role to %s (%p)\n",
+		role == AST_RTP_ICE_ROLE_CONTROLLED ? "CONTROLLED" : "CONTROLLING", instance);
+
 	if (!rtp->ice) {
+		ast_debug(3, "Set role failed; no ice instance (%p)\n", instance);
 		return;
 	}
 
@@ -1268,6 +1298,9 @@ static int ast_rtp_dtls_set_configuration(struct ast_rtp_instance *instance, con
 {
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 	int res;
+#ifndef HAVE_OPENSSL_ECDH_AUTO
+	EC_KEY *ecdh;
+#endif
 
 	if (!dtls_cfg->enabled) {
 		return 0;
@@ -1288,6 +1321,16 @@ static int ast_rtp_dtls_set_configuration(struct ast_rtp_instance *instance, con
 
 	SSL_CTX_set_read_ahead(rtp->ssl_ctx, 1);
 
+#ifdef HAVE_OPENSSL_ECDH_AUTO
+	SSL_CTX_set_ecdh_auto(rtp->ssl_ctx, 1);
+#else
+	ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+	if (ecdh) {
+		SSL_CTX_set_tmp_ecdh(rtp->ssl_ctx, ecdh);
+		EC_KEY_free(ecdh);
+	}
+#endif
+
 	rtp->dtls_verify = dtls_cfg->verify;
 
 	SSL_CTX_set_verify(rtp->ssl_ctx, (rtp->dtls_verify & AST_RTP_DTLS_VERIFY_FINGERPRINT) || (rtp->dtls_verify & AST_RTP_DTLS_VERIFY_CERTIFICATE) ?
@@ -2472,7 +2515,7 @@ static int ast_rtp_new(struct ast_rtp_instance *instance,
 	     create_new_socket("RTP",
 			       ast_sockaddr_is_ipv4(addr) ? AF_INET  :
 			       ast_sockaddr_is_ipv6(addr) ? AF_INET6 : -1)) < 0) {
-		ast_debug(1, "Failed to create a new socket for RTP instance '%p'\n", instance);
+		ast_log(LOG_WARNING, "Failed to create a new socket for RTP instance '%p'\n", instance);
 		ast_free(rtp);
 		return -1;
 	}
@@ -2513,6 +2556,7 @@ static int ast_rtp_new(struct ast_rtp_instance *instance,
 #ifdef HAVE_PJPROJECT
 	/* Create an ICE session for ICE negotiation */
 	if (icesupport) {
+		ast_debug(3, "Creating ICE session %s (%d) for RTP instance '%p'\n", ast_sockaddr_stringify(addr), x, instance);
 		if (ice_create(instance, addr, x, 0)) {
 			ast_log(LOG_NOTICE, "Failed to start ICE session\n");
 		} else {
@@ -3155,8 +3199,8 @@ static int ast_rtcp_write(const void *data)
 		/*
 		 * Not being rescheduled.
 		 */
-		ao2_ref(instance, -1);
 		rtp->rtcp->schedid = -1;
+		ao2_ref(instance, -1);
 	}
 
 	return res;
@@ -3267,7 +3311,7 @@ static int ast_rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame
 			rtp->txcount++;
 			rtp->txoctetcount += (res - hdrlen);
 
-			if (rtp->rtcp && rtp->rtcp->schedid < 1) {
+			if (rtp->rtcp && rtp->rtcp->schedid < 0) {
 				ast_debug(1, "Starting RTCP transmission on RTP instance '%p'\n", instance);
 				ao2_ref(instance, +1);
 				rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, instance);
@@ -4478,7 +4522,7 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
 	}
 
 	/* Do not schedule RR if RTCP isn't run */
-	if (rtp->rtcp && !ast_sockaddr_isnull(&rtp->rtcp->them) && rtp->rtcp->schedid < 1) {
+	if (rtp->rtcp && !ast_sockaddr_isnull(&rtp->rtcp->them) && rtp->rtcp->schedid < 0) {
 		/* Schedule transmission of Receiver Report */
 		ao2_ref(instance, +1);
 		rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, instance);
@@ -4504,6 +4548,10 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
 	}
 
 	payload = ast_rtp_codecs_get_payload(ast_rtp_instance_get_codecs(instance), payloadtype);
+	if (!payload) {
+		/* Unknown payload type. */
+		return AST_LIST_FIRST(&frames) ? AST_LIST_FIRST(&frames) : &ast_null_frame;
+	}
 
 	/* If the payload is not actually an Asterisk one but a special one pass it off to the respective handler */
 	if (!payload->asterisk_format) {
@@ -4530,10 +4578,7 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
 		/* Even if no frame was returned by one of the above methods,
 		 * we may have a frame to return in our frame list
 		 */
-		if (!AST_LIST_EMPTY(&frames)) {
-			return AST_LIST_FIRST(&frames);
-		}
-		return &ast_null_frame;
+		return AST_LIST_FIRST(&frames) ? AST_LIST_FIRST(&frames) : &ast_null_frame;
 	}
 
 	ao2_replace(rtp->lastrxformat, payload->format);
diff --git a/res/res_stasis.c b/res/res_stasis.c
index fc34fa3..1cab8c3 100644
--- a/res/res_stasis.c
+++ b/res/res_stasis.c
@@ -109,6 +109,11 @@ struct ao2_container *app_bridges_moh;
 
 struct ao2_container *app_bridges_playback;
 
+/*!
+ * \internal \brief List of registered event sources.
+ */
+AST_RWLIST_HEAD_STATIC(event_sources, stasis_app_event_source);
+
 static struct ast_json *stasis_end_to_json(struct stasis_message *message,
 		const struct stasis_message_sanitizer *sanitize)
 {
@@ -1289,7 +1294,9 @@ int stasis_app_exec(struct ast_channel *chan, const char *app_name, int argc,
 
 		if (bridge != last_bridge) {
 			app_unsubscribe_bridge(app, last_bridge);
-			app_subscribe_bridge(app, bridge);
+			if (bridge) {
+				app_subscribe_bridge(app, bridge);
+			}
 		}
 
 		if (bridge) {
@@ -1469,7 +1476,7 @@ struct ao2_container *stasis_app_get_all(void)
 	return ao2_bump(apps);
 }
 
-int stasis_app_register(const char *app_name, stasis_app_cb handler, void *data)
+static int __stasis_app_register(const char *app_name, stasis_app_cb handler, void *data, int all_events)
 {
 	RAII_VAR(struct stasis_app *, app, NULL, ao2_cleanup);
 
@@ -1482,8 +1489,20 @@ int stasis_app_register(const char *app_name, stasis_app_cb handler, void *data)
 	if (app) {
 		app_update(app, handler, data);
 	} else {
-		app = app_create(app_name, handler, data);
+		app = app_create(app_name, handler, data, all_events ? STASIS_APP_SUBSCRIBE_ALL : STASIS_APP_SUBSCRIBE_MANUAL);
 		if (app) {
+			if (all_events) {
+				struct stasis_app_event_source *source;
+				SCOPED_LOCK(lock, &event_sources, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
+
+				AST_LIST_TRAVERSE(&event_sources, source, next) {
+					if (!source->subscribe) {
+						continue;
+					}
+
+					source->subscribe(app, NULL);
+				}
+			}
 			ao2_link_flags(apps_registry, app, OBJ_NOLOCK);
 		} else {
 			ao2_unlock(apps_registry);
@@ -1499,6 +1518,16 @@ int stasis_app_register(const char *app_name, stasis_app_cb handler, void *data)
 	return 0;
 }
 
+int stasis_app_register(const char *app_name, stasis_app_cb handler, void *data)
+{
+	return __stasis_app_register(app_name, handler, data, 0);
+}
+
+int stasis_app_register_all(const char *app_name, stasis_app_cb handler, void *data)
+{
+	return __stasis_app_register(app_name, handler, data, 1);
+}
+
 void stasis_app_unregister(const char *app_name)
 {
 	RAII_VAR(struct stasis_app *, app, NULL, ao2_cleanup);
@@ -1526,11 +1555,6 @@ void stasis_app_unregister(const char *app_name)
 	cleanup();
 }
 
-/*!
- * \internal \brief List of registered event sources.
- */
-AST_RWLIST_HEAD_STATIC(event_sources, stasis_app_event_source);
-
 void stasis_app_register_event_source(struct stasis_app_event_source *obj)
 {
 	SCOPED_LOCK(lock, &event_sources, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
@@ -1727,8 +1751,8 @@ static enum stasis_app_subscribe_res app_subscribe(
 
 	ast_debug(3, "%s: Checking %s\n", app_name, uri);
 
-	if (!event_source->find ||
-	    (!(obj = event_source->find(app, uri + strlen(event_source->scheme))))) {
+	if (!ast_strlen_zero(uri + strlen(event_source->scheme)) &&
+	    (!event_source->find || (!(obj = event_source->find(app, uri + strlen(event_source->scheme)))))) {
 		ast_log(LOG_WARNING, "Event source not found: %s\n", uri);
 		return STASIS_ASR_EVENT_SOURCE_NOT_FOUND;
 	}
@@ -2062,6 +2086,7 @@ static int load_module(void)
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Stasis application support",
+	.load_pri = AST_MODPRI_APP_DEPEND,
 	.support_level = AST_MODULE_SUPPORT_CORE,
 	.load = load_module,
 	.unload = unload_module,
diff --git a/res/res_stasis_device_state.c b/res/res_stasis_device_state.c
index aec6a6e..c0b6859 100644
--- a/res/res_stasis_device_state.c
+++ b/res/res_stasis_device_state.c
@@ -44,6 +44,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 /*! Number of hash buckets for device state subscriptions */
 #define DEVICE_STATE_BUCKETS 37
 
+/*! The key used for tracking a subscription to all device states */
+#define DEVICE_STATE_ALL "__AST_DEVICE_STATE_ALL_TOPIC"
+
 /*! Container for subscribed device states */
 static struct ao2_container *device_state_subscriptions;
 
@@ -112,11 +115,17 @@ static void device_state_subscription_destroy(void *obj)
 static struct device_state_subscription *device_state_subscription_create(
 	const struct stasis_app *app, const char *device_name)
 {
-	struct device_state_subscription *sub = ao2_alloc(
-		sizeof(*sub), device_state_subscription_destroy);
+	struct device_state_subscription *sub;
 	const char *app_name = stasis_app_name(app);
-	size_t size = strlen(device_name) + strlen(app_name) + 2;
+	size_t size;
+
+	if (ast_strlen_zero(device_name)) {
+		device_name = DEVICE_STATE_ALL;
+	}
 
+	size = strlen(device_name) + strlen(app_name) + 2;
+
+ 	sub = ao2_alloc(sizeof(*sub), device_state_subscription_destroy);
 	if (!sub) {
 		return NULL;
 	}
@@ -314,25 +323,50 @@ static void *find_device_state(const struct stasis_app *app, const char *name)
 
 static int is_subscribed_device_state(struct stasis_app *app, const char *name)
 {
-	RAII_VAR(struct device_state_subscription *, sub,
-		 find_device_state_subscription(app, name), ao2_cleanup);
-	return sub != NULL;
+	struct device_state_subscription *sub;
+
+	sub = find_device_state_subscription(app, DEVICE_STATE_ALL);
+	if (sub) {
+		ao2_ref(sub, -1);
+		return 1;
+	}
+
+	sub = find_device_state_subscription(app, name);
+	if (sub) {
+		ao2_ref(sub, -1);
+		return 1;
+	}
+
+	return 0;
 }
 
 static int subscribe_device_state(struct stasis_app *app, void *obj)
 {
 	struct device_state_subscription *sub = obj;
+	struct stasis_topic *topic;
+
+	if (!sub) {
+		sub = device_state_subscription_create(app, NULL);
+		if (!sub) {
+			return -1;
+		}
+	}
 
-	ast_debug(3, "Subscribing to device %s", sub->device_name);
+	if (strcmp(sub->device_name, DEVICE_STATE_ALL)) {
+		topic = ast_device_state_topic(sub->device_name);
+	} else {
+		topic = ast_device_state_topic_all();
+	}
 
 	if (is_subscribed_device_state(app, sub->device_name)) {
 		ast_debug(3, "App %s is already subscribed to %s\n", stasis_app_name(app), sub->device_name);
 		return 0;
 	}
 
-	if (!(sub->sub = stasis_subscribe_pool(
-			ast_device_state_topic(sub->device_name),
-			device_state_cb, sub))) {
+	ast_debug(3, "Subscribing to device %s\n", sub->device_name);
+
+	sub->sub = stasis_subscribe_pool(topic, device_state_cb, sub);
+	if (!sub->sub) {
 		ast_log(LOG_ERROR, "Unable to subscribe to device %s\n",
 			sub->device_name);
 		return -1;
diff --git a/res/stasis/app.c b/res/stasis/app.c
index caa27ab..3539182 100644
--- a/res/stasis/app.c
+++ b/res/stasis/app.c
@@ -38,6 +38,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/stasis_endpoints.h"
 #include "asterisk/stasis_message_router.h"
 
+#define BRIDGE_ALL "__AST_BRIDGE_ALL_TOPIC"
+#define CHANNEL_ALL "__AST_CHANNEL_ALL_TOPIC"
+#define ENDPOINT_ALL "__AST_ENDPOINT_ALL_TOPIC"
+
 static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate);
 
 struct stasis_app {
@@ -47,12 +51,16 @@ struct stasis_app {
 	struct stasis_message_router *router;
 	/*! Router for handling messages to the bridge all \a topic. */
 	struct stasis_message_router *bridge_router;
+	/*! Optional router for handling endpoint messages in 'all' subscriptions */
+	struct stasis_message_router *endpoint_router;
 	/*! Container of the channel forwards to this app's topic. */
 	struct ao2_container *forwards;
 	/*! Callback function for this application. */
 	stasis_app_cb handler;
 	/*! Opaque data to hand to callback function. */
 	void *data;
+	/*! Subscription model for the application */
+	enum stasis_app_subscription_model subscription_model;
 	/*! Name of the Stasis application */
 	char name[];
 };
@@ -121,34 +129,33 @@ static struct app_forwards *forwards_create(struct stasis_app *app,
 static struct app_forwards *forwards_create_channel(struct stasis_app *app,
 	struct ast_channel *chan)
 {
-	RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
+	struct app_forwards *forwards;
 
-	if (!app || !chan) {
+	if (!app) {
 		return NULL;
 	}
 
-	forwards = forwards_create(app, ast_channel_uniqueid(chan));
+	forwards = forwards_create(app, chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL);
 	if (!forwards) {
 		return NULL;
 	}
 
 	forwards->forward_type = FORWARD_CHANNEL;
-	forwards->topic_forward = stasis_forward_all(ast_channel_topic(chan),
-		app->topic);
-	if (!forwards->topic_forward) {
-		return NULL;
+	if (chan) {
+		forwards->topic_forward = stasis_forward_all(ast_channel_topic(chan),
+			app->topic);
 	}
-
 	forwards->topic_cached_forward = stasis_forward_all(
-		ast_channel_topic_cached(chan), app->topic);
-	if (!forwards->topic_cached_forward) {
+		chan ? ast_channel_topic_cached(chan) : ast_channel_topic_all_cached(),
+		app->topic);
+
+	if ((!forwards->topic_forward && chan) || !forwards->topic_cached_forward) {
 		/* Half-subscribed is a bad thing */
-		stasis_forward_cancel(forwards->topic_forward);
-		forwards->topic_forward = NULL;
+		forwards_unsubscribe(forwards);
+		ao2_ref(forwards, -1);
 		return NULL;
 	}
 
-	ao2_ref(forwards, +1);
 	return forwards;
 }
 
@@ -156,69 +163,101 @@ static struct app_forwards *forwards_create_channel(struct stasis_app *app,
 static struct app_forwards *forwards_create_bridge(struct stasis_app *app,
 	struct ast_bridge *bridge)
 {
-	RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
+	struct app_forwards *forwards;
 
-	if (!app || !bridge) {
+	if (!app) {
 		return NULL;
 	}
 
-	forwards = forwards_create(app, bridge->uniqueid);
+	forwards = forwards_create(app, bridge ? bridge->uniqueid : BRIDGE_ALL);
 	if (!forwards) {
 		return NULL;
 	}
 
 	forwards->forward_type = FORWARD_BRIDGE;
-	forwards->topic_forward = stasis_forward_all(ast_bridge_topic(bridge),
-		app->topic);
-	if (!forwards->topic_forward) {
-		return NULL;
+	if (bridge) {
+		forwards->topic_forward = stasis_forward_all(ast_bridge_topic(bridge),
+			app->topic);
 	}
-
 	forwards->topic_cached_forward = stasis_forward_all(
-		ast_bridge_topic_cached(bridge), app->topic);
-	if (!forwards->topic_cached_forward) {
+		bridge ? ast_bridge_topic_cached(bridge) : ast_bridge_topic_all_cached(),
+		app->topic);
+
+	if ((!forwards->topic_forward && bridge) || !forwards->topic_cached_forward) {
 		/* Half-subscribed is a bad thing */
-		stasis_forward_cancel(forwards->topic_forward);
-		forwards->topic_forward = NULL;
+		forwards_unsubscribe(forwards);
+		ao2_ref(forwards, -1);
 		return NULL;
 	}
 
-	ao2_ref(forwards, +1);
 	return forwards;
 }
 
+static void endpoint_state_cb(void *data, struct stasis_subscription *sub,
+	struct stasis_message *message)
+{
+	struct stasis_app *app = data;
+
+	stasis_publish(app->topic, message);
+}
+
 /*! Forward a endpoint's topics to an app */
 static struct app_forwards *forwards_create_endpoint(struct stasis_app *app,
 	struct ast_endpoint *endpoint)
 {
-	RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
 
-	if (!app || !endpoint) {
+	struct app_forwards *forwards;
+	int ret = 0;
+
+	if (!app) {
 		return NULL;
 	}
 
-	forwards = forwards_create(app, ast_endpoint_get_id(endpoint));
+	forwards = forwards_create(app, endpoint ? ast_endpoint_get_id(endpoint) : ENDPOINT_ALL);
 	if (!forwards) {
 		return NULL;
 	}
 
 	forwards->forward_type = FORWARD_ENDPOINT;
-	forwards->topic_forward = stasis_forward_all(ast_endpoint_topic(endpoint),
-		app->topic);
-	if (!forwards->topic_forward) {
-		return NULL;
-	}
+	if (endpoint) {
+		forwards->topic_forward = stasis_forward_all(ast_endpoint_topic(endpoint),
+			app->topic);
+		forwards->topic_cached_forward = stasis_forward_all(
+			ast_endpoint_topic_cached(endpoint), app->topic);
+
+		if (!forwards->topic_forward || !forwards->topic_cached_forward) {
+			/* Half-subscribed is a bad thing */
+			forwards_unsubscribe(forwards);
+			ao2_ref(forwards, -1);
+			return NULL;
+		}
+	} else {
+		/* Since endpoint subscriptions also subscribe to channels, in the case
+		 * of all endpoint subscriptions, we only want messages for the endpoints.
+		 * As such, we route those particular messages and then re-publish them
+		 * on the app's topic.
+		 */
+		ast_assert(app->endpoint_router == NULL);
+		app->endpoint_router = stasis_message_router_create(ast_endpoint_topic_all_cached());
+		if (!app->endpoint_router) {
+			forwards_unsubscribe(forwards);
+			ao2_ref(forwards, -1);
+			return NULL;
+		}
 
-	forwards->topic_cached_forward = stasis_forward_all(
-		ast_endpoint_topic_cached(endpoint), app->topic);
-	if (!forwards->topic_cached_forward) {
-		/* Half-subscribed is a bad thing */
-		stasis_forward_cancel(forwards->topic_forward);
-		forwards->topic_forward = NULL;
-		return NULL;
+		ret |= stasis_message_router_add(app->endpoint_router,
+			ast_endpoint_state_type(), endpoint_state_cb, app);
+		ret |= stasis_message_router_add(app->endpoint_router,
+			ast_endpoint_contact_state_type(), endpoint_state_cb, app);
+
+		if (ret) {
+			ao2_ref(app->endpoint_router, -1);
+			app->endpoint_router = NULL;
+			ao2_ref(forwards, -1);
+			return NULL;
+		}
 	}
 
-	ao2_ref(forwards, +1);
 	return forwards;
 }
 
@@ -260,6 +299,7 @@ static void app_dtor(void *obj)
 
 	ast_assert(app->router == NULL);
 	ast_assert(app->bridge_router == NULL);
+	ast_assert(app->endpoint_router == NULL);
 
 	ao2_cleanup(app->topic);
 	app->topic = NULL;
@@ -793,7 +833,7 @@ static void bridge_default_handler(void *data, struct stasis_subscription *sub,
 	}
 }
 
-struct stasis_app *app_create(const char *name, stasis_app_cb handler, void *data)
+struct stasis_app *app_create(const char *name, stasis_app_cb handler, void *data, enum stasis_app_subscription_model subscription_model)
 {
 	RAII_VAR(struct stasis_app *, app, NULL, ao2_cleanup);
 	size_t size;
@@ -806,10 +846,10 @@ struct stasis_app *app_create(const char *name, stasis_app_cb handler, void *dat
 
 	size = sizeof(*app) + strlen(name) + 1;
 	app = ao2_alloc_options(size, app_dtor, AO2_ALLOC_OPT_LOCK_MUTEX);
-
 	if (!app) {
 		return NULL;
 	}
+	app->subscription_model = subscription_model;
 
 	app->forwards = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_MUTEX,
 		AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT,
@@ -877,7 +917,8 @@ struct stasis_app *app_create(const char *name, stasis_app_cb handler, void *dat
 	return app;
 }
 
-struct stasis_topic *ast_app_get_topic(struct stasis_app *app) {
+struct stasis_topic *ast_app_get_topic(struct stasis_app *app)
+{
 	return app->topic;
 }
 
@@ -930,6 +971,8 @@ void app_shutdown(struct stasis_app *app)
 	app->router = NULL;
 	stasis_message_router_unsubscribe(app->bridge_router);
 	app->bridge_router = NULL;
+	stasis_message_router_unsubscribe(app->endpoint_router);
+	app->endpoint_router = NULL;
 }
 
 int app_is_active(struct stasis_app *app)
@@ -1029,34 +1072,47 @@ struct ast_json *app_to_json(const struct stasis_app *app)
 
 int app_subscribe_channel(struct stasis_app *app, struct ast_channel *chan)
 {
+	struct app_forwards *forwards;
+	SCOPED_AO2LOCK(lock, app->forwards);
 	int res;
 
-	if (!app || !chan) {
+	if (!app) {
 		return -1;
-	} else {
-		RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
-		SCOPED_AO2LOCK(lock, app->forwards);
+	}
 
-		forwards = ao2_find(app->forwards, ast_channel_uniqueid(chan),
-			OBJ_SEARCH_KEY | OBJ_NOLOCK);
-		if (!forwards) {
-			/* Forwards not found, create one */
-			forwards = forwards_create_channel(app, chan);
-			if (!forwards) {
-				return -1;
-			}
+	/* If subscribed to all, don't subscribe again */
+	forwards = ao2_find(app->forwards, CHANNEL_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
+	if (forwards) {
+		ao2_ref(forwards, -1);
+		return 0;
+	}
 
-			res = ao2_link_flags(app->forwards, forwards,
-				OBJ_NOLOCK);
-			if (!res) {
-				return -1;
-			}
+	forwards = ao2_find(app->forwards,
+		chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL,
+		OBJ_SEARCH_KEY | OBJ_NOLOCK);
+	if (!forwards) {
+		/* Forwards not found, create one */
+		forwards = forwards_create_channel(app, chan);
+		if (!forwards) {
+			return -1;
 		}
 
-		++forwards->interested;
-		ast_debug(3, "Channel '%s' is %d interested in %s\n", ast_channel_uniqueid(chan), forwards->interested, app->name);
-		return 0;
+		res = ao2_link_flags(app->forwards, forwards,
+			OBJ_NOLOCK);
+		if (!res) {
+			ao2_ref(forwards, -1);
+			return -1;
+		}
 	}
+
+	++forwards->interested;
+	ast_debug(3, "Channel '%s' is %d interested in %s\n",
+		chan ? ast_channel_uniqueid(chan) : "ALL",
+		forwards->interested,
+		app->name);
+
+	ao2_ref(forwards, -1);
+	return 0;
 }
 
 static int subscribe_channel(struct stasis_app *app, void *obj)
@@ -1069,6 +1125,19 @@ static int unsubscribe(struct stasis_app *app, const char *kind, const char *id,
 	RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
 	SCOPED_AO2LOCK(lock, app->forwards);
 
+	if (!id) {
+		if (!strcmp(kind, "bridge")) {
+			id = BRIDGE_ALL;
+		} else if (!strcmp(kind, "channel")) {
+			id = CHANNEL_ALL;
+		} else if (!strcmp(kind, "endpoint")) {
+			id = ENDPOINT_ALL;
+		} else {
+			ast_log(LOG_WARNING, "Unknown subscription kind '%s'\n", kind);
+			return -1;
+		}
+	}
+
 	forwards = ao2_find(app->forwards, id, OBJ_SEARCH_KEY | OBJ_NOLOCK);
 	if (!forwards) {
 		ast_debug(3, "App '%s' not subscribed to %s '%s'\n", app->name, kind, id);
@@ -1095,16 +1164,16 @@ static int unsubscribe(struct stasis_app *app, const char *kind, const char *id,
 
 int app_unsubscribe_channel(struct stasis_app *app, struct ast_channel *chan)
 {
-	if (!app || !chan) {
+	if (!app) {
 		return -1;
 	}
 
-	return app_unsubscribe_channel_id(app, ast_channel_uniqueid(chan));
+	return app_unsubscribe_channel_id(app, chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL);
 }
 
 int app_unsubscribe_channel_id(struct stasis_app *app, const char *channel_id)
 {
-	if (!app || !channel_id) {
+	if (!app) {
 		return -1;
 	}
 
@@ -1114,6 +1183,10 @@ int app_unsubscribe_channel_id(struct stasis_app *app, const char *channel_id)
 int app_is_subscribed_channel_id(struct stasis_app *app, const char *channel_id)
 {
 	RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
+
+	if (ast_strlen_zero(channel_id)) {
+		channel_id = CHANNEL_ALL;
+	}
 	forwards = ao2_find(app->forwards, channel_id, OBJ_SEARCH_KEY);
 	return forwards != NULL;
 }
@@ -1133,28 +1206,39 @@ struct stasis_app_event_source channel_event_source = {
 
 int app_subscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
 {
-	if (!app || !bridge) {
+	struct app_forwards *forwards;
+	SCOPED_AO2LOCK(lock, app->forwards);
+
+	if (!app) {
 		return -1;
-	} else {
-		RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
-		SCOPED_AO2LOCK(lock, app->forwards);
+	}
 
-		forwards = ao2_find(app->forwards, bridge->uniqueid,
-			OBJ_SEARCH_KEY | OBJ_NOLOCK);
+	/* If subscribed to all, don't subscribe again */
+	forwards = ao2_find(app->forwards, BRIDGE_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
+	if (forwards) {
+		ao2_ref(forwards, -1);
+		return 0;
+	}
 
+	forwards = ao2_find(app->forwards, bridge ? bridge->uniqueid : BRIDGE_ALL,
+		OBJ_SEARCH_KEY | OBJ_NOLOCK);
+	if (!forwards) {
+		/* Forwards not found, create one */
+		forwards = forwards_create_bridge(app, bridge);
 		if (!forwards) {
-			/* Forwards not found, create one */
-			forwards = forwards_create_bridge(app, bridge);
-			if (!forwards) {
-				return -1;
-			}
-			ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
+			return -1;
 		}
-
-		++forwards->interested;
-		ast_debug(3, "Bridge '%s' is %d interested in %s\n", bridge->uniqueid, forwards->interested, app->name);
-		return 0;
+		ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
 	}
+
+	++forwards->interested;
+	ast_debug(3, "Bridge '%s' is %d interested in %s\n",
+		bridge ? bridge->uniqueid : "ALL",
+		forwards->interested,
+		app->name);
+
+	ao2_ref(forwards, -1);
+	return 0;
 }
 
 static int subscribe_bridge(struct stasis_app *app, void *obj)
@@ -1164,16 +1248,16 @@ static int subscribe_bridge(struct stasis_app *app, void *obj)
 
 int app_unsubscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
 {
-	if (!app || !bridge) {
+	if (!app) {
 		return -1;
 	}
 
-	return app_unsubscribe_bridge_id(app, bridge->uniqueid);
+	return app_unsubscribe_bridge_id(app, bridge ? bridge->uniqueid : BRIDGE_ALL);
 }
 
 int app_unsubscribe_bridge_id(struct stasis_app *app, const char *bridge_id)
 {
-	if (!app || !bridge_id) {
+	if (!app) {
 		return -1;
 	}
 
@@ -1182,9 +1266,26 @@ int app_unsubscribe_bridge_id(struct stasis_app *app, const char *bridge_id)
 
 int app_is_subscribed_bridge_id(struct stasis_app *app, const char *bridge_id)
 {
-	RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
-	forwards = ao2_find(app->forwards, bridge_id, OBJ_SEARCH_KEY);
-	return forwards != NULL;
+	struct app_forwards *forwards;
+	SCOPED_AO2LOCK(lock, app->forwards);
+
+	forwards = ao2_find(app->forwards, BRIDGE_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
+	if (forwards) {
+		ao2_ref(forwards, -1);
+		return 1;
+	}
+
+	if (ast_strlen_zero(bridge_id)) {
+		bridge_id = BRIDGE_ALL;
+	}
+
+	forwards = ao2_find(app->forwards, bridge_id, OBJ_SEARCH_KEY | OBJ_NOLOCK);
+	if (forwards) {
+		ao2_ref(forwards, -1);
+		return 1;
+	}
+
+	return 0;
 }
 
 static void *bridge_find(const struct stasis_app *app, const char *id)
@@ -1202,31 +1303,43 @@ struct stasis_app_event_source bridge_event_source = {
 
 int app_subscribe_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint)
 {
-	if (!app || !endpoint) {
+	struct app_forwards *forwards;
+	SCOPED_AO2LOCK(lock, app->forwards);
+
+	if (!app) {
 		return -1;
-	} else {
-		RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
-		SCOPED_AO2LOCK(lock, app->forwards);
+	}
 
-		forwards = ao2_find(app->forwards, ast_endpoint_get_id(endpoint),
-			OBJ_SEARCH_KEY | OBJ_NOLOCK);
+	/* If subscribed to all, don't subscribe again */
+	forwards = ao2_find(app->forwards, ENDPOINT_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
+	if (forwards) {
+		ao2_ref(forwards, -1);
+		return 0;
+	}
 
+	forwards = ao2_find(app->forwards,
+		endpoint ? ast_endpoint_get_id(endpoint) : ENDPOINT_ALL,
+		OBJ_SEARCH_KEY | OBJ_NOLOCK);
+	if (!forwards) {
+		/* Forwards not found, create one */
+		forwards = forwards_create_endpoint(app, endpoint);
 		if (!forwards) {
-			/* Forwards not found, create one */
-			forwards = forwards_create_endpoint(app, endpoint);
-			if (!forwards) {
-				return -1;
-			}
-			ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
-
-			/* Subscribe for messages */
-			messaging_app_subscribe_endpoint(app->name, endpoint, &message_received_handler, app);
+			return -1;
 		}
+		ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
 
-		++forwards->interested;
-		ast_debug(3, "Endpoint '%s' is %d interested in %s\n", ast_endpoint_get_id(endpoint), forwards->interested, app->name);
-		return 0;
+		/* Subscribe for messages */
+		messaging_app_subscribe_endpoint(app->name, endpoint, &message_received_handler, app);
 	}
+
+	++forwards->interested;
+	ast_debug(3, "Endpoint '%s' is %d interested in %s\n",
+		endpoint ? ast_endpoint_get_id(endpoint) : "ALL",
+		forwards->interested,
+		app->name);
+
+	ao2_ref(forwards, -1);
+	return 0;
 }
 
 static int subscribe_endpoint(struct stasis_app *app, void *obj)
@@ -1236,7 +1349,7 @@ static int subscribe_endpoint(struct stasis_app *app, void *obj)
 
 int app_unsubscribe_endpoint_id(struct stasis_app *app, const char *endpoint_id)
 {
-	if (!app || !endpoint_id) {
+	if (!app) {
 		return -1;
 	}
 
@@ -1246,6 +1359,10 @@ int app_unsubscribe_endpoint_id(struct stasis_app *app, const char *endpoint_id)
 int app_is_subscribed_endpoint_id(struct stasis_app *app, const char *endpoint_id)
 {
 	RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
+
+	if (ast_strlen_zero(endpoint_id)) {
+		endpoint_id = ENDPOINT_ALL;
+	}
 	forwards = ao2_find(app->forwards, endpoint_id, OBJ_SEARCH_KEY);
 	return forwards != NULL;
 }
diff --git a/res/stasis/app.h b/res/stasis/app.h
index 59574f5..2c8db1c 100644
--- a/res/stasis/app.h
+++ b/res/stasis/app.h
@@ -36,6 +36,19 @@
  */
 struct stasis_app;
 
+enum stasis_app_subscription_model {
+	/*
+	 * \brief An application must manually subscribe to each
+	 * resource that it cares about. This is the default approach.
+	 */
+	STASIS_APP_SUBSCRIBE_MANUAL,
+	/*
+	 * \brief An application is automatically subscribed to all
+	 * resources in Asterisk, even if it does not control them.
+	 */
+	STASIS_APP_SUBSCRIBE_ALL
+};
+
 /*!
  * \brief Create a res_stasis application.
  *
@@ -45,7 +58,7 @@ struct stasis_app;
  * \return New \c res_stasis application.
  * \return \c NULL on error.
  */
-struct stasis_app *app_create(const char *name, stasis_app_cb handler, void *data);
+struct stasis_app *app_create(const char *name, stasis_app_cb handler, void *data, enum stasis_app_subscription_model subscription_model);
 
 /*!
  * \brief Tears down an application.
diff --git a/res/stasis/messaging.c b/res/stasis/messaging.c
index fd7cf9f..229a3a6 100644
--- a/res/stasis/messaging.c
+++ b/res/stasis/messaging.c
@@ -38,6 +38,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "messaging.h"
 
 /*!
+ * \brief Subscription to all technologies
+ */
+#define TECH_WILDCARD "__AST_ALL_TECH"
+
+/*!
  * \brief Number of buckets for the \ref endpoint_subscriptions container
  */
 #define ENDPOINTS_NUM_BUCKETS 127
@@ -219,10 +224,14 @@ static int has_destination_cb(const struct ast_msg *msg)
 	for (i = 0; i < AST_VECTOR_SIZE(&tech_subscriptions); i++) {
 		sub = AST_VECTOR_GET(&tech_subscriptions, i);
 
-		if (sub && (!strncasecmp(sub->token, buf, strlen(sub->token))
-		            || !strncasecmp(sub->token, buf, strlen(sub->token)))) {
+		if (!sub) {
+			continue;
+		}
+
+		if (!strcmp(sub->token, TECH_WILDCARD)
+		    || !strncasecmp(sub->token, buf, strlen(sub->token))
+		    || !strncasecmp(sub->token, buf, strlen(sub->token))) {
 			ast_rwlock_unlock(&tech_subscriptions_lock);
-			sub = NULL; /* No ref bump! */
 			goto match;
 		}
 
@@ -231,6 +240,7 @@ static int has_destination_cb(const struct ast_msg *msg)
 
 	sub = ao2_find(endpoint_subscriptions, buf, OBJ_SEARCH_KEY);
 	if (sub) {
+		ao2_ref(sub, -1);
 		goto match;
 	}
 
@@ -238,7 +248,6 @@ static int has_destination_cb(const struct ast_msg *msg)
 	return 0;
 
 match:
-	ao2_cleanup(sub);
 	return 1;
 }
 
@@ -301,7 +310,8 @@ static int handle_msg_cb(struct ast_msg *msg)
 			continue;
 		}
 
-		if (!strncasecmp(sub->token, buf, strlen(sub->token))) {
+		if (!strcmp(sub->token, TECH_WILDCARD)
+		    || !strncasecmp(sub->token, buf, strlen(sub->token))) {
 			ast_rwlock_unlock(&tech_subscriptions_lock);
 			ao2_bump(sub);
 			endpoint_name = buf;
@@ -374,7 +384,7 @@ static struct message_subscription *get_subscription(struct ast_endpoint *endpoi
 {
 	struct message_subscription *sub = NULL;
 
-	if (!ast_strlen_zero(ast_endpoint_get_resource(endpoint))) {
+	if (endpoint && !ast_strlen_zero(ast_endpoint_get_resource(endpoint))) {
 		sub = ao2_find(endpoint_subscriptions, endpoint, OBJ_SEARCH_KEY);
 	} else {
 		int i;
@@ -383,7 +393,7 @@ static struct message_subscription *get_subscription(struct ast_endpoint *endpoi
 		for (i = 0; i < AST_VECTOR_SIZE(&tech_subscriptions); i++) {
 			sub = AST_VECTOR_GET(&tech_subscriptions, i);
 
-			if (sub && !strcmp(sub->token, ast_endpoint_get_tech(endpoint))) {
+			if (sub && !strcmp(sub->token, endpoint ? ast_endpoint_get_tech(endpoint) : TECH_WILDCARD)) {
 				ao2_bump(sub);
 				break;
 			}
@@ -400,10 +410,6 @@ void messaging_app_unsubscribe_endpoint(const char *app_name, const char *endpoi
 	RAII_VAR(struct ast_endpoint *, endpoint, NULL, ao2_cleanup);
 
 	endpoint = ast_endpoint_find_by_id(endpoint_id);
-	if (!endpoint) {
-		return;
-	}
-
 	sub = get_subscription(endpoint);
 	if (!sub) {
 		return;
@@ -417,11 +423,11 @@ void messaging_app_unsubscribe_endpoint(const char *app_name, const char *endpoi
 
 	AST_VECTOR_REMOVE_CMP_UNORDERED(&sub->applications, app_name, application_tuple_cmp, ao2_cleanup);
 	if (AST_VECTOR_SIZE(&sub->applications) == 0) {
-		if (!ast_strlen_zero(ast_endpoint_get_resource(endpoint))) {
+		if (endpoint && !ast_strlen_zero(ast_endpoint_get_resource(endpoint))) {
 			ao2_unlink(endpoint_subscriptions, sub);
 		} else {
 			ast_rwlock_wrlock(&tech_subscriptions_lock);
-			AST_VECTOR_REMOVE_CMP_UNORDERED(&tech_subscriptions, ast_endpoint_get_id(endpoint),
+			AST_VECTOR_REMOVE_CMP_UNORDERED(&tech_subscriptions, endpoint ? ast_endpoint_get_id(endpoint) : TECH_WILDCARD,
 				messaging_subscription_cmp, AST_VECTOR_ELEM_CLEANUP_NOOP);
 			ast_rwlock_unlock(&tech_subscriptions_lock);
 		}
@@ -429,9 +435,9 @@ void messaging_app_unsubscribe_endpoint(const char *app_name, const char *endpoi
 	ao2_unlock(sub);
 	ao2_ref(sub, -1);
 
-	ast_debug(3, "App '%s' unsubscribed to messages from endpoint '%s'\n", app_name, ast_endpoint_get_id(endpoint));
+	ast_debug(3, "App '%s' unsubscribed to messages from endpoint '%s'\n", app_name, endpoint ? ast_endpoint_get_id(endpoint) : "-- ALL --");
 	ast_test_suite_event_notify("StasisMessagingSubscription", "SubState: Unsubscribed\r\nAppName: %s\r\nToken: %s\r\n",
-		app_name, ast_endpoint_get_id(endpoint));
+		app_name, endpoint ? ast_endpoint_get_id(endpoint) : "ALL");
 }
 
 static struct message_subscription *get_or_create_subscription(struct ast_endpoint *endpoint)
@@ -442,12 +448,12 @@ static struct message_subscription *get_or_create_subscription(struct ast_endpoi
 		return sub;
 	}
 
-	sub = message_subscription_alloc(ast_endpoint_get_id(endpoint));
+	sub = message_subscription_alloc(endpoint ? ast_endpoint_get_id(endpoint) : TECH_WILDCARD);
 	if (!sub) {
 		return NULL;
 	}
 
-	if (!ast_strlen_zero(ast_endpoint_get_resource(endpoint))) {
+	if (endpoint && !ast_strlen_zero(ast_endpoint_get_resource(endpoint))) {
 		ao2_link(endpoint_subscriptions, sub);
 	} else {
 		ast_rwlock_wrlock(&tech_subscriptions_lock);
@@ -482,9 +488,9 @@ int messaging_app_subscribe_endpoint(const char *app_name, struct ast_endpoint *
 	AST_VECTOR_APPEND(&sub->applications, tuple);
 	ao2_unlock(sub);
 
-	ast_debug(3, "App '%s' subscribed to messages from endpoint '%s'\n", app_name, ast_endpoint_get_id(endpoint));
+	ast_debug(3, "App '%s' subscribed to messages from endpoint '%s'\n", app_name, endpoint ? ast_endpoint_get_id(endpoint) : "-- ALL --");
 	ast_test_suite_event_notify("StasisMessagingSubscription", "SubState: Subscribed\r\nAppName: %s\r\nToken: %s\r\n",
-		app_name, ast_endpoint_get_id(endpoint));
+		app_name, endpoint ? ast_endpoint_get_id(endpoint) : "ALL");
 
 	return 0;
 }
diff --git a/rest-api-templates/ari_model_validators.c.mustache b/rest-api-templates/ari_model_validators.c.mustache
index be20515..0fabbcf 100644
--- a/rest-api-templates/ari_model_validators.c.mustache
+++ b/rest-api-templates/ari_model_validators.c.mustache
@@ -50,7 +50,7 @@ int ast_ari_validate_{{c_id}}(struct ast_json *json)
 
 	discriminator = ast_json_string_get(ast_json_object_get(json, "{{discriminator.name}}"));
 	if (!discriminator) {
-		ast_log(LOG_ERROR, "ARI {{id}} missing required field {{discriminator.name}}");
+		ast_log(LOG_ERROR, "ARI {{id}} missing required field {{discriminator.name}}\n");
 		return 0;
 	}
 
diff --git a/rest-api/api-docs/applications.json b/rest-api/api-docs/applications.json
index 446dfdd..c8660cf 100644
--- a/rest-api/api-docs/applications.json
+++ b/rest-api/api-docs/applications.json
@@ -2,7 +2,7 @@
 	"_copyright": "Copyright (C) 2013, Digium, Inc.",
 	"_author": "David M. Lee, II <dlee at digium.com>",
 	"_svn_revision": "$Revision$",
-	"apiVersion": "1.8.0",
+	"apiVersion": "1.9.0",
 	"swaggerVersion": "1.1",
 	"basePath": "http://localhost:8088/ari",
 	"resourcePath": "/api-docs/applications.{format}",
diff --git a/rest-api/api-docs/asterisk.json b/rest-api/api-docs/asterisk.json
index cc1e3b8..9dbf382 100644
--- a/rest-api/api-docs/asterisk.json
+++ b/rest-api/api-docs/asterisk.json
@@ -2,7 +2,7 @@
 	"_copyright": "Copyright (C) 2012 - 2013, Digium, Inc.",
 	"_author": "David M. Lee, II <dlee at digium.com>",
 	"_svn_revision": "$Revision$",
-	"apiVersion": "1.8.0",
+	"apiVersion": "1.9.0",
 	"swaggerVersion": "1.1",
 	"basePath": "http://localhost:8088/ari",
 	"resourcePath": "/api-docs/asterisk.{format}",
@@ -297,6 +297,108 @@
 			]
 		},
 		{
+			"path": "/asterisk/logging",
+			"description": "Asterisk log channels",
+			"operations": [
+				{
+					"httpMethod": "GET",
+					"summary": "Gets Asterisk log channel information.",
+					"nickname": "listLogChannels",
+					"responseClass": "List[LogChannel]"
+				}
+			]
+		},
+		{
+			"path": "/asterisk/logging/{logChannelName}",
+			"description": "Asterisk log channel",
+			"operations": [
+				{
+					"httpMethod": "POST",
+					"summary": "Adds a log channel.",
+					"nickname": "addLog",
+					"responseClass": "void",
+					"parameters": [
+						{
+							"name": "logChannelName",
+							"description": "The log channel to add",
+							"paramType": "path",
+							"required": true,
+							"allowMultiple": false,
+							"dataType": "string"
+						},
+						{
+							"name": "configuration",
+							"description": "levels of the log channel",
+							"paramType": "query",
+							"required": true,
+							"allowMultiple": false,
+							"dataType": "string"
+						}
+					],
+					"errorResponses": [
+						{
+							"code": 400,
+							"reason": "Bad request body"
+						},
+						{
+							"code": 409,
+							"reason": "Log channel could not be created."
+						}
+					]
+				},
+				{
+					"httpMethod": "DELETE",
+					"summary": "Deletes a log channel.",
+					"nickname": "deleteLog",
+					"responseClass": "void",
+					"parameters": [
+						{
+							"name": "logChannelName",
+							"description": "Log channels name",
+							"paramType": "path",
+							"required": true,
+							"allowMultiple": false,
+							"dataType": "string"
+						}
+					],
+					"errorResponses": [
+						{
+							"code": 404,
+							"reason": "Log channel does not exist."
+						}
+					]
+				}
+			]
+		},
+		{
+			"path": "/asterisk/logging/{logChannelName}/rotate",
+			"description": "Asterisk log channel",
+			"operations": [
+				{
+					"httpMethod": "PUT",
+					"summary": "Rotates a log channel.",
+					"nickname": "rotateLog",
+					"responseClass": "void",
+					"parameters": [
+						{
+							"name": "logChannelName",
+							"description": "Log channel's name",
+							"paramType": "path",
+							"required": true,
+							"allowMultiple": false,
+							"dataType": "string"
+						}
+					],
+					"errorResponses": [
+						{
+							"code": 404,
+							"reason": "Log channel does not exist."
+						}
+					]
+				}
+			]
+		},
+		{
 			"path": "/asterisk/variable",
 			"description": "Global variables",
 			"operations": [
@@ -533,6 +635,32 @@
 				}
 			}
 		},
+		"LogChannel": {
+			"id": "LogChannel",
+			"description": "Details of an Asterisk log channel",
+			"properties": {
+				"channel": {
+					"type": "string",
+					"description": "The log channel path",
+					"required": true
+				},
+				"type": {
+					"type": "string",
+					"description": "Types of logs for the log channel",
+					"required": true
+				},
+				"status": {
+					"type": "string",
+					"description": "Whether or not a log type is enabled",
+					"required": true
+				},
+				"configuration": {
+					"type": "string",
+					"description": "The various log levels",
+					"required": true
+				}
+			}
+		},
 		"Variable": {
 			"id": "Variable",
 			"description": "The value of a channel variable",
diff --git a/rest-api/api-docs/bridges.json b/rest-api/api-docs/bridges.json
index 4bbbe10..0e726a5 100644
--- a/rest-api/api-docs/bridges.json
+++ b/rest-api/api-docs/bridges.json
@@ -2,7 +2,7 @@
 	"_copyright": "Copyright (C) 2012 - 2013, Digium, Inc.",
 	"_author": "David M. Lee, II <dlee at digium.com>",
 	"_svn_revision": "$Revision$",
-	"apiVersion": "1.8.0",
+	"apiVersion": "1.9.0",
 	"swaggerVersion": "1.1",
 	"basePath": "http://localhost:8088/ari",
 	"resourcePath": "/api-docs/bridges.{format}",
diff --git a/rest-api/api-docs/channels.json b/rest-api/api-docs/channels.json
index 1b7faf7..cb41fb6 100644
--- a/rest-api/api-docs/channels.json
+++ b/rest-api/api-docs/channels.json
@@ -2,7 +2,7 @@
 	"_copyright": "Copyright (C) 2012 - 2013, Digium, Inc.",
 	"_author": "David M. Lee, II <dlee at digium.com>",
 	"_svn_revision": "$Revision$",
-	"apiVersion": "1.8.0",
+	"apiVersion": "1.9.0",
 	"swaggerVersion": "1.1",
 	"basePath": "http://localhost:8088/ari",
 	"resourcePath": "/api-docs/channels.{format}",
diff --git a/rest-api/api-docs/deviceStates.json b/rest-api/api-docs/deviceStates.json
index fa68dcf..a268a18 100644
--- a/rest-api/api-docs/deviceStates.json
+++ b/rest-api/api-docs/deviceStates.json
@@ -2,7 +2,7 @@
 	"_copyright": "Copyright (C) 2012 - 2013, Digium, Inc.",
 	"_author": "Kevin Harwell <kharwell at digium.com>",
 	"_svn_revision": "$Revision$",
-	"apiVersion": "1.8.0",
+	"apiVersion": "1.9.0",
 	"swaggerVersion": "1.1",
 	"basePath": "http://localhost:8088/ari",
 	"resourcePath": "/api-docs/deviceStates.{format}",
diff --git a/rest-api/api-docs/endpoints.json b/rest-api/api-docs/endpoints.json
index 7346773..c6a3020 100644
--- a/rest-api/api-docs/endpoints.json
+++ b/rest-api/api-docs/endpoints.json
@@ -2,7 +2,7 @@
 	"_copyright": "Copyright (C) 2012 - 2013, Digium, Inc.",
 	"_author": "David M. Lee, II <dlee at digium.com>",
 	"_svn_revision": "$Revision$",
-	"apiVersion": "1.8.0",
+	"apiVersion": "1.9.0",
 	"swaggerVersion": "1.1",
 	"basePath": "http://localhost:8088/ari",
 	"resourcePath": "/api-docs/endpoints.{format}",
diff --git a/rest-api/api-docs/events.json b/rest-api/api-docs/events.json
index 8d74900..464e06f 100644
--- a/rest-api/api-docs/events.json
+++ b/rest-api/api-docs/events.json
@@ -2,7 +2,7 @@
 	"_copyright": "Copyright (C) 2012 - 2013, Digium, Inc.",
 	"_author": "David M. Lee, II <dlee at digium.com>",
 	"_svn_revision": "$Revision$",
-	"apiVersion": "1.8.0",
+	"apiVersion": "1.9.0",
 	"swaggerVersion": "1.2",
 	"basePath": "http://localhost:8088/ari",
 	"resourcePath": "/api-docs/events.{format}",
@@ -26,6 +26,14 @@
 							"required": true,
 							"allowMultiple": true,
 							"dataType": "string"
+						},
+						{
+							"name": "subscribeAll",
+							"description": "Subscribe to all Asterisk events. If provided, the applications listed will be subscribed to all events, effectively disabling the application specific subscriptions. Default is 'false'.",
+							"paramType": "query",
+							"required": false,
+							"allowMultiple": false,
+							"dataType": "boolean"
 						}
 					]
 				}
@@ -163,14 +171,83 @@
 				"ChannelTalkingFinished",
 				"ChannelHold",
 				"ChannelUnhold",
+				"ContactStatusChange",
 				"EndpointStateChange",
 				"Dial",
 				"StasisEnd",
 				"StasisStart",
 				"TextMessageReceived",
-				"ChannelConnectedLine"
+				"ChannelConnectedLine",
+				"PeerStatusChange"
 			]
 		},
+		"ContactInfo": {
+			"id": "ContactInfo",
+			"description": "Detailed information about a contact on an endpoint.",
+			"properties": {
+				"uri": {
+					"type": "string",
+					"description": "The location of the contact.",
+					"required": true
+				},
+				"contact_status": {
+					"type": "string",
+					"description": "The current status of the contact.",
+					"required": true,
+					"allowableValues": {
+						"valueType": "LIST",
+						"values": [
+							"Unreachable",
+							"Reachable",
+							"Unknown",
+							"Created",
+							"Removed"
+						]
+					}
+				},
+				"aor": {
+					"type": "string",
+					"description": "The Address of Record this contact belongs to.",
+					"required": true
+				},
+				"roundtrip_usec": {
+					"type": "string",
+					"description": "Current round trip time, in microseconds, for the contact.",
+					"required": false
+				}
+			}
+		},
+		"Peer": {
+			"id": "Peer",
+			"description": "Detailed information about a remote peer that communicates with Asterisk.",
+			"properties": {
+				"peer_status": {
+					"type": "string",
+					"description": "The current state of the peer. Note that the values of the status are dependent on the underlying peer technology.",
+					"required": true
+				},
+				"cause": {
+					"type": "string",
+					"description": "An optional reason associated with the change in peer_status.",
+					"required": false
+				},
+				"address": {
+					"type": "string",
+					"description": "The IP address of the peer.",
+					"required": false
+				},
+				"port": {
+					"type": "string",
+					"description": "The port of the peer.",
+					"required": false
+				},
+				"time": {
+					"type": "string",
+					"description": "The last known time the peer was contacted.",
+					"required": false
+				}
+			}
+		},
 		"DeviceStateChanged": {
 			"id": "DeviceStateChanged",
 			"description": "Notification that a device state has changed.",
@@ -654,6 +731,34 @@
 				}
 			}
 		},
+		"ContactStatusChange": {
+			"id": "ContactStatusChange",
+			"description": "The state of a contact on an endpoint has changed.",
+			"properties": {
+				"endpoint": {
+					"required": true,
+					"type": "Endpoint"
+				},
+				"contact_info": {
+					"required": true,
+					"type": "ContactInfo"
+				}
+			}
+		},
+		"PeerStatusChange": {
+			"id": "PeerStatusChange",
+			"description": "The state of a peer associated with an endpoint has changed.",
+			"properties": {
+				"endpoint": {
+					"required": true,
+					"type": "Endpoint"
+				},
+				"peer": {
+					"required": true,
+					"type": "Peer"
+				}
+			}
+		},
 		"EndpointStateChange": {
 			"id": "EndpointStateChange",
 			"description": "Endpoint state changed.",
diff --git a/rest-api/api-docs/mailboxes.json b/rest-api/api-docs/mailboxes.json
index 12b8832..5b290fc 100644
--- a/rest-api/api-docs/mailboxes.json
+++ b/rest-api/api-docs/mailboxes.json
@@ -2,7 +2,7 @@
 	"_copyright": "Copyright (C) 2013, Digium, Inc.",
 	"_author": "Jonathan Rose <jrose at digium.com>",
 	"_svn_revision": "$Revision$",
-	"apiVersion": "1.8.0",
+	"apiVersion": "1.9.0",
 	"swaggerVersion": "1.1",
 	"basePath": "http://localhost:8088/ari",
 	"resourcePath": "/api-docs/mailboxes.{format}",
diff --git a/rest-api/api-docs/playbacks.json b/rest-api/api-docs/playbacks.json
index d968380..e6cb749 100644
--- a/rest-api/api-docs/playbacks.json
+++ b/rest-api/api-docs/playbacks.json
@@ -2,7 +2,7 @@
 	"_copyright": "Copyright (C) 2012 - 2013, Digium, Inc.",
 	"_author": "David M. Lee, II <dlee at digium.com>",
 	"_svn_revision": "$Revision$",
-	"apiVersion": "1.8.0",
+	"apiVersion": "1.9.0",
 	"swaggerVersion": "1.1",
 	"basePath": "http://localhost:8088/ari",
 	"resourcePath": "/api-docs/playbacks.{format}",
diff --git a/rest-api/api-docs/recordings.json b/rest-api/api-docs/recordings.json
index 8686e88..bc2b902 100644
--- a/rest-api/api-docs/recordings.json
+++ b/rest-api/api-docs/recordings.json
@@ -2,7 +2,7 @@
 	"_copyright": "Copyright (C) 2012 - 2013, Digium, Inc.",
 	"_author": "David M. Lee, II <dlee at digium.com>",
 	"_svn_revision": "$Revision$",
-	"apiVersion": "1.8.0",
+	"apiVersion": "1.9.0",
 	"swaggerVersion": "1.1",
 	"basePath": "http://localhost:8088/ari",
 	"resourcePath": "/api-docs/recordings.{format}",
diff --git a/rest-api/api-docs/sounds.json b/rest-api/api-docs/sounds.json
index 4cfa7ed..70d65a4 100644
--- a/rest-api/api-docs/sounds.json
+++ b/rest-api/api-docs/sounds.json
@@ -2,7 +2,7 @@
 	"_copyright": "Copyright (C) 2012 - 2013, Digium, Inc.",
 	"_author": "David M. Lee, II <dlee at digium.com>",
 	"_svn_revision": "$Revision$",
-	"apiVersion": "1.8.0",
+	"apiVersion": "1.9.0",
 	"swaggerVersion": "1.1",
 	"basePath": "http://localhost:8088/ari",
 	"resourcePath": "/api-docs/sounds.{format}",
diff --git a/rest-api/resources.json b/rest-api/resources.json
index 995303d..bacbc78 100644
--- a/rest-api/resources.json
+++ b/rest-api/resources.json
@@ -2,7 +2,7 @@
 	"_copyright": "Copyright (C) 2012 - 2013, Digium, Inc.",
 	"_author": "David M. Lee, II <dlee at digium.com>",
 	"_svn_revision": "$Revision$",
-	"apiVersion": "1.8.0",
+	"apiVersion": "1.9.0",
 	"swaggerVersion": "1.1",
 	"basePath": "http://localhost:8088/ari",
 	"apis": [
diff --git a/tests/test_core_format.c b/tests/test_core_format.c
index a6614d6..a3819c6 100644
--- a/tests/test_core_format.c
+++ b/tests/test_core_format.c
@@ -45,6 +45,7 @@ static int test_core_format_clone(const struct ast_format *src, struct ast_forma
 static enum ast_format_cmp_res test_core_format_cmp(const struct ast_format *format1, const struct ast_format *format2);
 static struct ast_format *test_core_format_get_joint(const struct ast_format *format1, const struct ast_format *format2);
 static struct ast_format *test_core_format_attribute_set(const struct ast_format *format, const char *name, const char *value);
+static const void *test_core_format_attribute_get(const struct ast_format *format, const char *name);
 static struct ast_format *test_core_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes);
 static void test_core_format_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str);
 
@@ -55,6 +56,7 @@ static struct ast_format_interface test_core_format_attr = {
 	.format_cmp = &test_core_format_cmp,
 	.format_get_joint = &test_core_format_get_joint,
 	.format_attribute_set = &test_core_format_attribute_set,
+	.format_attribute_get = &test_core_format_attribute_get,
 	.format_parse_sdp_fmtp = &test_core_format_parse_sdp_fmtp,
 	.format_generate_sdp_fmtp = &test_core_format_generate_sdp_fmtp,
 };
@@ -202,6 +204,19 @@ static struct ast_format *test_core_format_attribute_set(const struct ast_format
 	return clone;
 }
 
+/*! \brief Format attribute callback for retrieving an attribute */
+static const void *test_core_format_attribute_get(const struct ast_format *format, const char *name)
+{
+	struct test_core_format_pvt *pvt = ast_format_get_attribute_data(format);
+
+	if (!strcmp(name, "one")) {
+		return &pvt->field_one;
+	} else if (!strcmp(name, "two")) {
+		return &pvt->field_two;
+	}
+	return NULL;
+}
+
 /*! \brief Format attribute callback to construct a format from an SDP fmtp line */
 static struct ast_format *test_core_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
 {
@@ -333,6 +348,55 @@ AST_TEST_DEFINE(format_create_attr)
 	return AST_TEST_PASS;
 }
 
+AST_TEST_DEFINE(format_retrieve_attr)
+{
+	RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_format *, format, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_format *, format_w_attr, NULL, ao2_cleanup);
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = __PRETTY_FUNCTION__;
+		info->category = TEST_CATEGORY;
+		info->summary = "Format attribute retrieval unit test";
+		info->description =
+			"Test retrieval of format attributes";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	codec = ast_codec_get("test_core_format_codec", AST_MEDIA_TYPE_AUDIO, 8000);
+	if (!codec) {
+		ast_test_status_update(test, "Could not retrieve test_core_format_codec codec\n");
+		return AST_TEST_FAIL;
+	}
+
+	format = ast_format_create(codec);
+	if (!format) {
+		ast_test_status_update(test, "Could not create format using test_core_format_codec codec\n");
+		return AST_TEST_FAIL;
+	}
+
+	format_w_attr = ast_format_attribute_set(format, "one", "1");
+	if (!format_w_attr) {
+		ast_test_status_update(test, "Could not create format with attributes using test_core_format_codec codec\n");
+		return AST_TEST_FAIL;
+	}
+
+	if (*((int *)ast_format_attribute_get(format_w_attr, "one")) != 1) {
+		ast_test_status_update(test, "Could not retrieve valid format attribute\n");
+		return AST_TEST_FAIL;
+	}
+
+	if (ast_format_attribute_get(format_w_attr, "foo") != NULL) {
+		ast_test_status_update(test, "Retrieved invalid format attribute\n");
+		return AST_TEST_FAIL;
+	}
+
+	return AST_TEST_PASS;
+}
+
 AST_TEST_DEFINE(format_clone)
 {
 	RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
@@ -829,6 +893,43 @@ AST_TEST_DEFINE(format_attribute_set_without_interface)
 	return AST_TEST_PASS;
 }
 
+AST_TEST_DEFINE(format_attribute_get_without_interface)
+{
+	RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_format *, format, NULL, ao2_cleanup);
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = __PRETTY_FUNCTION__;
+		info->category = TEST_CATEGORY;
+		info->summary = "Format attribute retrieval unit test";
+		info->description =
+			"Test that attribute retrieval on a format without an interface fails";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	codec = ast_codec_get("ulaw", AST_MEDIA_TYPE_AUDIO, 8000);
+	if (!codec) {
+		ast_test_status_update(test, "Could not retrieve built-in ulaw codec\n");
+		return AST_TEST_FAIL;
+	}
+
+	format = ast_format_create(codec);
+	if (!format) {
+		ast_test_status_update(test, "Could not create format using built-in codec\n");
+		return AST_TEST_FAIL;
+	}
+
+	if (ast_format_attribute_get(format, "bees") != NULL) {
+		ast_test_status_update(test, "Successfully retrieved an attribute on a format without an interface\n");
+		return AST_TEST_FAIL;
+	}
+
+	return AST_TEST_PASS;
+}
+
 AST_TEST_DEFINE(format_parse_sdp_fmtp_without_interface)
 {
 	RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
@@ -925,6 +1026,7 @@ static int unload_module(void)
 {
 	AST_TEST_UNREGISTER(format_create);
 	AST_TEST_UNREGISTER(format_create_attr);
+	AST_TEST_UNREGISTER(format_retrieve_attr);
 	AST_TEST_UNREGISTER(format_clone);
 	AST_TEST_UNREGISTER(format_cmp_same_codec);
 	AST_TEST_UNREGISTER(format_attr_cmp_same_codec);
@@ -934,6 +1036,7 @@ static int unload_module(void)
 	AST_TEST_UNREGISTER(format_joint_different_codec);
 	AST_TEST_UNREGISTER(format_copy);
 	AST_TEST_UNREGISTER(format_attribute_set_without_interface);
+	AST_TEST_UNREGISTER(format_attribute_get_without_interface);
 	AST_TEST_UNREGISTER(format_parse_sdp_fmtp_without_interface);
 	AST_TEST_UNREGISTER(format_parse_and_generate_sdp_fmtp);
 
@@ -955,6 +1058,7 @@ static int load_module(void)
 
 	AST_TEST_REGISTER(format_create);
 	AST_TEST_REGISTER(format_create_attr);
+	AST_TEST_REGISTER(format_retrieve_attr);
 	AST_TEST_REGISTER(format_clone);
 	AST_TEST_REGISTER(format_cmp_same_codec);
 	AST_TEST_REGISTER(format_attr_cmp_same_codec);
@@ -964,6 +1068,7 @@ static int load_module(void)
 	AST_TEST_REGISTER(format_joint_different_codec);
 	AST_TEST_REGISTER(format_copy);
 	AST_TEST_REGISTER(format_attribute_set_without_interface);
+	AST_TEST_REGISTER(format_attribute_get_without_interface);
 	AST_TEST_REGISTER(format_parse_sdp_fmtp_without_interface);
 	AST_TEST_REGISTER(format_parse_and_generate_sdp_fmtp);
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/asterisk.git



More information about the Pkg-voip-commits mailing list