[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