
; channel originate Local/s@alice extension s@caller1
; channel originate Local/s@bob extension s@caller2

; Asterisk 18.4, stock Allison Smith en gsm prompts

; DONT_OPTIMIZE and DEBUG_THREADS compiler flags

[public]
exten => 3951234,1,Set(GROUP(testing)=1)
	same => n,GotoIf($[${GROUP_COUNT(1@testing)}=1]?caller1,1:caller2,1)
exten => caller1,1,Gosub(generate-call-file,s,1(Local/${EXTEN}@bridgeaccess,${EXTEN},s))
	same => n,Goto(bridgeaccess,${EXTEN},1)
exten => caller2,1,Gosub(generate-call-file,s,1(Local/${EXTEN}@bridgeaccess,${EXTEN},s))
	same => n,Goto(bridgeaccess,${EXTEN},1)

[bridgeaccess]
exten => _[a-z].,1,ConfBridge(${EXTEN},silentbridge,incogtalker)
	same => n,Hangup()

[caller2]
exten => s,1,Answer()
	same => n,ConfBridge(coincall${trunkid},silentbridge,incoglistener) ; as soon as Bob enters the conference, even though he's muted, back things go down....
	same => n,Hangup()

[generate-call-file]
exten => s,1,System(echo Channel: ${ARG1} >> /tmp/${UNIQUEID}.call)
	same => n,System(echo Context: ${ARG2} >> /tmp/${UNIQUEID}.call)
	same => n,System(echo Extension: ${ARG3} >> /tmp/${UNIQUEID}.call)
	same => n,System(echo Priority: 1 >> /tmp/${UNIQUEID}.call)
	same => n,System(echo Setvar:cointrunkid=${cointrunkid} >> /tmp/${UNIQUEID}.call)
	same => n,System(mv /tmp/${UNIQUEID}.call /var/spool/asterisk/outgoing/)
	same => n,Return()

[caller1]
exten => s,1,Set(__cointrunkid=${EPOCH})
	same => n,Set(DB(coinchannels/${cointrunkid})=${CHANNEL})
	same => n,Set(GLOBAL(trunkid)=${cointrunkid})
	same => n,Gosub(generate-call-file,s,1(Local/${cointrunkid}@bridge-monitor,record-and-process,s)) ; bring detector (which records) into bridge, muted
	same => n,Gosub(generate-call-file,s,1(Local/${cointrunkid}@call-bridge,noise-for-caller,s)) ; bring line noise into bridge
	same => n,ConfBridge(coincall${cointrunkid},silentbridge,incoglistener)
	same => n,SoftHangup(${SHARED(coindetector,${cointrunkchannel})})
	same => n,Return()
exten => h,1,SoftHangup(${SHARED(coindetector,${cointrunkchannel})})

[noise-for-caller]
exten => s,1,Answer()
	same => n(loop),GotoIf($[${GROUP_COUNT(1@testing)}=0]?done)
	same => n,Playback(basic-pbx-ivr-main)
	same => n,Goto(loop)
	same => n(done),Hangup

[call-bridge]
exten => _X!,1,Answer()
	same => n,ConfBridge(coincall${EXTEN},silentbridge,incogtalker)
	same => n,Hangup()

[bridge-monitor]
exten => _X!,1,Answer()
	same => n,Set(cointrunkchannel=${DB(coinchannels/${cointrunkid})})
	same => n,ConfBridge(coincall${EXTEN},silentbridge,incoglistener)
	same => n,Hangup()

[record-and-process] ; listens to conference only, it doesn't need to inject audio INTO it, but it must have a PERFECT audio stream FROM it
exten => s,1,Answer()
	same => n,Wait(10)
	same => n,Set(cointrunkchannel=${DB(coinchannels/${cointrunkid})})
	same => n,Set(SHARED(coindetector,${cointrunkchannel})=${CHANNEL})
	same => n(loop),GotoIf($[${GROUP_COUNT(1@testing)}=0]?done)
	same => n,Set(file=/tmp/${UNIQUEID}-${STRFTIME(${EPOCH},,%s)}.wav)
	same => n,Record(${file},5,5,qx) ; q = quiet, x = ignore terminator keys
	;same => n,NoOp(call script to process audio file)
	same => n,System(rm -rf ${file}) ; done, discard
	same => n,Goto(loop)
	same => n(done),Hangup()
