Grab an answered call

Alright so I’m new to FreePBX and was wondering if this is a thing and I just don’t know what to call it.

I’m putting phones (Yealink T31P) in a classroom that already have a SIP PA speaker (Valcom VIP-431As). The phone and speaker each have their own extension. When calling the PA speaker’s extension, the PA speaker automatically picks up. What I’d love to do is have a button on the phone that can “take” the already answered call and bring it to the handset.

Scenario: if the office pages into the room, and the teacher doesn’t want to respond in front of the whole class. They walk over, press a button on the phone, and the call is “grabbed” from the speaker and brought to the phone. Kind of like a hostile transfer. Googling “freepbx hostile transfer” does not yield useful results :joy:

Is this a thing?

Have never tested this, but it should be doable with a custom dialplan.

Example: PJSIP/101=Yealink, PJSIP/102=Valcom

  • 101 Calls custom dialplan
  • Dialplan redirects the channel that is bridged to PJSIP/102 to a dynamic bridge or a parking slot
  • Dialplan joins the dynamic bridge or retrieves the call from the parking slot
  • If using a dynamic bridge, make sure it gets destroyed once 101 hangs up.

EDIT: This may be an interesting project, I think between the following applications we can come up with something that will work pretty smooth.

https://wiki.asterisk.org/wiki/display/AST/Asterisk+18+Application_Bridge
https://wiki.asterisk.org/wiki/display/AST/Asterisk+18+Application_BridgeAdd
https://wiki.asterisk.org/wiki/display/AST/Asterisk+18+Application_BridgeWait

The issue with this solution is it is an all or nothing solution and that’s the not scenario being described here. The office pages a class room, the page is answered by a 2-way intercom device so they can talk back and forth. A teach can choose to then pull the call to their desk phone so the conversation can’t be heard by the entire class. This doesn’t happen with every call, it may happen on 1 call of the 12 they send to a classroom throughout the day.

The proposed solution would require every call to be put into a confbridge/parking lot combo and not send the call to the intercom unit.

Sorry I wasn’t clear… 101 dials this custom dialplan after there’s already an active call

This still isn’t clear. 101 in this scenario would be the Office → 102 would be the intercom, there is still another phone (teachers). Since the teacher is the one that wants to redirect the call, the call would need to come from the teachers phone and know to get the proper channel (101’s channel) to pull from the bridge and put to the other phone.

There would be three devices in the scenario, you are only talking about two.

Could you give the teacher a DTMF box or mobile app configured to send the transfer request as as DTMF? Or even have a design and technology project to created a box to do this, that could be placed next to the wall phone.

This does require inband DTMF and the use of a tone capable codec, like alaw or µlaw.

On the other hand, it appears that FreePBX does have directed call pickup, which suggests the difficult bit (knowing the right channel to grab) has already been done. If you can work out how this works, you should be able to create a custom dialplan that uses Bridge to take over the channel.

Not sure how that is relevant here. Direct Call Pickup or even a group call pickup is only going to work on ringing channels not channels already in a bridge.

The Office (101) is calling the Intercom (102) which auto-answers the call there isn’t a chance for another device to pickup the call. The teacher decides that the call shouldn’t be heard by the class so goes to their Desk Phone (103) and wants to pull the Office from the already two-party bridged call. At this point you are pulling a channel from an established bridge and transferring it to another channel.

There’s a couple ways this can be done but they would involve AMI actions like Redirect or some others. Overall you could have a button on the desk phone that when pressed, will trigger some dialplan/AMI that grabs to the needed channel and transfers it to the desk phone. I’m not sure there is a pure dialplan way to do this.

Low tech workaround: Teacher presses a speed dial button to call the office. Office caller sees the call waiting, hangs up the intercom call, phone rings immediately, answers, teacher is on the line.

It means that there must already be logic that allows the dialplan to find the channel that is calling a particular number. I have assumed that would have to be done by storing the channel in a global variable.

As I suggested, the Bridge dialplan application should allow you to grab a channel from a bridge and bridge it to the current channel. There are some restrictions that were introduced in the great masquerading rework, but if the original bridging was done with Dial, I think it should be OK.

Even with those restrictions, it is still possible, from dialplan, but you would have to break the original bridge separately from forming the new bridge, so you would have to do a redirect to code that then did the bridge (or redirect to Wait, followed by Bridge, or redirect to Park, followed by a pickup of the parked call.

Yeah, forgot that it does that. Yeah, there could be a line/softkey on the desk phone that executes Bridge on the desired channel (office) and will bridge them together.

Well, I have a POC working. It’s essentially ONE line of dialplan… Nothing encourages you more than being told you can’t… :slight_smile:

Disclaimer, I tested this on FreePBX 14.

8791 = Principal
2547 = Valcom
6499 = Teacher

;8791 calls 2547
    --Executing [2547@from-internal:1] GotoIf("PJSIP/8791-00000043", "1?ext-local,2547,1:followme-check,2547,1") in new stack
...
    -- PJSIP/2547-0000004a is ringing
...

;2547 Answers

    -- PJSIP/2547-0000004a answered PJSIP/8791-00000049
    -- Channel PJSIP/2547-0000004a joined 'simple_bridge' basic-bridge <eb80c9ab-52a5-4e0e-b7d7-d87718467c58>
    -- Channel PJSIP/8791-00000049 joined 'simple_bridge' basic-bridge <eb80c9ab-52a5-4e0e-b7d7-d87718467c58>

Hers the magic: 6499 dials *372547 ad grabs the active call!

    -- Executing [*372547@from-internal:1] NoOp("PJSIP/6499-00000045", "Extnering custom context to seize call from 2547") in new stack
    -- Executing [*372547@from-internal:2] Bridge("PJSIP/6499-0000004b", "PJSIP/8791-00000049") in new stack
    
;8791 leaves the original bridge
    -- Channel PJSIP/8791-00000049 left 'simple_bridge' basic-bridge <eb80c9ab-52a5-4e0e-b7d7-d87718467c58>

;and then joins the new bridge along with 6499
    -- Channel PJSIP/8791-00000049 joined 'simple_bridge' basic-bridge <7fd1fe6d-93b0-4eb6-91cb-807a5cbac596>
    -- Channel PJSIP/6499-0000004b joined 'simple_bridge' basic-bridge <7fd1fe6d-93b0-4eb6-91cb-807a5cbac596>

;Since no one is in the original bridge, 2547 leaves the original bridge
    -- Channel PJSIP/2547-0000004a left 'simple_bridge' basic-bridge <eb80c9ab-52a5-4e0e-b7d7-d87718467c58>

Because of line updates, 8791 actually sees on their screen that they are now talking with 6499.

So, essentially, dialing *37 followed by a 4 digit extension will seize the call from them.

Obviously, this is a POC, and needs validation, restrictions etc etc.

Finally, here’s the dialplan that goes in extensions_custom.conf

[from-internal]
exten => _*37XXXX,1,Noop(Extnering custom context to seize call from ${EXTEN:3})
 same => n,Bridge(${IMPORT(${CHANNELS(${EXTEN:3})},BRIDGEPEER)})
 same => n,Hangup
5 Likes

Good gravy folks. This was incredible. First, thank you all who replied. I’m in awe. lol

@PitzKey , I just tested your solution and it worked perfectly. For the record, I’m on FreePBX 16.0.40 (should have mentioned that before, my apologies), but I plugged in your code in the extensions_custom.conf file, just tested it, and it seamlessly picked up the call from the speaker. And you’re right, the caller id’s on the phones instantly updated as well.

Again, thank you!

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

This is now in the latest edge version of Core and Framework in FreePBX16.

Core v16.0.68.13
Framework v16.0.40.1

If anyone can please test and provide feedback, I’d really appreciate it!

What is? What is it called? What is it listed under?

Dialing *37EXT will seize the call from EXT.

There is helper text that explains what *37 does, however, it seems to be broken in v16. I created a ticket to address that.

1 Like

Morning Pitzkey, testing *37 now in edge core.

When I have a call set up between two extensions, say between 100 and 200, and I dial *37100 from another idle phone, what is the expected outcome?

Also, I assume this feature code will break if you’re trying to seize a call using a shadow extension with an unexpected numeric prefix. I’ve fixed that issue with the targeted chanspy dialplan here: FreePBX Feature code prefix to allow spy/whisper/barge on the specified extension · GitHub

Lets say you dial *37100 from extension 300, then 200 will get connected to 300. 100 will see a disconnect.

Can you please give me an example of how a shadow extension would look like? I want to test that.

Got it.

If you login to UCP and enable the WebRTC phone there, you will see a pjsip contact registered with a 99 prefix to the primary linked extension. That’s the shadow extension. If you try to seize a call such that you are attempting to bridge the shadow extension it will fail. I just tested, but didn’t delve deeply into the logs, I presume the seize failed because of the numeric prefix in the channel name.

> pjsip show channels

  Channel:  <ChannelId........................................>  <State.....>  <Time.....>
      Exten: <DialedExten.............>  CLCID: <ConnectedLineCID.......>
==========================================================================================

  Channel: PJSIP/7010-00000024/AppDial                           Up            00:00:05
      Exten:                             CLCID: "S705" <7100>

  Channel: PJSIP/997100-00000023/Dial                            Up            00:00:06
      Exten: s                           CLCID: "P370" <7010>


Objects found: 2