feat: Implement attended transfer functionality in SIP UA - #571
Conversation
COACHIKO
commented
Jan 9, 2026
- Added attended transfer events to manage transfer states (trying, progress, accepted, failed).
- Introduced Replaces class to handle SIP Replaces header for attended transfers.
- Created AttendedTransferScreen to manage the attended transfer UI flow.
- Updated SIP UA helper to support attended transfer methods.
- Enhanced sip_ua.dart exports to include new event and replaces classes.
- Added attended transfer events to manage transfer states (trying, progress, accepted, failed). - Introduced Replaces class to handle SIP Replaces header for attended transfers. - Created AttendedTransferScreen to manage the attended transfer UI flow. - Updated SIP UA helper to support attended transfer methods. - Enhanced sip_ua.dart exports to include new event and replaces classes.
There was a problem hiding this comment.
Pull request overview
This PR implements attended transfer functionality (RFC 5589) for the SIP UA library, allowing users to consult with a third party before completing a call transfer. The implementation adds comprehensive SIP signaling support and a complete UI flow for managing attended transfers.
Key Changes:
- Added SIP Replaces header support for attended transfers with proper dialog identification
- Implemented attended transfer methods in the Call helper with callbacks for transfer lifecycle events
- Created a dedicated UI screen to manage the consultation call and transfer completion flow
Reviewed changes
Copilot reviewed 8 out of 10 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/src/sip_ua_helper.dart | Added attendedTransfer() and attendedTransferWithParams() methods with dialog info getters |
| lib/src/replaces.dart | New class representing SIP Replaces header for dialog replacement |
| lib/src/event_manager/attended_transfer_events.dart | New event classes for attended transfer state tracking |
| lib/sip_ua.dart | Exported new attended transfer events, refer events, replaces class, and refer subscriber |
| example/lib/src/attended_transfer_screen.dart | New screen managing the attended transfer UI flow with consultation call handling |
| example/lib/src/callscreen.dart | Enhanced with attended/blind transfer dialog options and platform-specific speaker handling |
| example/lib/src/dialpad.dart | Added logic to prevent automatic navigation during attended transfer |
| example/macos/* | CocoaPods configuration updates (generated files) |
Files not reviewed (1)
- example/macos/Runner.xcworkspace/contents.xcworkspacedata: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| /// Builds the encoded Replaces parameter for a Refer-To URI. | ||
| /// | ||
| /// Returns a properly formatted and URI-encoded string that can be | ||
| /// appended to a Refer-To header. | ||
| /// | ||
| /// Format: `Call-ID;to-tag=xxx;from-tag=yyy` (URI encoded) | ||
| String toEncodedString() { | ||
| String replaces = callId; | ||
| replaces += ';to-tag=$toTag'; | ||
| replaces += ';from-tag=$fromTag'; | ||
| return Uri.encodeComponent(replaces); | ||
| } |
There was a problem hiding this comment.
The toEncodedString() method in the Replaces class duplicates the encoding logic that already exists in refer_subscriber.dart (lines 34-37). This violates the DRY principle. Since refer_subscriber.dart is the code that actually uses this encoding, consider whether this method is needed or if the logic should be consolidated in one place.
| /// Builds the encoded Replaces parameter for a Refer-To URI. | |
| /// | |
| /// Returns a properly formatted and URI-encoded string that can be | |
| /// appended to a Refer-To header. | |
| /// | |
| /// Format: `Call-ID;to-tag=xxx;from-tag=yyy` (URI encoded) | |
| String toEncodedString() { | |
| String replaces = callId; | |
| replaces += ';to-tag=$toTag'; | |
| replaces += ';from-tag=$fromTag'; | |
| return Uri.encodeComponent(replaces); | |
| } |
|
@copilot open a new pull request to apply changes based on the comments in this thread |