summaryrefslogtreecommitdiff
path: root/res/parking/parking_applications.c
diff options
context:
space:
mode:
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;
}