mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 11:25:35 +00:00
ari/pjsip: Make it possible to control transfers through ARI
Introduce a ChannelTransfer event and the ability to notify progress to
ARI. Implement emitting this event from the PJSIP channel instead of
handling the transfer in Asterisk when configured.
Introduce a dialplan function to the PJSIP channel to switch between the
"core" and "ari-only" behavior.
UserNote: Call transfers on the PJSIP channel can now be controlled by
ARI. This can be enabled by using the PJSIP_TRANSFER_HANDLING(ari-only)
dialplan function.
(cherry picked from commit 71eb8a262f
)
This commit is contained in:
committed by
Asterisk Development Team
parent
007e281313
commit
0e8bde6bde
58
main/refer.c
58
main/refer.c
@@ -35,6 +35,8 @@
|
||||
#include "asterisk/datastore.h"
|
||||
#include "asterisk/pbx.h"
|
||||
#include "asterisk/manager.h"
|
||||
#include "asterisk/stasis_bridges.h"
|
||||
#include "asterisk/stasis_channels.h"
|
||||
#include "asterisk/strings.h"
|
||||
#include "asterisk/astobj2.h"
|
||||
#include "asterisk/vector.h"
|
||||
@@ -535,3 +537,59 @@ int ast_refer_init(void)
|
||||
ast_register_cleanup(refer_shutdown);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ast_refer_notify_transfer_request(struct ast_channel *source, const char *referred_by,
|
||||
const char *exten, const char *protocol_id,
|
||||
struct ast_channel *dest, struct ast_refer_params *params,
|
||||
enum ast_control_transfer state)
|
||||
{
|
||||
RAII_VAR(struct ast_ari_transfer_message *, transfer_message, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct ast_bridge *, source_bridge, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct ast_bridge *, dest_bridge, NULL, ao2_cleanup);
|
||||
|
||||
transfer_message = ast_ari_transfer_message_create(source, referred_by, exten, protocol_id, dest, params, state);
|
||||
if (!transfer_message) {
|
||||
return -1;
|
||||
}
|
||||
source_bridge = ast_bridge_transfer_acquire_bridge(source);
|
||||
if (source_bridge) {
|
||||
RAII_VAR(struct ast_channel *, peer, NULL, ast_channel_cleanup);
|
||||
|
||||
ast_bridge_lock(source_bridge);
|
||||
transfer_message->source_bridge = ast_bridge_get_snapshot(source_bridge);
|
||||
peer = ast_bridge_peer_nolock(source_bridge, source);
|
||||
if (peer) {
|
||||
ast_channel_lock(peer);
|
||||
transfer_message->source_peer = ao2_bump(ast_channel_snapshot(peer));
|
||||
ast_channel_unlock(peer);
|
||||
}
|
||||
ast_bridge_unlock(source_bridge);
|
||||
}
|
||||
|
||||
if (dest) {
|
||||
dest_bridge = ast_bridge_transfer_acquire_bridge(dest);
|
||||
if (dest_bridge) {
|
||||
RAII_VAR(struct ast_channel *, peer, NULL, ast_channel_cleanup);
|
||||
|
||||
ast_bridge_lock(dest_bridge);
|
||||
transfer_message->dest_bridge = ast_bridge_get_snapshot(dest_bridge);
|
||||
peer = ast_bridge_peer_nolock(dest_bridge, dest);
|
||||
if (peer) {
|
||||
ast_channel_lock(peer);
|
||||
transfer_message->dest_peer = ao2_bump(ast_channel_snapshot(peer));
|
||||
ast_channel_unlock(peer);
|
||||
}
|
||||
ast_bridge_unlock(dest_bridge);
|
||||
}
|
||||
}
|
||||
|
||||
msg = stasis_message_create(ast_channel_transfer_request_type(), transfer_message);
|
||||
if (msg) {
|
||||
ast_channel_lock(source);
|
||||
stasis_publish(ast_channel_topic(source), msg);
|
||||
ast_channel_unlock(source);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user