Hi, please find attached a rudimentary patch for adding a "call completed elsewhere"-notification for the orginal-called channel in "app_channelredirect".
We use "ChannelRedirect" for call-pickups so that the pickup-phone will ring first instead of directly answering the incoming call. "ChannelRedirect" does exactly what we wanted to have, but it was really disturbing that after a successfully picked-up call the original called device still showed a missed call. And I don't know a way how to inform already ringing channels through Asterisk dialplans about that the call will be completed elsewhere. That patch should work with all available Asterisk versions, but unfortunately is not compatible with existing dialplans as it adds an additional parameter "origCalledChan" before the parameter "label". And "origCalledChan" expects a single channel name, so it's not possible to inform multiple called channels with "AST_CAUSE_ANSWERED_ELSEWHERE" at once at the moment. I have no idea how to get all called channels from a calling channel within the asterisk source code. Maybe someone could give me a hint how to do that properly. A dialplan could look like this then: ---------------------------------------------------------------------------------------------------- [macro-stdexten] ; ARG1 = Exten ; ARG2 = Hint exten = s,1,ExecIf($[${LEN(${CALLERID(RDNIS)})}>2]?SIPAddHeader(History-Info: <sip:${CALLERID(RDNIS)}@[IP]>\;index=1)) exten = s,n,ExecIf($[${LEN(${BLINDTRANSFER})}>2]?SIPAddHeader(History-Info: <sip:${CALLERID(DNID)}@[IP]>\;index=1)) exten = s,n,Set(SrcDevice=${CUT(CHANNEL,-,1)}) exten = s,n,GotoIf($["${EXTENSION_STATE(${ARG1})}" = "NOT_INUSE" | ${REGEX("${SrcDevice}" ${ARG2})}]?s-DIAL,1:s-INUSE,1) exten = s-DIAL,1,Ringing() exten = s-DIAL,n,Wait(1) exten = s-DIAL,n,Set(CalledDevices=${ARG2}) exten = s-DIAL,n,While($["${SET(CalledExten=${SHIFT(CalledDevices,&)})}" != ""]) exten = s-DIAL,n,Set(CalledExten=${CalledExten:4}) exten = s-DIAL,n,Set(DB(CALLERCHAN/${CalledExten})=${CHANNEL}) exten = s-DIAL,n,EndWhile exten = s-DIAL,n,Dial(${ARG2},60,${DIALOPTIONS}) exten = s-DIAL,n,Goto(s-${DIALSTATUS},1) (...) [CallPickup] exten = _**.,1,NoOP(Pickup trial from ${CHANNEL} for ${EXTEN:2}) exten = _**.,n,Set(EXTTOBEPICKUP=${EXTEN:2}) exten = _**.,n,NoOp(-> this device is ${EXTENSION_STATE(${EXTTOBEPICKUP})}) exten = _**.,n,ExecIf($["${EXTENSION_STATE(${EXTTOBEPICKUP})}"!="RINGING"]?Busy()) exten = _**.,n,Set(CALLERCHAN=${DB(CALLERCHAN/${EXTEN:2})}) exten = _**.,n,Set(CALLEDCHANS=${CHANNELS(SIP/${EXTTOBEPICKUP})}) exten = _**.,n,Set(CALLEDCHAN=${CUT(CALLEDCHANS, ,1)}) exten = _**.,n,GotoIf($["${CALLERCHAN}"=""]?CallPickupOldSchool,${EXTEN},1) exten = _**.,n,Answer() exten = _**.,n,SoftHangup(${CHANNEL}) exten = _**.,n,NoOp(this will never be executed) exten = h,1,ChannelRedirect(${CALLERCHAN},${CALLEDCHAN},DLPN_DialPlan1,${CALLERID(num)},1) ----------------------------------------------------------------------------------------------------
--- app_channelredirect.c.orig 2020-12-22 22:00:08.000000000 +0100 +++ app_channelredirect.c 2021-02-05 15:07:22.800149000 +0100 @@ -32,6 +32,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/file.h" +#include "asterisk/causes.h" #include "asterisk/channel.h" #include "asterisk/pbx.h" #include "asterisk/module.h" @@ -46,6 +47,7 @@ </synopsis> <syntax> <parameter name="channel" required="true" /> + <parameter name="origCalledChannel" required="false" /> <parameter name="context" required="false" /> <parameter name="extension" required="false" /> <parameter name="priority" required="true" /> @@ -71,14 +73,16 @@ int res = -1; char *info; struct ast_channel *chan2 = NULL; + struct ast_channel *origChan = NULL; AST_DECLARE_APP_ARGS(args, AST_APP_ARG(channel); + AST_APP_ARG(origCalledChannel); AST_APP_ARG(label); ); if (ast_strlen_zero(data)) { - ast_log(LOG_WARNING, "%s requires an argument (channel,[[context,]exten,]priority)\n", app); + ast_log(LOG_WARNING, "%s requires an argument (channel,origCalledChannel,[[context,]exten,]priority)\n", app); return -1; } @@ -86,7 +90,7 @@ AST_STANDARD_APP_ARGS(args, info); if (ast_strlen_zero(args.channel) || ast_strlen_zero(args.label)) { - ast_log(LOG_WARNING, "%s requires an argument (channel,[[context,]exten,]priority)\n", app); + ast_log(LOG_WARNING, "%s requires an argument (channel,origCalledChannel,[[context,]exten,]priority)\n", app); return -1; } @@ -94,6 +98,19 @@ ast_log(LOG_WARNING, "No such channel: %s\n", args.channel); pbx_builtin_setvar_helper(chan, "CHANNELREDIRECT_STATUS", "NOCHANNEL"); return 0; + } + + if (ast_strlen_zero(args.origCalledChannel)) { + /* ast_log(LOG_WARNING, "No original-called channel supplied - not informing former called channel about the call being completed elsewhere\n"); */ + } else { + if (!(origChan = ast_channel_get_by_name(args.origCalledChannel))) { + ast_log(LOG_WARNING, "No such original-called channel: %s\n", args.origCalledChannel); + pbx_builtin_setvar_helper(chan, "CHANNELREDIRECT_STATUS", "NOCHANNEL"); + return 0; + } else { + ast_channel_hangupcause_set(origChan, AST_CAUSE_ANSWERED_ELSEWHERE); + origChan = ast_channel_unref(origChan); + } } res = ast_async_parseable_goto(chan2, args.label);
-- _____________________________________________________________________ -- 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