AccelerateNetworks / PagingServer

SIP-based Announcement / PA / Paging / Public Address Server system
GNU General Public License v2.0
28 stars 14 forks source link
answering-machine paging pjsip pjsua public-announcement pulseaudio sip telephony

PagingServer

SIP-based Announcement / PA / Paging / Public Address Server system.

Main component of this project is a script to run PJSUA SIP client connected to a PulseAudio sound server routing audio to whatever sound cards and speaker sets.

It picks up calls, plays klaxon on speakers, followed by the announcement made in that call. Music plays in-between announcements.

Script controls PJSUA and PulseAudio (muting/unmuting streams there) to make them work to that effect.

|

.. contents:: :backlinks: none

Usage

After installation (see below), the script should be configured, providing it with at least the SIP account data for the general usage.

Configuration file (ini format_) locations:

All files will be looked up and parsed in that order, values in next ones overriding corresponding ones in the previous and defaults.

See output of paging --help for info on how to specify additional configuration, more up-to-date list of default paths, as well as general information for all the other options available.

Provided paging.example.conf_ file has all the available configuration options and their descriptions.

To see default configuration options, use paging --dump-conf-defaults, and run paging --dump-conf ... to see the actual options being picked-up and used at any time.

There are two general (supported) ways to start and run the script:

Both are described in more detail below.

Start/run in the foreground


First - make sure PulseAudio_ and its ALSA_ backend are configured (and unmuted,
in case of ALSA) as they should be and pulse server can run/runs for same user
that this script will be running as.

How to do that is out of scope for this README.

Then just run the thing as::

  % paging

Can be used directly from terminal, or with any init system or daemon manager,
including systemd, upstart, openrc, runit, daemontools, debian's
"start-stop-daemon", simple bash scripts, etc.

For systemd in particular, see the "Running as a systemd service" section below.

Running from terminal to understand what's going on, these options might be also
useful::

  % paging --debug
  % paging --debug --pjsua-log-level 10
  % paging --dump-conf

See also "Installation" and "Audio configuration" sections below.

Running as a systemd service

This method should be preferred, as it correctly notifies init when service is actually ready (i.e. pjsua inputs/outputs initialized), so that others can be scheduled around that, and primes watchdog timer, detecting if/when app might hang due to some bug.

Provided paging.service file (in the repository, just an ini file) should be installed to /etc/systemd/system, and assumes following things:

With all these correct, service can then be used like this:

See systemctl(1) manpage_ for more info on such commands.

If either app itself is installed to another location (not /usr/local/bin/paging) or extra command-line parameters for it are required, ExecStart= line can be altered either in installed systemd unit file directly, or via systemctl edit paging.

systemctl daemon-reload should be run for any modifications to /etc/systemd/system/paging.service to take effect.

Similarly, User=paging line can be altered or overidden to change system uid to use for the app.

If python-systemd module is unavailable, following lines should be dropped from the paging.service::

Type=notify WatchdogSec=...

And --systemd option removed from ExecStart= line, so that app would be started as a simple non-forking process, which will then be treated correctly by systemd without two options above.

Installation

This is a regular package for Python 2.7 (not 3.X), but with some extra run-time requirements (see below), which can't be installed from PyPI.

Package itself can be installed at any time using pip_, e.g. via pip install PagingServer (this will try to install stuff to /usr!!!).

Unless you know python packaging though, please look at pip2014.com, python packaging tutorial, documentation below for easy installation (from packages/repo) on specific systems.

Requirements


* `Python 2.7`_ (NOT 3.X).

* PJSUA_ (PJSIP User Agent) and its python bindings.

  Can be packaged as "pjsip", "pjsua" or "pjproject" in linux distros.

  Python bindings (from the same tarball) can also be packaged separately as
  "python-pjproject" or something like that.

  If either of those isn't available, be sure to build and install pjsua AND its
  python bindings manually from the same sources, and NOT e.g. install pjsua
  from package and then build bindings separately.

* PulseAudio_

* `pulsectl python module`_

* (optional) ffmpeg_ binary - if audio samples are not wav files (will be
  converted on every startup, if needed).

* (optional) python-systemd_ - only if ``--systemd`` option is used (e.g. with
  shipped .service file).

  Developed and shipped separately from main systemd package since v223
  (2015-07-29), likely comes installed with systemd prior to that.

  Would probably make sense to install that module from OS package, which should
  be available if systemd is used there as init by default.

* (optional) raven_ python module - for reporting any errors via sentry.

Debian Jessie

Other systems


Just build/install all the requirements above from OS packages or however.

Audio configuration
-------------------

Overview of the software stack related to audio flow:

* PJSUA picks-up the calls, decoding audio streams from SIP connections.

* PJSUA outputs call audio to via PortAudio_.

* PortAudio can use multiple backends on linux systems, including:

  * ALSA_ libs (and straight down to linux kernel)
  * OSS (/dev/dsp*, only supported through emulation layer in modern kernels)
  * JACK sound server
  * PulseAudio_ sound server (through ALSA compatibility layer)

  In this particular implementation, PulseAudio backend is assumed.

* PulseAudio serves as a "hub", receiving streams from music players (mpd_
  instances), klaxon sounds, calls picked-up by PJSUA.

  Depending on PulseAudio and music players' configuration, these outputs can be
  then mixed together and mapped to audio cards (or specific channels of these)
  as necessary.

* PulseAudio outputs sound through ALSA libs and that goes to kernel driver and
  hardware, eventually.

  Here make sure that ALSA is also configured properly - sound hardware unmuted,
  volume level is set correctly and any other necessary mixer controls are set.

  This all is usually easy to do with "alsamixer" tool.

Whole stack can always be tested with command like this::

  % paging --test-audio-file my-sound.wav

That option makes script just play the specified file through pjsua (as it would
output the sound of the incoming call or a klaxon sound) and exit.

If that works correctly, all that sound output pipeline from pjsua to alsa
should be fine.

PagingServer audio configuration

Configuration here can be roughly divided into these sections (at the moment):

All settings mentioned here are located in the [audio] section of the configuration file.

See paging.example.conf_ for more detailed descriptons.

Misc tips and tricks

Collection of various things related to this project.

Pre-convert klaxon sound(s) to wav from any format


Can be done via ffmpeg_ with::

  ffmpeg -y -v 0 -i sample.mp3 -f wav sample.wav

Where it doesn't actually matter which format source "sample.mp3" is in - can be
mp3, ogg, aac, mpc, mp4 or whatever else ffmpeg supports.

Might help to avoid startup delays due to conversion of these on each run.

If pjsua will be complaining about sample-rate difference between wav file and
output, e.g. ``-ar 44100`` option can be used (after ``-f wav``) to have any
sampling rate for the output file.

Benchmark script (callram.py)

Description below is from old README.md file pretty much verbatim.

We've tested this script with thousands of calls, it is fairly reliable and light on resources. Total CPU use on a Pentium 4 @ 2.8ghz hovered around 0.5% with 4MB ram usage. identical figures were observed on a Celeron D @ 2.53Ghz, you could probably get away with whatever your operating system requires to run in terms of hardware.

To benchmark, you'll need to set up callram.py.

Sending error reports to Sentry



Sentry_ is a "modern error logging and aggregation platform".

Python raven_ module has to be installed in order for this to work.

Uncomment and/or set "sentry_dsn" option under the ``[server]`` section of the
configuration file.

It can also be set via ``--sentry-dsn`` command-line option, e.g. in systemd
unit distributed with the package, to apply on all setups where package is deployed.

Copyright and License
---------------------

| Code and documentation copyright 2015 Accelerate Networks.
| Code released under the GNU General Public License v2.0.
| See LICENSE file in the repository for more details.
| Docs released under Creative Commons.

.. _PJSUA: http://www.pjsip.org/
.. _PulseAudio: https://wiki.freedesktop.org/www/Software/PulseAudio/
.. _ALSA: http://www.alsa-project.org/main/index.php/Main_Page
.. _ini format: https://en.wikipedia.org/wiki/INI_file
.. _paging.example.conf: https://github.com/AccelerateNetworks/PagingServer/blob/master/paging.example.conf
.. _PortAudio: http://www.portaudio.com/
.. _ffmpeg: http://ffmpeg.org/
.. _systemctl(1) manpage: http://www.freedesktop.org/software/systemd/man/systemctl.html
.. _mpd: http://musicpd.org/
.. _Sentry: https://getsentry.com/
.. _pip: http://pip-installer.org/
.. _pip2014.com: http://pip2014.com/
.. _python packaging tutorial: https://packaging.python.org/en/latest/installing.html
.. _Python 2.7: http://python.org/
.. _pulsectl python module: https://github.com/mk-fg/python-pulse-control
.. _raven: https://pypi.python.org/pypi/raven/5.5.0
.. _python-systemd: https://github.com/systemd/python-systemd
.. _install.debian_jessie.sh: https://github.com/AccelerateNetworks/PagingServer/blob/master/setup-scripts/install.debian_jessie.sh