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 ...]

--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to