[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