Skip to content

Node-API addon that embeds Baresip for a simple, session‑centric SIP stack in Node.js and Electron.

License

Notifications You must be signed in to change notification settings

Siperb/baresip-node

Repository files navigation

baresip-node

baresip logo

Prebuilts CI Platforms Node License

Node-API addon that embeds Baresip for a simple, session‑centric SIP stack in Node.js and Electron.


Projects using this repository

  • Siperb – Modern softphone (WebRTC + SIP) for Asterisk, FreeSWITCH, and other PBXs.
  • Siperb Softphone leverages BareSIP for native UDP/RTP today and will converge with WebRTC for a unified experience.
  • Issues / Discussions

Contents

  • Highlights
  • Requirements
  • Build (from source)
  • Prebuilt binary for distribution
  • Install without building (prebuilt branch)
  • Quick start
  • API
  • Examples
  • Troubleshooting
  • Contributing

Highlights

  • Session object with Answer, Hangup, GetStats, SendDTMF
  • Clean, mapped event callbacks (no more unknowns)
  • Configurable User-Agent, log level, and SIP trace
  • Cross-platform audio backend selection (macOS, Windows, Linux)
  • Codec control: preload, advertise specific codecs per Register, enumerate available codecs
  • Register expires control

How it fits together

Electron (UI) ──IPC──▶ Node child (engine) ──N-API──▶ baresip_node.node ──▶ libre/baresip
	▲                              │                         │
	└────────────── events ◀───────┴────────────── RTP/SIP ─┘

Requirements

  • Node 18+ (20/22 recommended)
  • CMake 3.20+
  • A C/C++ toolchain
    • macOS: Xcode Command Line Tools
    • Windows: MSVC 2022 Build Tools
    • Linux: build-essential

Build (from source)

  • npm ci
  • npm run build

This will produce build/Release/baresip_node.node (the native addon). The JS wrapper is at lib/index.js.

Prebuilt binary for distribution

For GitHub consumers who shouldn’t compile locally, we stage the built addon under prebuilt/<platform>-<arch>/node/baresip_node.node and commit it.

  • The JS loader in lib/index.js loads only from prebuilt/<platform>-<arch>/node. There is no fallback to a local build.

Note: The prebuilt path is fixed to node and does not vary by Node ABI. If the prebuilt was built with a different Node than your runtime, ensure compatibility or rebuild. For local development without CI prebuilts, copy build/Release/baresip_node.node to prebuilt/<platform>-<arch>/node/.

Install without building (prebuilt branch)

If you prefer to consume prebuilts directly from this repo (no local compile), install from the dedicated prebuilt branch. This branch contains the same sources plus committed prebuilts under prebuilt/<platform>-<arch>/node/.

  • npm install (one-off):
    • npm i github:Siperb/baresip-node#prebuilt
  • package.json dependency:
    • { "dependencies": { "baresip-node": "github:Siperb/baresip-node#prebuilt" } }

Notes

  • The prebuilt branch is updated by CI and includes only prebuilts; main remains source-first.
  • A single Node-API binary per OS/arch is used for both Node and Electron on that platform/arch.
  • TLS is disabled by default in the prebuilt to avoid OpenSSL/BoringSSL conflicts in Electron; enable only if you know your environment supports it.

Quick start

Minimal outbound call flow using registration:

const {
	Init, Register, Invite, Shutdown, Callbacks,
	SetLogLevel, EnableSipTrace
} = require('baresip-node');

(async () => {
	// Observe events (optional)
	Callbacks.OnRegisterSuccess = () => console.log('Registered');
	Callbacks.OnInviteIncoming = (session) => console.log('Incoming call', session.id);
	Callbacks.OnCallConnected = (session) => console.log('Connected', session.callId);
	Callbacks.OnCallEnded = (endedSession) => console.log('Ended', endedSession.id);

	await Init({
		userAgent: 'baresip-node/0.1',
		// SIP account
		SipUserName: '<user>',
		SipAuthUser: '<auth-user>',
		SipPassword: '<password>',
		SipRegisterServer: '<sip.example.com>',
		SipTransport: 'udp',
		RegisterExpires: 300,
		// Observability
		logLevel: 'info',
		sipTrace: false,
		// Audio backend (defaults shown per platform)
		// audio: { srcMod: 'coreaudio', playMod: 'coreaudio' },
		// Codec preload and offer control
		codecs: { enableAll: false, preload: ['g711', 'g722'] },
		AudioCodecs: ['PCMU/8000', 'PCMA/8000']
	});

	EnableSipTrace(true); // optional at runtime
	SetLogLevel('debug'); // optional at runtime

	const ok = await Register();
	if (!ok) throw new Error('Register failed');

	// Place a call to extension 201
	const session = await Invite('201', { id: 'my-call-uuid' });
	console.log('Invited, callId =', session && session.callId);
})();

If you’re developing inside this repository (not consuming via npm), you can require the local entrypoint instead:

const api = require('./lib/index.js');

See the Electron example in examples/electron for a full end-to-end UI.

API

Init(options)

Initializes Baresip, configures logging/audio/codecs, and registers an event bridge. Returns a Promise that resolves to true.

Options (all optional unless noted):

  • userAgent: string – SIP User-Agent token for UA
  • logLevel: 'none' | 'error' | 'warn' | 'info' | 'debug' – Baresip log level
  • sipTrace: boolean – Enable SIP message logging
  • logStdout, logTimestamps, logColor: booleans – Console formatting controls
  • audio: { srcMod?: string, playMod?: string, srcDev?: string, playDev?: string }
    • Platform defaults: macOS coreaudio, Windows winwave, Linux alsa
  • codecs: { enableAll?: boolean, preload?: string[] }
    • enableAll tries to preload common audio/video codecs
    • preload lists module names to preload at startup (e.g., 'g711', 'g722', 'opus')
  • SIP account fields bundled for Register convenience:
    • SipUserName, SipAuthUser, SipPassword, SipRegisterServer, SipTransport, RegisterExpires
    • AudioCodecs, VideoCodecs: array or comma string; if 'all', no restriction is applied

Register()

Uses Init-provided account fields to register the UA. Returns Promise.

Codec control at registration time:

  • AudioCodecs: string[] | string – e.g., ['PCMU/8000','PCMA/8000']
  • VideoCodecs: string[] | string – e.g., ['VP8/90000','H264/90000']
  • Special value 'all' removes restrictions so Baresip can offer all enabled codecs.
  • If unspecified and enableAll=false, defaults to G.711 PCMU/PCMA.

Expires:

  • RegisterExpires or SipRegisterExpires: number (seconds), applied via account_set_regint before ua_register

Invite(handle: string, args?: { id?: string, server?: string })

Places a call to sip:<handle>@<server>. Server is resolved from SipRegisterServer or SipDomain, unless overridden by args.server. Returns Promise.

Hangup(callId: number)

Hangs up a call by numeric callId. Returns boolean.

Shutdown()

Stops the Baresip main loop and releases the UA.

Observability

  • SetLogLevel(level)
  • EnableSipTrace(enable)

Capabilities

  • GetAvailableAudioCodecs(): string[]
  • GetAvailableVideoCodecs(): string[]

Session object

Represents a call and tracks state and event history.

Fields

  • id: string – external app-level id (auto-UUID if not provided)
  • callId: number – native Baresip call id
  • state: 'new' | 'incoming' | 'outgoing' | 'inviting' | 'progress' | 'ringing' | 'answered' | 'connected' | 'ended'
  • direction: 'incoming' | 'outgoing'
  • hold: boolean
  • mute: boolean
  • video: boolean
  • localSDP / remoteSDP: string
  • Events: Array<{ Activity, Timestamp, Data }>

Methods

  • Answer(): boolean
  • Hangup(): boolean
  • GetStats(): object
  • SendDTMF(dtmf: string): void

Callbacks

Assign handlers on Callbacks to observe events. Relevant ones include:

  • Registration: OnRegistering, OnRegisterSuccess, OnRegisterFailure, OnUnregistering
  • Lifecycle: OnShutdown, OnExit, OnModule, OnCustom
  • Calls: OnInviteIncoming(session), OnCallOutgoing(session), OnCallLocalSDP(session), OnCallRemoteSDP(session), OnCallProgress(session), OnCallAnswered(session), OnCallRinging(session), OnCallConnected(session), OnCallEnded(sessionSnapshot), OnCallTransfer(session), OnCallRedirect(session), OnCallTransferFailed(session), OnDTMFReceived(session), OnRTPEstablished(session), OnCallRTCP(session), OnCallMENC(session), OnVUTX(session), OnVURX(session), OnAudioError(event), OnCallHold(session), OnCallResume(session), OnRefer(session), OnSipSessConn(event)

Notes

  • OnCallEnded receives a deep-copied snapshot; the live session is removed from Sessions.
  • Unknown event payloads are sanitized for readability.

Examples

  • examples/electron – Standalone Electron app that consumes github:Siperb/baresip-node#prebuilt

Run the Electron example (standalone)

  • From repo root:
    • npm run example:electron

This installs the example’s dependencies and launches Electron. The app spawns a separate Node child process for the SIP engine to avoid Electron/OpenSSL conflicts and uses the platform’s default audio backend (CoreAudio/ALSA/WASAPI). On macOS, grant microphone permission when prompted.

Notes

  • The example depends on github:Siperb/baresip-node#prebuilt, so it behaves like an external consumer and does not use any local build outputs.
  • TLS is disabled by default; enable only if you control the environment and understand the implications with Electron’s BoringSSL.

Project layout

  • src/baresip_addon.cc – Native addon bridge to Baresip (Node-API)
  • lib/index.js – JavaScript wrapper and Session model
  • deps/ – vendored dependencies (baresip, libre, openssl, libsrtp, opus)
  • build/ – cmake-js build output

Troubleshooting

  • No audio on macOS: Ensure CoreAudio is selected (default). You can set audio: { srcMod: 'coreaudio', playMod: 'coreaudio' }.
  • No audio on Linux: Ensure ALSA devices are accessible; set audio: { srcMod: 'alsa', playMod: 'alsa' } and use srcDev/playDev if needed.
  • Codecs not offered: Check codecs.enableAll, codecs.preload, and AudioCodecs/VideoCodecs passed to Register.
  • SIP trace: EnableSipTrace(true) after Init to view SIP messages.

Contributing: deps and builds

  • Dependencies are vendored under deps/ and built via CMake as part of the native target. On macOS, a sample ./build_deps_mac.sh shows how to build and stage certain libs if you want static linking; it’s optional for most users.
  • CI publishes prebuilts to the prebuilt branch. The main branch is source-first.

About

Node-API addon that embeds Baresip for a simple, session‑centric SIP stack in Node.js and Electron.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published