Hello,

information available on channels involved in attended transfer is inadequate 
for my purposes, so I have created a function which sets some variables on 
these channels, and also runs transferee and transfer target through dialplan. 
It works, but I am unsure that I did it correctly. Two specific questions of 
note:

1. Do I have to set autoservice_chan parameter in ast_app_exec_sub? I don't 
know what autoservice is.

2. When ast_app_exec_sub is run, the following message appears in debug log:

"Thread LWP 822 is blocking 'PJSIP/444-0000004b', already blocked by thread LWP 
6204 in procedure ast_waitfor_nandfds"

I am using fast AGI, and I assume this happens when AGI app is called from 
dialplan. Is there a way to avoid this?

The function follows (I call it from two_bridge_attended_transfer and 
ast_bridge_transfer_attended functions).

/*!
 * \internal
 * \brief Set variables on channels involved in attended transfer and run them 
through dialplan.
 *
 * \param to_transferee The channel that is bridged to the transferee
 * \param to_transfer_target The channel that dialed or is bridged to the 
transfer target(s)
 * \param transferee_channels A two-channel container containing the transferer 
and transferee
 * \param to_target_bridge The bridge between to_transfer_target and the 
transfer_target (NULL if transfer_target did not answer yet)
 *
 * \retval 0 on success.
 * \retval -1 on error.
 */
static int ast_bridge_transfer_attended_to_dialplan(struct ast_channel 
*to_transferee,
                struct ast_channel *to_transfer_target,
                struct ao2_container *transferee_channels, struct ast_bridge 
*to_target_bridge)
{
        RAII_VAR(struct ao2_container *, target_channels, NULL, ao2_cleanup);
        RAII_VAR(struct ast_channel *, transferee, NULL, ao2_cleanup);
        RAII_VAR(struct ast_channel *, transfer_target, NULL, ao2_cleanup);
        const char *to_transferee_name;
        const char *to_transfer_target_name;
        const char *transferee_name;
        const char *dialed_channels;

        transferee = get_transferee(transferee_channels, to_transferee);
        if (!transferee)
                return -1;
        if (to_target_bridge) {
                target_channels = ast_bridge_peers_nolock(to_target_bridge);
                if (!target_channels)
                        return -1;
                transfer_target = get_transferee(target_channels, 
to_transfer_target);
        } else {
                transfer_target = NULL;
        }

        ast_channel_lock(to_transferee);
        ast_channel_lock(to_transfer_target);
        ast_channel_lock(transferee);

        to_transferee_name = ast_strdupa(ast_channel_name(to_transferee));
        to_transfer_target_name = 
ast_strdupa(ast_channel_name(to_transfer_target));
        transferee_name = ast_strdupa(ast_channel_name(transferee));
        dialed_channels = pbx_builtin_getvar_helper(to_transfer_target, 
"DIALEDCHANNELS");

        pbx_builtin_setvar_helper(to_transferee, ATTENDEDTRANSFERER1, 
to_transferee_name);
        pbx_builtin_setvar_helper(to_transferee, ATTENDEDTRANSFERER2, 
to_transfer_target_name);
        ast_channel_unlock(to_transferee);
        pbx_builtin_setvar_helper(to_transfer_target, ATTENDEDTRANSFERER1, 
to_transferee_name);
        pbx_builtin_setvar_helper(to_transfer_target, ATTENDEDTRANSFERER2, 
to_transfer_target_name);
        ast_channel_unlock(to_transfer_target);
        pbx_builtin_setvar_helper(transferee, ATTENDEDTRANSFERER1, 
to_transferee_name);
        pbx_builtin_setvar_helper(transferee, ATTENDEDTRANSFERER2, 
to_transfer_target_name);
        ast_channel_unlock(transferee);

        ast_app_exec_sub(NULL, transferee, "attended_transferee_connect,s,1", 
1);

        if (transfer_target) {
                ast_channel_lock(transfer_target);
                pbx_builtin_setvar_helper(transfer_target, ATTENDEDTRANSFEREE, 
transferee_name);
                pbx_builtin_setvar_helper(transfer_target, ATTENDEDTRANSFERER1, 
to_transferee_name);
                pbx_builtin_setvar_helper(transfer_target, ATTENDEDTRANSFERER2, 
to_transfer_target_name);
                ast_channel_unlock(transfer_target);
                ast_app_exec_sub(NULL, transfer_target, 
"attended_target_connect,s,1", 1);
        } else {
                if (!ast_strlen_zero(dialed_channels)) {
                        char *b_channel_names = ast_strdupa(dialed_channels);
                        char *b_channel_name;
                        while ((b_channel_name = strtok_r(b_channel_names, " ", 
&b_channel_names))) {
                                struct ast_channel *b_channel = 
ast_channel_get_by_name(b_channel_name);
                                if (b_channel) {
                                        ast_channel_lock(b_channel);
                                        pbx_builtin_setvar_helper(b_channel, 
ATTENDEDTRANSFEREE, transferee_name);
                                        pbx_builtin_setvar_helper(b_channel, 
ATTENDEDTRANSFERER1, to_transferee_name);
                                        pbx_builtin_setvar_helper(b_channel, 
ATTENDEDTRANSFERER2, to_transfer_target_name);
                                        ast_channel_unlock(b_channel);
                                        ast_app_exec_sub(NULL, b_channel, 
"attended_target_connect,s,1", 1);
                                        ast_channel_unref(b_channel);
                                }
                        }
                }
        }

        return 0;
}

-- 
Nikša Baldun

Vox Diversa

Sjedište:
IX Trokut 1
10020 Zagreb

Ured:
Ilica 425
10090 Zagreb
Tel.: +385 1 8000676
Web: www.voxdiversa.hr

-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-dev

Reply via email to