summaryrefslogtreecommitdiff
path: root/res/parking/parking_applications.c
diff options
context:
space:
mode:
authorJonathan Rose <jrose@digium.com>2013-07-04 18:46:56 +0000
committerJonathan Rose <jrose@digium.com>2013-07-04 18:46:56 +0000
commit93ed5ef0ffdffc342ef2e0670b9cf51686027401 (patch)
tree71e36bba6f8e575ed9aa542f4183f33cb816fce2 /res/parking/parking_applications.c
parentfb03bf9b39ad1f8b8bb50077cc54457edd8d6d9a (diff)
res_parking: Replace Parker snapshots with ParkerDialString
This process also involved a large amount of rework regarding how to redial the Parker when a channel leaves a parking lot due to timeout. An attended transfer channel variable has been added to attended transfers to extensions that will eventually park (but haven't at the time of transfer) as well. This resolves one of the two BUGBUG comments remaining in res_parking. (issues ASTERISK-21877) Reported by: Matt Jordan Review: https://reviewboard.asterisk.org/r/2638/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@393704 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/parking/parking_applications.c')
-rw-r--r--res/parking/parking_applications.c110
1 files changed, 78 insertions, 32 deletions
diff --git a/res/parking/parking_applications.c b/res/parking/parking_applications.c
index eceeaca18..f7e279766 100644
--- a/res/parking/parking_applications.c
+++ b/res/parking/parking_applications.c
@@ -284,14 +284,24 @@ static int park_app_parse_data(const char *data, int *disable_announce, int *use
return 0;
}
-static void park_common_datastore_destroy(void *data)
+void park_common_datastore_free(struct park_common_datastore *datastore)
{
- struct park_common_datastore *datastore = data;
+ if (!datastore) {
+ return;
+ }
+
ast_free(datastore->parker_uuid);
+ ast_free(datastore->parker_dial_string);
ast_free(datastore->comeback_override);
ast_free(datastore);
}
+static void park_common_datastore_destroy(void *data)
+{
+ struct park_common_datastore *datastore = data;
+ park_common_datastore_free(datastore);
+}
+
static const struct ast_datastore_info park_common_info = {
.type = "park entry data",
.destroy = park_common_datastore_destroy,
@@ -314,6 +324,9 @@ static int setup_park_common_datastore(struct ast_channel *parkee, const char *p
{
struct ast_datastore *datastore = NULL;
struct park_common_datastore *park_datastore;
+ const char *attended_transfer;
+ const char *blind_transfer;
+ char *parker_dial_string = NULL;
wipe_park_common_datastore(parkee);
@@ -326,7 +339,27 @@ static int setup_park_common_datastore(struct ast_channel *parkee, const char *p
return -1;
}
- park_datastore->parker_uuid = ast_strdup(parker_uuid);
+ if (parker_uuid) {
+ park_datastore->parker_uuid = ast_strdup(parker_uuid);
+ }
+
+ ast_channel_lock(parkee);
+
+ attended_transfer = pbx_builtin_getvar_helper(parkee, "ATTENDEDTRANSFER");
+ blind_transfer = pbx_builtin_getvar_helper(parkee, "BLINDTRANSFER");
+
+ if (attended_transfer || blind_transfer) {
+ parker_dial_string = ast_strdupa(S_OR(attended_transfer, blind_transfer));
+ }
+
+ ast_channel_unlock(parkee);
+
+ if (!ast_strlen_zero(parker_dial_string)) {
+ ast_channel_name_to_dial_string(parker_dial_string);
+ ast_verb(5, "Setting dial string to %s from %s value", parker_dial_string, attended_transfer ? "ATTENDEDTRANSFER" : "BLINDTRANSFER");
+ park_datastore->parker_dial_string = ast_strdup(parker_dial_string);
+ }
+
park_datastore->randomize = randomize;
park_datastore->time_limit = time_limit;
park_datastore->silence_announce = silence_announce;
@@ -344,16 +377,15 @@ static int setup_park_common_datastore(struct ast_channel *parkee, const char *p
return 0;
}
-void get_park_common_datastore_data(struct ast_channel *parkee, char **parker_uuid, char **comeback_override,
- int *randomize, int *time_limit, int *silence_announce)
+struct park_common_datastore *get_park_common_datastore_copy(struct ast_channel *parkee)
{
struct ast_datastore *datastore;
struct park_common_datastore *data;
+ struct park_common_datastore *data_copy;
- ast_channel_lock(parkee);
+ SCOPED_CHANNELLOCK(lock, parkee);
if (!(datastore = ast_channel_datastore_find(parkee, &park_common_info, NULL))) {
- ast_channel_unlock(parkee);
- return;
+ return NULL;
}
data = datastore->data;
@@ -363,16 +395,37 @@ void get_park_common_datastore_data(struct ast_channel *parkee, char **parker_uu
ast_assert(0);
}
- *parker_uuid = ast_strdup(data->parker_uuid);
- *randomize = data->randomize;
- *time_limit = data->time_limit;
- *silence_announce = data->silence_announce;
+ data_copy = ast_calloc(1, sizeof(*data_copy));
+ if (!data_copy) {
+ return NULL;
+ }
+
+ if (!(data_copy->parker_uuid = ast_strdup(data->parker_uuid))) {
+ park_common_datastore_free(data_copy);
+ return NULL;
+ }
+
+ data_copy->randomize = data->randomize;
+ data_copy->time_limit = data->time_limit;
+ data_copy->silence_announce = data->silence_announce;
if (data->comeback_override) {
- *comeback_override = ast_strdup(data->comeback_override);
+ data_copy->comeback_override = ast_strdup(data->comeback_override);
+ if (!data_copy->comeback_override) {
+ park_common_datastore_free(data_copy);
+ return NULL;
+ }
}
- ast_channel_unlock(parkee);
+ if (data->parker_dial_string) {
+ data_copy->parker_dial_string = ast_strdup(data->parker_dial_string);
+ if (!data_copy->parker_dial_string) {
+ park_common_datastore_free(data_copy);
+ return NULL;
+ }
+ }
+
+ return data_copy;
}
struct ast_bridge *park_common_setup(struct ast_channel *parkee, struct ast_channel *parker,
@@ -382,6 +435,10 @@ struct ast_bridge *park_common_setup(struct ast_channel *parkee, struct ast_chan
struct ast_bridge *parking_bridge;
RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
+ if (!parker) {
+ parker = parkee;
+ }
+
/* If the name of the parking lot isn't specified in the arguments, find it based on the channel. */
if (ast_strlen_zero(lot_name)) {
ast_channel_lock(parker);
@@ -433,18 +490,6 @@ struct ast_bridge *park_application_setup(struct ast_channel *parkee, struct ast
}
-/* XXX BUGBUG - determining the parker when transferred to deep park priority
- * Currently all parking by the park application is treated as calls parking themselves.
- * However, it's possible for calls to be transferred here when the Park application is
- * set after the first priority of an extension. In that case, there used to be a variable
- * (BLINDTRANSFER) set indicating which channel placed that call here.
- *
- * If BLINDTRANSFER is set, this channel name will need to be referenced in Park events
- * generated by stasis. Ideally we would get a whole channel snapshot and use that for the
- * parker, but that would likely require applying the channel snapshot to a channel datastore
- * on all transfers. Alternatively just the name of the parking channel could be applied along
- * with an indication that it's dead.
- */
int park_app_exec(struct ast_channel *chan, const char *data)
{
RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
@@ -452,7 +497,7 @@ int park_app_exec(struct ast_channel *chan, const char *data)
struct ast_bridge_features chan_features;
int res;
int silence_announcements = 0;
- const char *blind_transfer;
+ const char *transferer;
/* Answer the channel if needed */
if (ast_channel_state(chan) != AST_STATE_UP) {
@@ -460,14 +505,15 @@ int park_app_exec(struct ast_channel *chan, const char *data)
}
ast_channel_lock(chan);
- if ((blind_transfer = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"))) {
- blind_transfer = ast_strdupa(blind_transfer);
+ if (!(transferer = pbx_builtin_getvar_helper(chan, "ATTENDEDTRANSFER"))) {
+ transferer = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
}
+ transferer = ast_strdupa(S_OR(transferer, ""));
ast_channel_unlock(chan);
/* Handle the common parking setup stuff */
- if (!(parking_bridge = park_application_setup(chan, chan, data, &silence_announcements))) {
- if (!silence_announcements && !blind_transfer) {
+ if (!(parking_bridge = park_application_setup(chan, NULL, data, &silence_announcements))) {
+ if (!silence_announcements && !transferer) {
ast_stream_and_wait(chan, "pbx-parkingfailed", "");
}
return 0;
@@ -767,7 +813,7 @@ int park_and_announce_app_exec(struct ast_channel *chan, const char *data)
}
/* Handle the common parking setup stuff */
- if (!(parking_bridge = park_application_setup(chan, chan, data, &silence_announcements))) {
+ if (!(parking_bridge = park_application_setup(chan, NULL, data, &silence_announcements))) {
return 0;
}