sip icon indicating copy to clipboard operation
sip copied to clipboard

SIP Cold Transfer fails with SIP 603

Open rmonvfer opened this issue 1 year ago • 5 comments

Hello!

I've been using LiveKit (Cloud) for a while and been enjoying it so far (thank you for building and maintaining it everyday).

I'm building a voice agent using LiveKit Agents and relying on LiveKit SIP for inbound and outbound telephony alongside Twilio for (elastic) trunking and a local VoIP company that provides me with local (regional) phone numbers.

I have set up inbound and outbound trunks as well as the appropriate dispatch rules to handle incoming SIP traffic.

For reference, here are my (redacted) trunks and dispatch rules:

> lk sip outbound list
Using default project [<redacted>]
┌─────────────────┬──────────────────────────┬────────────────────────────┬───────────┬──────────────┬────────────────┬──────────┐
│ SipTrunkID      │ Name                     │ Address                    │ Transport │ Numbers      │ Authentication │ Metadata │
├─────────────────┼──────────────────────────┼────────────────────────────┼───────────┼──────────────┼────────────────┼──────────┤
│ ST_u<redacted>  │ Outbound Trunk           │ <redacted>.pstn.twilio.com │ UDP       │ +34123456789 │                │          │
└─────────────────┴──────────────────────────┴────────────────────────────┴───────────┴──────────────┴────────────────┴──────────┘

> lk sip inbound list
Using default project [<redacted>]
┌─────────────────┬─────────────────────────┬───────────────────────────┬──────────────────┬────────────────┬────────────────┬──────────┐
│ SipTrunkID      │ Name                    │ Numbers                   │ AllowedAddresses │ AllowedNumbers │ Authentication │ Metadata │
├─────────────────┼─────────────────────────┼───────────────────────────┼──────────────────┼────────────────┼────────────────┼──────────┤
│ ST_mn<redacted> │ Inbound Trunk.          │ +34123456789,+34123456789 │                  │                │                │          │
└─────────────────┴─────────────────────────┴───────────────────────────┴──────────────────┴────────────────┴────────────────┴──────────┘

> lk sip dispatch list
Using default project [<redacted>]
┌───────────────────┬─────────────────────────┬───────────┬─────────────────────┬────────────────────────┬─────┬───────────┬──────────┐
│ SipDispatchRuleID │ Name                    │ SipTrunks │ Type                │ RoomName               │ Pin │ HidePhone │ Metadata │
├───────────────────┼─────────────────────────┼───────────┼─────────────────────┼────────────────────────┼─────┼───────────┼──────────┤
│ SDR_QG<redacted>  │ Dispatch Rule.          │ <any>     │ Individual (Caller) │ call_<caller>_<random> │     │ false     │          │
└───────────────────┴─────────────────────────┴───────────┴─────────────────────┴────────────────────────┴─────┴───────────┴──────────┘

My agent needs to transfer calls to a human operator using one of its tools. Originally, the implementation used the transfer_sip_participant method like this:

await sip_service.transfer_sip_participant(
    TransferSIPParticipantRequest(
         participant_identity=self._participant.identity, #Provided elsewhere
         room_name=self._room.name, #Provided elsewhere
         transfer_to="sip:+34<called_number>@<redacted>.pstn.twilio.es;transport=udp"
    )
)

Unfortunately, during testing I discovered that when the agent calls this tool, it fails with

livekit.api.twirp_client.TwirpError: ('internal', 'SIP REFER failed with code 603')

Further debugging revealed that, apparently, the SIP request never reaches Twilio, as there are no logs regarding failed connection attempts (or any logs at all, for the matter).

I've also tried using other transfer_to values (as per the docs), none of them work.

  • transfer_to="sip:+34123456789@<redacted>.pstn.twilio.com;transport=udp"
  • transfer_to="tel:+34<called_number>"

My understanding here is that this must be a bug or me somehow messing up the outbound rules.

In the meantime, I had to implement a temporary call transfer method using outbound calling and that works without any issue.

The implementation looks like


sip_participant = await sip_service.create_sip_participant(
    CreateSIPParticipantRequest(
        sip_trunk_id="ST_u<redacted>",
        sip_call_to="+34<called_number>",
        participant_identity=f"sip_{nanoid.generate()}",
        room_name=self._room.name,
        participant_name="SIP",
        play_dialtone=True
    )
)
# Remove the agent
await room_service.remove_participant(
    RoomParticipantIdentity(
        room=self._room.name,
        identity=self._room.local_participant.identity
    )
)

Which, again, works fine and the called number receives a call from the number configured in my outbound trunk (which is also properly authorized in Twilio as a caller ID).

My issue with this method is that it's messy and the called number sees the outbound trunk's number as the caller id (ideally, it should see the original caller's caller ID)

Let me know if you need more details.

Best Regards, Ramón

rmonvfer avatar Nov 26 '24 19:11 rmonvfer

Hello again! I haven't been able to fix this yet, but I'm willing to put in the work. I would appreciate some pointers because I'm not very proficient in golang and it's quite hard for me to fully grasp the more complex bits.

rmonvfer avatar Dec 26 '24 14:12 rmonvfer

Hello @rmonvfer ! Could you please provide more details on the recent failed transfers? You could join our Slack and share your project ID there, so we can debug further.

dennwc avatar Dec 26 '24 15:12 dennwc

Thanks @dennwc, I'll definitely join the Slack!

rmonvfer avatar Dec 27 '24 09:12 rmonvfer

I get a deadline_exceeded error

andrewcbuensalida avatar Mar 04 '25 07:03 andrewcbuensalida

have you solved that problem to transfer the call ?

kapilkarda avatar May 19 '25 08:05 kapilkarda

any one solved this issue? me facing the same

khurram4000 avatar Jul 14 '25 12:07 khurram4000

I have the same problem, were you able to transfer to different trunkIDs?

Wil-macedo avatar Jul 17 '25 11:07 Wil-macedo