Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

README.md

06 · Attended transfer (consultative, REFER + Replaces)

Beta status: Supported. REFER (RFC 3515) with an RFC 3891 Replaces is beta-supported. See COMPATIBILITY_MATRIX.md.

Overview

An attended (consultative) transfer: the transferor talks to the transfer target before completing the transfer. Alice calls Bob; Bob places a consultation call to Charlie; then Bob attended-transfers Alice to Charlie. Unlike a blind transfer, the REFER carries a Replaces header that identifies the consultation dialog.

Three primitives make this work (all on SessionHandle):

  • consultation.dialog_identity() → the SIP dialog identity (Call-ID + tags).
  • DialogIdentity::to_replaces_value() → formats it as an RFC 3891 Replaces.
  • original.transfer_attended(target, &replaces) → sends Alice a REFER whose Refer-To target embeds that Replaces.

Alice completes the transfer by calling the Refer-To target; the embedded Replaces (also surfaced separately on Event::ReferReceived.replaces) ties the new call to the consultation leg.

Demo flow

  1. Alice (:5080) calls Bob (:5081); Bob answers (the original call).
  2. Bob calls Charlie (:5082) — the consultation call — and waits for answer.
  3. Bob reads the consultation's dialog_identity, formats Replaces, and calls transfer_attended on the Alice leg.
  4. Alice receives the REFER (with Replaces), hangs up with Bob, and calls the Refer-To target. Charlie answers the transferred call. ✅

Ports default to 50805082 so the combined examples-smoke suite does not collide with quickstart-p2p / SRTP demos that use 5060/5061.

Architecture

   Alice (:5080) ── INVITE ─▶ Bob (:5081) ── INVITE (consult) ─▶ Charlie (:5082)
        │  ◀── REFER (Refer-To: Charlie; Replaces=consult dialog) ──┘
        │ hangup Bob
        └──────────────── INVITE (completes transfer) ─▶ Charlie  ✅ connected

Quick start

./run_demo.sh

Or manually, in three terminals (defaults shown):

CHARLIE_PORT=5082 cargo run --bin charlie
BOB_PORT=5081 CHARLIE_PORT=5082 cargo run --bin bob
ALICE_PORT=5080 BOB_PORT=5081 cargo run --bin alice

Expected output

  [ALICE] Got REFER to sip:charlie@127.0.0.1:5082
  [ALICE] Replaces = Some("session-…@rvoip-sip;to-tag=…;from-tag=…")
  [ALICE] ✅ Connected to Charlie (attended transfer complete).
  [BOB] Consultation with Charlie established.
  [BOB] Attended-transferring Alice to Charlie (Replaces=…)
  [CHARLIE] Consultation answered.
  [CHARLIE] ✅ Answered transferred call.

✅ DEMO SUCCESSFUL — Alice was attended-transferred to Charlie

Beta scope notes

  • The transferor side uses the supported attended-transfer primitives (dialog_identity, to_replaces_value, transfer_attended). The transferee side (placing the replacing INVITE) is application orchestration — this example shows the canonical implementation.

Troubleshooting

  • "consultation dialog identity not confirmed yet" — the consultation call wasn't fully answered before Bob read its identity; the example waits, but a slow/declined Charlie can trip this.
  • Port conflicts — override the *_PORT env vars.

Next steps