[asterisk-dev] Pickup peculiarities
asterisk at phreaknet.org
asterisk at phreaknet.org
Sat Sep 2 17:33:04 CDT 2023
Some architectural questions about the current incarnation of the
builtin call pickup code... at some point I decided it was horribly
deficient and wrote my own module that I typically use, but I wanted to
see if I could get something to work for an environment just using
simple building blocks.
A slightly atypical use case I was toying with was picking up incoming
calls arriving on FXO ports (chan_dahdi), but that aren't ringing any
FXS stations. For example, the call could come in on FXO line 1 and ring
FXS line 1, and the call ringing FXS line 1 could be picked up, but I
was trying to see if the original call to FXO 1 could be picked up
without ringing any channels, i.e. pickup without ringing (which is
maybe a bit contradictory). In the case of an FXO channel, it's already
executing dialplan (so has a PBX), although it may still be in the
"ring" state since it hasn't answered yet.
In pickup.c, a channel is only eligible for pickup if there is no PBX
running on it[1], so this seems to preclude the case above. As such, I
have a couple questions, just to confirm I'm understanding this right:
* Semantically, should the above scenario work with the builtin pickup
functionality, or is it by design that this case is excluded, e.g.
channels with a PBX but not yet answered (I'm guessing no, since how
would one distinguish between valid cases such as these, and most
any other? After all, to the core, it's a channel that's executing
dialplan)
* What would be the prototypical "Asterisk way" of doing the above
scenario? Something like ChannelRedirect() should work, but I mean
more within the bounds of the pickup construct (and maybe there
isn't any, just want to confirm I haven't missed something). Put
another way, how would you do the above, in the simplest way
possible? (high level, no code necessary)
* I'm thinking that one way to accomplish this given the way that
pickup is would be to have some kind of dummy "sink" channel driver,
e.g. something that can be called, but will never actually answer,
and can't do anything useful. This should make the above scenario
function without creating any further additional channels or ringing
any "real" endpoints. Local channels would not suffice, because they
begin executing dialplan immediately. The dummy channel driver
wouldn't do that, or really do anything, it would just be a valid
target for Dial() that would satisfy the properties expected by
pickup.c, to allow a channel currently ringing the dummy channel
driver to be picked up. A toy example:
[from-fxo-port] ; Allow the incoming call from the FXO port to be picked
up by any station in the same call group for up to 30 seconds, go to
voicemail otherwise.
exten => s,1,NoOp(Incoming call from ${CALLERID(all)}) ; after 1 ring,
chan_dahdi spawns PBX execution to handle the FXO port
same => n,Dial(WaitPickup/group1,30) ; not shown for simplicity, but
would probably need to use a pre-dial subroutine to execute
Set(CHANNEL(pickupgroup)=1) on the called channel, or the dummy driver
would need to accept this and call ast_channel_callgroup_set in its _new
callback.
same => n,NoOp(channel was not picked up within 30 seconds)
same => n,VoiceMail(1234)
Let's ignore exactly how an end user is alerted to the fact there is an
incoming call on the FXO port; that's not relevant to the situation here
- for example, suppose there's an external ringer in parallel on the line.
Any thoughts on doing something like this? I'm assuming there isn't such
a channel driver already (since why would there be?), one would need to
be written although it'd be fairly simple. Might there be a more elegant
way of doing this that comes to mind?
[1] https://github.com/asterisk/asterisk/blob/master/main/pickup.c#L79
More information about the asterisk-dev
mailing list