FOOD FOR THOUGHT Feasibility of Insta-conference

Joined
Jun 18, 2014
Messages
13
Reaction score
6
I'm trying to develop a "quick conference" routine, because some phones have an easy way to conference and some don't. I want a consistent UI across devices, hence this.

The code should grab all the active channels for a given extension and transfer them all to a MeetMe conference, then join that MeetMe conf itself. Then I'd map that to a feature code so users could just do *88 (or whatever) rather than have to initiate a transfer for each line they have active.

Trying to think it through, I dialed into my Asterisk phone from two outside lines and then looked at core show channels and see this:

a) SIP/inboundtg-000000 s@macro-dial:7 Up Dial(SIP/1000
b) SIP/inboundtg-000000 s@macro-dial:7 Up Dial(SIP/1000
c) SIP/1000-000000d6 s@macro-dial:1 Up AppDial((Outgoing Line))
d) SIP/1000-000000d2 s@macro-dial:1 Up AppDial((Outgoing Line))

Makes sense to me: two channels for each leg of the call. I can use channels() to get the list of channels that have 1000- in them and then use ChannelRedirect() to throw them to a place in the dialplan that'll send them to MeetMe(1000).

But then I realized those last two channels (c & d) are the legs going to my softphone, and the ones I want (a & b) are the other two. So I think what I need is to get the ${BRIDGEPEER} for c & d. The following pseudocode forms in my fevered brain:

cList = ${CHANNELS(1000-)}
for each channel...
bridgedchannel = importvars(channel.BRIDGEDPEER)
ChannelRedirect(bridgedchannel,meetme(1000))
end
MeetMe(1000)

And presto, all parties are in a MeetMe conference. Coding in the AEL always takes me longer than I think it should, so I wanted to run this by somebody before I start hacking on it. Not looking for somebody to do the work, just for somebody to say "yeah, that oughta work" or "are you nuts?".
 
Joined
Jun 18, 2014
Messages
13
Reaction score
6
Because I am a strange person, I stayed up late writing code to do this, failed, and here prostrate myself to the community looking for ideas.

I pointed *5 to the following macro.

[macro-instaconf]
; Get the extension (eg 1000) and get all channels for that extension
exten =>s,1,Set(cls=${CHANNELS(${CALLERID(number)})})
; Replace spaces with commas for easier parsing
exten =>s,n,Set(cls=${REPLACE(cls," ",\,)})
exten =>s,n,NoOp(==================== MASTER PROCESSING CHANNELS FOR ${cls} ========================"
; Get the next channel, if blank goto end
exten =>s,n,set(n=1)
exten =>s,n(top),Set(c=${CUT(cls,\,,${n})})
exten =>s,n,GotoIf($["foo${c}"="foo"]?end)
; Get the bridged peer for that channel
exten =>s,n,ImportVar(bc=${c},BRIDGEPEER)
; Save the channel name and original extension to the db
exten =>s,n,Set(dbk=${bc})
exten =>s,n,Set(DB(instaconf/${dbk})=${CALLERID(number)})
; Redirect the bridged channel into an extension that will join a confbridge
exten =>s,n,NoOp(===== INSTACONF MASTER ON ${c} REDIRECTING ${bc}, n=${n} ======)
exten =>s,n,ChannelRedirect(${bc},from-internal-custom,8002,1)
; Increment the counter and go back to process any remaining channels
exten =>s,n,Set(n=$[${n} + 1])
exten =>s,n,Goto(s,top)
; Once we've processed all channels, join the conference
exten =>s,n(end),NoOP()
exten =>s,n,NoOp(==== MASTER JOINING CONF CHANNEL ${CHANNEL} ====)
exten =>s,n,Set(CONFBRIDGE(user,admin)=yes)
exten =>s,n,ConfBridge(${CALLERID(number)})

The 8002 extension the ChannelRedirect points to does this

exten => 8002,1,NoOp(==============INSTACONF BEGIN GUEST ${CHANNEL}==================)
exten => 8002,n,Set(m=${CHANNEL})
; Retrieve the extension number from the database and remove that key from the db
exten => 8002,n,Set(confid=${DB(instaconf/${CHANNEL})})
exten => 8002,n,DBdel(instaconf/${CHANNEL})
; Join the conference
exten => 8002,n,ConfBridge(${confid})
exten => 8002,n,NoOp(==============INSTACONF END GUEST ${CHANNEL}==================)

Then when I call into this from two outside lines and do a *5 from one of them, this happens (cutting out 99% of the output and just showing the NoOp debug lines)

NoOp("SIP/10001-0000006b", "===== MASTER PROCESSING CHANNELS FOR SIP/10001-00000067,SIP/10001-0000006b ========="") in new stack
NoOp("SIP/10001-0000006b", "===== INSTACONF MASTER ON SIP/10001-00000067 REDIRECTING SIP/inboundtg-00000066, n=1 ======") in new stack
NoOp("SIP/10001-0000006b", "===== INSTACONF MASTER ON SIP/10001-0000006b REDIRECTING SIP/inboundtg-0000006a, n=2 ======") in new stack
NoOp("SIP/10001-0000006b", "==== MASTER JOINING CONF CHANNEL SIP/10001-0000006b ====") in new stack
== Spawn extension (from-internal-custom, 8002, 1) exited non-zero on 'SIP/inboundtg-00000066' in macro 'dial'
== Spawn extension (from-internal-custom, 8002, 1) exited non-zero on 'SIP/inboundtg-00000066' NoOp("SIP/inboundtg-00000066", "==============INSTACONF BEGIN GUEST SIP/inboundtg-00000066==================") in new stack

Augh. The redirect is executing (as evidenced by the 2nd and 3rd lines above), but the 8002 only executes once and stops executing at the second-to-last line where it goes to ConfBridge.
 
Joined
Jun 18, 2014
Messages
13
Reaction score
6
Ok, ConfBridge is the fly in the ointment here. Replaced it with:

Dial(SIP/[email protected],60,D(wwwww<host or participant code>#))

And it works! I get two people on the line, *5, and in a few seconds we're all conferenced together. Still some kinks to work out, but I think I'll get there. Next up: implement my own SIP conference bridge so I don't have to use an external one.
 

Members online

Forum statistics

Threads
25,812
Messages
167,763
Members
19,240
Latest member
nikko
Get 3CX - Absolutely Free!

Link up your team and customers Phone System Live Chat Video Conferencing

Hosted or Self-managed. Up to 10 users free forever. No credit card. Try risk free.

3CX
A 3CX Account with that email already exists. You will be redirected to the Customer Portal to sign in or reset your password if you've forgotten it.
Top