aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_misdn.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_misdn.c')
-rw-r--r--channels/chan_misdn.c118
1 files changed, 12 insertions, 106 deletions
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index a47d1aa7d..fe8033383 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -8504,40 +8504,6 @@ static void release_chan_early(struct chan_list *ch)
/*!
* \internal
- * \brief Copy the source connected line information to the destination for a transfer.
- * \since 1.8
- *
- * \param dest Destination connected line
- * \param src Source connected line
- *
- * \return Nothing
- */
-static void misdn_connected_line_copy_transfer(struct ast_party_connected_line *dest, struct ast_party_connected_line *src)
-{
- struct ast_party_connected_line connected;
-
- connected = *src;
- connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
-
- /* Make sure empty strings will be erased. */
- if (!connected.id.name.str) {
- connected.id.name.str = "";
- }
- if (!connected.id.number.str) {
- connected.id.number.str = "";
- }
- if (!connected.id.subaddress.str) {
- connected.id.subaddress.str = "";
- }
- if (!connected.id.tag) {
- connected.id.tag = "";
- }
-
- ast_party_connected_line_copy(dest, &connected);
-}
-
-/*!
- * \internal
* \brief Attempt to transfer the active channel party to the held channel party.
*
* \param active_ch Channel currently connected.
@@ -8585,95 +8551,35 @@ static int misdn_attempt_transfer(struct chan_list *active_ch, struct chan_list
held_ch->ast->name, target->name);
ast_party_connected_line_init(&target_colp);
- misdn_connected_line_copy_transfer(&target_colp, &target->connected);
+ ast_party_connected_line_copy(&target_colp, &target->connected);
ast_party_connected_line_init(&transferee_colp);
- misdn_connected_line_copy_transfer(&transferee_colp, &held_ch->ast->connected);
+ ast_party_connected_line_copy(&transferee_colp, &held_ch->ast->connected);
held_ch->hold.state = MISDN_HOLD_TRANSFER;
/*
* Before starting a masquerade, all channel and pvt locks must
* be unlocked. Any recursive channel locks held before
- * ast_channel_masquerade() invalidates deadlock avoidance. Any
- * recursive channel locks held before ast_do_masquerade()
- * invalidates channel container locking order. Since we are
- * unlocking both the pvt and its owner channel it is possible
- * for "target" and "transferee" to be destroyed by their pbx
- * threads. To prevent this we must give "target" and
- * "transferee" a reference before any unlocking takes place.
+ * ast_channel_transfer_masquerade() invalidates deadlock
+ * avoidance. Since we are unlocking both the pvt and its owner
+ * channel it is possible for "target" and "transferee" to be
+ * destroyed by their pbx threads. To prevent this we must give
+ * "target" and "transferee" a reference before any unlocking
+ * takes place.
*/
ao2_ref(target, +1);
ao2_ref(transferee, +1);
ast_channel_unlock(held_ch->ast);
ast_channel_unlock(active_ch->ast);
- /* Release hold on the transferee channel. */
- ast_indicate(transferee, AST_CONTROL_UNHOLD);
-
/* Setup transfer masquerade. */
- retval = ast_channel_masquerade(target, transferee);
- if (retval) {
- /* Masquerade setup failed. */
- ast_party_connected_line_free(&target_colp);
- ast_party_connected_line_free(&transferee_colp);
- ao2_ref(target, -1);
- ao2_ref(transferee, -1);
- return -1;
- }
- ao2_ref(transferee, -1);
-
- /*
- * Make sure masquerade is complete.
- *
- * After the masquerade, the "target" channel pointer actually
- * points to the new transferee channel and the bridged channel
- * is still the intended target of the transfer.
- *
- * By manually completing the masquerade, we can send connected
- * line updates where they need to go.
- */
- ast_do_masquerade(target);
-
- /* Transfer COLP between target and transferee channels. */
- {
- /*
- * Since "target" may not actually be bridged to another
- * channel, there is no way for us to queue a frame so that its
- * connected line status will be updated. Instead, we use the
- * somewhat hackish approach of using a special control frame
- * type that instructs ast_read() to perform a specific action.
- * In this case, the frame we queue tells ast_read() to call the
- * connected line interception macro configured for "target".
- */
- struct ast_control_read_action_payload *frame_payload;
- int payload_size;
- int frame_size;
- unsigned char connected_line_data[1024];
-
- payload_size = ast_connected_line_build_data(connected_line_data,
- sizeof(connected_line_data), &target_colp, NULL);
- if (payload_size != -1) {
- frame_size = payload_size + sizeof(*frame_payload);
- frame_payload = alloca(frame_size);
- frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
- frame_payload->payload_size = payload_size;
- memcpy(frame_payload->payload, connected_line_data, payload_size);
- ast_queue_control_data(target, AST_CONTROL_READ_ACTION, frame_payload,
- frame_size);
- }
- /*
- * In addition to queueing the read action frame so that the
- * connected line info on "target" will be updated, we also
- * are going to queue a plain old connected line update on
- * "target" to update the target channel.
- */
- ast_channel_queue_connected_line_update(target, &transferee_colp, NULL);
- }
+ retval = ast_channel_transfer_masquerade(target, &target_colp, 0,
+ transferee, &transferee_colp, 1);
ast_party_connected_line_free(&target_colp);
ast_party_connected_line_free(&transferee_colp);
-
ao2_ref(target, -1);
- return 0;
+ ao2_ref(transferee, -1);
+ return retval;
}