Dialplan hints without enumeraiton

I’ve been using hints for some while for BLFs. One problem I’ve had that I’ve had to workaround is that the hint extensions seem to require hardcoding, and while they support pattern matching, they don’t support any other logic. For instance, say I have extension 121 going to SIP/A, 122 going to SIP/B, and 123 going to DAHDI/A.

The documentation says to do something like this:

[internal]
exten = 6001,hint,SIP/Alice&SIP/Alice-mobile
exten = 6002,hint,SIP/Bob
exten = 6003,hint,SIP/Charlie&DAHDI/3
exten = 6004,hint,SIP/Diane,CustomPresence:Diane
exten = 6005,hint,,CustomPresence:Ellen

Maybe it’s just me, but this seems very inefficient, especially if you have lots of extensions.

I know one can do something like exten => _6XXX,hint,${EXTEN}

However, this assumes that peers are named exactly the same as extensions. In my case, they are not, and this is a primitive and unrecommended practice anyways.

I already have a lookup subroutine that returns the peer associated with an extension, if there is one, e.g.:

exten => 2121,1,Return(SIP/MyDevice)

But if my understanding is correct, there is no way to do something like:

exten => 2121,hint,Gosub(some-lookup-subroutine,{EXTEN},1) same => n,Return({GOSUB_RETVAL})

Partly because this requires two priorities, and applications can’t be used as part of a hint.

To avoid having to enumerate and duplicate code, I ended up doing something like this for one setup:

exten => _[A-Z].,hint,SIP/${EXTEN}

On the client side, instead of using the actual extension, I provide the full peer name. The problem with this is that, while a / (forward slash) is a perfectly valid extension character in most cases, and I use this regularly, for hints specifically it seems not to work. In this environment here, SIP is used exclusively, so my SIP clients use everything after the SIP/ as the number. As the name, I put in the actual extension, so basically it’s backwards, but it’s a hack that allows for useful pattern matching.

At the same time, it’s not ideal, since this isn’t how this was intended to be used.

Is there any way to do more complex logic with hints that would provide an efficient way to do this more properly? Or would the only way to do it right be to essentially enumerate every single extension again just for hints? What I’d like to do is have the extension NOT be the device name, be able to do some processing on it, and then return the device name, which simple pattern matching cannot do.

I may be missing something, but it seems like since these are individually evaluated for every presence subscription, there is no reason why the hint priority could not evaluate something at run time, the same as calling a subroutine and running logic.

If you want to put things in one place, use Dial(${HINT(${EXTEN})}), and make the hints the definitive mapping between extension and dialstrings.

Hmm… not what I was expecting, but that should work - thanks! I can just have my subroutine return the result of the HINT function instead, since that gets used in a lot of places. I’ll spend some time playing around with this.

I’m a bit confused what the n option means, though: Retrieve name on the hint instead of list of devices.

We use this:

exten => ${DB(${EXTEN}/HINT)}

and store all the hints in the database. It does mean you have to reload the dialplan whenever this information changes.