Discussion: Asterisk func group

Comments Filter

What is group

Hopefully, this will be useful. I struggled with understanding what groups are and how to use them and finally just started experimenting till I came up with this.


GROUP() is somewhat like a magic global variable repository. You give it names and it takes care of globally incrementing and decrementing that name for each instance of the dial plan that is using a channel. If 6 people all make outgoing calls with the same group name assigned to each individual dial plan instance that the GROUP_COUNT() called with that name will return 6.

If you assign something to a group before you dial or answer like this:

exten => s,n,set(GROUP()=ZAP1)

Then a group, ZAP1, will be incremented for every connection made and decremented for every connection disconnected. This is useful for limiting the number of calls made on any line or channel. In my case I have a SIP channel that allows 2 simultaneous calls and domestic outgoing is free. I always want to make an outgoing call on this line unless it's already being used, in that case I'll use my 1.1 cent per minute outgoing line if it's up. The following macro uses GROUP() and GROUP_COUNT() to implement these features. GROUP_COUNT() is the function that tells you how many active channels belong to the specified GROUP() and allows easily limiting the number of calls made on any one channel.

I'm reasonably happy with this macro but if you can point out how to do this without the TRY1, TRY2, ... variable assignments I'd be pleased.

Because I'm clearly a bit clueless and I can't see how to get square brackets in the code, I've replaced all instances of them with << and >>. Feel free to tell me how to fix it and I'll do so.

<<macro-dial-long>>
; ARG1 is the number you want to call
; This macro tries all our outgoing channels in the order and call volume I want
exten => s,1,set(TRIES=0) ;
; here we list the outgoing lines specified as TRYn = NNtype/name
; where TRYn is TRY1 to TRYn and NN is maximum number of calls I want to allow on the channel
exten => s,n,set(TRY1=01SIP/fishing) ; max of 1 simultaneous call
exten => s,n,set(TRY2=03IAX2/seattle) ; max of 3 simultaneous calls
exten => s,n,set(TRY3=03IAX2/newyork)
exten => s,n,set(TRY4=01SIP/sipdiscount)
exten => s,n,set(TRY5=01SIP/internetcalls)
exten => s,n,set(TRY6=01Zap/3)
exten => s,n,set(TRY7=01Zap/1)
exten => s,n,set(TRY8=01Zap/2)
exten => s,n(nextone),set(TRIES=$<<${TRIES} + 1>>]) ; increment TRIES by 1

exten => s,n,set(DIALSTRING=${TRY${TRIES}}) ; assign TRYn to DIALSTRING
exten => s,n,gotoif($<<"${DIALSTRING}" = "">>?donehere) ; see if we've run out of things to try
exten => s,n,gotoif($<<${GROUP_COUNT(${DIALSTRING:2})} >= ${DIALSTRING:0:2}>>?nextone) ; see if we've used up the allowed calls on this channel
exten => s,n,ChanIsAvail(${DIALSTRING:2}) ; see if we can make a call on this channel
exten => s,n,gotoif($<<${AVAILSTATUS} = 0>>?:nextone)
exten => s,n,set(GROUP()=${DIALSTRING:2}) ; assign the current GROUP to the contents of DIALSTRING
exten => s,n,dial(${DIALSTRING:2}/${ARG1},,j) ; dial the phone
exten => s,n,hangup()
exten => s,n(donehere),congestion() ; we only get here if everything failed

I also add the occasional:

exten => s,n,set(GROUP()=SIP/fishing)
throughout my code where calls are coming in so GROUP_COUNT() is aware of incoming calls on a particular channel.

by ira, Monday 05 of June, 2006 (21:48:11 UTC)