mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-02 10:22:46 +00:00
Merge "res_parking: Misc fixes." into 13
This commit is contained in:
@@ -380,16 +380,17 @@ static int setup_park_common_datastore(struct ast_channel *parkee, const char *p
|
|||||||
ast_datastore_free(datastore);
|
ast_datastore_free(datastore);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
datastore->data = park_datastore;
|
||||||
|
|
||||||
if (parker_uuid) {
|
|
||||||
park_datastore->parker_uuid = ast_strdup(parker_uuid);
|
park_datastore->parker_uuid = ast_strdup(parker_uuid);
|
||||||
|
if (!park_datastore->parker_uuid) {
|
||||||
|
ast_datastore_free(datastore);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_channel_lock(parkee);
|
ast_channel_lock(parkee);
|
||||||
|
|
||||||
attended_transfer = pbx_builtin_getvar_helper(parkee, "ATTENDEDTRANSFER");
|
attended_transfer = pbx_builtin_getvar_helper(parkee, "ATTENDEDTRANSFER");
|
||||||
blind_transfer = pbx_builtin_getvar_helper(parkee, "BLINDTRANSFER");
|
blind_transfer = pbx_builtin_getvar_helper(parkee, "BLINDTRANSFER");
|
||||||
|
|
||||||
if (!ast_strlen_zero(attended_transfer)) {
|
if (!ast_strlen_zero(attended_transfer)) {
|
||||||
parker_dial_string = ast_strdupa(attended_transfer);
|
parker_dial_string = ast_strdupa(attended_transfer);
|
||||||
} else if (!ast_strlen_zero(blind_transfer)) {
|
} else if (!ast_strlen_zero(blind_transfer)) {
|
||||||
@@ -397,7 +398,6 @@ static int setup_park_common_datastore(struct ast_channel *parkee, const char *p
|
|||||||
/* Ensure that attended_transfer is NULL and not an empty string. */
|
/* Ensure that attended_transfer is NULL and not an empty string. */
|
||||||
attended_transfer = NULL;
|
attended_transfer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_channel_unlock(parkee);
|
ast_channel_unlock(parkee);
|
||||||
|
|
||||||
if (!ast_strlen_zero(parker_dial_string)) {
|
if (!ast_strlen_zero(parker_dial_string)) {
|
||||||
@@ -406,6 +406,10 @@ static int setup_park_common_datastore(struct ast_channel *parkee, const char *p
|
|||||||
parker_dial_string,
|
parker_dial_string,
|
||||||
attended_transfer ? "ATTENDEDTRANSFER" : "BLINDTRANSFER");
|
attended_transfer ? "ATTENDEDTRANSFER" : "BLINDTRANSFER");
|
||||||
park_datastore->parker_dial_string = ast_strdup(parker_dial_string);
|
park_datastore->parker_dial_string = ast_strdup(parker_dial_string);
|
||||||
|
if (!park_datastore->parker_dial_string) {
|
||||||
|
ast_datastore_free(datastore);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
park_datastore->randomize = randomize;
|
park_datastore->randomize = randomize;
|
||||||
@@ -414,10 +418,13 @@ static int setup_park_common_datastore(struct ast_channel *parkee, const char *p
|
|||||||
|
|
||||||
if (comeback_override) {
|
if (comeback_override) {
|
||||||
park_datastore->comeback_override = ast_strdup(comeback_override);
|
park_datastore->comeback_override = ast_strdup(comeback_override);
|
||||||
|
if (!park_datastore->comeback_override) {
|
||||||
|
ast_datastore_free(datastore);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
datastore->data = park_datastore;
|
|
||||||
ast_channel_lock(parkee);
|
ast_channel_lock(parkee);
|
||||||
ast_channel_datastore_add(parkee, datastore);
|
ast_channel_datastore_add(parkee, datastore);
|
||||||
ast_channel_unlock(parkee);
|
ast_channel_unlock(parkee);
|
||||||
@@ -432,23 +439,23 @@ struct park_common_datastore *get_park_common_datastore_copy(struct ast_channel
|
|||||||
struct park_common_datastore *data_copy;
|
struct park_common_datastore *data_copy;
|
||||||
|
|
||||||
SCOPED_CHANNELLOCK(lock, parkee);
|
SCOPED_CHANNELLOCK(lock, parkee);
|
||||||
|
|
||||||
if (!(datastore = ast_channel_datastore_find(parkee, &park_common_info, NULL))) {
|
if (!(datastore = ast_channel_datastore_find(parkee, &park_common_info, NULL))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = datastore->data;
|
data = datastore->data;
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
/* This data should always be populated if this datastore was appended to the channel */
|
/* This data should always be populated if this datastore was appended to the channel */
|
||||||
ast_assert(0);
|
ast_assert(data != NULL);
|
||||||
}
|
|
||||||
|
|
||||||
data_copy = ast_calloc(1, sizeof(*data_copy));
|
data_copy = ast_calloc(1, sizeof(*data_copy));
|
||||||
if (!data_copy) {
|
if (!data_copy) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(data_copy->parker_uuid = ast_strdup(data->parker_uuid))) {
|
data_copy->parker_uuid = ast_strdup(data->parker_uuid);
|
||||||
|
if (!data_copy->parker_uuid) {
|
||||||
park_common_datastore_free(data_copy);
|
park_common_datastore_free(data_copy);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -498,7 +505,6 @@ struct ast_bridge *park_common_setup(struct ast_channel *parkee, struct ast_chan
|
|||||||
if (!lot) {
|
if (!lot) {
|
||||||
lot = parking_create_dynamic_lot(lot_name, parker);
|
lot = parking_create_dynamic_lot(lot_name, parker);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lot) {
|
if (!lot) {
|
||||||
ast_log(LOG_ERROR, "Could not find parking lot: '%s'\n", lot_name);
|
ast_log(LOG_ERROR, "Could not find parking lot: '%s'\n", lot_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -545,7 +551,7 @@ static int park_app_exec(struct ast_channel *chan, const char *data)
|
|||||||
struct ast_bridge_features chan_features;
|
struct ast_bridge_features chan_features;
|
||||||
int res;
|
int res;
|
||||||
int silence_announcements = 0;
|
int silence_announcements = 0;
|
||||||
const char *transferer;
|
int blind_transfer;
|
||||||
|
|
||||||
/* Answer the channel if needed */
|
/* Answer the channel if needed */
|
||||||
if (ast_channel_state(chan) != AST_STATE_UP) {
|
if (ast_channel_state(chan) != AST_STATE_UP) {
|
||||||
@@ -553,15 +559,12 @@ static int park_app_exec(struct ast_channel *chan, const char *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ast_channel_lock(chan);
|
ast_channel_lock(chan);
|
||||||
if (!(transferer = pbx_builtin_getvar_helper(chan, "ATTENDEDTRANSFER"))) {
|
blind_transfer = !ast_strlen_zero(pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"));
|
||||||
transferer = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
|
|
||||||
}
|
|
||||||
transferer = ast_strdupa(S_OR(transferer, ""));
|
|
||||||
ast_channel_unlock(chan);
|
ast_channel_unlock(chan);
|
||||||
|
|
||||||
/* Handle the common parking setup stuff */
|
/* Handle the common parking setup stuff */
|
||||||
if (!(parking_bridge = park_application_setup(chan, NULL, data, &silence_announcements))) {
|
if (!(parking_bridge = park_application_setup(chan, NULL, data, &silence_announcements))) {
|
||||||
if (!silence_announcements && !transferer) {
|
if (!silence_announcements && !blind_transfer) {
|
||||||
ast_stream_and_wait(chan, "pbx-parkingfailed", "");
|
ast_stream_and_wait(chan, "pbx-parkingfailed", "");
|
||||||
}
|
}
|
||||||
publish_parked_call_failure(chan);
|
publish_parked_call_failure(chan);
|
||||||
@@ -634,7 +637,6 @@ static int parked_call_app_exec(struct ast_channel *chan, const char *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
lot = parking_lot_find_by_name(lot_name);
|
lot = parking_lot_find_by_name(lot_name);
|
||||||
|
|
||||||
if (!lot) {
|
if (!lot) {
|
||||||
ast_log(LOG_ERROR, "Could not find the requested parking lot\n");
|
ast_log(LOG_ERROR, "Could not find the requested parking lot\n");
|
||||||
ast_stream_and_wait(chan, "pbx-invalidpark", "");
|
ast_stream_and_wait(chan, "pbx-invalidpark", "");
|
||||||
|
@@ -167,7 +167,7 @@ static struct parked_user *generate_parked_user(struct parking_lot *lot, struct
|
|||||||
if (parker_dial_string) {
|
if (parker_dial_string) {
|
||||||
new_parked_user->parker_dial_string = ast_strdup(parker_dial_string);
|
new_parked_user->parker_dial_string = ast_strdup(parker_dial_string);
|
||||||
} else {
|
} else {
|
||||||
if (parked_user_set_parker_dial_string(new_parked_user, parker)) {
|
if (!parker || parked_user_set_parker_dial_string(new_parked_user, parker)) {
|
||||||
ao2_ref(new_parked_user, -1);
|
ao2_ref(new_parked_user, -1);
|
||||||
ao2_unlock(lot);
|
ao2_unlock(lot);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -269,14 +269,11 @@ static int bridge_parking_push(struct ast_bridge_parking *self, struct ast_bridg
|
|||||||
* the park application. It's possible that the channel that transferred it is still alive (particularly
|
* the park application. It's possible that the channel that transferred it is still alive (particularly
|
||||||
* when a multichannel bridge is parked), so try to get the real parker if possible. */
|
* when a multichannel bridge is parked), so try to get the real parker if possible. */
|
||||||
ast_channel_lock(bridge_channel->chan);
|
ast_channel_lock(bridge_channel->chan);
|
||||||
blind_transfer = S_OR(pbx_builtin_getvar_helper(bridge_channel->chan, "BLINDTRANSFER"),
|
blind_transfer = pbx_builtin_getvar_helper(bridge_channel->chan, "BLINDTRANSFER");
|
||||||
ast_channel_name(bridge_channel->chan));
|
blind_transfer = ast_strdupa(S_OR(blind_transfer, ""));
|
||||||
if (blind_transfer) {
|
|
||||||
blind_transfer = ast_strdupa(blind_transfer);
|
|
||||||
}
|
|
||||||
ast_channel_unlock(bridge_channel->chan);
|
ast_channel_unlock(bridge_channel->chan);
|
||||||
|
if ((!parker || parker == bridge_channel->chan)
|
||||||
if (parker == bridge_channel->chan) {
|
&& !ast_strlen_zero(blind_transfer)) {
|
||||||
struct ast_channel *real_parker = ast_channel_get_by_name(blind_transfer);
|
struct ast_channel *real_parker = ast_channel_get_by_name(blind_transfer);
|
||||||
|
|
||||||
if (real_parker) {
|
if (real_parker) {
|
||||||
@@ -300,8 +297,8 @@ static int bridge_parking_push(struct ast_bridge_parking *self, struct ast_bridg
|
|||||||
/* Generate ParkedCall Stasis Message */
|
/* Generate ParkedCall Stasis Message */
|
||||||
publish_parked_call(pu, PARKED_CALL);
|
publish_parked_call(pu, PARKED_CALL);
|
||||||
|
|
||||||
/* If the parkee and the parker are the same and silence_announce isn't set, play the announcement to the parkee */
|
/* If not a blind transfer and silence_announce isn't set, play the announcement to the parkee */
|
||||||
if (!strcmp(blind_transfer, ast_channel_name(bridge_channel->chan)) && !park_datastore->silence_announce) {
|
if (ast_strlen_zero(blind_transfer) && !park_datastore->silence_announce) {
|
||||||
char saynum_buf[16];
|
char saynum_buf[16];
|
||||||
|
|
||||||
snprintf(saynum_buf, sizeof(saynum_buf), "%d %d", 0, pu->parking_space);
|
snprintf(saynum_buf, sizeof(saynum_buf), "%d %d", 0, pu->parking_space);
|
||||||
|
@@ -239,6 +239,7 @@ static struct ast_channel *park_local_transfer(struct ast_channel *parker, const
|
|||||||
ast_channel_parkinglot_set(parkee, ast_channel_parkinglot(parker));
|
ast_channel_parkinglot_set(parkee, ast_channel_parkinglot(parker));
|
||||||
ast_connected_line_copy_from_caller(ast_channel_connected(parkee), ast_channel_caller(parker));
|
ast_connected_line_copy_from_caller(ast_channel_connected(parkee), ast_channel_caller(parker));
|
||||||
ast_channel_inherit_variables(parker, parkee);
|
ast_channel_inherit_variables(parker, parkee);
|
||||||
|
ast_bridge_set_transfer_variables(parkee, ast_channel_name(parker), 0);
|
||||||
ast_channel_datastore_inherit(parker, parkee);
|
ast_channel_datastore_inherit(parker, parkee);
|
||||||
ast_channel_unlock(parker);
|
ast_channel_unlock(parker);
|
||||||
|
|
||||||
@@ -253,8 +254,6 @@ static struct ast_channel *park_local_transfer(struct ast_channel *parker, const
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_bridge_set_transfer_variables(parkee_side_2, ast_channel_name(parker), 0);
|
|
||||||
|
|
||||||
ast_channel_unref(parkee_side_2);
|
ast_channel_unref(parkee_side_2);
|
||||||
|
|
||||||
/* Since the above worked fine now we actually call it and return the channel */
|
/* Since the above worked fine now we actually call it and return the channel */
|
||||||
|
@@ -537,12 +537,12 @@ static int manager_park(struct mansession *s, const struct message *m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ast_strlen_zero(timeout)) {
|
if (!ast_strlen_zero(timeout)) {
|
||||||
if (sscanf(timeout, "%30d", &timeout_override) != 1 || timeout < 0) {
|
if (sscanf(timeout, "%30d", &timeout_override) != 1 || timeout_override < 0) {
|
||||||
astman_send_error(s, m, "Invalid Timeout value.");
|
astman_send_error(s, m, "Invalid Timeout value.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout_override > 0) {
|
if (timeout_override) {
|
||||||
/* If greater than zero, convert to seconds for internal use. Must be >= 1 second. */
|
/* If greater than zero, convert to seconds for internal use. Must be >= 1 second. */
|
||||||
timeout_override = MAX(1, timeout_override / 1000);
|
timeout_override = MAX(1, timeout_override / 1000);
|
||||||
}
|
}
|
||||||
@@ -554,11 +554,11 @@ static int manager_park(struct mansession *s, const struct message *m)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_channel_lock(chan);
|
|
||||||
if (!ast_strlen_zero(timeout_channel)) {
|
if (!ast_strlen_zero(timeout_channel)) {
|
||||||
|
ast_channel_lock(chan);
|
||||||
ast_bridge_set_transfer_variables(chan, timeout_channel, 0);
|
ast_bridge_set_transfer_variables(chan, timeout_channel, 0);
|
||||||
}
|
|
||||||
ast_channel_unlock(chan);
|
ast_channel_unlock(chan);
|
||||||
|
}
|
||||||
|
|
||||||
parker_chan = ast_channel_bridge_peer(chan);
|
parker_chan = ast_channel_bridge_peer(chan);
|
||||||
if (!parker_chan || strcmp(ast_channel_name(parker_chan), timeout_channel)) {
|
if (!parker_chan || strcmp(ast_channel_name(parker_chan), timeout_channel)) {
|
||||||
|
@@ -782,31 +782,21 @@ int parking_lot_cfg_create_extensions(struct parking_lot_cfg *lot_cfg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We need the contexts list locked to safely be able to both read and lock the specific context within */
|
/* We need the contexts list locked to safely be able to both read and lock the specific context within */
|
||||||
if (ast_wrlock_contexts()) {
|
ast_wrlock_contexts();
|
||||||
ast_log(LOG_ERROR, "Failed to lock the contexts list.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(lot_context = ast_context_find_or_create(NULL, NULL, lot_cfg->parking_con, parkext_registrar_pointer))) {
|
if (!(lot_context = ast_context_find_or_create(NULL, NULL, lot_cfg->parking_con, parkext_registrar_pointer))) {
|
||||||
ast_log(LOG_ERROR, "Parking lot '%s' -- Needs a context '%s' which does not exist and Asterisk was unable to create\n",
|
ast_log(LOG_ERROR, "Parking lot '%s' -- Needs a context '%s' which does not exist and Asterisk was unable to create\n",
|
||||||
lot_cfg->name, lot_cfg->parking_con);
|
lot_cfg->name, lot_cfg->parking_con);
|
||||||
if (ast_unlock_contexts()) {
|
ast_unlock_contexts();
|
||||||
ast_assert(0);
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Once we know what context we will be modifying, we need to write lock it because we will be reading extensions
|
/* Once we know what context we will be modifying, we need to write lock it because we will be reading extensions
|
||||||
* and we don't want something else to destroy them while we are looking at them.
|
* and we don't want something else to destroy them while we are looking at them.
|
||||||
*/
|
*/
|
||||||
if (ast_wrlock_context(lot_context)) {
|
ast_wrlock_context(lot_context);
|
||||||
ast_log(LOG_ERROR, "failed to obtain write lock on context\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ast_unlock_contexts()) {
|
ast_unlock_contexts();
|
||||||
ast_assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle generation/confirmation for the Park extension */
|
/* Handle generation/confirmation for the Park extension */
|
||||||
if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, lot_cfg->parking_con, lot_cfg->parkext, 1, NULL, NULL, E_MATCH))) {
|
if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, lot_cfg->parking_con, lot_cfg->parkext, 1, NULL, NULL, E_MATCH))) {
|
||||||
@@ -874,9 +864,7 @@ int parking_lot_cfg_create_extensions(struct parking_lot_cfg *lot_cfg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ast_unlock_context(lot_context)) {
|
ast_unlock_context(lot_context);
|
||||||
ast_assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user