[asterisk-commits] mmichelson: branch mmichelson/bridged_channel r396042 - in /team/mmichelson/b...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Aug 1 16:47:41 CDT 2013


Author: mmichelson
Date: Thu Aug  1 16:47:38 2013
New Revision: 396042

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=396042
Log:
Resolve conflicts from features purge.


Modified:
    team/mmichelson/bridged_channel/   (props changed)
    team/mmichelson/bridged_channel/channels/chan_dahdi.c
    team/mmichelson/bridged_channel/channels/chan_iax2.c
    team/mmichelson/bridged_channel/channels/chan_mgcp.c
    team/mmichelson/bridged_channel/channels/chan_skinny.c
    team/mmichelson/bridged_channel/channels/sig_analog.c
    team/mmichelson/bridged_channel/include/asterisk/features.h
    team/mmichelson/bridged_channel/include/asterisk/parking.h
    team/mmichelson/bridged_channel/main/bridge.c
    team/mmichelson/bridged_channel/main/bridge_channel.c
    team/mmichelson/bridged_channel/main/features.c
    team/mmichelson/bridged_channel/main/parking.c
    team/mmichelson/bridged_channel/main/sorcery.c
    team/mmichelson/bridged_channel/res/parking/parking_bridge_features.c
    team/mmichelson/bridged_channel/res/res_parking.c

Propchange: team/mmichelson/bridged_channel/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Aug  1 16:47:38 2013
@@ -1,1 +1,1 @@
-/trunk:1-396013
+/trunk:1-396037

Modified: team/mmichelson/bridged_channel/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/bridged_channel/channels/chan_dahdi.c?view=diff&rev=396042&r1=396041&r2=396042
==============================================================================
--- team/mmichelson/bridged_channel/channels/chan_dahdi.c (original)
+++ team/mmichelson/bridged_channel/channels/chan_dahdi.c Thu Aug  1 16:47:38 2013
@@ -126,6 +126,7 @@
 #include "asterisk/features_config.h"
 #include "asterisk/bridge.h"
 #include "asterisk/stasis_channels.h"
+#include "asterisk/parking.h"
 #include "chan_dahdi.h"
 #include "dahdi/bridge_native_dahdi.h"
 
@@ -9230,6 +9231,10 @@
 	int idx;
 	struct ast_format tmpfmt;
 	RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_parking_bridge_feature_fn_table *, parking_provider,
+		ast_parking_get_bridge_features(),
+		ao2_cleanup);
+	int is_exten_parking;
 	const char *pickupexten;
 
 	ast_mutex_lock(&ss_thread_lock);
@@ -9560,11 +9565,13 @@
 				exten[len++]=res;
 				exten[len] = '\0';
 			}
-			if (!ast_ignore_pattern(ast_channel_context(chan), exten))
+			if (!ast_ignore_pattern(ast_channel_context(chan), exten)) {
 				tone_zone_play_tone(p->subs[idx].dfd, -1);
-			else
+			} else {
 				tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE);
-			if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num) && !ast_parking_ext_valid(exten, chan, ast_channel_context(chan))) {
+			}
+			is_exten_parking = (parking_provider ? parking_provider->parking_is_exten_park(ast_channel_context(chan), exten) : 0);
+			if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num) && !is_exten_parking) {
 				if (!res || !ast_matchmore_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num)) {
 					if (getforward) {
 						/* Record this as the forwarding extension */
@@ -9700,20 +9707,17 @@
 				getforward = 0;
 				memset(exten, 0, sizeof(exten));
 				len = 0;
-			} else if ((p->transfer || p->canpark) && ast_parking_ext_valid(exten, chan, ast_channel_context(chan)) &&
-						p->subs[SUB_THREEWAY].owner &&
-						ast_channel_is_bridged(p->subs[SUB_THREEWAY].owner)) {
-				RAII_VAR(struct ast_channel *, bridged, ast_channel_bridge_peer(p->subs[SUB_THREEWAY].owner), ast_channel_cleanup);
-
-				if (!bridged) {
-					/* Channel is in a bridge but with more than one bridged party */
-					break;
-				}
-
+			} else if ((p->transfer || p->canpark) && is_exten_parking &&
+						p->subs[SUB_THREEWAY].owner) {
+				RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
 				/* This is a three way call, the main call being a real channel,
 					and we're parking the first call. */
-				ast_masq_park_call_exten(bridged, chan, exten, ast_channel_context(chan), 0, NULL);
-				ast_verb(3, "Parking call to '%s'\n", ast_channel_name(chan));
+				ast_channel_lock(chan);
+				bridge_channel = ast_channel_get_bridge_channel(chan);
+				ast_channel_unlock(chan);
+				if (bridge_channel && !parking_provider->parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), exten)) {
+					ast_verb(3, "Parking call to '%s'\n", ast_channel_name(chan));
+				}
 				break;
 			} else if (p->hidecallerid && !strcmp(exten, "*82")) {
 				ast_verb(3, "Enabling Caller*ID on %s\n", ast_channel_name(chan));

Modified: team/mmichelson/bridged_channel/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/bridged_channel/channels/chan_iax2.c?view=diff&rev=396042&r1=396041&r2=396042
==============================================================================
--- team/mmichelson/bridged_channel/channels/chan_iax2.c (original)
+++ team/mmichelson/bridged_channel/channels/chan_iax2.c Thu Aug  1 16:47:38 2013
@@ -9203,7 +9203,7 @@
 	memset(&ied1, 0, sizeof(ied1));
 	mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
 	/* Must be started */
-	if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
+	if (ast_exists_extension(NULL, context, callednum, 1, callerid)) {
 		dpstatus = IAX_DPSTATUS_EXISTS;
 	} else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
 		dpstatus = IAX_DPSTATUS_CANEXIST;

Modified: team/mmichelson/bridged_channel/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/bridged_channel/channels/chan_mgcp.c?view=diff&rev=396042&r1=396041&r2=396042
==============================================================================
--- team/mmichelson/bridged_channel/channels/chan_mgcp.c (original)
+++ team/mmichelson/bridged_channel/channels/chan_mgcp.c Thu Aug  1 16:47:38 2013
@@ -84,6 +84,7 @@
 #include "asterisk/stasis.h"
 #include "asterisk/bridge.h"
 #include "asterisk/features_config.h"
+#include "asterisk/parking.h"
 
 /*
  * Define to work around buggy dlink MGCP phone firmware which
@@ -2979,6 +2980,9 @@
 	int getforward = 0;
 	int loop_pause = 100;
 	RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_parking_bridge_feature_fn_table *, parking_provider,
+		ast_parking_get_bridge_features(),
+		ao2_cleanup);
 	const char *pickupexten;
 
 	len = strlen(p->dtmf_buf);
@@ -3147,18 +3151,17 @@
 			getforward = 0;
 			memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
 			len = 0;
-		} else if (ast_parking_ext_valid(p->dtmf_buf, chan, ast_channel_context(chan)) &&
-			sub->next->owner && ast_channel_is_bridged(sub->next->owner)) {
-			RAII_VAR(struct ast_channel *, bridged, ast_channel_bridge_peer(sub->next->owner), ast_channel_cleanup);
-
-			if (!bridged) {
-				break;
-			}
-
+		} else if (parking_provider && parking_provider->parking_is_exten_park(ast_channel_context(chan), p->dtmf_buf) &&
+			sub->next->owner) {
+			RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
 			/* This is a three way call, the main call being a real channel,
-			   and we're parking the first call. */
-			ast_masq_park_call_exten(bridged, chan, p->dtmf_buf, ast_channel_context(chan), 0, NULL);
-			ast_verb(3, "Parking call to '%s'\n", ast_channel_name(chan));
+				and we're parking the first call. */
+			ast_channel_lock(chan);
+			bridge_channel = ast_channel_get_bridge_channel(chan);
+			ast_channel_unlock(chan);
+			if (bridge_channel && !parking_provider->parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), p->dtmf_buf)) {
+				ast_verb(3, "Parking call to '%s'\n", ast_channel_name(chan));
+			}
 			break;
 		} else if (!ast_strlen_zero(p->lastcallerid) && !strcmp(p->dtmf_buf, "*60")) {
 			ast_verb(3, "Blacklisting number %s\n", p->lastcallerid);

Modified: team/mmichelson/bridged_channel/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/bridged_channel/channels/chan_skinny.c?view=diff&rev=396042&r1=396041&r2=396042
==============================================================================
--- team/mmichelson/bridged_channel/channels/chan_skinny.c (original)
+++ team/mmichelson/bridged_channel/channels/chan_skinny.c Thu Aug  1 16:47:38 2013
@@ -82,6 +82,7 @@
 #include "asterisk/linkedlists.h"
 #include "asterisk/stasis_endpoints.h"
 #include "asterisk/bridge.h"
+#include "asterisk/parking.h"
 
 /*** DOCUMENTATION
 	<manager name="SKINNYdevices" language="en_US">
@@ -6406,27 +6407,37 @@
 		break;
 	case STIMULUS_CALLPARK:
 		{
-		int extout;
+		char extout[AST_MAX_EXTENSION];
 		char message[32];
-
+		RAII_VAR(struct ast_parking_bridge_feature_fn_table *, parking_provider,
+			ast_parking_get_bridge_features(),
+			ao2_cleanup);
+		RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
 		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received STIMULUS_CALLPARK from %s, inst %d, callref %d\n",
 			d->name, instance, callreference);
 
+		if (!parking_provider) {
+			transmit_displaynotify(d, "Call Park not available", 10);
+			break;
+		}
+
 		if ((sub && sub->owner) && (ast_channel_state(sub->owner) ==  AST_STATE_UP)) {
-			RAII_VAR(struct ast_channel *, bridged, NULL, ast_channel_cleanup);
-
 			c = sub->owner;
-			bridged = ast_channel_bridge_peer(c);
-			if (bridged) {
-				if (!ast_masq_park_call(bridged, c, 0, &extout)) {
-					snprintf(message, sizeof(message), "Call Parked at: %d", extout);
-					transmit_displaynotify(d, message, 10);
-				} else {
-					transmit_displaynotify(d, "Call Park failed", 10);
-				}
-			} else {
-				transmit_displaynotify(d, "Call Park not available", 10);
-			}
+			ast_channel_lock(c);
+			bridge_channel = ast_channel_get_bridge_channel(c);
+			ast_channel_unlock(c);
+
+			if (!bridge_channel) {
+				transmit_displaynotify(d, "Call Park failed", 10);
+				break;
+			}
+
+			if (!parking_provider->parking_park_call(bridge_channel, extout, sizeof(extout))) {
+				snprintf(message, sizeof(message), "Call Parked at: %s", extout);
+				transmit_displaynotify(d, message, 10);
+				break;
+			}
+			transmit_displaynotify(d, "Call Park failed", 10);
 		} else {
 			transmit_displaynotify(d, "Call Park not available", 10);
 		}
@@ -7146,27 +7157,39 @@
 		break;
 	case SOFTKEY_PARK:
 		{
-		int extout;
+		char extout[AST_MAX_EXTENSION];
 		char message[32];
-
+		RAII_VAR(struct ast_parking_bridge_feature_fn_table *, parking_provider,
+			ast_parking_get_bridge_features(),
+			ao2_cleanup);
+		RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
 		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received SOFTKEY_PARK from %s, inst %d, callref %d\n",
 			d->name, instance, callreference);
 
-		if ((sub && sub->owner) && (ast_channel_state(sub->owner) ==  AST_STATE_UP)){
+		if (!parking_provider) {
+			transmit_displaynotify(d, "Call Park not available", 10);
+			break;
+		}
+
+		if ((sub && sub->owner) && (ast_channel_state(sub->owner) ==  AST_STATE_UP)) {
 			RAII_VAR(struct ast_channel *, bridged, NULL, ast_channel_cleanup);
 
 			c = sub->owner;
-			bridged = ast_channel_bridge_peer(c);
-			if (bridged) {
-				if (!ast_masq_park_call(bridged, c, 0, &extout)) {
-					snprintf(message, sizeof(message), "Call Parked at: %d", extout);
-					transmit_displaynotify(d, message, 10);
-				} else {
-					transmit_displaynotify(d, "Call Park failed", 10);
-				}
-			} else {
-				transmit_displaynotify(d, "Call Park not available", 10);
-			}
+			ast_channel_lock(c);
+			bridge_channel = ast_channel_get_bridge_channel(c);
+			ast_channel_unlock(c);
+
+			if (!bridge_channel) {
+				transmit_displaynotify(d, "Call Park failed", 10);
+				break;
+			}
+
+			if (!parking_provider->parking_park_call(bridge_channel, extout, sizeof(extout))) {
+				snprintf(message, sizeof(message), "Call Parked at: %s", extout);
+				transmit_displaynotify(d, message, 10);
+				break;
+			}
+			transmit_displaynotify(d, "Call Park failed", 10);
 		} else {
 			transmit_displaynotify(d, "Call Park not available", 10);
 		}

Modified: team/mmichelson/bridged_channel/channels/sig_analog.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/bridged_channel/channels/sig_analog.c?view=diff&rev=396042&r1=396041&r2=396042
==============================================================================
--- team/mmichelson/bridged_channel/channels/sig_analog.c (original)
+++ team/mmichelson/bridged_channel/channels/sig_analog.c Thu Aug  1 16:47:38 2013
@@ -44,6 +44,7 @@
 #include "asterisk/causes.h"
 #include "asterisk/features_config.h"
 #include "asterisk/bridge.h"
+#include "asterisk/parking.h"
 
 #include "sig_analog.h"
 
@@ -1713,7 +1714,11 @@
 	int idx;
 	struct ast_callid *callid;
 	RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_parking_bridge_feature_fn_table *, parking_provider,
+		ast_parking_get_bridge_features(),
+		ao2_cleanup);
 	const char *pickupexten;
+	int is_exten_parking;
 
 	analog_increase_ss_count();
 
@@ -2094,7 +2099,8 @@
 			} else {
 				analog_play_tone(p, idx, ANALOG_TONE_DIALTONE);
 			}
-			if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num) && !ast_parking_ext_valid(exten, chan, ast_channel_context(chan))) {
+			is_exten_parking = (parking_provider ? parking_provider->parking_is_exten_park(ast_channel_context(chan), exten) : 0);
+			if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num) && !is_exten_parking) {
 				if (!res || !ast_matchmore_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num)) {
 					if (getforward) {
 						/* Record this as the forwarding extension */
@@ -2238,19 +2244,18 @@
 				getforward = 0;
 				memset(exten, 0, sizeof(exten));
 				len = 0;
-			} else if ((p->transfer || p->canpark) && ast_parking_ext_valid(exten, chan, ast_channel_context(chan)) &&
-						p->subs[ANALOG_SUB_THREEWAY].owner &&
-						ast_channel_is_bridged(p->subs[ANALOG_SUB_THREEWAY].owner)) {
-				RAII_VAR(struct ast_channel *, bridged, ast_channel_bridge_peer(p->subs[ANALOG_SUB_THREEWAY].owner), ast_channel_cleanup);
-
-				if (!bridged) {
-					break;
-				}
-
+			} else if ((p->transfer || p->canpark) && is_exten_parking &&
+						p->subs[ANALOG_SUB_THREEWAY].owner) {
+				struct ast_bridge_channel *bridge_channel;
 				/* This is a three way call, the main call being a real channel,
 					and we're parking the first call. */
-				ast_masq_park_call_exten(bridged, chan, exten, ast_channel_context(chan), 0, NULL);
-				ast_verb(3, "Parking call to '%s'\n", ast_channel_name(chan));
+				ast_channel_lock(chan);
+				bridge_channel = ast_channel_get_bridge_channel(chan);
+				ast_channel_unlock(chan);
+				if (bridge_channel && !parking_provider->parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), exten)) {
+					ast_verb(3, "Parking call to '%s'\n", ast_channel_name(chan));
+				}
+				ao2_ref(bridge_channel, -1);
 				break;
 			} else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
 				ast_verb(3, "Blacklisting number %s\n", p->lastcid_num);

Modified: team/mmichelson/bridged_channel/include/asterisk/features.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/bridged_channel/include/asterisk/features.h?view=diff&rev=396042&r1=396041&r2=396042
==============================================================================
--- team/mmichelson/bridged_channel/include/asterisk/features.h (original)
+++ team/mmichelson/bridged_channel/include/asterisk/features.h Thu Aug  1 16:47:38 2013
@@ -62,50 +62,6 @@
 	AST_FEATURE_FLAG_BYCALLER =  (1 << 4),
 	AST_FEATURE_FLAG_BYBOTH	 =   (3 << 3),
 };
-
-/*!
- * \brief Park a call via a masqueraded channel
- *
- * \param park_me Channel to be parked.
- * \param parker Channel parking the call.
- * \param timeout is a timeout in milliseconds
- * \param extout is a parameter to an int that will hold the parked location, or NULL if you want.
- *
- * \details
- * Masquerade the park_me channel into a new, empty channel which is then parked.
- *
- * \note Use ast_masq_park_call_exten() instead.
- *
- * \retval 0 on success.
- * \retval -1 on failure.
- */
-int ast_masq_park_call(struct ast_channel *park_me, struct ast_channel *parker, int timeout, int *extout);
-
-/*!
- * \brief Park a call via a masqueraded channel
- * \since 1.8.9
- *
- * \param park_me Channel to be parked.
- * \param parker Channel parking the call.
- * \param park_exten Parking lot access extension
- * \param park_context Parking lot context
- * \param timeout is a timeout in milliseconds
- * \param extout is a parameter to an int that will hold the parked location, or NULL if you want.
- *
- * \details
- * Masquerade the park_me channel into a new, empty channel which is then parked.
- *
- * \retval 0 on success.
- * \retval -1 on failure.
- */
-int ast_masq_park_call_exten(struct ast_channel *park_me, struct ast_channel *parker, const char *park_exten, const char *park_context, int timeout, int *extout);
-
-/*!
- * \brief Determine if parking extension exists in a given context
- * \retval 0 if extension does not exist
- * \retval 1 if extension does exist
-*/
-int ast_parking_ext_valid(const char *exten_str, struct ast_channel *chan, const char *context);
 
 /*! \brief Bridge a call, optionally allowing redirection */
 int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer,struct ast_bridge_config *config);

Modified: team/mmichelson/bridged_channel/include/asterisk/parking.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/bridged_channel/include/asterisk/parking.h?view=diff&rev=396042&r1=396041&r2=396042
==============================================================================
--- team/mmichelson/bridged_channel/include/asterisk/parking.h (original)
+++ team/mmichelson/bridged_channel/include/asterisk/parking.h Thu Aug  1 16:47:38 2013
@@ -25,6 +25,9 @@
 
 #include "asterisk/stringfields.h"
 
+/*!
+ * \brief The default parking application that Asterisk expects.
+ */
 #define PARK_APPLICATION "Park"
 
 /*!
@@ -79,6 +82,10 @@
 		struct ast_channel_snapshot *retriever_snapshot, const char *parkinglot,
 		unsigned int parkingspace, unsigned long int timeout, unsigned long int duration);
 
+/*! \addtogroup StasisTopicsAndMessages
+ * @{
+ */
+
 /*!
  * \brief accessor for the parking stasis topic
  * \since 12
@@ -97,75 +104,110 @@
  */
 struct stasis_message_type *ast_parked_call_type(void);
 
-/*!
- * \brief invoke an installable park callback to asynchronously park a bridge_channel in a bridge
- * \since 12
- *
- * \param bridge_channel the bridge channel that initiated parking
- * \parkee_uuid channel id of the channel being parked
- * \parker_uuid channel id of the channel that initiated parking
- * \param app_data string of application data that might be applied to parking
- */
-void ast_bridge_channel_park(struct ast_bridge_channel *bridge_channel,
-	const char *parkee_uuid,
-	const char *parker_uuid,
-	const char *app_data);
-
-typedef int (*ast_park_blind_xfer_fn)(struct ast_bridge_channel *parker, struct ast_exten *park_exten);
-
-/*!
- * \brief install a callback for handling blind transfers to a parking extension
- * \since 12
- *
- * \param parking_func Function to use for transfers to 'Park' applications
- */
-void ast_install_park_blind_xfer_func(ast_park_blind_xfer_fn park_blind_xfer_func);
-
-/*!
- * \brief uninstall a callback for handling blind transfers to a parking extension
- * \since 12
- */
-void ast_uninstall_park_blind_xfer_func(void);
-
-/*!
- * \brief use the installed park blind xfer func
- * \since 12
- *
- * \param parker Bridge channel initiating the park
- * \param park_exten Exten to blind transfer part to.
+/*! @} */
+
+#define PARKING_MODULE_VERSION 1
+
+/*!
+ * \brief A function table providing parking functionality to the \ref AstBridging
+ * Bridging API and other consumers
+ */
+struct ast_parking_bridge_feature_fn_table {
+
+	/*!
+	 * \brief The version of this function table. If the ABI for this table
+	 * changes, the module version (/ref PARKING_MODULE_VERSION) should be
+	 * incremented.
+	 */
+	unsigned int module_version;
+
+	/*!
+	 * \brief The name of the module that provides this parking functionality
+	 */
+	const char *module_name;
+
+	/*!
+	 * \brief Determine if the context/exten is a "parking" extension
+	 *
+	 * \retval 0 if the extension is not a parking extension
+	 * \retval 1 if the extension is a parking extension
+	 */
+	int (* parking_is_exten_park)(const char *context, const char *exten);
+
+	/*!
+	 * \brief Park the bridge and/or callers that this channel is in
+	 *
+	 * \param parker The bridge_channel parking the bridge
+	 * \param exten Optional. The extension the channel or bridge was parked at if the
+	 * call succeeds.
+	 * \param length Optional. If \c exten is specified, the size of the buffer.
+	 *
+	 * \note This is safe to be called outside of the \ref AstBridging Bridging API.
+	 *
+	 * \retval 0 on success
+	 * \retval non-zero on error
+	 */
+	int (* parking_park_call)(struct ast_bridge_channel *parker, char *exten, size_t length);
+
+	/*!
+	 * \brief Perform a blind transfer to a parking extension.
+	 *
+	 * \param parker The \ref bridge_channel object that is initiating the parking
+	 * \param context The context to blind transfer to
+	 * \param exten The extension to blind transfer to
+	 *
+	 * \note If the bridge \ref parker is in has more than one other occupant, the entire
+	 * bridge will be parked using a Local channel
+	 *
+	 * \note This is safe to be called outside of the \ref AstBridging Bridging API.
+	 *
+	 * \retval 0 on success
+	 * \retval non-zero on error
+	 */
+	int (* parking_blind_transfer_park)(struct ast_bridge_channel *parker, const char *context, const char *exten);
+
+	/*!
+	 * \brief Perform a direct park on a channel in a bridge.
+	 *
+	 * \param parkee The channel in the bridge to be parked.
+	 * \param parkee_uuid The UUID of the channel being packed.
+	 * \param parker_uuid The UUID of the channel performing the park.
+	 * \param app_data Data to pass to the Park application
+	 *
+	 * \note This must be called within the context of the \ref AstBridging Bridging API.
+	 * External entities should not call this method directly, but should instead use
+	 * the direct call parking method or the blind transfer method.
+	 *
+	 * \retval 0 on success
+	 * \retval non-zero on error
+	 */
+	int (* parking_park_bridge_channel)(struct ast_bridge_channel *parkee, const char *parkee_uuid, const char *parker_uuid, const char *app_data);
+};
+
+/*!
+ * \brief Obtain the current parking provider
+ *
+ * \retval NULL if no provider exists
+ * \retval an ao2 ref counted object of the existing provider's function table
+ */
+struct ast_parking_bridge_feature_fn_table *ast_parking_get_bridge_features(void);
+
+/*!
+ * \brief Register a parking provider
+ *
+ * \param fn_table The \ref ast_parking_bridge_feature_fn_table to register
  *
  * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_park_blind_xfer(struct ast_bridge_channel *parker, struct ast_exten *park_exten);
-
-typedef void (*ast_bridge_channel_park_fn)(struct ast_bridge_channel *parkee, const char *parkee_uuid,
-	const char *parker_uuid, const char *app_data);
-
-/*!
- * \brief Install a function for ast_bridge_channel_park
- * \since 12
- *
- * \param bridge_channel_park_func function callback to use for ast_bridge_channel_park
- */
-void ast_install_bridge_channel_park_func(ast_bridge_channel_park_fn bridge_channel_park_func);
-
-/*!
- * \brief Uninstall the ast_bridge_channel_park function callback
- * \since 12
- */
-void ast_uninstall_bridge_channel_park_func(void);
-
-
-/*!
- * \brief Determines whether a certain extension is a park application extension or not.
- * \since 12
- *
- * \param exten_str string representation of the extension sought
- * \param chan channel the extension is sought for
- * \param context context the extension is sought from
- *
- * \retval pointer to the extension if the extension is a park extension
- * \retval NULL if the extension was not a park extension
- */
-struct ast_exten *ast_get_parking_exten(const char *exten_str, struct ast_channel *chan, const char *context);
+ * \retval -1 on error
+ */
+int ast_parking_register_bridge_features(struct ast_parking_bridge_feature_fn_table *fn_table);
+
+/*!
+ * \brief Unregister the current parking provider
+ *
+ * \param The module name of the provider to unregister
+ *
+ * \retval 0 if the parking provider \c module_name was unregsistered
+ * \retval -1 on error
+ */
+int ast_parking_unregister_bridge_features(const char *module_name);

Modified: team/mmichelson/bridged_channel/main/bridge.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/bridged_channel/main/bridge.c?view=diff&rev=396042&r1=396041&r2=396042
==============================================================================
--- team/mmichelson/bridged_channel/main/bridge.c (original)
+++ team/mmichelson/bridged_channel/main/bridge.c Thu Aug  1 16:47:38 2013
@@ -3781,32 +3781,31 @@
 	return transferee;
 }
 
-enum try_parking_result {
-	PARKING_SUCCESS,
-	PARKING_FAILURE,
-	PARKING_NOT_APPLICABLE,
-};
-
-static enum try_parking_result try_parking(struct ast_channel *transferer, const char *exten, const char *context)
+static enum ast_transfer_result try_parking(struct ast_channel *transferer, const char *context, const char *exten)
 {
 	RAII_VAR(struct ast_bridge_channel *, transferer_bridge_channel, NULL, ao2_cleanup);
-	struct ast_exten *parking_exten;
+	RAII_VAR(struct ast_parking_bridge_feature_fn_table *, parking_provider,
+		ast_parking_get_bridge_features(),
+		ao2_cleanup);
+
+	if (!parking_provider) {
+		return AST_BRIDGE_TRANSFER_FAIL;
+	}
 
 	ast_channel_lock(transferer);
 	transferer_bridge_channel = ast_channel_get_bridge_channel(transferer);
 	ast_channel_unlock(transferer);
 
 	if (!transferer_bridge_channel) {
-		return PARKING_FAILURE;
-	}
-
-	parking_exten = ast_get_parking_exten(exten, NULL, context);
-	if (parking_exten) {
-		return ast_park_blind_xfer(transferer_bridge_channel, parking_exten) == 0 ?
-			PARKING_SUCCESS : PARKING_FAILURE;
-	}
-
-	return PARKING_NOT_APPLICABLE;
+		return AST_BRIDGE_TRANSFER_FAIL;
+	}
+
+	if (parking_provider->parking_blind_transfer_park(transferer_bridge_channel,
+		context, exten)) {
+		return AST_BRIDGE_TRANSFER_FAIL;
+	}
+
+	return AST_BRIDGE_TRANSFER_SUCCESS;
 }
 
 /*!
@@ -3883,7 +3882,6 @@
 	RAII_VAR(struct ast_channel *, transferee, NULL, ast_channel_cleanup);
 	int do_bridge_transfer;
 	int transfer_prohibited;
-	enum try_parking_result parking_result;
 	enum ast_transfer_result transfer_result;
 
 	bridge = acquire_bridge(transferer);
@@ -3902,17 +3900,9 @@
 	/* Take off hold if they are on hold. */
 	ast_bridge_channel_write_unhold(bridge_channel);
 
-	parking_result = try_parking(transferer, exten, context);
-	switch (parking_result) {
-	case PARKING_SUCCESS:
-		transfer_result = AST_BRIDGE_TRANSFER_SUCCESS;
+	transfer_result = try_parking(transferer, context, exten);
+	if (transfer_result == AST_BRIDGE_TRANSFER_SUCCESS) {
 		goto publish;
-	case PARKING_FAILURE:
-		transfer_result = AST_BRIDGE_TRANSFER_FAIL;
-		goto publish;
-	case PARKING_NOT_APPLICABLE:
-	default:
-		break;
 	}
 
 	{

Modified: team/mmichelson/bridged_channel/main/bridge_channel.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/bridged_channel/main/bridge_channel.c?view=diff&rev=396042&r1=396041&r2=396042
==============================================================================
--- team/mmichelson/bridged_channel/main/bridge_channel.c (original)
+++ team/mmichelson/bridged_channel/main/bridge_channel.c Thu Aug  1 16:47:38 2013
@@ -757,9 +757,22 @@
  */
 static void bridge_channel_park(struct ast_bridge_channel *bridge_channel, struct bridge_park *payload)
 {
-	ast_bridge_channel_park(bridge_channel, payload->parkee_uuid,
+	RAII_VAR(struct ast_parking_bridge_feature_fn_table *, parking_provider,
+		ast_parking_get_bridge_features(),
+		ao2_cleanup);
+
+	if (!parking_provider) {
+		ast_log(AST_LOG_WARNING, "Unable to park %s: No parking provider loaded!\n",
+			ast_channel_name(bridge_channel->chan));
+		return;
+	}
+
+	if (parking_provider->parking_park_bridge_channel(bridge_channel, payload->parkee_uuid,
 		&payload->parkee_uuid[payload->parker_uuid_offset],
-		payload->app_data_offset ? &payload->parkee_uuid[payload->app_data_offset] : NULL);
+		payload->app_data_offset ? &payload->parkee_uuid[payload->app_data_offset] : NULL)) {
+		ast_log(AST_LOG_WARNING, "Error occurred while parking %s\n",
+			ast_channel_name(bridge_channel->chan));
+	}
 }
 
 /*!

Modified: team/mmichelson/bridged_channel/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/bridged_channel/main/features.c?view=diff&rev=396042&r1=396041&r2=396042
==============================================================================
--- team/mmichelson/bridged_channel/main/features.c (original)
+++ team/mmichelson/bridged_channel/main/features.c Thu Aug  1 16:47:38 2013
@@ -470,19 +470,10 @@
 /*! \brief The configured parking lots container. Always at least one  - the default parking lot */
 static struct ao2_container *parkinglots;
 
-/*!
- * \brief Default parking lot.
- * \note Holds a parkinglot reference.
- * \note Will not be NULL while running.
- */
-static struct ast_parkinglot *default_parkinglot;
-
 /*! Force a config reload to reload regardless of config file timestamp. */
 #ifdef TEST_FRAMEWORK
 static int force_reload_load;
 #endif
-
-static int parkeddynamic = 0;                              /*!< Enable creation of parkinglots dynamically */
 
 /*!
  * \brief Context for parking dialback to parker.
@@ -496,8 +487,6 @@
 
 /*! Ensure that features.conf reloads on one thread at a time. */
 AST_MUTEX_DEFINE_STATIC(features_reload_lock);
-
-static int adsipark;
 
 static char *registrar = "features";		   /*!< Registrar for operations */
 
@@ -511,9 +500,6 @@
 	AST_APP_ARG(pl_name);		/*!< Parking lot name to use if present. */
 	AST_APP_ARG(dummy);			/*!< Place to put any remaining args string. */
 	);
-
-/* module and CLI command definitions */
-static const char *parkcall = "Park";
 
 static pthread_t parking_thread;
 struct ast_dial_features {
@@ -670,50 +656,7 @@
 }
 
 /* Forward declarations */
-static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
-static struct ast_parkinglot *find_parkinglot(const char *name);
-static struct ast_parkinglot *create_parkinglot(const char *name);
-static struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot);
-static int parkinglot_activate(struct ast_parkinglot *parkinglot);
-static int play_message_on_chan(struct ast_channel *play_to, struct ast_channel *other, const char *msg, const char *audiofile);
-
-/*!
- * \internal
- * \brief Get the parking extension if it exists.
- *
- * \param exten_str Parking extension to see if exists.
- * \param chan Channel to autoservice while looking for exten.  (Could be NULL)
- * \param context Parking context to look in for exten.
- *
- * \retval exten on success.
- * \retval NULL on error or exten does not exist.
- */
-static struct ast_exten *get_parking_exten(const char *exten_str, struct ast_channel *chan, const char *context)
-{
-	struct ast_exten *exten;
-	struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
-	const char *app_at_exten;
-
-	ast_debug(4, "Checking if %s@%s is a parking exten\n", exten_str, context);
-	exten = pbx_find_extension(chan, NULL, &q, context, exten_str, 1, NULL, NULL,
-		E_MATCH);
-	if (!exten) {
-		return NULL;
-	}
-
-	app_at_exten = ast_get_extension_app(exten);
-	if (!app_at_exten || strcasecmp(parkcall, app_at_exten)) {
-		return NULL;
-	}
-
-	return exten;
-}
-
-int ast_parking_ext_valid(const char *exten_str, struct ast_channel *chan, const char *context)
-{
-	return get_parking_exten(exten_str, chan, context) ? 1 : 0;
-}
 
 struct ast_bridge_thread_obj
 {
@@ -754,46 +697,6 @@
 	.type = "Channel appdata datastore",
 	.destroy = ast_free_ptr,
 };
-
-/*!
- * \brief Announce call parking by ADSI
- * \param chan .
- * \param parkingexten .
- * Create message to show for ADSI, display message.
- * \retval 0 on success.
- * \retval -1 on failure.
- */
-static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
-{
-	int res;
-	int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
-	char tmp[256];
-	char *message[5] = {NULL, NULL, NULL, NULL, NULL};
-
-	snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
-	message[0] = tmp;
-	res = ast_adsi_load_session(chan, NULL, 0, 1);
-	if (res == -1)
-		return res;
-	return ast_adsi_print(chan, message, justify, 1);
-}
-
-/*!
- * \brief Find parking lot name from channel
- * \note Channel needs to be locked while the returned string is in use.
- */
-static const char *findparkinglotname(struct ast_channel *chan)
-{
-	const char *name;
-
-	/* The channel variable overrides everything */
-	name = pbx_builtin_getvar_helper(chan, "PARKINGLOT");
-	if (!name && !ast_strlen_zero(ast_channel_parkinglot(chan))) {
-		/* Use the channel's parking lot. */
-		name = ast_channel_parkinglot(chan);
-	}
-	return name;
-}
 
 /*! \brief Notify metermaids that we've changed an extension */
 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
@@ -854,705 +757,6 @@
 	/*! \brief Parkinglot to be parked in */
 	struct ast_parkinglot *parkinglot;
 };
-
-/*!
- * \internal
- * \brief Create a dynamic parking lot.
- *
- * \param name Dynamic parking lot name to create.
- * \param chan Channel to get dynamic parking lot parameters.
- *
- * \retval parkinglot on success.
- * \retval NULL on error.
- */
-static struct ast_parkinglot *create_dynamic_parkinglot(const char *name, struct ast_channel *chan)
-{
-	const char *dyn_context;
-	const char *dyn_exten;
-	const char *dyn_range;
-	const char *template_name;
-	struct ast_parkinglot *template_parkinglot = NULL;
-	struct ast_parkinglot *parkinglot;
-	int dyn_start;
-	int dyn_end;
-
-	ast_channel_lock(chan);
-	template_name = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNAMIC"), ""));
-	dyn_context = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNCONTEXT"), ""));
-	dyn_exten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNEXTEN"), ""));
-	dyn_range = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNPOS"), ""));
-	ast_channel_unlock(chan);
-
-	if (!ast_strlen_zero(template_name)) {
-		template_parkinglot = find_parkinglot(template_name);
-		if (!template_parkinglot) {
-			ast_debug(1, "PARKINGDYNAMIC lot %s does not exist.\n",
-				template_name);
-		} else if (template_parkinglot->cfg.is_invalid) {
-			ast_debug(1, "PARKINGDYNAMIC lot %s has invalid config.\n",
-				template_name);
-			parkinglot_unref(template_parkinglot);
-			template_parkinglot = NULL;
-		}
-	}
-	if (!template_parkinglot) {
-		template_parkinglot = parkinglot_addref(default_parkinglot);
-		ast_debug(1, "Using default parking lot for template\n");
-	}
-
-	parkinglot = copy_parkinglot(name, template_parkinglot);
-	if (!parkinglot) {
-		ast_log(LOG_ERROR, "Could not build dynamic parking lot!\n");
-	} else {
-		/* Configure the dynamic parking lot. */
-		if (!ast_strlen_zero(dyn_context)) {
-			ast_copy_string(parkinglot->cfg.parking_con, dyn_context,
-				sizeof(parkinglot->cfg.parking_con));
-		}
-		if (!ast_strlen_zero(dyn_exten)) {
-			ast_copy_string(parkinglot->cfg.parkext, dyn_exten,
-				sizeof(parkinglot->cfg.parkext));
-		}
-		if (!ast_strlen_zero(dyn_range)) {
-			if (sscanf(dyn_range, "%30d-%30d", &dyn_start, &dyn_end) != 2) {
-				ast_log(LOG_WARNING,
-					"Format for parking positions is a-b, where a and b are numbers\n");
-			} else if (dyn_end < dyn_start || dyn_start <= 0 || dyn_end <= 0) {
-				ast_log(LOG_WARNING,
-					"Format for parking positions is a-b, where a <= b\n");
-			} else {
-				parkinglot->cfg.parking_start = dyn_start;
-				parkinglot->cfg.parking_stop = dyn_end;
-			}
-		}
-
-		/*
-		 * Sanity check for dynamic parking lot configuration.
-		 *
-		 * XXX It may be desirable to instead check if the dynamic
-		 * parking lot overlaps any existing lots like what is done for
-		 * a reload.
-		 */
-		if (!strcmp(parkinglot->cfg.parking_con, template_parkinglot->cfg.parking_con)) {
-			if (!strcmp(parkinglot->cfg.parkext, template_parkinglot->cfg.parkext)
-				&& parkinglot->cfg.parkext_exclusive) {
-				ast_log(LOG_WARNING,
-					"Parking lot '%s' conflicts with template parking lot '%s'!\n"
-					"Change either PARKINGDYNCONTEXT or PARKINGDYNEXTEN.\n",
-					parkinglot->name, template_parkinglot->name);
-			}
-			if ((template_parkinglot->cfg.parking_start <= parkinglot->cfg.parking_start
-					&& parkinglot->cfg.parking_start <= template_parkinglot->cfg.parking_stop)
-				|| (template_parkinglot->cfg.parking_start <= parkinglot->cfg.parking_stop
-					&& parkinglot->cfg.parking_stop <= template_parkinglot->cfg.parking_stop)
-				|| (parkinglot->cfg.parking_start < template_parkinglot->cfg.parking_start
-					&& template_parkinglot->cfg.parking_stop < parkinglot->cfg.parking_stop)) {
-				ast_log(LOG_WARNING,
-					"Parking lot '%s' parking spaces overlap template parking lot '%s'!\n"
-					"Change PARKINGDYNPOS.\n",
-					parkinglot->name, template_parkinglot->name);
-			}
-		}
-
-		parkinglot_activate(parkinglot);
-		ao2_link(parkinglots, parkinglot);
-	}
-	parkinglot_unref(template_parkinglot);
-
-	return parkinglot;
-}
-
-/*!
- * \internal
- * \brief Abort parking a call that has not completed parking yet.
- *
- * \param pu Parked user item to clean up.
- *
- * \note The parking lot parkings list is locked on entry.
- *
- * \return Nothing
- */
-static void park_space_abort(struct parkeduser *pu)
-{
-	struct ast_parkinglot *parkinglot;
-
-	parkinglot = pu->parkinglot;
-
-	/* Put back the parking space just allocated. */
-	--parkinglot->next_parking_space;
-
-	AST_LIST_REMOVE(&parkinglot->parkings, pu, list);
-
-	AST_LIST_UNLOCK(&parkinglot->parkings);
-	parkinglot_unref(parkinglot);
-	ast_free(pu);
-}
-
-/*!
- * \internal
- * \brief Reserve a parking space in a parking lot for a call being parked.
- *
- * \param park_me Channel being parked.
- * \param parker Channel parking the call.
- * \param args Optional additional parking options when parking a call.
- *
- * \return Parked call descriptor or NULL if failed.
- * \note The parking lot list is locked if successful.
- */
-static struct parkeduser *park_space_reserve(struct ast_channel *park_me, struct ast_channel *parker, struct ast_park_call_args *args)
-{
-	struct parkeduser *pu;
-	int i;
-	int parking_space = -1;
-	const char *parkinglotname;
-	const char *parkingexten;
-	struct parkeduser *cur;
-	struct ast_parkinglot *parkinglot = NULL;
-
-	if (args->parkinglot) {
-		parkinglot = parkinglot_addref(args->parkinglot);
-		parkinglotname = parkinglot->name;
-	} else {
-		if (parker) {
-			parkinglotname = findparkinglotname(parker);
-		} else { /* parker was NULL, check park_me (ParkAndAnnounce / res_agi) */
-			parkinglotname = findparkinglotname(park_me);
-		}
-		if (!ast_strlen_zero(parkinglotname)) {
-			parkinglot = find_parkinglot(parkinglotname);
-		} else {
-			/* Parking lot is not specified, so use the default parking lot. */
-			ast_debug(4, "This could be an indication channel driver needs updating, using default lot.\n");
-			parkinglot = parkinglot_addref(default_parkinglot);
-		}
-	}
-
-	/* Dynamically create parkinglot */
-	if (!parkinglot && parkeddynamic && !ast_strlen_zero(parkinglotname)) {

[... 1605 lines stripped ...]



More information about the asterisk-commits mailing list