flutter_sip_ua

Pure-Dart SIP user agent and Flutter client for the dart-pbx server. The UI is modelled on InnovateAsterisk Browser-Phone with a Riverpod-driven state layer and a modular widget tree.

Repository: github.com/KellyKinyama/flutter_sip_ua

Features

  • Pure-Dart SIP signalling stack (lib/sip/) — registration, calls, MESSAGE, digest auth, SDP, RTP/RTCP helpers.
  • Pure-Dart media path — G.711 codec, RTP packetizer, jitter buffer. No flutter_webrtc, no libwebrtc binary.
  • Multiple transports out of the box: WS/WSS, UDP, and optional RTP-over-QUIC datagrams (pure_dart_quic).
  • Riverpod-based state management (lib/providers/sip_providers.dart).
  • Browser-Phone-style UI:
    • Two-pane shell with buddy sidebar + active stream.
    • Modular call screen (lib/ui/widgets/call/).
    • Dialer sheet, message composer, transfer sheet.
  • Light and dark themes that mirror phone.light.css / phone.dark.css. Theme choice is persisted via SharedPreferences and toggled from the sidebar toolbar (system → light → dark).

Why not dart-sip-ua + flutter_webrtc?

dart-sip-ua is a JsSIP port that delegates all media to flutter_webrtc, which bundles libwebrtc — roughly 10M lines of C++ extracted from Chromium, shipped as tens of megabytes of native binaries per platform. flutter_sip_ua keeps the entire stack — signalling, transport, RTP, codecs — in pure Dart, targeting the same capability surface as dart-webrtc without the native dependency.

dart-sip-ua + flutter_webrtc flutter_sip_ua
Language end-to-end Dart + ~10M LOC C++ (libwebrtc) Pure Dart
Binary footprint Tens of MB of native libs per ABI/platform Kilobytes
Native toolchain NDK / CocoaPods / MSVC / depot_tools None
Web support Browser's WebRTC (different impl) Same Dart code
Transports WS / WSS only WS / WSS / UDP / QUIC datagrams (TCP/TLS/SCTP pluggable)
Memory safety C++ attack surface Dart, memory-safe
Debuggability RTC_LOG + Chromium source Set a breakpoint

Transports beyond WebSockets

dart-sip-ua is effectively WebSocket-only — a browser-era constraint inherited from JsSIP. flutter_sip_ua ships:

  • WS / WSS via web_socket_channel (works on dart:io and web).
  • UDP via RawDatagramSocket (lib/sip/transport_udp_io.dart) — talk directly to Asterisk / FreeSWITCH / Kamailio on :5060 with no WS gateway.
  • RTP-over-QUIC datagrams via pure_dart_quic — multiplexed, congestion-controlled, NAT/firewall-friendly.
  • A pluggable transport interface so TCP, TLS, SCTP, or WebTransport can be added without native plugin work.

Current state vs. roadmap

Today: G.711 audio, RTP/RTCP, jitter buffer, SIP REGISTER / INVITE / MESSAGE, RFC 2617 digest, WS/WSS/UDP, optional QUIC datagrams.

Planned (pure-Dart parity with dart-webrtc): ICE / STUN / TURN, DTLS-SRTP, Opus, video codecs (VP8 / H.264), data channels, AEC / AGC.

dart-sip-ua + flutter_webrtc is more battle-tested today because it inherits everything from libwebrtc. flutter_sip_ua is the better fit when you want a small, auditable, web-friendly client that speaks to a real SIP server without dragging a Chromium-derived binary into your app.

Getting started

flutter pub get
flutter run -d windows   # or chrome / android / ios / linux / macos

Tests:

flutter test

Project layout

lib/
  main.dart
  providers/sip_providers.dart   # Riverpod facade over the SIP UA + UI state
  sip/                           # Pure-Dart SIP UA, SDP, transport, audio/video
  ui/
    theme.dart                   # Light/dark ThemeData built from BP palette
    bp_palette.dart              # Browser-Phone color tokens + ThemeExtension
    home_page.dart               # Two-pane shell + dialer sheet
    call_page.dart               # Slim call orchestrator
    widgets/
      buddy_sidebar.dart         # Left rail incl. theme toggle
      dial_pad.dart
      dialer_action_row.dart
      call/                      # Modular call UI pieces

Libraries

main
providers/log_path_io
Native (dart:io) log-path builder. Picks a temp directory per launch.
providers/log_path_stub
Web stub for log-path resolution. The web logger is a no-op so the path is meaningless — return an empty string.
providers/sip_providers
Riverpod providers for the SIP user agent and the UI-facing state derived from its event streams.
sip/audio/audio_sink
sip/audio/g711
G.711 μ-law and A-law codec — pure Dart.
sip/audio/jitter_buffer
sip/audio/media_session
Media plane for SIP calls.
sip/audio/media_session_platform
Platform facade for MediaSession.
sip/audio/media_session_stub
No-op stub for MediaSession used on platforms without dart:io (e.g. web). Constructing it throws UnsupportedError so callers that forget to gate media setup behind a platform check fail loudly.
sip/audio/pcm_audio_sink
Cross-platform AudioSink that pushes decoded PCM into flutter_pcm_sound. Works on Windows / macOS / Linux / Android / iOS.
sip/audio/rtcp
Minimal RFC 3550 RTCP packet codec — pure Dart.
sip/audio/rtp
Minimal RFC 3550 RTP packet builder + parser — pure Dart.
sip/audio/rtp_quic_session
Public surface for RTP-over-QUIC support.
sip/audio/rtp_quic_session_io
dart:io implementation of RtpQuicSession backed by package:pure_dart_quic.
sip/audio/rtp_quic_session_platform
Platform facade for RtpQuicSession. Re-exports the native dart:io-backed implementation when available, otherwise the web stub.
sip/audio/rtp_quic_session_stub
Web stub for RtpQuicSession. RTP-over-QUIC requires UDP sockets, which dart:html-based web builds cannot provide.
sip/audio/rtp_stats
RTP send/receive bookkeeping needed to emit RFC 3550 SR/RR reports.
sip/audio/rtp_types
Pure-Dart RTP / codec types shared by signalling (SDP) and the platform-specific media plane.
sip/digest
Client side of RFC 2617 / RFC 3261 §22.4 digest authentication.
sip/is_web
Web detection for the pure-Dart SIP layer (no Flutter dep).
sip/is_web_io
Native override of isWeb used when dart:io is available.
sip/sdp
Tiny SDP helper — only what the SIP UA needs to negotiate G.711 audio (and optional VP8 video) against dart-pbx. Not a full RFC 4566 parser.
sip/sip_file_logger
Append-only SIP wire-format logger.
sip/sip_file_logger_io
dart:io implementation of SipFileLogger.
sip/sip_file_logger_stub
No-op SipFileLogger used on platforms without dart:io (web).
sip/sip_message
Minimal RFC 3261 message model — enough to talk to the dart-pbx server.
sip/sip_user_agent
Pure-Dart SIP user agent.
sip/transport
SIP transports.
sip/transport_udp_io
dart:io UDP implementation of SipTransport.
sip/transport_udp_stub
UDP transport stub used on platforms without dart:io (web).
sip/video/video_codec
Pluggable video codec for VideoSession.
sip/video/video_session
Video media plane: RTP/RTCP transport for VP8 frames over RFC 7741.
sip/video/video_session_platform
Platform facade for VideoSession.
sip/video/video_session_stub
No-op stub for VideoSession used on platforms without dart:io (e.g. web). Constructing it throws UnsupportedError.
sip/video/video_types
Web-safe video media types shared by signalling, the native impl, and the web stub. No dart:io.
sip/video/vp8_rtp
RFC 7741 — RTP payload format for VP8.
ui/bp_palette
ui/call_page
ui/home_page
ui/login_page
ui/theme
ui/widgets/buddy_sidebar
ui/widgets/buddy_stream
ui/widgets/call/call_action_panels
ui/widgets/call/call_backdrop
ui/widgets/call/call_buttons
ui/widgets/call/call_party_card
ui/widgets/call/call_stats_panel
ui/widgets/call/call_top_bar
ui/widgets/call/transfer_sheet
ui/widgets/dial_pad
ui/widgets/dialer_action_row
ui/widgets/status_chip
ui/widgets/welcome_pane