Skip to content

About

Free, open-source desktop SIP softphone written in Rust. UDP/TCP/TLS/WS/WSS, G.711 audio, hold, transfer, DND, auto-answer, English and Russian UI. macOS, Windows, Linux.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

RustSIPPhone icon

RustSIPPhone 1.2

A free, open-source desktop SIP phone written in Rust. Sign in to your PBX, dial a number, answer calls — on macOS, Windows and Linux.

Build Release License: MIT Platforms Rust

Download · Quick start · Verify · Build from source · License


📸 Screenshots

Sign-in screen
Sign in
station, number, password
Dialer
Dial
keypad or keyboard
Recent calls
Recent
incoming, outgoing, missed
Incoming call
Incoming call
answer or decline
Outgoing call ringing
Calling
cancel at any time
Call with the microphone muted
In a call
timer, mute, hang up
Keypad tones during a call
Keypad tones
for voice menus

✨ Features

  • Outgoing and incoming calls over SIP, with digest authentication.
  • Sign in inside the app — no config files, no command line. Your password is kept in the system keychain.
  • Dialer with an on-screen keypad and keyboard input.
  • Every common way to connect: UDP, TCP, TLS (encrypted), WebSocket (WS) and secure WebSocket (WSS), picked in Settings → Network.
  • Station by name or by IP. Type a host name and the phone finds the station through its DNS records (SRV, RFC 3263), or enter an IP address and a port yourself.
  • Settings for real setups: SIP domain, outbound proxy, registration time, display name, an extra certificate for private TLS, and an option to advertise your public address behind a router (NAT).
  • Choose your microphone and speaker in Settings → Audio; the ringtone follows the speaker.
  • Hear the call ring. You get a ringback tone while the other phone rings, and the station's own tones or music when it sends them before the answer (early media).
  • Recent calls — incoming, outgoing and missed, one click to call back.
  • In-call controls — mute, hold and resume, transfer the call to another number, keypad tones (DTMF) for voice menus, hang up. If the other side puts you on hold, the screen says so and the phone answers the station correctly.
  • Call options: Do not disturb (incoming calls are turned away and listed as missed), auto-answer (the microphone stays off until you switch it on, so nobody can listen in without your knowledge), and a choice of how keypad tones are sent (as audio, as SIP INFO, or automatic).
  • Ringtone that plays on every platform, with nothing extra to install.
  • Runs in the background. Closing the window does not quit the app, so the phone stays registered and can still ring. On macOS the window simply goes away, as in any Mac app, and a click on the Dock icon brings it back; on Windows it goes to the system tray (click the tray icon to bring it back, right-click for the menu); on Linux it is minimized to the taskbar. An incoming call restores the window, raises it above other windows, gives it focus and bounces the Dock icon / flashes the taskbar button.
  • Two interface languages: English (the default) and Russian. Pick it from a drop-down list on the sign-in screen or in the top bar at any time; the choice is remembered.
  • Single small binary. No runtime, no installer required.

📦 Download

Grab the package for your system from the latest release.

System Package What's inside
🍎 macOS 11+ (Apple Silicon and Intel) RustSIPPhone-1.2.0.dmg Disk image with RustSIPPhone.app
🪟 Windows 10+ (64-bit) RustSIPPhone-windows.zip rust_sip_phone.exe
🐧 Linux (x86_64) RustSIPPhone-linux-x86_64.tar.gz Binary, desktop entry and icon

Every release also includes SHA256SUMS.txt so you can verify your download.

🚀 Quick start

macOS

  1. Open the .dmg and drag RustSIPPhone into Applications.
  2. Open it from Applications. Release builds are signed with a Developer ID certificate and notarized by Apple, so they open normally, with no security warning.
  3. Allow Microphone access when asked. Without it calls cannot start.
  4. Allow Keychain access if prompted — that is where your password is stored.

Built it yourself, or downloaded a CI artifact instead of a release? Those are only ad-hoc signed, and macOS may say it "could not verify" the app. Open System Settings → Privacy & Security, scroll to Security and press Open Anyway — or run xattr -dr com.apple.quarantine /Applications/RustSIPPhone.app. Apps you build on your own Mac open without any warning.

Windows

  1. Unzip RustSIPPhone-windows.zip anywhere (for example C:\Tools\RustSIPPhone).
  2. Double-click rust_sip_phone.exe.
  3. If Windows protected your PC appears: More info → Run anyway.
  4. Allow microphone access when Windows asks (Settings → Privacy & security → Microphone).
  5. When you close the window, RustSIPPhone keeps running in the system tray (the ^ arrow in the taskbar, bottom right, if the icon is not shown). Drag the icon out to pin it. Left-click it to open the window, right-click for Show / Quit.

Linux

tar -xzf RustSIPPhone-linux-x86_64.tar.gz
cd RustSIPPhone
./rust_sip_phone

You need ALSA, a graphical session (X11 or Wayland) and, to remember your password, a keyring service (GNOME Keyring or KWallet). On Debian/Ubuntu:

sudo apt install libasound2 libxkbcommon0 libwayland-client0 gnome-keyring

Optional — add it to your application menu:

mkdir -p ~/.local/bin ~/.local/share/applications ~/.local/share/icons
cp rust_sip_phone ~/.local/bin/
cp rustsipphone.png ~/.local/share/icons/
cp rustsipphone.desktop ~/.local/share/applications/

No keyring service? The phone still works; it just asks for the password each time you start it.

First launch

  1. Open the language drop-down in the top-right corner if you want something other than English.
  2. Enter the station address (your PBX, for example 192.168.1.10:5060; the port defaults to 5060), your extension number and your password — your administrator or provider gives you these.
  3. Press Sign in. When the dot in the top-left turns green and says Online, you are registered.
  4. Type or tap a number and press Call.
  5. Incoming calls ring and open an Answer / Decline screen, even if the window was closed or minimized.
  6. To really quit, press Quit app at the bottom of the window, use ⌘Q on macOS, or choose Quit in the tray icon's menu on Windows. Closing the window with the red button / × only sends it to the background.

✅ Verify your download

1. Check the checksum. Download SHA256SUMS.txt next to your package, then:

# macOS
shasum -a 256 -c SHA256SUMS.txt --ignore-missing

# Linux
sha256sum -c SHA256SUMS.txt --ignore-missing
# Windows (PowerShell) — compare the output with the line in SHA256SUMS.txt
Get-FileHash .\RustSIPPhone-windows.zip -Algorithm SHA256

You should see OK next to your file name.

2. Check the macOS signature and notarization.

codesign --verify --deep --strict --verbose=2 /Applications/RustSIPPhone.app
codesign -dvv /Applications/RustSIPPhone.app 2>&1 | grep -E "Identifier|Authority=Developer|TeamIdentifier"
# Identifier=com.rustsipphone.app
# Authority=Developer ID Application: INSTITUT REPRODUKTIVNOI MEDITSINY, TOO (7SXHSZ7GU6)
# TeamIdentifier=7SXHSZ7GU6

spctl --assess --type exec --verbose=2 /Applications/RustSIPPhone.app
# /Applications/RustSIPPhone.app: accepted
# source=Notarized Developer ID

xcrun stapler validate /Applications/RustSIPPhone.app
# The validate action worked!

3. Check that it works.

Step Expected result
Sign in with your account Green dot and Online
Call a second extension Ringing…, then a timer when answered
Call an echo-test number (on Asterisk usually *43 or 600) You hear yourself, both directions work
Call the phone from another extension Ringtone and the answer screen
Press Keypad during a call and dial a digit Voice menus react to the tone

If a call connects but you hear nothing, the app tells you when no audio arrived from the other side — that usually points to a NAT or firewall problem (see Notes).

🛠 Build from source

You need Rust 1.85 or newer (the project uses the 2024 edition).

git clone https://github.com/DjTim0n/RustSIPPhone.git
cd RustSIPPhone
cargo run --release

Linux build dependencies (Debian/Ubuntu):

sudo apt install pkg-config libasound2-dev libxkbcommon-dev libwayland-dev \
  libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libgtk-3-dev libssl-dev

Run the tests:

cargo test

Package for your system:

Target Command Result
macOS .app ./scripts/bundle-macos.sh dist/RustSIPPhone.app
macOS .app + .dmg ./scripts/bundle-macos.sh --dmg dist/RustSIPPhone-1.2.0.dmg
macOS universal (Intel + Apple Silicon) ./scripts/bundle-macos.sh --universal --dmg one app for both
macOS signed and notarized ./scripts/bundle-macos.sh --universal --dmg --notarize ready to distribute
Windows / Linux cargo build --release target/release/rust_sip_phone[.exe]

By default the app gets an ad-hoc signature, which is enough on your own Mac. To distribute it, sign with your own Apple Developer ID: set SIGN_IDENTITY="Developer ID Application: …", or pass --notarize, which finds the certificate in your keychain, sends the app and the disk image to Apple and staples the result. Notarization needs credentials; the header of scripts/bundle-macos.sh shows the three ways to supply them.

Releases are built by GitHub Actions on macOS, Windows and Linux. Push a tag like v1.2.0 and the workflow publishes the packages and checksums. On tags (and manual runs) the macOS build is signed and notarized when these repository secrets exist: APPLE_CERTIFICATE_P12 (base64), APPLE_CERTIFICATE_PASSWORD, APPLE_ID, APPLE_TEAM_ID and APPLE_APP_PASSWORD.

🧭 How it works

 ┌────────────┐   commands    ┌────────────┐  SIP (UDP)   ┌────────┐
 │  egui UI   │ ────────────▶ │   engine   │ ───────────▶ │  PBX   │
 │  ui.rs     │ ◀──────────── │ engine.rs  │ ◀─────────── │        │
 └────────────┘    events     └─────┬──────┘              └───┬────┘
                                    │ calls                   │
                              ┌─────▼──────┐   RTP (G.711)    │
                              │  call.rs   │ ◀────────────────┘
                              │  media.rs  │ ──▶ microphone / speaker (cpal)
                              └────────────┘
Module Role
ui.rs Desktop interface (egui): sign-in, dialer, recent calls, call screen, language switch
i18n.rs Interface languages and the text of every message the core reports
engine.rs SIP registration, incoming-request routing, command handling
call.rs Outgoing and incoming calls, call state
media.rs RTP send/receive, DTMF, protection against stray audio packets
audio.rs, ringtone.rs Microphone, speaker and ringtone through cpal
g711.rs, rtp.rs, sdp.rs Codec, packet format and session description
store.rs Settings file, call history and keychain access

The SIP signalling is handled by rsipstack.

Your account, call history and language choice live in:

System Settings and history Password
macOS ~/Library/Application Support/RustSIPPhone/settings.json Keychain
Windows %APPDATA%\RustSIPPhone\settings.json Credential Manager
Linux ~/.config/RustSIPPhone/settings.json Secret Service (GNOME Keyring, KWallet)

📝 Notes and limitations

  • One account, one call at a time.
  • Fixed-size window: it cannot be resized or maximized.
  • Transport: UDP, TCP, TLS, WS and WSS. Audio is IPv4-only, so the phone prefers IPv4 addresses of a station. TLS trusts the operating system's certificates plus an optional extra file; a self-signed station certificate must be added there. WSS trusts the system's certificates only.
  • Audio: G.711 (PCMU/PCMA) only. Calls are not encrypted (no SRTP); use a trusted network or a VPN.
  • Not supported yet: attended transfer, being transferred by the other side, several calls at once, conferences and video.
  • NAT: works when the PBX is on your network or reachable publicly. If you are behind NAT and the other side hears nothing, check that your router does not block UDP media from the PBX.
  • Safety: the phone only accepts incoming calls from the server you signed in to, and only accepts audio from the addresses negotiated for the call.
  • Developed mainly on macOS; Windows and Linux builds come from CI. Please open an issue if something misbehaves there.

🤝 Contributing

Issues and pull requests are welcome. Please run cargo test before sending a change and keep the code formatted with cargo fmt.

Adding a language: add a variant to Lang in i18n.rs, then supply its text where Lang::t is used (the interface in ui.rs and the messages in i18n.rs). A test checks that every message exists in every language.

📄 License

RustSIPPhone is open source software released under the MIT License — you may use, copy, modify and distribute it freely, including commercially, as long as the copyright notice is kept.

Copyright © 2026 Tim

Built with Rust 🦀 · egui · cpal · rsipstack

About

Free, open-source desktop SIP softphone written in Rust. UDP/TCP/TLS/WS/WSS, G.711 audio, hold, transfer, DND, auto-answer, English and Russian UI. macOS, Windows, Linux.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages