[asterisk-commits] kmoore: branch kmoore/stasis-bridging-channel_events r386333 - in /team/kmoor...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 23 08:33:01 CDT 2013


Author: kmoore
Date: Tue Apr 23 08:32:56 2013
New Revision: 386333

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386333
Log:
Multiple revisions 386007-386008,386014-386015,386021,386055,386136,386142,386147,386162,386191,386212,386237,386290,386303

........
  r386007 | rmudgett | 2013-04-18 11:09:29 -0500 (Thu, 18 Apr 2013) | 4 lines
  
  Rename ast_bridge_merge() and bridge_merge_do() parameter names.
  
  bridge1 and bridge2 are so lacking in description.
........
  r386008 | rmudgett | 2013-04-18 11:13:52 -0500 (Thu, 18 Apr 2013) | 5 lines
  
  Fix crash when run out of file descriptors.
  
  You cannot reference peer_features after the call to ast_bridge_impart()
  in ast_bridge_call() even if the impart fails.
........
  r386014 | rmudgett | 2013-04-18 11:24:03 -0500 (Thu, 18 Apr 2013) | 2 lines
  
  Fix deadlock potential when dissolving a bridge.
........
  r386015 | rmudgett | 2013-04-18 11:25:14 -0500 (Thu, 18 Apr 2013) | 1 line
  
  Update some bridging comments.
........
  r386021 | root | 2013-04-18 13:17:20 -0500 (Thu, 18 Apr 2013) | 39 lines
  
  Multiple revisions 386019-386020
  
  ........
    r386019 | dlee | 2013-04-18 12:26:29 -0500 (Thu, 18 Apr 2013) | 17 lines
    
    Fix lock errors on startup.
    
    In messages.c, there are several places in the code where we create a
    tmp_tech_holder and pass that into an ao2_find call. Unfortunately, we
    weren't initializing the rwlock on the tmp_tech_holder, which the hash
    function was locking. It's apparently harmless, but still not the best
    code.
    
    This patch extracts all that copy/pasted code into two functions,
    msg_find_by_tech and msg_find_by_tech_name, which properly initialize
    and destroy the rwlock on the tmp_tech_holder.
    
    Review: https://reviewboard.asterisk.org/r/2454/
    ........
    
    Merged revisions 386006 from http://svn.asterisk.org/svn/asterisk/branches/11
  ........
    r386020 | dlee | 2013-04-18 12:30:28 -0500 (Thu, 18 Apr 2013) | 12 lines
    
    Allow WebSocket connections on more URL's
    
    This patch adds the concept of ast_websocket_server to
    res_http_websocket, allowing WebSocket connections on URL's more more
    than /ws.
    
    The existing funcitons for managing the WebSocket subprotocols on /ws
    still work, so this patch should be completely backward compatible.
    
    (closes issue ASTERISK-21279)
    Review: https://reviewboard.asterisk.org/r/2453/
  ........
  
  Merged revisions 386019-386020 from file:///srv/subversion/repos/asterisk/trunk
........
  r386055 | root | 2013-04-19 01:17:20 -0500 (Fri, 19 Apr 2013) | 13 lines
  
  cli.c: Properly initialize debug_modules and verbose_modules.
  
  This avoids some lock errors on the core set {debug,verbose} commands.
  ........
  
  Merged revisions 386049 from http://svn.asterisk.org/svn/asterisk/branches/1.8
  ........
  
  Merged revisions 386051 from http://svn.asterisk.org/svn/asterisk/branches/11
  ........
  
  Merged revisions 386054 from file:///srv/subversion/repos/asterisk/trunk
........
  r386136 | rmudgett | 2013-04-19 12:13:57 -0500 (Fri, 19 Apr 2013) | 19 lines
  
  Create the basic bridge subclass of struct ast_bridge.
  
  This bridge class is the normal bridge for most calls.  It adds management
  of the DTMF feature hooks for each channel while they are in this bridge.
  When the basic two party bridge expands into a multi-party bridge, the
  various parties can drop out of the bridge without destroying it.
  
  The new bridging API does not allow casual knowledge of what channels are
  bridged with a particular channel because there can be more than one.
  With this restriction, the support of the [applicationmap] ActivatedBy
  feature option no longer makes sense and cannot be supported.  The
  ActivatedBy option is now just ignored.  The feature can only be activated
  by the channel it is attached to and not by its peer.
  
  (closes issue ASTERISK-21332)
  Reported by: Matt Jordan
  
  Review: https://reviewboard.asterisk.org/r/2446/
........
  r386142 | rmudgett | 2013-04-19 13:07:39 -0500 (Fri, 19 Apr 2013) | 5 lines
  
  Separate bridge and bridge channel feature flags.
  
  * Made the bridge/bridge-channel feature flags function parameters
  unsigned since a flag does not have a sign.
........
  r386147 | rmudgett | 2013-04-19 14:10:31 -0500 (Fri, 19 Apr 2013) | 1 line
  
  Remove local channel /b option.
........
  r386162 | root | 2013-04-19 18:17:20 -0500 (Fri, 19 Apr 2013) | 58 lines
  
  Prevent res_timing_pthread from blocking callers
  
  There were several reports of deadlock when using
  res_timing_pthread. Backtraces indicated that one thread was blocked
  waiting for the write to the pipe to complete and this thread held
  the container lock for the timers.  Therefore any thread that wanted
  to create a new timer or read an existing timer would block waiting
  for either the timer lock or the container lock and deadlock ensued.
  
  This patch changes the way the pipe is used to eliminate this source
  of deadlocks:
  
  1) The pipe is placed in non-blocking mode so that it would never
  block even if the following changes someone fail...
  
  2) Instead of writing bytes into the pipe for each "tick" that's
  fired the pipe now has two states--signaled and unsignaled. If
  signaled, the pipe is hot and any pollers of the read side
  filedescriptor will be woken up. If unsigned the pipe is idle. This
  eliminates even the chance of filling up the pipe and reduces the
  potential overhead of calling unnecessary writes.
  
  3) Since we're tracking the signaled / unsignaled state, we can
  eliminate the exta poll system call for every firing because we know
  that there is data to be read.
  
  (closes issue ASTERISK-21389)
  Reported by: Matt Jordan
  Tested by: Shaun Ruffell, Matt Jordan, Tony Lewis
  patches:
    0001-res_timing_pthread-Reduce-probability-of-deadlocking.patch uploaded by sruffell (License 5417)
  
  (closes issue ASTERISK-19754)
  Reported by: Nikola Ciprich
  
  (closes issue ASTERISK-20577)
  Reported by: Kien Kennedy
  
  (closes issue ASTERISK-17436)
  Reported by: Henry Fernandes
  
  (closes issue ASTERISK-17467)
  Reported by: isrl
  
  (closes issue ASTERISK-17458)
  Reported by: isrl
  
  Review: https://reviewboard.asterisk.org/r/2441/
  ........
  
  Merged revisions 386109 from http://svn.asterisk.org/svn/asterisk/branches/1.8
  ........
  
  Merged revisions 386159 from http://svn.asterisk.org/svn/asterisk/branches/11
  ........
  
  Merged revisions 386160 from file:///srv/subversion/repos/asterisk/trunk
........
  r386191 | root | 2013-04-21 20:17:50 -0500 (Sun, 21 Apr 2013) | 9 lines
  
  sla: remove redundant locking.
  
  sla.lock was already locked in the only place that sla_check_reload() was called.
  Remove the redundant locking of sla.lock done in this function.  Less recursive
  locking is A Good Thing.
  ........
  
  Merged revisions 386190 from file:///srv/subversion/repos/asterisk/trunk
........
  r386212 | root | 2013-04-22 08:17:53 -0500 (Mon, 22 Apr 2013) | 7 lines
  
  Fix mistake in Doxygen. 
  
  Doxygen is only *ONE* comment that applies to the NEXT piece of code.
  ........
  
  Merged revisions 386211 from file:///srv/subversion/repos/asterisk/trunk
........
  r386237 | root | 2013-04-22 10:17:21 -0500 (Mon, 22 Apr 2013) | 24 lines
  
  This patch adds a RESTful HTTP interface to Asterisk.
  
  The API itself is documented using Swagger, a lightweight mechanism for
  documenting RESTful API's using JSON. This allows us to use swagger-ui
  to provide executable documentation for the API, generate client
  bindings in different languages, and generate a lot of the boilerplate
  code for implementing the RESTful bindings. The API docs live in the
  rest-api/ directory.
  
  The RESTful bindings are generated from the Swagger API docs using a set
  of Mustache templates.  The code generator is written in Python, and
  uses Pystache. Pystache has no dependencies, and be installed easily
  using pip. Code generation code lives in rest-api-templates/.
  
  The generated code reduces a lot of boilerplate when it comes to
  handling HTTP requests. It also helps us have greater consistency in the
  REST API.
  
  (closes issue ASTERISK-20891)
  Review: https://reviewboard.asterisk.org/r/2376/
  ........
  
  Merged revisions 386232 from file:///srv/subversion/repos/asterisk/trunk
........
  r386290 | root | 2013-04-22 12:17:21 -0500 (Mon, 22 Apr 2013) | 36 lines
  
  Multiple revisions 386266,386289
  
  ........
    r386266 | lathama | 2013-04-22 11:22:00 -0500 (Mon, 22 Apr 2013) | 6 lines
    
    Doxygen - Markup Guidelines
    
    Expand on a commit by OEJ to use the Coding-Guidelines
    
    (issue ASTERISK-20259)
  ........
    r386289 | rmudgett | 2013-04-22 11:44:21 -0500 (Mon, 22 Apr 2013) | 20 lines
    
    Fix crash when AMI redirect action redirects two channels out of a bridge.
    
    The two party bridging loops were changing the bridge peer pointers
    without the channel locks held.  Thus when ast_channel_massquerade()
    tested and used the pointer there is a small window of opportunity for the
    pointers to become NULL even though the masquerade code has the channels
    locked.
    
    (closes issue ASTERISK-21356)
    Reported by: William luke
    Patches:
          jira_asterisk_21356_v11.patch (license #5621) patch uploaded by rmudgett
    Tested by: William luke
    ........
    
    Merged revisions 386256 from http://svn.asterisk.org/svn/asterisk/branches/1.8
    ........
    
    Merged revisions 386286 from http://svn.asterisk.org/svn/asterisk/branches/11
  ........
  
  Merged revisions 386266,386289 from file:///srv/subversion/repos/asterisk/trunk
........
  r386303 | rmudgett | 2013-04-22 12:35:14 -0500 (Mon, 22 Apr 2013) | 20 lines
  
  Get local channel optimization working again using the new bridging model.
  
  The primary method of optimization is to merge bridges together.  The
  optimizing local channels continuously check for empty queues in the
  local;1 and local;2 channels.  Once it is found that the queues are empty
  and the bridges allow merging, either BridgeA or BridgeB is merged into
  the other bridge.
  
  A future additional way to optimize out local channels in more
  circumstances is to swap the Local;2 channel in BridgeB with the only peer
  channel (A) in BridgeA.  This optimization strategy would be needed if
  BridgeB prohibits bridge merges.
  
  A -- BridgeA -- Local;1-Local;2 -- BridgeB -- B
  
  (closes issue ASTERISK-21058)
  Reported by: Matt Jordan
  
  Review: https://reviewboard.asterisk.org/r/2461/
........

Merged revisions 386007-386008,386014-386015,386021,386055,386136,386142,386147,386162,386191,386212,386237,386290,386303 from http://svn.asterisk.org/svn/asterisk/team/group/bridge_construction

Added:
    team/kmoore/stasis-bridging-channel_events/configs/stasis_http.conf.sample
      - copied unchanged from r386303, team/group/bridge_construction/configs/stasis_http.conf.sample
    team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging_basic.h
      - copied unchanged from r386303, team/group/bridge_construction/include/asterisk/bridging_basic.h
    team/kmoore/stasis-bridging-channel_events/include/asterisk/stasis_http.h
      - copied unchanged from r386303, team/group/bridge_construction/include/asterisk/stasis_http.h
    team/kmoore/stasis-bridging-channel_events/main/bridging_basic.c
      - copied unchanged from r386303, team/group/bridge_construction/main/bridging_basic.c
    team/kmoore/stasis-bridging-channel_events/res/res_stasis_http.c
      - copied unchanged from r386303, team/group/bridge_construction/res/res_stasis_http.c
    team/kmoore/stasis-bridging-channel_events/res/res_stasis_http.exports.in
      - copied unchanged from r386303, team/group/bridge_construction/res/res_stasis_http.exports.in
    team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_asterisk.c
      - copied unchanged from r386303, team/group/bridge_construction/res/res_stasis_http_asterisk.c
    team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_bridges.c
      - copied unchanged from r386303, team/group/bridge_construction/res/res_stasis_http_bridges.c
    team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_channels.c
      - copied unchanged from r386303, team/group/bridge_construction/res/res_stasis_http_channels.c
    team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_endpoints.c
      - copied unchanged from r386303, team/group/bridge_construction/res/res_stasis_http_endpoints.c
    team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_events.c
      - copied unchanged from r386303, team/group/bridge_construction/res/res_stasis_http_events.c
    team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_playback.c
      - copied unchanged from r386303, team/group/bridge_construction/res/res_stasis_http_playback.c
    team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_recordings.c
      - copied unchanged from r386303, team/group/bridge_construction/res/res_stasis_http_recordings.c
    team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_sounds.c
      - copied unchanged from r386303, team/group/bridge_construction/res/res_stasis_http_sounds.c
    team/kmoore/stasis-bridging-channel_events/res/stasis_http/   (props changed)
      - copied from r386303, team/group/bridge_construction/res/stasis_http/
    team/kmoore/stasis-bridging-channel_events/res/stasis_http.make
      - copied unchanged from r386303, team/group/bridge_construction/res/stasis_http.make
    team/kmoore/stasis-bridging-channel_events/rest-api/
      - copied from r386303, team/group/bridge_construction/rest-api/
    team/kmoore/stasis-bridging-channel_events/rest-api-templates/   (props changed)
      - copied from r386303, team/group/bridge_construction/rest-api-templates/
    team/kmoore/stasis-bridging-channel_events/tests/test_stasis_http.c
      - copied unchanged from r386303, team/group/bridge_construction/tests/test_stasis_http.c
Modified:
    team/kmoore/stasis-bridging-channel_events/   (props changed)
    team/kmoore/stasis-bridging-channel_events/CHANGES
    team/kmoore/stasis-bridging-channel_events/Makefile
    team/kmoore/stasis-bridging-channel_events/UPGRADE.txt
    team/kmoore/stasis-bridging-channel_events/apps/app_meetme.c
    team/kmoore/stasis-bridging-channel_events/bridges/bridge_builtin_features.c
    team/kmoore/stasis-bridging-channel_events/channels/chan_local.c
    team/kmoore/stasis-bridging-channel_events/configs/features.conf.sample
    team/kmoore/stasis-bridging-channel_events/funcs/func_channel.c
    team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging.h
    team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging_features.h
    team/kmoore/stasis-bridging-channel_events/include/asterisk/http.h
    team/kmoore/stasis-bridging-channel_events/include/asterisk/http_websocket.h
    team/kmoore/stasis-bridging-channel_events/include/asterisk/json.h
    team/kmoore/stasis-bridging-channel_events/include/asterisk/srv.h
    team/kmoore/stasis-bridging-channel_events/include/asterisk/stasis_app.h
    team/kmoore/stasis-bridging-channel_events/include/asterisk/strings.h
    team/kmoore/stasis-bridging-channel_events/main/bridging.c
    team/kmoore/stasis-bridging-channel_events/main/channel.c
    team/kmoore/stasis-bridging-channel_events/main/cli.c
    team/kmoore/stasis-bridging-channel_events/main/features.c
    team/kmoore/stasis-bridging-channel_events/main/http.c
    team/kmoore/stasis-bridging-channel_events/main/json.c
    team/kmoore/stasis-bridging-channel_events/main/message.c
    team/kmoore/stasis-bridging-channel_events/res/Makefile
    team/kmoore/stasis-bridging-channel_events/res/res_http_websocket.c
    team/kmoore/stasis-bridging-channel_events/res/res_stasis.c
    team/kmoore/stasis-bridging-channel_events/res/res_timing_pthread.c
    team/kmoore/stasis-bridging-channel_events/tests/test_stasis.c
    team/kmoore/stasis-bridging-channel_events/tests/test_strings.c

Propchange: team/kmoore/stasis-bridging-channel_events/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Propchange: team/kmoore/stasis-bridging-channel_events/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Apr 23 08:32:56 2013
@@ -1,1 +1,1 @@
-/team/group/bridge_construction:1-385974
+/team/group/bridge_construction:1-386332

Modified: team/kmoore/stasis-bridging-channel_events/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/CHANGES?view=diff&rev=386333&r1=386332&r2=386333
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/CHANGES (original)
+++ team/kmoore/stasis-bridging-channel_events/CHANGES Tue Apr 23 08:32:56 2013
@@ -61,6 +61,10 @@
 
 Channel Drivers
 ------------------
+
+chan_local
+------------------
+ * The /b option is removed.
 
 chan_mobile
 ------------------

Modified: team/kmoore/stasis-bridging-channel_events/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/Makefile?view=diff&rev=386333&r1=386332&r2=386333
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/Makefile (original)
+++ team/kmoore/stasis-bridging-channel_events/Makefile Tue Apr 23 08:32:56 2013
@@ -453,6 +453,9 @@
 		$(INSTALL) -m 644 $$x "$(DESTDIR)$(ASTDATADIR)/images" ; \
 	done
 	$(MAKE) -C sounds install
+	find rest-api -name "*.json" | while read x; do \
+		$(INSTALL) -m 644 $$x "$(DESTDIR)$(ASTDATADIR)/rest-api" ; \
+	done
 
 ifneq ($(GREP),)
   XML_core_en_US = $(foreach dir,$(MOD_SUBDIRS),$(shell $(GREP) -l "language=\"en_US\"" $(dir)/*.c $(dir)/*.cc 2>/dev/null))
@@ -537,8 +540,8 @@
 	"$(ASTLOGDIR)/cel-custom" "$(ASTDATADIR)" "$(ASTDATADIR)/documentation" \
 	"$(ASTDATADIR)/documentation/thirdparty" "$(ASTDATADIR)/firmware" \
 	"$(ASTDATADIR)/firmware/iax" "$(ASTDATADIR)/images" "$(ASTDATADIR)/keys" \
-	"$(ASTDATADIR)/phoneprov" "$(ASTDATADIR)/static-http" "$(ASTDATADIR)/sounds" \
-	"$(ASTDATADIR)/moh" "$(ASTMANDIR)/man8" "$(AGI_DIR)" "$(ASTDBDIR)"
+	"$(ASTDATADIR)/phoneprov" "$(ASTDATADIR)/rest-api" "$(ASTDATADIR)/static-http" \
+	"$(ASTDATADIR)/sounds" "$(ASTDATADIR)/moh" "$(ASTMANDIR)/man8" "$(AGI_DIR)" "$(ASTDBDIR)"
 
 installdirs:
 	@for i in $(INSTALLDIRS); do \
@@ -958,6 +961,19 @@
 	@cat sounds/sounds.xml >> $@
 	@echo "</menu>" >> $@
 
+# We don't want to require Python or Pystache for every build, so this is its
+# own target.
+stasis-stubs:
+ifeq ($(PYTHON),:)
+	@echo "--------------------------------------------------------------------------"
+	@echo "---        Please install python to build Stasis HTTP stubs            ---"
+	@echo "--------------------------------------------------------------------------"
+	@false
+else
+	$(PYTHON) rest-api-templates/make_stasis_http_stubs.py \
+		rest-api/resources.json res/
+endif
+
 .PHONY: menuselect
 .PHONY: main
 .PHONY: sounds
@@ -977,6 +993,7 @@
 .PHONY: installdirs
 .PHONY: validate-docs
 .PHONY: _clean
+.PHONY: stasis-stubs
 .PHONY: $(SUBDIRS_INSTALL)
 .PHONY: $(SUBDIRS_DIST_CLEAN)
 .PHONY: $(SUBDIRS_CLEAN)

Modified: team/kmoore/stasis-bridging-channel_events/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/UPGRADE.txt?view=diff&rev=386333&r1=386332&r2=386333
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/UPGRADE.txt (original)
+++ team/kmoore/stasis-bridging-channel_events/UPGRADE.txt Tue Apr 23 08:32:56 2013
@@ -69,6 +69,9 @@
    pauses dialing for one second.
  - The default for inband_on_proceeding has changed to no.
 
+chan_local:
+ - The /b option is removed.
+
 Dialplan:
  - All channel and global variable names are evaluated in a case-sensitive manner.
    In previous versions of Asterisk, variables created and evaluated in the
@@ -80,6 +83,12 @@
  - BRIDGE_FEATURES channel variable is now casesensitive for feature letter codes.
    Uppercase variants apply them to the calling party while lowercase variants
    apply them to the called party.
+
+Features:
+ - The features.conf [applicationmap] <FeatureName>  ActivatedBy option is
+   no longer honored.  The feature is activated by which channel
+   DYNAMIC_FEATURES includes the feature is on.  Use predial to set different
+   values of DYNAMIC_FEATURES on the channels
 
 From 10 to 11:
 

Modified: team/kmoore/stasis-bridging-channel_events/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/apps/app_meetme.c?view=diff&rev=386333&r1=386332&r2=386333
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/apps/app_meetme.c (original)
+++ team/kmoore/stasis-bridging-channel_events/apps/app_meetme.c Tue Apr 23 08:32:56 2013
@@ -6437,17 +6437,18 @@
 
 static int sla_load_config(int reload);
 
-/*! \brief Check if we can do a reload of SLA, and do it if we can */
+/*!
+ * \internal
+ * \brief Check if we can do a reload of SLA, and do it if we can
+ * \pre sla.lock is locked.
+ */
 static void sla_check_reload(void)
 {
 	struct sla_station *station;
 	struct sla_trunk *trunk;
 
-	ast_mutex_lock(&sla.lock);
-
 	if (!AST_LIST_EMPTY(&sla.event_q) || !AST_LIST_EMPTY(&sla.ringing_trunks) 
 		|| !AST_LIST_EMPTY(&sla.ringing_stations)) {
-		ast_mutex_unlock(&sla.lock);
 		return;
 	}
 
@@ -6458,7 +6459,6 @@
 	}
 	AST_RWLIST_UNLOCK(&sla_stations);
 	if (station) {
-		ast_mutex_unlock(&sla.lock);
 		return;
 	}
 
@@ -6469,15 +6469,12 @@
 	}
 	AST_RWLIST_UNLOCK(&sla_trunks);
 	if (trunk) {
-		ast_mutex_unlock(&sla.lock);
 		return;
 	}
 
 	/* yay */
 	sla_load_config(1);
 	sla.reload = 0;
-
-	ast_mutex_unlock(&sla.lock);
 }
 
 static void *sla_thread(void *data)

Modified: team/kmoore/stasis-bridging-channel_events/bridges/bridge_builtin_features.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/bridges/bridge_builtin_features.c?view=diff&rev=386333&r1=386332&r2=386333
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/bridges/bridge_builtin_features.c (original)
+++ team/kmoore/stasis-bridging-channel_events/bridges/bridge_builtin_features.c Tue Apr 23 08:32:56 2013
@@ -193,7 +193,7 @@
 	}
 
 	/* Impart the new channel onto the bridge, and have it take our place. */
-	if (ast_bridge_impart(bridge, chan, bridge_channel->chan, NULL, 1)) {
+	if (ast_bridge_impart(bridge_channel->bridge, chan, bridge_channel->chan, NULL, 1)) {
 		ast_hangup(chan);
 		return 0;
 	}
@@ -255,6 +255,8 @@
 	const char *context;
 	enum atxfer_code transfer_code = ATXFER_INCOMPLETE;
 
+	bridge = ast_bridge_channel_merge_inhibit(bridge_channel, +1);
+
 /* BUGBUG the peer needs to be put on hold for the transfer. */
 	ast_channel_lock(bridge_channel->chan);
 	context = ast_strdupa(get_transfer_context(bridge_channel->chan,
@@ -263,12 +265,16 @@
 
 	/* Grab the extension to transfer to */
 	if (grab_transfer(bridge_channel->chan, exten, sizeof(exten), context)) {
+		ast_bridge_merge_inhibit(bridge, -1);
+		ao2_ref(bridge, -1);
 		return 0;
 	}
 
 	/* Get a channel that is the destination we wish to call */
 	peer = dial_transfer(bridge_channel->chan, exten, context);
 	if (!peer) {
+		ast_bridge_merge_inhibit(bridge, -1);
+		ao2_ref(bridge, -1);
 /* BUGBUG beeperr needs to be configurable from features.conf */
 		ast_stream_and_wait(bridge_channel->chan, "beeperr", AST_DIGIT_NONE);
 		return 0;
@@ -294,6 +300,8 @@
 			attended_transfer_threeway, &transfer_code, NULL, 0)) {
 		ast_bridge_features_cleanup(&caller_features);
 		ast_hangup(peer);
+		ast_bridge_merge_inhibit(bridge, -1);
+		ao2_ref(bridge, -1);
 /* BUGBUG beeperr needs to be configurable from features.conf */
 		ast_stream_and_wait(bridge_channel->chan, "beeperr", AST_DIGIT_NONE);
 		return 0;
@@ -306,10 +314,13 @@
 	if (!attended_bridge) {
 		ast_bridge_features_cleanup(&caller_features);
 		ast_hangup(peer);
+		ast_bridge_merge_inhibit(bridge, -1);
+		ao2_ref(bridge, -1);
 /* BUGBUG beeperr needs to be configurable from features.conf */
 		ast_stream_and_wait(bridge_channel->chan, "beeperr", AST_DIGIT_NONE);
 		return 0;
 	}
+	ast_bridge_merge_inhibit(attended_bridge, +1);
 
 	/* This is how this is going down, we are imparting the channel we called above into this bridge first */
 /* BUGBUG we should impart the peer as an independent and move it to the original bridge. */
@@ -317,6 +328,8 @@
 		ast_bridge_destroy(attended_bridge);
 		ast_bridge_features_cleanup(&caller_features);
 		ast_hangup(peer);
+		ast_bridge_merge_inhibit(bridge, -1);
+		ao2_ref(bridge, -1);
 /* BUGBUG beeperr needs to be configurable from features.conf */
 		ast_stream_and_wait(bridge_channel->chan, "beeperr", AST_DIGIT_NONE);
 		return 0;
@@ -361,7 +374,7 @@
 	case ATXFER_COMPLETE:
 		/* The peer takes our place in the bridge. */
 		ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
-		xfer_failed = ast_bridge_impart(bridge, peer, bridge_channel->chan, NULL, 1);
+		xfer_failed = ast_bridge_impart(bridge_channel->bridge, peer, bridge_channel->chan, NULL, 1);
 		break;
 	case ATXFER_THREEWAY:
 		/*
@@ -370,12 +383,14 @@
 		 * Just impart the peer onto the bridge and have us return to it
 		 * as normal.
 		 */
-		xfer_failed = ast_bridge_impart(bridge, peer, NULL, NULL, 1);
+		xfer_failed = ast_bridge_impart(bridge_channel->bridge, peer, NULL, NULL, 1);
 		break;
 	case ATXFER_ABORT:
 		/* Transferer decided not to transfer the call after all. */
 		break;
 	}
+	ast_bridge_merge_inhibit(bridge, -1);
+	ao2_ref(bridge, -1);
 	if (xfer_failed) {
 		ast_hangup(peer);
 		if (!ast_check_hangup_locked(bridge_channel->chan)) {

Modified: team/kmoore/stasis-bridging-channel_events/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/channels/chan_local.c?view=diff&rev=386333&r1=386332&r2=386333
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/channels/chan_local.c (original)
+++ team/kmoore/stasis-bridging-channel_events/channels/chan_local.c Tue Apr 23 08:32:56 2013
@@ -54,6 +54,7 @@
 #include "asterisk/stringfields.h"
 #include "asterisk/devicestate.h"
 #include "asterisk/astobj2.h"
+#include "asterisk/bridging.h"
 
 /*** DOCUMENTATION
 	<manager name="LocalOptimizeAway" language="en_US">
@@ -108,7 +109,6 @@
 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
 static int local_sendtext(struct ast_channel *ast, const char *text);
 static int local_devicestate(const char *data);
-static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
 static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
 static int local_setoption(struct ast_channel *chan, int option, void *data, int datalen);
 
@@ -131,7 +131,6 @@
 	.send_html = local_sendhtml,
 	.send_text = local_sendtext,
 	.devicestate = local_devicestate,
-	.bridged_channel = local_bridgedchannel,
 	.queryoption = local_queryoption,
 	.setoption = local_setoption,
 };
@@ -153,11 +152,9 @@
 	struct ast_channel *chan;       /*!< Outbound channel - PBX is run here */
 };
 
-#define LOCAL_ALREADY_MASQED  (1 << 0) /*!< Already masqueraded */
-#define LOCAL_LAUNCHED_PBX    (1 << 1) /*!< PBX was launched */
-#define LOCAL_NO_OPTIMIZATION (1 << 2) /*!< Do not optimize using masquerading */
-#define LOCAL_BRIDGE          (1 << 3) /*!< Report back the "true" channel as being bridged to */
-#define LOCAL_MOH_PASSTHRU    (1 << 4) /*!< Pass through music on hold start/stop frames */
+#define LOCAL_LAUNCHED_PBX    (1 << 0) /*!< PBX was launched */
+#define LOCAL_NO_OPTIMIZATION (1 << 1) /*!< Do not optimize using masquerading */
+#define LOCAL_MOH_PASSTHRU    (1 << 2) /*!< Pass through music on hold start/stop frames */
 
 /*!
  * \brief Send a pvt in with no locks held and get all locks
@@ -329,37 +326,6 @@
 	return res;
 }
 
-/*! \brief Return the bridged channel of a Local channel */
-static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge)
-{
-	struct local_pvt *p = ast_channel_tech_pvt(bridge);
-	struct ast_channel *bridged = bridge;
-
-	if (!p) {
-		ast_debug(1, "Asked for bridged channel on '%s'/'%s', returning <none>\n",
-			ast_channel_name(chan), ast_channel_name(bridge));
-		return NULL;
-	}
-
-	ao2_lock(p);
-
-	if (ast_test_flag(p, LOCAL_BRIDGE)) {
-		/* Find the opposite channel */
-		bridged = (bridge == p->owner ? p->chan : p->owner);
-
-		/* Now see if the opposite channel is bridged to anything */
-		if (!bridged) {
-			bridged = bridge;
-		} else if (ast_channel_internal_bridged_channel(bridged)) {
-			bridged = ast_channel_internal_bridged_channel(bridged);
-		}
-	}
-
-	ao2_unlock(p);
-
-	return bridged;
-}
-
 /* Called with ast locked */
 static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
 {
@@ -483,146 +449,32 @@
 
 /*!
  * \internal
- * \note This function assumes that we're only called from the "outbound" local channel side
+ * \brief Check and optimize out the local channels between bridges.
+ * \since 12.0.0
  *
- * \note it is assummed p is locked and reffed before entering this function
+ * \param ast Channel writing a frame into the local channels.
+ * \param p Local channel private.
+ *
+ * \note It is assumed that ast is locked.
+ * \note It is assumed that p is locked.
+ *
+ * \retval 0 if local channels were not optimized out.
+ * \retval non-zero if local channels were optimized out.
  */
-static void check_bridge(struct ast_channel *ast, struct local_pvt *p)
-{
-	struct ast_channel *owner;
-	struct ast_channel *chan;
-	struct ast_channel *bridged_chan;
-	struct ast_frame *f;
-
+static int got_optimized_out(struct ast_channel *ast, struct local_pvt *p)
+{
 	/* Do a few conditional checks early on just to see if this optimization is possible */
-	if (ast_test_flag(p, LOCAL_NO_OPTIMIZATION | LOCAL_ALREADY_MASQED)
-		|| !p->chan || !p->owner) {
-		return;
-	}
-
-	/* Safely get the channel bridged to p->chan */
-	chan = ast_channel_ref(p->chan);
-
-	ao2_unlock(p); /* don't call bridged channel with the pvt locked */
-	bridged_chan = ast_bridged_channel(chan);
-	ao2_lock(p);
-
-	chan = ast_channel_unref(chan);
-
-	/* since we had to unlock p to get the bridged chan, validate our
-	 * data once again and verify the bridged channel is what we expect
-	 * it to be in order to perform this optimization */
-	if (ast_test_flag(p, LOCAL_NO_OPTIMIZATION | LOCAL_ALREADY_MASQED)
-		|| !p->chan || !p->owner
-		|| (ast_channel_internal_bridged_channel(p->chan) != bridged_chan)) {
-		return;
-	}
-
-	/* only do the masquerade if we are being called on the outbound channel,
-	   if it has been bridged to another channel and if there are no pending
-	   frames on the owner channel (because they would be transferred to the
-	   outbound channel during the masquerade)
-	*/
-	if (!ast_channel_internal_bridged_channel(p->chan) /* Not ast_bridged_channel!  Only go one step! */
-		|| !AST_LIST_EMPTY(ast_channel_readq(p->owner))
-		|| ast != p->chan /* Sanity check (should always be false) */) {
-		return;
-	}
-
-	/* Masquerade bridged channel into owner */
-	/* Lock everything we need, one by one, and give up if
-	   we can't get everything.  Remember, we'll get another
-	   chance in just a little bit */
-	if (ast_channel_trylock(ast_channel_internal_bridged_channel(p->chan))) {
-		return;
-	}
-	if (ast_check_hangup(ast_channel_internal_bridged_channel(p->chan))
-		|| ast_channel_trylock(p->owner)) {
-		ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
-		return;
-	}
-
-	/*
-	 * At this point we have 4 locks:
-	 * p, p->chan (same as ast), p->chan->_bridge, p->owner
-	 *
-	 * Flush a voice or video frame on the outbound channel to make
-	 * the queue empty faster so we can get optimized out.
-	 */
-	f = AST_LIST_FIRST(ast_channel_readq(p->chan));
-	if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
-		AST_LIST_REMOVE_HEAD(ast_channel_readq(p->chan), frame_list);
-		ast_frfree(f);
-		f = AST_LIST_FIRST(ast_channel_readq(p->chan));
-	}
-
-	if (f
-		|| ast_check_hangup(p->owner)
-		|| ast_channel_masquerade(p->owner, ast_channel_internal_bridged_channel(p->chan))) {
-		ast_channel_unlock(p->owner);
-		ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
-		return;
-	}
-
-	/* Masquerade got setup. */
-	ast_debug(4, "Masquerading %s <- %s\n",
-		ast_channel_name(p->owner),
-		ast_channel_name(ast_channel_internal_bridged_channel(p->chan)));
-	if (ast_channel_monitor(p->owner)
-		&& !ast_channel_monitor(ast_channel_internal_bridged_channel(p->chan))) {
-		struct ast_channel_monitor *tmp;
-
-		/* If a local channel is being monitored, we don't want a masquerade
-		 * to cause the monitor to go away. Since the masquerade swaps the monitors,
-		 * pre-swapping the monitors before the masquerade will ensure that the monitor
-		 * ends up where it is expected.
-		 */
-		tmp = ast_channel_monitor(p->owner);
-		ast_channel_monitor_set(p->owner, ast_channel_monitor(ast_channel_internal_bridged_channel(p->chan)));
-		ast_channel_monitor_set(ast_channel_internal_bridged_channel(p->chan), tmp);
-	}
-	if (ast_channel_audiohooks(p->chan)) {
-		struct ast_audiohook_list *audiohooks_swapper;
-
-		audiohooks_swapper = ast_channel_audiohooks(p->chan);
-		ast_channel_audiohooks_set(p->chan, ast_channel_audiohooks(p->owner));
-		ast_channel_audiohooks_set(p->owner, audiohooks_swapper);
-	}
-
-	/* If any Caller ID was set, preserve it after masquerade like above. We must check
-	 * to see if Caller ID was set because otherwise we'll mistakingly copy info not
-	 * set from the dialplan and will overwrite the real channel Caller ID. The reason
-	 * for this whole preswapping action is because the Caller ID is set on the channel
-	 * thread (which is the to be masqueraded away local channel) before both local
-	 * channels are optimized away.
-	 */
-	if (ast_channel_caller(p->owner)->id.name.valid || ast_channel_caller(p->owner)->id.number.valid
-		|| ast_channel_caller(p->owner)->id.subaddress.valid || ast_channel_caller(p->owner)->ani.name.valid
-		|| ast_channel_caller(p->owner)->ani.number.valid || ast_channel_caller(p->owner)->ani.subaddress.valid) {
-		SWAP(*ast_channel_caller(p->owner), *ast_channel_caller(ast_channel_internal_bridged_channel(p->chan)));
-	}
-	if (ast_channel_redirecting(p->owner)->from.name.valid || ast_channel_redirecting(p->owner)->from.number.valid
-		|| ast_channel_redirecting(p->owner)->from.subaddress.valid || ast_channel_redirecting(p->owner)->to.name.valid
-		|| ast_channel_redirecting(p->owner)->to.number.valid || ast_channel_redirecting(p->owner)->to.subaddress.valid) {
-		SWAP(*ast_channel_redirecting(p->owner), *ast_channel_redirecting(ast_channel_internal_bridged_channel(p->chan)));
-	}
-	if (ast_channel_dialed(p->owner)->number.str || ast_channel_dialed(p->owner)->subaddress.valid) {
-		SWAP(*ast_channel_dialed(p->owner), *ast_channel_dialed(ast_channel_internal_bridged_channel(p->chan)));
-	}
-	ast_app_group_update(p->chan, p->owner);
-	ast_set_flag(p, LOCAL_ALREADY_MASQED);
-
-	ast_channel_unlock(p->owner);
-	ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
-
-	/* Do the masquerade now. */
-	owner = ast_channel_ref(p->owner);
-	ao2_unlock(p);
-	ast_channel_unlock(ast);
-	ast_do_masquerade(owner);
-	ast_channel_unref(owner);
-	ast_channel_lock(ast);
-	ao2_lock(p);
+	if (ast_test_flag(p, LOCAL_NO_OPTIMIZATION) || !p->chan || !p->owner) {
+		return 0;
+	}
+	if (ast == p->owner) {
+		return ast_bridge_local_optimized_out(p->owner, p->chan);
+	}
+	if (ast == p->chan) {
+		return ast_bridge_local_optimized_out(p->chan, p->owner);
+	}
+	/* ast is not valid to optimize. */
+	return 0;
 }
 
 static struct ast_frame  *local_read(struct ast_channel *ast)
@@ -634,28 +486,24 @@
 {
 	struct local_pvt *p = ast_channel_tech_pvt(ast);
 	int res = -1;
-	int isoutbound;
 
 	if (!p) {
 		return -1;
 	}
 
 	/* Just queue for delivery to the other side */
-	ao2_ref(p, 1); /* ref for local_queue_frame */
+	ao2_ref(p, 1);
 	ao2_lock(p);
-	isoutbound = IS_OUTBOUND(ast, p);
-
-	if (isoutbound
-		&& (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
-		check_bridge(ast, p);
-	}
-
-	if (!ast_test_flag(p, LOCAL_ALREADY_MASQED)) {
-		res = local_queue_frame(p, isoutbound, f, ast, 1);
-	} else {
-		ast_debug(1, "Not posting to '%s' queue since already masqueraded out\n",
-			ast_channel_name(ast));
-		res = 0;
+	switch (f->frametype) {
+	case AST_FRAME_VOICE:
+	case AST_FRAME_VIDEO:
+		if (got_optimized_out(ast, p)) {
+			break;
+		}
+		/* fall through */
+	default:
+		res = local_queue_frame(p, IS_OUTBOUND(ast, p), f, ast, 1);
+		break;
 	}
 	ao2_unlock(p);
 	ao2_ref(p, -1);
@@ -1192,9 +1040,6 @@
 					"to use the 'j' option to enable the jitterbuffer\n");
 			}
 		}
-		if (strchr(opts, 'b')) {
-			ast_set_flag(tmp, LOCAL_BRIDGE);
-		}
 		if (strchr(opts, 'm')) {
 			ast_set_flag(tmp, LOCAL_MOH_PASSTHRU);
 		}

Modified: team/kmoore/stasis-bridging-channel_events/configs/features.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/configs/features.conf.sample?view=diff&rev=386333&r1=386332&r2=386333
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/configs/features.conf.sample (original)
+++ team/kmoore/stasis-bridging-channel_events/configs/features.conf.sample Tue Apr 23 08:32:56 2013
@@ -176,10 +176,10 @@
 ;                   application on the same channel that activated the feature. "peer"
 ;                   means run the application on the opposite channel from the one that
 ;                   has activated the feature.
-;  ActivatedBy   -> This is which channel is allowed to activate this feature. Valid
-;                   values are "caller", "callee", and "both". "both" is the default.
-;                   The "caller" is the channel that executed the Dial application, while
-;                   the "callee" is the channel called by the Dial application.
+;  ActivatedBy   -> ActivatedBy is no longer honored.  The feature is activated by which
+;                   channel DYNAMIC_FEATURES includes the feature is on.  Use predial
+;                   to set different values of DYNAMIC_FEATURES on the channels.
+;                   Historic values are: "caller", "callee", and "both".
 ;  Application   -> This is the application to execute.
 ;  AppArguments  -> These are the arguments to be passed into the application.  If you need
 ;                   commas in your arguments, you should use either the second or third
@@ -194,8 +194,9 @@
 ;   applications. When applications are used in extensions.conf, they are executed
 ;   by the PBX core. In this case, these applications are executed outside of the
 ;   PBX core, so it does *not* make sense to use any application which has any
-;   concept of dialplan flow. Examples of this would be things like Macro, Goto,
-;   Background, WaitExten, and many more.
+;   concept of dialplan flow. Examples of this would be things like Goto,
+;   Background, WaitExten, and many more.  The exceptions to this are Gosub and
+;   Macro routines which must complete for the call to continue.
 ;

[... 2906 lines stripped ...]



More information about the asterisk-commits mailing list