Is order of channels shown by Function_CHANNELS consistently newest first?

After originating a PJSIP call, I need to get the channel for that call, so I can end it later in a hangup handler.

So I use CHANNELS In this bit of dialplan:

    same => n,Originate(PJSIP/0203123456@voipfone-205,exten,bcab-bridge-conference,s,1)
    same => n,Verbose(1,***CHANNELS ARE ${CHANNELS()})
    same => n,SET(GLOBAL(chan)=${CHANNELS(PJSIP\/voipfone-205-(.*))})

Now, of course, I get more than one channel shown, like this:

***CHAN WE WANT IS PJSIP/voipfone-205-00000249 PJSIP/voipfone-205-0000024c PJSIP/voipfone-205-0000024d

Assuming I use CUT to trim out the first in the list, can we ALWAYS be absolutely sure that the channel just created by Originate is the highest numbered/first in list?

Otherwise, I’m wondering if there’s a reliable way to get the channel created by originate, when there may be many other active channels on the system, too.

In case anyone’s wondering, I’m using it so that when there is only one party left in a conference, it’ll clear down the newly created external channel.

    same => n,GotoIf($["${CONFBRIDGE_INFO(parties,1234)}" = "1"]?hangchan)
    same => n,Return()   
    same => n(hangchan),SoftHangup(${GLOBAL(chan)})

Why not use GROUP and GROUP_COUNT to keep track of how many users are in your conference?

I’m not sure I’m following - I want to get the name of the newly created channel.
I also want to know how many people are in a particular conference

I don’t see that GROUP_COUNT helps me do either?

You can use GROUP_COUNT to tell how many people are in the conference.

Thank you - but I already have the number of people in the conference from CONFBRIDGE_INFO(parties,1234)

That is not the problem I have - the question is, when listing CHANNELS:

“can we ALWAYS be absolutely sure that the channel just created by Originate is the highest numbered/first in list?”

Listing in Asterisk tend to be traverses of hash tables, so will result in time within hash bucket, order, not pure time order. Without looking a the code I can’t be sure that is doesn’t use a degenerate configuration, with only one hash bucket, for channels.

Thanks David. So I guess that still leaves the question of how I reliably find the correct channel name of the newly originated channel?
I definitely can’t go hanging up the wrong channel!

I assume this relates to Orginate, as there are typically variables in other cases.

If you are using AMI, use an event.

Although uniqueids are supposed to be opaque, they actually increase for every new channel. They can be used instead of the channel name, but they change under different circumstances from the channel name (the latter tracks the channel technology’s underlying name, whereas the former track the actual data structure instance.

Most reliable would be to pass the originating channel and then have the new channel set a global variable or database entry. You can use compound extension numbers to pass information to originated local channels.

Not sure I follow - I’ve been DumpChanneling left right and centre and see nothing which I could use.

Are you saying that there is an undocumented method in SoftHangup which takes an undocumented GUID available from the Originated channel, which could be used to later hangup that originated channeld?

PS - using Dialplan, not AMI.

I’m talking about the third item in the output of dumpchan, which you can use as an alternative name for the channel in all cases where you identify a channel by name. It can change if you do non-trivial things with the call.

However, dumpchan doesn’t give you all the channels, and I’d n normally use interfaces intended for third party control, for that (CLI, AMI).

Also, if you told us your overall goal, there may be easier ways of achieving it. Using Originate is just a way you are thinking of approaching the goal. Hanging up a channel created by originate is not your real goal.

Sure; OK well this explains the overall goal most clearly, which is:

First person that dials in triggers an outgoing call which connects to a web-based ZOOM conference.
First person and Zoom conference are bridged.
Subsequent callers go straight to the conference.
Last caller to hang up their call to Asterisk (meaning 1 channel (the zoom conference) is left in the conference) causes the outgoing call to terminate.

So I asked this question:

Along the way I encountered this issue with incorrect documentation

I then tried phrasing it a different way

After trying every single possible combination of options, it seems that “DIAL” followed by confbridge ended any possible further interaction on that channel.

In fact, the solution became clear from this answer:

As soon as I used Originate rather than DIAL, everything fell into place. Except one thing - DIAL sets:

  • DIALEDPEERNAME - The name of the outbound channel that answered the call.

but Originate doesn’t have an equivalent. But I know I can get a list of CHANNELS - all I need to know is, reliably, which is the channel created by Originate.

If there’s a better way of doing it, I’m very much open to it, but I’ve spent over 40 hours since Aug 3rd, along with help from a former Asterisk dev via email as a second pair of eyes, and no-one over the course of 4 threads and three months has come up with anything closer than “Originate”.

So I’m very definitely receptive to new ideas here! But like I said, the only missing piece for me at this point is getting the correct channel that was Originated.


In case you’re wondering, here’s my dialplan:

exten => s,1,Answer()
    same => n,Set(CONFBRIDGE(user,announce_join_leave)=no)
    same => n,Verbose(1,***NUMBER IN BCAB CONFERENCE IS ${CONFBRIDGE_INFO(parties,1234)})
    same => n,Set(CHANNEL(hangup_handler_push)=bcab-hangup-handler,s,1)
    same => n,Set(CHANNEL(language)=en_GB)    
    same => n,GotoIf($["${CONFBRIDGE_INFO(parties,1234)}" = "0"]?bcab-dial-zoom,s,1)
    same => n,ConfBridge(1234)
exten => s,1,Answer()
    same => n,Originate(PJSIP/0203456789@voipfone-205,exten,bcab-bridge-conference,s,1)
    same => n,SET(tempchans=${CHANNELS(PJSIP\/voipfone-205-(.*))})
    same => n,Verbose(1,***CHANNELS ARE ${tempchans})
    same => n,SET(GLOBAL(chan)=${CUT(tempchans, ,1)})
    same => n,Verbose(1,***CHAN WE WANT IS ${GLOBAL(chan)})
    same => n,ConfBridge(1234)

exten => s,1,Verbose(1,*** Entered bcab-bridge-conference)
    same => n,Answer()
    same => n,SET(PJSIP_DTMF_MODE()=inband)
    same => n,SendDTMF(WW12345678#WWWWW#WW)
    same => n,Playback(technical-support)
    same => n,SendDTMF(#)
    same => n,ConfBridge(1234)

exten => s,1,Verbose(1, **** BCAB HANGUP HANDLER)
    same => n,Verbose(1,***NUMBER IN CONFERENCE IS ${CONFBRIDGE_INFO(parties,1234)})
    same => n,GotoIf($["${CONFBRIDGE_INFO(parties,1234)}" = "1"]?hangchan)
    same => n,Return()   
    same => n(hangchan),SoftHangup(${GLOBAL(chan)}) 
    same => n,Return()        
1 Like

That’s quite complex, and it is clear you are operating outside the intended usage of conferences by effectively wanting the conference to hangup a participant, when it is designed to work the other way.

However, a very quick skim suggests to me that there is only ever one such conference, so there is no problem in managing global variables, so you should just have the channel that is going to upstream conference store its name or unique-ID (neither should change in this application) in a global variable, before entering the downstream conference.

I’ve never tried it, but I imagine there is a risk of audio instability from conferencing conferences.

Yes, exactly - you got it! So the big question is, where do I find this name or unique-ID, given the lack of equivalence of DIALEDPEERNAME which DIAL would give?

PS: No audio problems conferencing conferences - it works rather well in fact!

Do it using the CHANNEL function from the channel itself. You don’t even need a local channel in this case, as you can do it after the upstream call connects.

1 Like

Thanks, David.

Hmm, but how do I do it from the channel when I don’t know what the channel is? Unless I was doing something wrong, in all my tests and dumpchans (and I did many, everywhere!), “channel” was always the channel of the “triggering” incoming call. I never found out how to “tap into” the “Originate”-ed channel.

Use ${CHANNEL} it provides information on the current channel.

1 Like

Thanks David,

I’ve put “CHANNEL” all over the place, and it only ever seems to relate to the the channel I am on, ie, the “calling in” channel.

But it’s not the current channel I want information about, it’s the Originated channel…

Put it in extension s in bcab-bridge-conference

1 Like

I think at this stage the easiest thing would be to rent an extra ITSP extension for £2 a month (say, ext 206) and just use that exclusively for this outgoing call. At least then I could guarantee that the only thing I would get from
same => n,SET(tempchans=${CHANNELS(PJSIP\/voipfone-206-(.*))})
would be that call. Unless… unless there’s a way of aliasing one pjsip entry to another, while making it seem unique, if that makes sense? Because it definitely doesn’t like two extensions joined to the same ITSP login!