diff options
-rw-r--r-- | include/asterisk/channel.h | 47 | ||||
-rw-r--r-- | main/bridging.c | 120 | ||||
-rw-r--r-- | main/channel.c | 232 | ||||
-rw-r--r-- | main/channel_internal_api.c | 9 |
4 files changed, 133 insertions, 275 deletions
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index bc8358d44..77629b7a8 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -2035,52 +2035,6 @@ int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1); int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone); /*! - * \brief Setup a masquerade to transfer a call. - * \since 1.8 - * - * \param target_chan Target of the call transfer. (Masquerade original channel) - * \param target_id New connected line information for the target channel. - * \param target_held TRUE if the target call is on hold. - * \param transferee_chan Transferee of the call transfer. (Masquerade clone channel) - * \param transferee_id New connected line information for the transferee channel. - * \param transferee_held TRUE if the transferee call is on hold. - * - * \details - * Party A - Transferee - * Party B - Transferer - * Party C - Target of transfer - * - * Party B transfers A to C. - * - * Party A is connected to bridged channel B1. - * Party B is connected to channels C1 and C2. - * Party C is connected to bridged channel B2. - * - * Party B -- C1 == B1 -- Party A - * __/ - * / - * Party B -- C2 == B2 -- Party C - * - * Bridged channel B1 is masqueraded into channel C2. Where B1 - * is the masquerade clone channel and C2 is the masquerade - * original channel. - * - * \see ast_channel_masquerade() - * - * \note Has the same locking requirements as ast_channel_masquerade(). - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_channel_transfer_masquerade( - struct ast_channel *target_chan, - const struct ast_party_connected_line *target_id, - int target_held, - struct ast_channel *transferee_chan, - const struct ast_party_connected_line *transferee_id, - int transferee_held); - -/*! * \brief Gives the string form of a given cause code. * * \param state cause to get the description of @@ -4023,6 +3977,7 @@ struct ast_frame *ast_channel_dtmff(struct ast_channel *chan); struct ast_jb *ast_channel_jb(struct ast_channel *chan); struct ast_party_caller *ast_channel_caller(struct ast_channel *chan); struct ast_party_connected_line *ast_channel_connected(struct ast_channel *chan); +struct ast_party_connected_line *ast_channel_connected_indicated(struct ast_channel *chan); struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan); struct ast_party_dialed *ast_channel_dialed(struct ast_channel *chan); struct ast_party_redirecting *ast_channel_redirecting(struct ast_channel *chan); diff --git a/main/bridging.c b/main/bridging.c index 38ec43195..7738bd30d 100644 --- a/main/bridging.c +++ b/main/bridging.c @@ -608,6 +608,52 @@ static void bridge_dissolve_check_stolen(struct ast_bridge *bridge, struct ast_b /*! * \internal + * \brief Update connected line information after a bridge has been reconfigured. + * + * \param bridge The bridge itself. + * + * \return Nothing + */ +static void bridge_reconfigured_connected_line_update(struct ast_bridge *bridge) +{ + struct ast_party_connected_line connected; + struct ast_bridge_channel *bridge_channel = AST_LIST_FIRST(&bridge->channels), *peer; + unsigned char data[1024]; + size_t datalen; + + if (!bridge_channel || + !(bridge->technology->capabilities & (AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_NATIVE)) || + !(peer = ast_bridge_channel_peer(bridge_channel)) || + ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_ZOMBIE) || + ast_test_flag(ast_channel_flags(peer->chan), AST_FLAG_ZOMBIE) || + ast_check_hangup_locked(bridge_channel->chan) || + ast_check_hangup_locked(peer->chan)) { + return; + } + + ast_party_connected_line_init(&connected); + + ast_channel_lock(bridge_channel->chan); + ast_connected_line_copy_from_caller(&connected, ast_channel_caller(bridge_channel->chan)); + ast_channel_unlock(bridge_channel->chan); + + if ((datalen = ast_connected_line_build_data(data, sizeof(data), &connected, NULL)) != (size_t) -1) { + ast_bridge_channel_queue_control_data(peer, AST_CONTROL_CONNECTED_LINE, data, datalen); + } + + ast_channel_lock(peer->chan); + ast_connected_line_copy_from_caller(&connected, ast_channel_caller(peer->chan)); + ast_channel_unlock(peer->chan); + + if ((datalen = ast_connected_line_build_data(data, sizeof(data), &connected, NULL)) != (size_t) -1) { + ast_bridge_channel_queue_control_data(bridge_channel, AST_CONTROL_CONNECTED_LINE, data, datalen); + } + + ast_party_connected_line_free(&connected); +} + +/*! + * \internal * \brief Pull the bridge channel out of its current bridge. * \since 12.0.0 * @@ -1240,8 +1286,6 @@ static void bridge_handle_trip(struct ast_bridge_channel *bridge_channel) break; } -/* BUGBUG bridge join or impart needs to do CONNECTED_LINE updates if the channels are being swapped and it is a 1-1 bridge. */ - /* Simply write the frame out to the bridge technology. */ /* BUGBUG The tech is where AST_CONTROL_ANSWER hook should go. (early bridge) */ /* BUGBUG The tech is where incoming BUSY/CONGESTION hangup should happen? (early bridge) */ @@ -2241,6 +2285,7 @@ static void set_bridge_peer_vars(struct ast_bridge *bridge) * \since 12.0.0 * * \param bridge Reconfigured bridge. + * \param colp_update Whether to perform COLP updates. * * \details * After a series of bridge_channel_push and @@ -2252,7 +2297,7 @@ static void set_bridge_peer_vars(struct ast_bridge *bridge) * * \return Nothing */ -static void bridge_reconfigured(struct ast_bridge *bridge) +static void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update) { if (!bridge->reconfigured) { return; @@ -2272,6 +2317,10 @@ static void bridge_reconfigured(struct ast_bridge *bridge) check_bridge_play_sounds(bridge); set_bridge_peer_vars(bridge); ast_bridge_publish_state(bridge); + + if (colp_update) { + bridge_reconfigured_connected_line_update(bridge); + } } /*! @@ -2562,10 +2611,37 @@ static void bridge_channel_blind_transfer(struct ast_bridge_channel *bridge_chan static void after_bridge_move_channel(struct ast_channel *chan_bridged, void *data) { RAII_VAR(struct ast_channel *, chan_target, data, ao2_cleanup); + struct ast_party_connected_line connected_target; + unsigned char connected_line_data[1024]; + int payload_size; + + ast_party_connected_line_init(&connected_target); + + ast_channel_lock(chan_target); + ast_party_connected_line_copy(&connected_target, ast_channel_connected(chan_target)); + ast_channel_unlock(chan_target); + ast_party_id_reset(&connected_target.priv); if (ast_channel_move(chan_target, chan_bridged)) { ast_softhangup(chan_target, AST_SOFTHANGUP_DEV); + ast_party_connected_line_free(&connected_target); + return; } + + if ((payload_size = ast_connected_line_build_data(connected_line_data, + sizeof(connected_line_data), &connected_target, NULL)) != -1) { + struct ast_control_read_action_payload *frame_payload; + int frame_size; + + frame_size = payload_size + sizeof(*frame_payload); + frame_payload = ast_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(chan_target, AST_CONTROL_READ_ACTION, frame_payload, frame_size); + } + + ast_party_connected_line_free(&connected_target); } static void after_bridge_move_channel_fail(enum ast_after_bridge_cb_reason reason, void *data) @@ -2891,7 +2967,7 @@ static void bridge_channel_wait(struct ast_bridge_channel *bridge_channel) ast_channel_clear_softhangup(bridge_channel->chan, AST_SOFTHANGUP_UNBRIDGE); ast_bridge_channel_lock_bridge(bridge_channel); bridge_channel->bridge->reconfigured = 1; - bridge_reconfigured(bridge_channel->bridge); + bridge_reconfigured(bridge_channel->bridge, 0); ast_bridge_unlock(bridge_channel->bridge); } ast_bridge_channel_lock(bridge_channel); @@ -3008,7 +3084,7 @@ static void bridge_channel_join(struct ast_bridge_channel *bridge_channel) if (bridge_channel_push(bridge_channel)) { ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP); } - bridge_reconfigured(bridge_channel->bridge); + bridge_reconfigured(bridge_channel->bridge, 1); if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) { /* @@ -3032,7 +3108,7 @@ static void bridge_channel_join(struct ast_bridge_channel *bridge_channel) } bridge_channel_pull(bridge_channel); - bridge_reconfigured(bridge_channel->bridge); + bridge_reconfigured(bridge_channel->bridge, 1); ast_bridge_unlock(bridge_channel->bridge); @@ -3692,7 +3768,7 @@ void ast_bridge_notify_masquerade(struct ast_channel *chan) /* BUGBUG this needs more work. The channels need to be made compatible again if the formats change. The bridge_channel thread needs to monitor for this case. */ /* The channel we want to notify is still in a bridge. */ bridge->v_table->notify_masquerade(bridge, bridge_channel); - bridge_reconfigured(bridge); + bridge_reconfigured(bridge, 1); } ast_bridge_unlock(bridge); ao2_ref(bridge_channel, -1); @@ -3990,7 +4066,8 @@ static void bridge_channel_change_bridge(struct ast_bridge_channel *bridge_chann * This moves the channels in src_bridge into the bridge pointed * to by dst_bridge. */ -static void bridge_merge_do(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_bridge_channel **kick_me, unsigned int num_kick) +static void bridge_merge_do(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_bridge_channel **kick_me, unsigned int num_kick, + unsigned int optimized) { struct ast_bridge_channel *bridge_channel; unsigned int idx; @@ -4061,8 +4138,8 @@ static void bridge_merge_do(struct ast_bridge *dst_bridge, struct ast_bridge *sr } } - bridge_reconfigured(dst_bridge); - bridge_reconfigured(src_bridge); + bridge_reconfigured(dst_bridge, !optimized); + bridge_reconfigured(src_bridge, !optimized); ast_debug(1, "Merged bridge %s into bridge %s\n", src_bridge->uniqueid, dst_bridge->uniqueid); @@ -4230,7 +4307,7 @@ static int bridge_merge_locked(struct ast_bridge *dst_bridge, struct ast_bridge } } - bridge_merge_do(merge.dest, merge.src, kick_them, num_kick); + bridge_merge_do(merge.dest, merge.src, kick_them, num_kick, 0); return 0; } @@ -4262,7 +4339,8 @@ int ast_bridge_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridg * \retval 0 on success. * \retval -1 on failure. */ -static int bridge_move_do(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery) +static int bridge_move_do(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery, + unsigned int optimized) { struct ast_bridge *orig_bridge; int was_in_bridge; @@ -4287,7 +4365,7 @@ static int bridge_move_do(struct ast_bridge *dst_bridge, struct ast_bridge_chann * The channel died as a result of being pulled. Leave it * pointing to the original bridge. */ - bridge_reconfigured(orig_bridge); + bridge_reconfigured(orig_bridge, 0); return -1; } @@ -4310,8 +4388,8 @@ static int bridge_move_do(struct ast_bridge *dst_bridge, struct ast_bridge_chann res = -1; } - bridge_reconfigured(dst_bridge); - bridge_reconfigured(orig_bridge); + bridge_reconfigured(dst_bridge, !optimized); + bridge_reconfigured(orig_bridge, !optimized); ao2_ref(orig_bridge, -1); return res; } @@ -4390,7 +4468,7 @@ static int bridge_move_locked(struct ast_bridge *dst_bridge, struct ast_bridge * } bridge_channel->swap = swap; - return bridge_move_do(dst_bridge, bridge_channel, attempt_recovery); + return bridge_move_do(dst_bridge, bridge_channel, attempt_recovery, 0); } int ast_bridge_move(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery) @@ -4724,7 +4802,7 @@ static int try_swap_optimize_out(struct ast_bridge *chan_bridge, ast_set_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN); } other->swap = dst_bridge_channel->chan; - if (!bridge_move_do(dst_bridge, other, 1)) { + if (!bridge_move_do(dst_bridge, other, 1, 1)) { ast_bridge_change_state(src_bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP); res = -1; if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) { @@ -4836,7 +4914,7 @@ static int try_merge_optimize_out(struct ast_bridge *chan_bridge, pvt->callbacks->optimization_started(pvt); ast_set_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN); } - bridge_merge_do(merge.dest, merge.src, kick_me, ARRAY_LEN(kick_me)); + bridge_merge_do(merge.dest, merge.src, kick_me, ARRAY_LEN(kick_me), 1); if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) { pvt->callbacks->optimization_finished(pvt); } @@ -6481,7 +6559,7 @@ static enum ast_transfer_result bridge_swap_attended_transfer(struct ast_bridge && !ast_test_flag(&bridged_to_source->features->feature_flags, AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE)) { bridged_to_source->swap = swap_channel; - if (bridge_move_do(dest_bridge, bridged_to_source, 1)) { + if (bridge_move_do(dest_bridge, bridged_to_source, 1, 0)) { return AST_BRIDGE_TRANSFER_FAIL; } /* Must kick the source channel out of its bridge. */ @@ -6537,12 +6615,12 @@ static enum ast_transfer_result two_bridge_attended_transfer(struct ast_channel goto end; case AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE: final_bridge = to_transferee_bridge; - bridge_merge_do(to_transferee_bridge, to_target_bridge, kick_me, ARRAY_LEN(kick_me)); + bridge_merge_do(to_transferee_bridge, to_target_bridge, kick_me, ARRAY_LEN(kick_me), 0); res = AST_BRIDGE_TRANSFER_SUCCESS; goto end; case AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE: final_bridge = to_target_bridge; - bridge_merge_do(to_target_bridge, to_transferee_bridge, kick_me, ARRAY_LEN(kick_me)); + bridge_merge_do(to_target_bridge, to_transferee_bridge, kick_me, ARRAY_LEN(kick_me), 0); res = AST_BRIDGE_TRANSFER_SUCCESS; goto end; case AST_BRIDGE_OPTIMIZE_PROHIBITED: diff --git a/main/channel.c b/main/channel.c index 2d73bf112..f2519c40f 100644 --- a/main/channel.c +++ b/main/channel.c @@ -892,6 +892,7 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char ast_party_dialed_init(ast_channel_dialed(tmp)); ast_party_caller_init(ast_channel_caller(tmp)); ast_party_connected_line_init(ast_channel_connected(tmp)); + ast_party_connected_line_init(ast_channel_connected_indicated(tmp)); ast_party_redirecting_init(ast_channel_redirecting(tmp)); if (cid_name) { @@ -2284,6 +2285,7 @@ static void ast_channel_destructor(void *obj) ast_party_dialed_free(ast_channel_dialed(chan)); ast_party_caller_free(ast_channel_caller(chan)); ast_party_connected_line_free(ast_channel_connected(chan)); + ast_party_connected_line_free(ast_channel_connected_indicated(chan)); ast_party_redirecting_free(ast_channel_redirecting(chan)); /* Close pipes if appropriate */ @@ -2366,6 +2368,7 @@ static void ast_dummy_channel_destructor(void *obj) ast_party_dialed_free(ast_channel_dialed(chan)); ast_party_caller_free(ast_channel_caller(chan)); ast_party_connected_line_free(ast_channel_connected(chan)); + ast_party_connected_line_free(ast_channel_connected_indicated(chan)); ast_party_redirecting_free(ast_channel_redirecting(chan)); /* loop over the variables list, freeing all data and deleting list items */ @@ -2648,7 +2651,7 @@ int ast_hangup(struct ast_channel *chan) * * NOTE: We must hold the channel lock after testing for a * pending masquerade and setting the channel as a zombie to - * prevent __ast_channel_masquerade() from setting up a + * prevent ast_channel_masquerade() from setting up a * masquerade with a dead channel. */ while (ast_channel_masq(chan)) { @@ -4404,6 +4407,8 @@ int ast_indicate_data(struct ast_channel *chan, int _condition, case AST_CONTROL_CONNECTED_LINE: { struct ast_party_connected_line connected; + unsigned char current[1024], proposed[1024]; + int current_size, proposed_size; ast_party_connected_line_set_init(&connected, ast_channel_connected(chan)); res = ast_connected_line_parse_data(data, datalen, &connected); @@ -4411,6 +4416,23 @@ int ast_indicate_data(struct ast_channel *chan, int _condition, ast_channel_set_connected_line(chan, &connected, NULL); } ast_party_connected_line_free(&connected); + + current_size = ast_connected_line_build_data(current, sizeof(current), + ast_channel_connected_indicated(chan), NULL); + proposed_size = ast_connected_line_build_data(proposed, sizeof(proposed), + ast_channel_connected(chan), NULL); + + if (current_size == -1 || proposed_size == -1) { + goto indicate_cleanup; + } + + if (!res && current_size == proposed_size && + !memcmp(current, proposed, current_size)) { + goto indicate_cleanup; + } + + ast_party_connected_line_copy(ast_channel_connected_indicated(chan), + ast_channel_connected(chan)); } break; @@ -6114,7 +6136,7 @@ int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *pe return rc; } -static int __ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clonechan, struct ast_datastore *xfer_ds) +int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clonechan) { int res = -1; @@ -6143,9 +6165,6 @@ static int __ast_channel_masquerade(struct ast_channel *original, struct ast_cha if (!ast_channel_masqr(original) && !ast_channel_masq(original) && !ast_channel_masq(clonechan) && !ast_channel_masqr(clonechan)) { ast_channel_masq_set(original, clonechan); ast_channel_masqr_set(clonechan, original); - if (xfer_ds) { - ast_channel_datastore_add(original, xfer_ds); - } ast_queue_frame(original, &ast_null_frame); ast_queue_frame(clonechan, &ast_null_frame); ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", ast_channel_name(clonechan), ast_channel_name(original)); @@ -6171,121 +6190,6 @@ static int __ast_channel_masquerade(struct ast_channel *original, struct ast_cha return res; } -int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone) -{ - return __ast_channel_masquerade(original, clone, NULL); -} - -/*! - * \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 party_connected_line_copy_transfer(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src) -{ - struct ast_party_connected_line connected; - - connected = *((struct ast_party_connected_line *) 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); -} - -/*! Transfer masquerade connected line exchange data. */ -struct xfer_masquerade_ds { - /*! New ID for the target of the transfer (Masquerade original channel) */ - struct ast_party_connected_line target_id; - /*! New ID for the transferee of the transfer (Masquerade clone channel) */ - struct ast_party_connected_line transferee_id; - /*! TRUE if the target call is held. (Masquerade original channel) */ - int target_held; - /*! TRUE if the transferee call is held. (Masquerade clone channel) */ - int transferee_held; -}; - -/*! - * \internal - * \brief Destroy the transfer connected line exchange datastore information. - * \since 1.8 - * - * \param data The datastore payload to destroy. - * - * \return Nothing - */ -static void xfer_ds_destroy(void *data) -{ - struct xfer_masquerade_ds *ds = data; - - ast_party_connected_line_free(&ds->target_id); - ast_party_connected_line_free(&ds->transferee_id); - ast_free(ds); -} - -static const struct ast_datastore_info xfer_ds_info = { - .type = "xfer_colp", - .destroy = xfer_ds_destroy, -}; - -/* - * BUGBUG ast_channel_transfer_masquerade() can be deleted when bridging COLP has been reimplemented. - * - * ast_bridge_transfer_attended() will need to do something like - * this when it has to do a masquerade into an application. - */ -int ast_channel_transfer_masquerade( - struct ast_channel *target_chan, - const struct ast_party_connected_line *target_id, - int target_held, - struct ast_channel *transferee_chan, - const struct ast_party_connected_line *transferee_id, - int transferee_held) -{ - struct ast_datastore *xfer_ds; - struct xfer_masquerade_ds *xfer_colp; - int res; - - xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL); - if (!xfer_ds) { - return -1; - } - - xfer_colp = ast_calloc(1, sizeof(*xfer_colp)); - if (!xfer_colp) { - ast_datastore_free(xfer_ds); - return -1; - } - party_connected_line_copy_transfer(&xfer_colp->target_id, target_id); - xfer_colp->target_held = target_held; - party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id); - xfer_colp->transferee_held = transferee_held; - xfer_ds->data = xfer_colp; - - res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds); - if (res) { - ast_datastore_free(xfer_ds); - } - return res; -} - /*! \brief this function simply changes the name of the channel and issues a manager_event * with out unlinking and linking the channel from the ao2_container. This should * only be used when the channel has already been unlinked from the ao2_container. @@ -6444,62 +6348,6 @@ void ast_channel_name_to_dial_string(char *channel_name) } /*! - * \internal - * \brief Transfer COLP between target and transferee channels. - * \since 1.8 - * - * \param transferee Transferee channel to exchange connected line information. - * \param colp Connected line information to exchange. - * - * \return Nothing - */ -static void masquerade_colp_transfer(struct ast_channel *transferee, struct xfer_masquerade_ds *colp) -{ - struct ast_control_read_action_payload *frame_payload; - int payload_size; - int frame_size; - unsigned char connected_line_data[1024]; - - /* Release any hold on the target. */ - if (colp->target_held) { - ast_queue_unhold(transferee); - } - - /* - * Since transferee 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 transferee. - */ - - /* Reset any earlier private connected id representation */ - ast_party_id_reset(&colp->target_id.priv); - ast_party_id_reset(&colp->transferee_id.priv); - - payload_size = ast_connected_line_build_data(connected_line_data, - sizeof(connected_line_data), &colp->target_id, NULL); - if (payload_size != -1) { - frame_size = payload_size + sizeof(*frame_payload); - frame_payload = ast_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(transferee, AST_CONTROL_READ_ACTION, frame_payload, - frame_size); - } - /* - * In addition to queueing the read action frame so that the - * connected line info on transferee will be updated, we also are - * going to queue a plain old connected line update on transferee to - * update the target. - */ - ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL); -} - -/*! * \brief Masquerade a channel * * \note Assumes _NO_ channels and _NO_ channel pvt's are locked. If a channel is locked while calling @@ -6524,8 +6372,6 @@ void ast_do_masquerade(struct ast_channel *original) } exchange; struct ast_channel *clonechan, *chans[2]; struct ast_channel *bridged; - struct ast_datastore *xfer_ds; - struct xfer_masquerade_ds *xfer_colp; struct ast_format rformat; struct ast_format wformat; struct ast_format tmp_format; @@ -6593,15 +6439,6 @@ void ast_do_masquerade(struct ast_channel *original) ao2_unlink(channels, original); ao2_unlink(channels, clonechan); - /* Get any transfer masquerade connected line exchange data. */ - xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL); - if (xfer_ds) { - ast_channel_datastore_remove(original, xfer_ds); - xfer_colp = xfer_ds->data; - } else { - xfer_colp = NULL; - } - /* * Stop any visible indication on the original channel so we can * transfer it to the clonechan taking the original's place. @@ -6610,14 +6447,6 @@ void ast_do_masquerade(struct ast_channel *original) ast_channel_unlock(original); ast_indicate(original, -1); - /* - * Release any hold on the transferee channel before going any - * further with the masquerade. - */ - if (xfer_colp && xfer_colp->transferee_held) { - ast_indicate(clonechan, AST_CONTROL_UNHOLD); - } - /* Start the masquerade channel contents rearangement. */ ast_channel_lock_both(original, clonechan); @@ -6948,19 +6777,6 @@ void ast_do_masquerade(struct ast_channel *original) } ast_indicate(original, AST_CONTROL_SRCCHANGE); - if (xfer_colp) { - /* - * After the masquerade, the original channel pointer actually - * points to the new transferee channel and the bridged channel - * is still the intended transfer target party. - */ - masquerade_colp_transfer(original, xfer_colp); - } - - if (xfer_ds) { - ast_datastore_free(xfer_ds); - } - if (!clone_was_zombie) { ao2_link(channels, clonechan); } diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c index bb63eebe1..a1d20871d 100644 --- a/main/channel_internal_api.c +++ b/main/channel_internal_api.c @@ -134,6 +134,11 @@ struct ast_channel { */ struct ast_party_connected_line connected; + /*! + * \brief Channel Connected Line ID information that was last indicated. + */ + struct ast_party_connected_line connected_indicated; + /*! \brief Redirecting/Diversion information */ struct ast_party_redirecting redirecting; @@ -972,6 +977,10 @@ struct ast_party_connected_line *ast_channel_connected(struct ast_channel *chan) { return &chan->connected; } +struct ast_party_connected_line *ast_channel_connected_indicated(struct ast_channel *chan) +{ + return &chan->connected_indicated; +} struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan) { return ast_party_id_merge(&chan->connected.id, &chan->connected.priv); |