One of our clients needed to dynamically add and remove extensions to a ring-group. These are very similar to call-groups or call-queues in Asterisk but slightly different. We created a method where an extension could bind other extensions to it's call group.

From ExtensionA dial *30 then input the Extension to add. Dial *31 and input the extension to remove.

By using the DB routines of Asterisk and a clever hack of Gosub() we were able to add and remove items from the list that is handed to Dial().

DialGroup Add/Remove

This was implemented as generic functions which can add and remove items from any list with a given delimiter.

First add these routines to your extensions.conf. They perform the add and remove functionality necessary for this dynamic add/remove.

[func]
; tag_del - removes tag from tag_str (seperated by tag_sep)
; @param tag_str
; @param tag_sep
; @param tag
exten => tag_del,1,While($[ ${LEN(${tag_str})} ])
exten => tag_del,n,Set(ff0=${CUT(tag_str,${tag_sep},1)})
exten => tag_del,n,Set(ff1=${CUT(tag_str,${tag_sep},2-)})
exten => tag_del,n,GoToIf($["${ff0}" = "${tag}"]?skip)
exten => tag_del,n,NoOp(Including ${ff0})
exten => tag_del,n,Set(ret=${IF($[ ${LEN(${ret})} ] ? ${ret}${tag_sep}${ff0} : ${ff0} )})
exten => tag_del,n,Set(ff0=" = No")
exten => tag_del,n(skip),NoOp(Skipped ${ff0})
exten => tag_del,n,Set(tag_str=${ff1})
exten => tag_del,n,EndWhile()
exten => tag_del,n,Set(tag_str=${ret})
exten => tag_del,n,Return

; Add an Item to a List
; tag_add - appends tag to tag_str (seperated by tag), if needed
; @param tag_str
; @param tag_sep
; @param tag
exten => tag_add,1,NoOp(tag_add)
exten => tag_add,n,NoOp(TagStr: ${tag_str})
exten => tag_add,n,NoOp(TagSep: ${tag_sep})
exten => tag_add,n,NoOp(Tag: ${tag})
exten => tag_add,n,GoToIf($[ ${REGEX("${tag}" ${tag_str}) ]?nadd)
exten => tag_add,n,GoToIf($[ ${LEN(${tag_str})} = 0 ]?nsep)
exten => tag_add,n,Set(tag_str=${tag_str}${tag_sep})
exten => tag_add,n(nsep),Set(tag_str=${tag_str}${tag})
exten => tag_add,n,GoTo(back)
exten => tag_add,n(nadd),NoOp(No Add)
exten => tag_add,n(back),NoOp()
exten => tag_add,n,Return

To use them simply pre-set the tag_str,tag_sep and tag values before calling these subs.

; To Add
exten => s,n,Set(tag_sep=&)
exten => s,n,Set(tag_str=${DB(bind/${ext})})
exten => s,n,Set(tag=SIP/200)
exten => s,n,Gosub(func,tag_add,1)
; now tag_str has the new item added
; To Remove
exten => s,n,Set(tag_sep=&)
exten => s,n,Set(tag_str=${DB(bind/${ext})})
exten => s,n,Set(tag=SIP/200)
exten => s,n,Gosub(func,tag_rem,1)
; tag_str has "SIP/200" removed (if it was present)

Enable Dynamic Group Logic

For our system we wanted users at ExtensionA to designate which extensions should be added to their ring. So we added this to our stdExtension macro. We detect if a ring-group is defined and if so add that to the current extension being dialed. This is only a snippet.

; Look Bind
exten => s,n,Set(list=${DB(bind/${ARG1})})
; Skip if Empty
exten => s,n,GoToIf($[ ${LEN(${list})} = 0 ]?next)
; Add cause not Empty
exten => s,n,Set(ARG2=${ARG2}&${list})
; Dial Updated ARG2
exten => s,n(next),Dial(${ARG2},20)					; Ring the interface, 20 seconds maximum

Edoceo has been providing Asterisk consulting and solutions since 2005.