res_parking: Give parking timeout comebacktoorigin channel DTMF features.
authorRichard Mudgett <rmudgett@digium.com>
Tue, 22 Oct 2013 16:33:16 +0000 (16:33 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Tue, 22 Oct 2013 16:33:16 +0000 (16:33 +0000)
Parking timeouts did not set any DTMF features for the channel calling the
parker back.

* Added code to set the parkedcalltransfers, parkedcallreparking,
parkedcallhangup, and parkedcallrecording options appropriately for the
channels when a parking timeout occurs.  The recall channel DTMF options
are set using the BRIDGE_FEATURES channel variable to allow the other
timeout options to have the DTMF features available.

(closes issue ASTERISK-22630)
Reported by: Kevin Harwell

Review: https://reviewboard.asterisk.org/r/2942/
........

Merged revisions 401422 from http://svn.asterisk.org/svn/asterisk/branches/12

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@401423 65c4cc65-6c06-0410-ace0-fbb531ad65f3

res/parking/parking_bridge.c
res/parking/parking_bridge_features.c

index d0bdfa0..9bc1345 100644 (file)
@@ -368,16 +368,16 @@ static void bridge_parking_pull(struct ast_bridge_parking *self, struct ast_brid
        case PARK_UNSET:
                /* This should be impossible now since the resolution is forcibly set to abandon if it was unset at this point. Resolution
                   isn't allowed to be changed when it isn't currently PARK_UNSET. */
-               return;
+               break;
        case PARK_ABANDON:
                /* Since the call was abandoned without additional handling, we need to issue the give up event and unpark the user. */
                publish_parked_call(pu, PARKED_CALL_GIVEUP);
                unpark_parked_user(pu);
-               return;
+               break;
        case PARK_FORCED:
                /* PARK_FORCED is currently unused, but it is expected that it would be handled similar to PARK_ANSWERED.
                 * There is currently no event related to forced parked calls either */
-               return;
+               break;
        case PARK_ANSWERED:
                /* If answered or forced, the channel should be pulled from the bridge as part of that process and unlinked from
                 * the parking lot afterwards. We do need to apply bridge features though and play the courtesy tone if set. */
@@ -387,14 +387,14 @@ static void bridge_parking_pull(struct ast_bridge_parking *self, struct ast_brid
                if (pu->lot->cfg->parkedplay & AST_FEATURE_FLAG_BYCALLEE) {
                        ast_bridge_channel_queue_playfile(bridge_channel, NULL, pu->lot->cfg->courtesytone, NULL);
                }
-
-               return;
+               break;
        case PARK_TIMEOUT:
                /* Timeout is similar to abandon because it simply sets the bridge state to end and doesn't
                 * actually pull the channel. Because of that, unpark should happen in here. */
                publish_parked_call(pu, PARKED_CALL_TIMEOUT);
+               parked_call_retrieve_enable_features(bridge_channel->chan, pu->lot, AST_FEATURE_FLAG_BYCALLEE);
                unpark_parked_user(pu);
-               return;
+               break;
        }
 }
 
index 6c1d4d6..4f39e2e 100644 (file)
@@ -452,6 +452,43 @@ static int feature_park_call(struct ast_bridge_channel *bridge_channel, void *ho
        return parking_park_call(bridge_channel, NULL, 0);
 }
 
+/*!
+ * \internal
+ * \brief Setup the caller features for when that channel is dialed.
+ * \since 12.0.0
+ *
+ * \param chan Parked channel leaving the parking lot.
+ * \param cfg Parking lot configuration.
+ *
+ * \return Nothing
+ */
+static void parking_timeout_set_caller_features(struct ast_channel *chan, struct parking_lot_cfg *cfg)
+{
+       char features[5];
+       char *pos;
+
+       /*
+        * We are setting the callee Dial flag values because in the
+        * timeout case, the caller is who is being called back.
+        */
+       pos = features;
+       if (cfg->parkedcalltransfers & AST_FEATURE_FLAG_BYCALLER) {
+               *pos++ = 't';
+       }
+       if (cfg->parkedcallreparking & AST_FEATURE_FLAG_BYCALLER) {
+               *pos++ = 'k';
+       }
+       if (cfg->parkedcallhangup & AST_FEATURE_FLAG_BYCALLER) {
+               *pos++ = 'h';
+       }
+       if (cfg->parkedcallrecording & AST_FEATURE_FLAG_BYCALLER) {
+               *pos++ = 'x';
+       }
+       *pos = '\0';
+
+       pbx_builtin_setvar_helper(chan, "BRIDGE_FEATURES", features);
+}
+
 /*! \internal
  * \brief Interval hook. Pulls a parked call from the parking bridge after the timeout is passed and sets the resolution to timeout.
  *
@@ -481,25 +518,26 @@ static int parking_duration_callback(struct ast_bridge_channel *bridge_channel,
                ao2_unlock(user);
                return -1;
        }
-
        user->resolution = PARK_TIMEOUT;
        ao2_unlock(user);
 
        ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE,
                AST_CAUSE_NORMAL_CLEARING);
 
+       dial_string = user->parker_dial_string;
+       dial_string_flat = ast_strdupa(dial_string);
+       flatten_dial_string(dial_string_flat);
+
        /* Set parking timeout channel variables */
        snprintf(parking_space, sizeof(parking_space), "%d", user->parking_space);
+       ast_channel_stage_snapshot(chan);
        pbx_builtin_setvar_helper(chan, "PARKING_SPACE", parking_space);
        pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parking_space); /* Deprecated version of PARKING_SPACE */
        pbx_builtin_setvar_helper(chan, "PARKEDLOT", user->lot->name);
-
-       dial_string = user->parker_dial_string;
-       dial_string_flat = ast_strdupa(dial_string);
-       flatten_dial_string(dial_string_flat);
-
        pbx_builtin_setvar_helper(chan, "PARKER", dial_string);
        pbx_builtin_setvar_helper(chan, "PARKER_FLAT", dial_string_flat);
+       parking_timeout_set_caller_features(chan, user->lot->cfg);
+       ast_channel_stage_snapshot_done(chan);
 
        /* Dialplan generation for park-dial extensions */
 
@@ -532,7 +570,6 @@ static int parking_duration_callback(struct ast_bridge_channel *bridge_channel,
                user->lot->cfg->comebackdialtime);
 
        duplicate_returnexten = ast_strdup(returnexten);
-
        if (!duplicate_returnexten) {
                ast_log(LOG_ERROR, "Failed to create parking redial parker extension %s@%s - Dial(%s)\n",
                        dial_string_flat, PARK_DIAL_CONTEXT, returnexten);