Sipwise Community Edition Handbook
Sipwise Community Edition Handbook
CE
Sipwise GmbH <[email protected]>
Table of Contents
1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
2. Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.1. Platforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3. Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4. Concept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.1. Contacts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2. Resellers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.4. Contracts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.5. Customers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.6. Subscribers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
5. Kick-off. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
6. Billing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
7. Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Appendix. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
Chapter 1. Introduction
1.1. About this Handbook
This handbook describes the architecture and the operational steps to install, operate and modify the
Sipwise C5 CE.
In various chapters, it describes the system architecture, the installation and upgrade procedures and
the initial configuration steps to get your first users online. It then dives into advanced preference
configurations such as rewrite rules, call blocking, call forwarding, etc.
There is a description of the customer self-care interface, how to configure the billing system and how
to provision the system via the API.
Finally, it describes the internal configuration framework, the network configuration and gives hints
about tweaking the system for better security and performance.
Sipwise C5 has three solutions that differ in call capacity and service redundancy: CARRIER, PRO and
CE. The current handbook describes the CE solution.
The Sipwise C5 CE can be installed in a few steps within a couple of minutes and requires no
knowledge about configuration files of specific software components.
Using a highly modular design approach, Sipwise C5 leverages popular open-source software like
MySQL, NGINX, Kamailio, SEMS, Asterisk, etc. as its core building blocks. These blocks are glued
together using optimized and proven configurations and workflows and are complemented by
functionality developed by Sipwise to provide fully-featured and easy-to-operate VoIP services.
After downloading and starting the installer, it will fetch and install all the required Debian packages
from the relevant Debian repositories. The installed applications are managed by the Sipwise C5
Configuration Framework. This configuration framework makes it possible to change low-level system
parameters in a single place, so Sipwise C5 administrators don’t need to have any knowledge of dozens
of different configuration files from different packages. This provides a bullet-proof way of operating,
changing and tweaking an otherwise quite complex system.
Once configured, integrated web interfaces are provided for both end users and Sipwise C5
administrators. Provisioning and billing API allows companies to tightly integrate Sipwise C5 into
existing OSS/BSS infrastructures to optimize workflows.
In the past, creating a business-ready VoIP service included installation and configuration of SIP
software like Asterisk, OpenSER, Kamailio, etc., which can get quite difficult when it comes to
implementing advanced features. It required implementing different web interfaces, billing engines and
connectors to existing OSS/BSS infrastructure. These things are now obsolete due to the Sipwise C5
CE, which covers all these requirements.
Sipwise also provides training and commercial support for the platform. Additionally, we offer a
migration path to the Sipwise C5 PRO or CARRIER appliance, which is the commercial, carrier-grade
version of the Sipwise C5 CE. If the user base grows on the Sipwise C5 CE, this will allow operators to
migrate seamlessly to a highly available and scalable platform with defined service level agreements,
phone support and on-call duty. Please visit www.sipwise.com for more information on commercial
offerings.
Chapter 2. Architecture
2.1. Platforms
2.1.1. CE Platform
The Sipwise C5 CE platform is one single node running all necessary components of the system. The
components are outlined in the following figure:
Operator
Infrastructure
Customer
SNMP Admin Panel API
Self-Care
Back-to-Back
Voice Mail Billing Mediation Database
User Agent
SIP
SIP
Peerings
Endpoints
• Provisioning
• SIP Signaling and Media Relay
• Mediation and Billing
The components involved in SIP and Media on the Sipwise C5 CE are shown in the following figure:
SIP Back-to-Back
SIP Proxy
loadbalancer User Agent
SIP Signalling
Early Media,
Music on Hold,
SIP Auto-attendant,
Endpoints Conferences, etc.
and
LOAD-
BALANCER
Peerings
Application
Server
Media
Relay
RTP Media Control Voicemail,
(e.g. voice, video, FAX
fax, DTMF, etc.)
Media Relay
PROXY
The load-balancer is the only SIP element in the system which exposes a SIP interface to the public
network. Its second leg binds in the switch-internal network to pass traffic from the public internet to
the corresponding internal components.
The name load-balancer comes from the fact that in the commercial version, when scaling out the
system beyond one pair of servers, the load-balancer instance becomes its own physical node and
then handles multiple pairs of proxies behind it.
On the public interface, the load-balancer listens on port 5060 for UDP and TCP, as well as on 5061 for
TLS connections. On the internal interface, it speaks SIP via UDP on port 5060 to the other system
components, and listens for XMLRPC connections on TCP port 5060, which can be used to control the
daemon.
The SIP load-balancer can be managed via the commands ngcp-service start
kamailio-lb, ngcp-service stop kamailio-lb and ngcp-service restart
kamailio-lb. Its status can be queried by executing ngcp-service status
kamailio-lb or ngcp-service summary | grep "kamailio-lb". Also ngcp-
TIP
kamctl lb and ngcp-kamcmd lb are provided for querying kamailio functions, for
example: ngcp-kamcmd lb htable.dump ipban. Execute the command: ngcp-kamctl
lb fifo system.listMethods or ngcp-kamcmd lb system.listMethods to get the
list of all available queries.
It also writes start- and stop-records for each call, which are then transformed into call detail records
(CDR) by the mediation system.
If the endpoints indicate negotiation of one or more media streams, the proxy also interacts with the
Media Relay to open, change and close port pairs for relaying media streams over Sipwise C5, which is
especially important to traverse NAT.
The proxy listens on UDP port 5062 in the system-internal network. It cannot be reached directly from
the outside, but only via the SIP load-balancer.
The SIP proxy can be controlled via the commands ngcp-service start kamailio-
proxy, ngcp-service stop kamailio-proxy and ngcp-service restart
kamailio-proxy. Its status can be queried by executing ngcp-service status
kamailio-proxy or ngcp-service summary | grep "kamailio-proxy". Also
TIP
ngcp-kamctl proxy and ngcp-kamcmd proxy are provided for querying kamailio
functions, for example: ngcp-kamctl proxy ul show. Execute the command: ngcp-
kamctl proxy fifo system.listMethods or ngcp-kamcmd proxy
system.listMethods to get the list of all available queries.
This element is typically optional in SIP systems, but it is always used for SIP calls (INVITE) that don’t
have Sipwise C5 as endpoint. It acts as application server for various scenarios (e.g. for feature
provisioning via Vertical Service Codes and as Conferencing Server) and performs the B2BUA
decoupling, topology hiding, caller information hiding, SIP header and Media feature filtering, outbound
registration, outbound authentication and call length limitation as well as Session Keep-Alive handler.
Due to the fact that typical SIP proxies (like the load-balancer and proxy in Sipwise C5) do only interfere
with the content of SIP messages where it’s necessary for the SIP routing, but otherwise leave the
message intact as received from the endpoints, whereas the B2BUA creates a new call leg with a new
SIP message from scratch towards the called party, SIP message sizes are reduced significantly by the
B2BUA. This helps to bring the message size under 1500 bytes (which is a typical default value for the
MTU size) when it leaves Sipwise C5. That way, chances of packet fragmentation are quite low, which
reduces the risk of running into issues with low-cost SOHO routers at customer sides, which typically
have problems with UDP packet fragmentation.
The SIP B2BUA only binds to the system-internal network and listens on UDP port 5080 for SIP
messages from the load-balancer or the proxy, on UDP port 5048 for control messages from the cli tool
and on TCP port 8090 for XMLRPC connections to control the daemon.
In cases when B2B is engaged into processing the media (RTP/RTCP data), it uses this UDP ports range
by default: 15000 - 19999.
The SIP B2BUA can be controlled via the commands ngcp-service start sems, ngcp-
TIP service stop sems and ngcp-service restart sems. Its status can be queried by
executing ngcp-service status sems or ngcp-service summary | grep "sems".
The App-Server listens on the internal interface on UDP port 5070 for SIP messages and by default
uses media ports in the range from UDP port 10000 to 14999.
The SIP App-Server can be controlled via the commands ngcp-service start
asterisk, ngcp-service stop asterisk and ngcp-service restart asterisk.
TIP
Its status can be queried by executing ngcp-service status asterisk or ngcp-
service summary | grep "asterisk".
The rtpengine internally listens on UDP port 12222 for control messages from the SIP proxy. For each
media stream, it opens two pairs of UDP ports on the public interface in the range of 30000 and 40000
per default, one pair on even port numbers for the media data, and one pair on the next odd port
numbers for metadata, e.g. RTCP in case of RTP streams. Each endpoint communicates with one
dedicated port per media stream (opposed to some implementations which use one pair for both
endpoints) to avoid issues in determining where to send a packet to. The rtpengine also sets the
QoS/ToS/DSCP field of each IP packet it sends to a configured value, 184 (0xB8, expedited forwarding)
by default.
The kernel-internal part of the rtpengine is facilitated through an iptables module having the target
name RTPENGINE. If any additional firewall or packet filtering rules are installed, it is imperative that this
rule remains untouched and stays in place. Otherwise, if the rule is removed from iptables, the kernel
will not be able to forward the media packets and forwarding will fall back to the user-space daemon.
The packets will still be forwarded normally, but performance will be much worse under those
circumstances, which will be especially noticeable when a lot of media streams are active concurrently.
See the section on Firewalling for more information.
The Media Relay can be controlled via the commands ngcp-service start
rtpengine, ngcp-service stop rtpengine and ngcp-serivce restart
TIP
rtpengine. Its status can be queried by executing ngcp-service status rtpengine"
or ngcp-service summary | grep "rtpengine".
DB01→prx01a + DB01→prx01b are master→slave replication for read/write scale (write to remote/shared
db01, read from local prx DB).
Separate hot and cold data. Hot in Redis for low IO. Cold in MariaDB.
Separate huge data (e.g. voicemail, voisniff data) to separate 'storage' DB node.
With such setup the central db01 pair can handle all the planned and unexpected DB load without the
significant hardware resource usage. DB01a and DB01b can be located in different Geo-locations for
High-Availability (low latency link is required for replications).
Further DB nodes scalability can be achieved using Geo-redundant setup. Please contact Sipwise sales
team for more details here.
The load balancers use the Path extension of SIP to make sure during SIP registration that calls
targeted to a subscriber are routed via the same load balancer pair which the subscriber used during
registration for proper traversal of symmetric NAT at the customer premise.
A SIP or XMPP request reaching a load balancer can be routed to any available proxy in the whole
system, or only to proxies belonging to the same chassis as the load balancer, depending on the
system configuration.
Chapter 3. Deployment
This chapter provides a step by step instruction on how to set up a Sipwise C5 from scratch.
Hardware Requirements
Internet Connection
You can install the current Sipwise C5 CE version mr10.4.1 using install CD image (checksums: sha1,
md5).
When DHCP is available in your infrastructure then you shouldn’t have to configure
anything, instead choose DHCP and press enter. If network configuration still doesn’t work
TIP
as needed a console based network configuration system will assist you in setting up your
network configuration. VLANs are also supported at this stage.
Also, you can use Sipwise C5 install CD to boot the Grml (Debian based live system) rescue system,
check RAM using a memory testing tool or install plain Debian system for manual installation using
Sipwise C5 installer.
You need to install Debian 11 (bullseye) 64-bit on the server. A basic installation without any additional
task selection (like Desktop System, Web Server etc.) is sufficient.
TIP Sipwise recommends using the latest Netinstall ISO as installation medium.
If you use other kinds of installation media (e.g. provided by your hosting
provider), prepare for some issues that might come up during installation. For
IMPORTANT example, you might be forced to manually resolve package dependencies in
order to install Sipwise C5 . Therefore, it is HIGHLY RECOMMENDED to use a
clean Debian installation to simplify the installation process.
If you installed your system using the Debian CDs/DVDs (so neither using Sipwise C5
install CD nor the Debian Netinstall ISO) apt-get might prompt to insert disk to proceed
NOTE during Sipwise C5 installation. The prompt won’t be visible for you and installation
hangs. Please disable the cdrom entries in /etc/apt/sources.list and enable a Debian
mirror (e.g. https://deb.debian.org/debian/) instead.
If you plan to install Sipwise C5 on Virtual Hosting Providers like Dreamhost with their provided Debian
installer, you might need to manually prepare the system for Sipwise C5 installation, otherwise the
installer will fail installing certain package versions required to function properly.
A Dreamhost virtual server uses apt-pinning and installs specific versions of MySQL and apache, so you
need to clean this up beforehand.
Apache is not used by default since mr3.6.1, still better to remove pinned Apache
NOTE
version.
Be aware that this step will break your web-based system administration provided
WARNING
by Dreamhost. Only do it if you are certain that you won’t need it.
PKG=ngcp-installer-mr10.4.1.deb
wget http://deb.sipwise.com/spce/${PKG}
dpkg -i ${PKG}
ngcp-installer
NOTE You can find the previous versions of Sipwise C5 installer package here.
The installer will ask you to confirm that you want to start the installation. Read the given information
carefully, and if you agree, proceed with y.
The installation process will take several minutes, depending on your network connection and server
performance. If everything goes well, the installer will (depending on the language you use), show
something like this:
Be aware that all services will be disabled. If you need a specific service - re-
WARNING
enable it when the initial configuration is done.
During the installation, you can watch the background processing by executing the following command
on a separate console:
tail -f /var/log/ngcp-installer.log
Initial Configuration
After the installation has finished successfully and the server gets rebooted it is necessary to perform
the initial configuration:
screen -S ngcp
ngcp-initial-configuration
The tool will ask you to confirm the network configuration which is based on the current one. Read
carefully the information printed on screen, and if you agree, proceed by typing y. If you want to
change these parameters, you can edit the file /etc/ngcp-installer/config_deploy.inc and adjust the
variables with the desired values.
System was successfully configured, now you have the best VoIP software.
Vagrant is an open-source software for creating and configuring virtual development environments.
Sipwise provides a so called Vagrant base box for your service, to easily get direct access to your own
Sipwise C5 Virtual Machine without any hassles.
The following software must be installed to use Vagrant boxes: VirtualBox v.5.2.26+ and
NOTE
Vagrant v.2.2.3+.
As soon as the machine is up and ready you should have your local copy of Sipwise C5 with the
following benefits:
• all the software and database are automatically updated to the latest available version
• the system is configured to use your LAN IP address (received over DHCP)
• basic SIP credentials to make SIP-2-SIP calls out of the box are available
vagrant ssh
password administrator).
There are two ways to access VM resources, through NAT or Bridge interface:
VM ports smaller then 1024 mapped to ports 22<vm_port> through NAT, otherwise root
NOTE on host machine requires to map them. It means SSH port 22 mapped to port 2222,
WEB port 443 → 22443.
VM IP address (a.b.c.d), as well as SIP credentials will be printed to terminal during "vagrant up" stage,
e.g.:
vagrant halt
vagrant destroy
vagrant box remove spce-mr10.4.1
• Default SSH login is root and password is sipwise. SSH connection details can be displayed via:
vagrant ssh-config
• VirtualBox Guest Additions is installed by default but disabled. Enable it to use Vagrant Synced
Folders feature. Execute the following commands inside VM:
• You can download a Vagrant box for VirtualBox from here manually (checksums: sha1, md5).
VirtualBox image
You can download a VirtualBox image from here (checksums: sha1, md5). Once you have downloaded
the file you can import it to VirtualBox via its import utility.
The format of the image is ova. If you have VirtualBox 3.x running, which is not compatible with ova
format, you need to extract the file with any tar compatible software and import the ovf file which is
inside the archive.
On Windows, right-click on the ova file, choose Open with and select WinZIP or WinRAR or any other
application able to extract tar archives. Extract the files to any place and import the resulting ovf file in
VirtualBox.
VMware image
You can download a VMware image from here (checksums: sha1, md5). Once you have downloaded
the file, extract the zip file and copy its content to your virtual machines folder.
• The network configuration is set to DHCP. You’ll need to change it to the appropriate static
configuration.
• As the virtual image is a static file, it won’t contain the most updated versions of our software.
Please upgrade the system via apt as soon as you boot it for the first time.
Sipwise provides AMI (Amazon Machine Images) images in several Amazon EC2 regions for the
supported Sipwise C5 releases only. Please find the appropriate AMI ID for your region in release
announcement.
If the release is out of support you can still find AMI image for it but only in one region -
NOTE
eu-central-1
The current documentation will use Amazon region eu-central-1 with AMI ID ami-
NOTE 0868999d7ba41b562 as an example. Please find the appropriate AMI ID for your region
in the latest release announcement.
If you want to use Sipwise C5 AMI image in one of the regions where it’s not available, you
can create your own private AMI image based on the one provided by Sipwise.
You can create your private image in any region following these steps
For more details please follow the official Amazon AWS documentation about how to
create and copy AMI images.
Select "Community AMIs" option, enter "ami-0868999d7ba41b562" inside the search field and press
"Select" button:
Select the Instance Type you want to use for running Sipwise C5 (recommended: >=4GB RAM):
• Configure Instance: optional (no special configuration required from Sipwise C5)
• Add Storage: choose >=8GB disk size (no further special configuration required from Sipwise C5)
• Tag Instance: optional (no special configuration required from Sipwise C5)
• Configure Security Group: create a new security group, using the following rules:
◦ TCP port 22 (SSH)
◦ TCP port 443 (HTTPS/CSC)
◦ TCP port 1443 (Admin Panel)
◦ TCP port 5060 (SIP/TCP)
◦ UDP port 5060 (SIP/UDP)
◦ TCP port 5061 (SIP/TLS)
◦ TCP port 5222 (SIP)
◦ TCP port 5269 (SIP)
◦ UDP port 30000:44999 (RTP)
Please feel free to restrict the 'Source' options in your Security Group to your own
NOTE
(range of) IP addresses, especially for SSH and Admin Panel!
Finally review instance in the last step (Review Instance Launch) and press Launch button.
Choose an existing key pair which you want to use for logging in, or create a new one if you don’t have
one.
You should have a running instance after a few seconds/minutes now (check DNS name/IP address).
First step should be logging in to the Admin panel (username administrator, password administrator)
and changing the default password: https://$DNS:1443/ and then follow Security, Performance and
Troubleshooting to secure your installation.
Logging in via SSH should work now, using the key pair name (being sip-provider-ce.pem as $keypair in
our example) and the DNS name/IP address the system got assigned.
Now you can increase your privileges to user root for further system configuration:
sudo -s
Don’t forget to add the Advertised IP for kamailio lb instance, since it’s required by the Amazon EC2
network infrastructure:
Now feel free to use your newly started Amazon EC2 Sipwise C5 instance!
To do this, you have to specify the interface where your listening address is configured, which you can
do with the following command (assuming your public interface is eth0):
If you want to enable IPv6 as well, you have to set the address on the proper interface as well, like this
(assuming you have an IPv6 address fdda:5cc1:23:4:0:0:0:1f on interface eth0):
Always use a full IPv6 address with 8 octets. Leaving out zero octets (e.g.
TIP
FDDA:5CC1:23:4::1F) is not allowed.
You should use the IPv6 address in upper-case because LB (kamailio) handles
IMPORTANT
the IPv6 addresses internally in upper-case format.
editor /etc/ngcp-config/network.yml
The following configuration shows NGCP running in the internal 192.168.0.0/24 network behind the
NAT:
...
self:
eth0:
dns_nameservers:
- 192.168.0.1
hwaddr: 11:22:33:44:55:66
ip: 192.168.0.10
gateway: 192.168.0.1
netmask: 255.255.255.0
type:
- ssh_ext
- web_ext
- web_int
- sip_ext
- rtp_ext
interfaces:
- lo
- eth0
lo:
...
Apply the adjusted network configuration, and /etc/network/interfaces will be regenerated from the
new configuration.
# lo ----------------------
auto lo
iface lo inet loopback
# --------------------------------------------
# eth0 ----------------------
auto eth0
iface eth0 inet static
address 192.168.0.10
netmask 255.255.255.0
gateway 192.168.0.1
dns-nameservers 192.168.0.1
# --------------------------------------------
reboot
passwd cdrexport
The installer has set up a MySQL database on your server. You need to set a password for the MySQL
root user to protect it from unauthorized access by executing this command:
For the Administrative Web Panel located at https://<your-server-ip>:1443/, a default user administrator
with password administrator has been created. Connect to the panel (accept the SSL certificate for
now) using those credentials and change the password of this user by going to Settings→Administrators
and click the Edit when hovering over the row.
if you want to use a specific editor only temporarily, set the EDITOR environment variable
TIP instead. For example to run command with the editor set to vim, invoke "EDITOR=vim
command".
You are free to install and configure any other MTA (e.g. postfix) on the system, if
IMPORTANT
you are more comfortable with that.
Chapter 4. Concept
4.1. Contacts
A contact contains information such as the name, the postal and email addresses, and others. A
contact’s main purpose is to identify entities (resellers, customers, peers and subscribers) it is
associated with.
A person or an organization may represent a few entities and it is handy to create a corresponding
organization’s contact beforehand and use it repeatedly when creating new entities. In this case we
suggest populating the External # field to distinguish between customers associated with the same
contact.
Note that the only required contact field is email. For contacts associated with customers, it will be
used for sending invoices and notifications such as password reset, new subscriber creation and others.
A contact for a subscriber is created automatically but only if you specify an email address for this
subscriber. It is mainly used to send notification messages, e.g. in case of a password reset.
4.2. Resellers
The reseller model allows you to expand your presence in the market by including virtual operators in
the sales chain. A virtual operator can be a company without its own VoIP platform and even without a
technical background, but with sales presence in a market. You define such a company as a reseller in
the platform: grant limited access to the administrative web interface (the reseller administrator will
only see his own customers, domains and billing profiles) and define wholesale rates for this reseller.
Then, the reseller is free to operate under its own brand, make up its retail rates, establish the customer
base and resell your services to its customers. The reseller’s profit is a margin between the wholesale
and retail rates.
A reseller usually uses dedicated IP addresses or SIP domain names to provide services. Also, a reseller
can rebrand the self-care web interface for its customers and select languages per SIP domain that
allows the reseller to operate even in multiple countries.
4.4. Contracts
A contract is a combination of a contact and a billing profile, hence it represents a business contract for
your resellers and peering partners.
Contracts can be created in advance on the Reseller and Peering Contracts page, or immediately during
creation of a peer or a reseller.
Note that the customer entity (described below) is a special type of the contract. A customer entity has
an email and an invoice templates in addition to a contact and a billing profile.
4.5. Customers
A customer is a physical or legal entity whom you provide the VoIP service with and send invoices to.
Here are the main features of a customer:
• Contains the contact and legal information. For example, an address or an email address for
invoicing.
• Associated with a billing profile (to define fees per destination) and tracks the balance (used mostly
for post-paid customers).
• Contains a certain number of subscribers who actually use the service and whose calls appear in
the customer’s list of CDRs.
• Provides some default parameters for all its subscribers. For example, voice prompts and call
restriction.
For a residential customer you usually create one customer entity with one subscriber under it. A
residential customer can register multiple devices with the same number thus having a convenient
Viber or Skype-like service: any device can be used to make a call and all of them will ring
simultaneously when there is an incoming call. At the end of the billing period, you send an invoice to
the customer.
For SOHO customers you usually create multiple subscribers under the same customer and assign
every subscriber a dedicated number to allow users make and receive calls. A common invoice will
contain calls of all the subscribers.
Legacy PBX devices that are not capable of passing the challenge-based authentication can be
authenticated by the IP address. Optionally, every user of such a PBX can be authenticated separately
by the FROM header and the IP address. For more details, refer to the Trusted Sources section.
4.6. Subscribers
Every subscriber represents a SIP line or a SIP trunk. For example, in the residential services a
subscriber entity is dedicated to every user. In the SIP trunking scenario, a subscriber can be used to
authenticate all VoIP traffic from the remote PBX device.
In the following table logical subscriber types and their purpose are described.
TIP Subscriber Aliases can provide Extra DIDs or extension numbers to a subscriber.
SIP peerings also enable incoming calls to your platform. For example, if you rent a pool of DID
numbers from a SIP peer and offer them to your residential and business customers.
An interconnection with your termination partners and DID number providers can include multiple
servers and enable both outbound and inbound calls, hence such a configuration is called a SIP peering
group. You configure at least one SIP peering group for every partner and the main principle here is that
all servers in a group terminate calls to the same set of listed destinations.
Any SIP peering group is associated with a contract for reconciliation and billing purposes and includes
two main technical configurations:
• Peering Servers Represent connections to/from your SIP peering’s network. The parameters
include an IP address and/or a hostname of the remote part. For outbound calls, this is the
destination address where to send calls to and for inbound calls it is an IP authorization of the
remote server.
• Outbound/Inbound Peering Rules Outbound rules define through which SIP peering group a call
from a specific subscriber will be sent for termination to a specific destination.
The example below shows four SIP peering groups with different priorities, callee prefixes (actual
destinations offered by this SIP peering) and callee / called patterns (fine-tuning which callee request
URIs and caller URIs are allowed through this SIP peering group).
The figure shows how calls from premium subscribers can in the first place be routed through a
dedicated SIP peering group unavailable to regular subscribers.
See the Routing Order Selection section for details about call routing.
Inbound rules allow filtering out incoming INVITE requests arriving from the corresponding SIP peering
servers.
Chapter 5. Kick-off
A basic VoIP service configuration is fast, easy and straight-forward. Provided that your network and
required DNS records have been preconfigured, the configuration of a VoIP service can be done purely
via the administrative web interface. The configuration mainly includes the following steps:
Let us assume you are using the 1.2.3.4 IP address with an associated sip.yourdomain.com domain to
provision VoIP services. This allows you to provide an easy-to-remember domain name instead of the
IP address as the proxy server. Also, your subscribers' URIs will look like [email protected].
Using an IP address instead of an associated FQDN (domain name) for a SIP domain is not
TIP suggested as it could add extra administrative work if you decide to relocate your servers
to another datacenter or change IP addresses.
Go to the Administrative Web Panel (Admin Panel) running on https://<ip>:1443/ and follow the steps
below. The default web panel user and password are administrator, if you have not already changed it
in Changing Administrator Password.
Thoroughly plan your domain names policy in advance and take into account that: 1) the
TIP name of a SIP domain cannot be changed after creating it in the administrative web panel;
2) subscribers cannot be moved from one domain to another and must be recreated.
The domain name must point to the physical IP address you are going to use for providing the VoIP
service. A good approach is to create an SRV record:
Go to the Domains page and create a new SIP Domain using the FQDN created above.
Select a Reseller who will own the subscribers in this SIP domain. Use the default virtual reseller if
you provide services directly. Enter your SIP domain name and press Save.
You can create multiple SIP domains reusing the existing IP address or adding a new one. Extra SIP
domains are required e.g. if you would like to host a virtual operator on your platform, create separate
domains for providing services in different countries or offer a new service.
For correct billing, notification and invoicing, create a customer with a single SIP
subscriber for the residential service (as it normally has only one telephone line) and a
TIP
customer with multiple SIP subscribers to provide a service to a company with many
telephone lines.
Each Customer has a Contact — a container for the personal and legal information that identifies a private
or corporate customer.
Create a dedicated Contact for every Customer as it contains specific data e.g. name,
TIP
address and IBAN that identifies this customer.
Select the required Reseller and enter the contact details (at least an Email is required), then press Save.
You will be redirected back to the Customer form. The newly created Contact is selected by default
now, so only select a Billing Profile and press Save.
You will now see your first Customer in the list. Hover over the customer and click Details to make extra
configuration if necessary.
Select a SIP Domain created earlier and specify required and optional parameters:
• Domain: The domain part of the SIP URI for your subscriber.
• E164 Number: This is the telephone number mapped to the subscriber, separated into Country Code
(CC), Area Code (AC) and Subscriber Number (SN). For the first tests, you can set an imaginary
number here and change it later when you get number blocks assigned by your PSTN interconnect
partner. So in our example, we’ll use 43 as CC, 99 as AC and 1001 as SN to form the imaginary
number +43 99 1001.
This number can actually be used to place calls between local subscribers, even if you
don’t have any PSTN interconnection. This comes in handy if you use phones instead of
TIP
soft-clients for your tests. The format in which this number can be dialled, so the
subscriber is reached is defined in Configuring Rewrite Rule Sets.
The web username needs to be unique. The system will return a fault if you try to
CAUTION
use the same web username twice.
• Web Password: This is the password for the subscriber to log into her Customer Self Care Interface.
It must be at least 6 characters long.
• SIP Username: The user part of the SIP URI for your subscriber.
• SIP Password: The password of your subscriber to authenticate on the SIP proxy. It must be at least
6 characters long.
• Status: You can lock a subscriber here, but for creating one, you will most certainly want to use the
active status.
• External ID: You can provision an arbitrary string here (e.g. an ID of a 3rd party provisioning/billing
system).
• Administrative: If you have multiple subscribers in one account and set this option for one of them,
this subscriber can administrate other subscribers via the Customer Self Care Interface.
Repeat the creation of Customers and Subscribers for all your test accounts. You should have at least 3
subscribers to test the functionality of the NGCP.
At this point, you’re able to register your subscribers to Sipwise C5 and place calls
TIP
between these subscribers.
• for incoming calls - which SIP message headers to take numbers from
• for outgoing calls - where in the SIP messages to put certain numbers to
• for both - how these numbers are normalized to E164 format and vice versa
To assign a Rewrite Rule Set to a Domain, create a set first as described in Configuring Rewrite Rule Sets,
then assign it to the domain by editing the rewrite_rule_set preference.
Then, select the field you want the User Provided Number to be taken from for inbound INVITE
messages. Usually the From-Username should be fine, but you can also take it from the Display-Name
of the From-Header, and other options are available as well.
To configure your Subscriber, go to Settings→Subscribers and click Details on the row of your subscriber.
There, click on the Preferences button on top.
You want to look into the Number Manipulations and Access Restrictions options in particular, which
control what is used as user-provided and network-provided calling numbers.
• For outgoing calls, you may define multiple numbers or patterns to control what a subscriber is
allowed to send as user-provided calling numbers using the allowed_clis preference.
• If allowed_clis does not match the number sent by the subscriber, then the number configured in cli
(the network-provided number) preference will be used as user-provided calling number instead.
• You can override any user-provided number coming from the subscriber using the user_cli
preference.
Suppose there is Sipwise C5 and some other Class 5 system (can be just another Sipwise C5). You have
recently migrated part of subscribers from another Class 5 system to Sipwise C5. But, you still have SIP
peerings (with ITSPs) at that system, and you would like that recently migrated subscribers are still able
to terminate calls via that another Class 5 system.
This is when the 'Remote Authentication' parameters start helping you. The call flow in this scenario will
be: Sipwise C5→another Class 5 system→SIP peering
And that system (another Class 5 system) will of course treat a call coming to it from Sipwise C5, as if
that would be a direct call from the subscriber (indeed it’s not).
This is when you need to be capable of the authentication and Sipwise C5 gives you this possibility.
You will need to go to subscriber’s preferences and to know specific credentials to be used for that, in
order to pass the authorization. To configure this setting, open the Remote Authentication tab and edit
the following four preferences:
As soon as you define those parameters, a call from behalf of the subscriber, which will be terminated
at another system, can be successfully authenticated.
Location record which will be saved at a remote system, will contain the contact of
NOTE
Sipwise C5 Load-Balancer, not the contact of the end subscriber.
The reason why you might need Sipwise C5 to register at remote system from behalf of the subscriber:
• you want to receive calls from remote system to your subscriber, as if your subscriber would
receive this directly;
• that remote system doesn’t accept a call sent from Sipwise C5 from behalf of the subscriber,
without a registration beforehand;
This registration process will be completely independent from the end subscriber, and
NOTE
will be only triggered and controlled by Sipwise C5.
This is when the 'Remote Authentication' parameters help you again. You need to go to susbcriber’s
preferences, open the Remote Authentication tab and now additionally enable outbound registration:
• peer_auth_register: True
Now in common with the preferences you defined previously in the 'Subscriber authentication for
outbound calls' section, the registration process will start using given credentials.
• Force IPv4 - the subscriber prefers to send the media flow via IPv4
• Force IPv6 - the subscriber prefers to send the media flow via IPv6
• Auto-detect - auto detection is enabled and depending on the IP Family used during the
registration, the preference for media will be picked out accordingly
• use domain default - preference is inherited from the domain values
Both the domain and subscriber preferences contain the NAT and Media Flow Control section, which
gives an access to the ipv46_for_rtpproxy preference.
In order to create a group, you must select a peering contract. You will most likely want to create one
contract per peering group.
Click Save on the Contacts form, and you will get redirected back to the form for creating the actual
Peering Group. Put a name, priority and description there, for example:
The Priority option defines which Peering Group to favor (Priority 1 gives the highest precedence) if two
peering groups have peering rules matching an outbound call. Peering Rules are described below.
To add your first Peering Server, click on the Create Peering Server button.
In this example, we will create a peering server with IP 2.3.4.5 and port 5060:
• Name: test-gw-1
• IP Address: 2.3.4.5
• Hostname: leave empty
• Port: 5060
• Protocol: UDP
• Weight: 1
• Via Route: None
• Enable Probing: enable it, if remote side supports SIP OPTIONS ping
The hostname field for a peering server is optional. Usually, the IP address of the peer is
used as the domain part of the Request URI. Fill in this field if a peer requires a particular
hostname instead of the IP address. The IP address must always be given though as it is
used for the selection of the inbound peer. By default outbound requests will always be
TIP
sent to the specified IP address, no matter what you put into the hostname field. If you
want to send the request using the DNS resolution of the configured hostname,
disregarding in that way the IP, you have to enable outbound_hostname_resolution option
in peer preferences.
If you want to add a peering server with an IPv6 address, enter the address without
TIP
surrounding square brackets into the IP Address column, e.g. ::1.
You can force an additional hop (e.g. via an external SBC) towards the peering server by using the Via
Route option. The available options you can select there are defined in /etc/ngcp-config/config.yml,
where you can add an array of SIP URIs in kamailio→lb→external_sbc like this:
kamailio:
lb:
external_sbc:
- sip:192.168.0.1:5060
- sip:192.168.0.2:5060
Execute ngcpcfg apply "added external sbc gateways", then edit your peering server and select the
hop from the Via Route selection.
Once a peering server has been created, this server can already send calls to the system.
Requests coming from a SIP peering are matched not only by the IP address and a
transport protocol, but also using the source port of a message. This means, if your SIP
peering server created at Sipwise C5 has the 'Port' value set to '5060', then it’s expected
NOTE
that messages (requests) coming from this SIP peering, will have the source port '5060'.
This however applies only to the UDP transport based connections (TCP and TLS are
matched only using an IP address and a transport protocol).
To be able to send outbound calls towards the servers in the Peering Group, you
also need to define Outbound Peering Rules. They specify which source and
IMPORTANT
destination numbers are going to be terminated over this group. To create a rule,
click the Create Outbound Peering Rule button.
Since the previously created peering group will be the only one in our example, we have to add a
default rule to route all calls via this group. To do so, create a new peering rule with the following
values:
In contrast to the callee/caller pattern, the callee prefix has a regular alphanumeric string
TIP
and can not contain any regular expression.
If you set the caller or callee rules to refine what is routed via this peer, enter all phone
TIP
numbers in full E.164 format, that is <cc><ac><sn>.
The Caller Pattern field covers the whole URI including the subscriber domain, so you can
TIP only allow certain domains over this peer by putting for example @example\.com into this
field.
Starting from mr5.0 release, Sipwise C5 supports filtering SIP INVITE requests sent by SIP peers. The
system administrator may define one or more matching rules for SIP URIs that are present in the
headers of SIP INVITE requests, and select which SIP header (or part of the header) must match the
pattern declared in the rule.
If the incoming SIP INVITE message has the proper headers, Sipwise C5 will accept and further process
the request. If the message does not match the rule it will be rejected.
An incoming SIP INVITE message must match all the inbound peering rules so that
CAUTION
Sipwise C5 does not reject the request.
In order to create an inbound peering rule you have to select a peering group, press Details and then
press Create Inbound Peering Rule button.
• Match Field: select which header and which part of that header in a SIP INVITE message will be
checked for matching the pattern
• Pattern: a POSIX regular expression that defines the accepted value of a header; example:
^sip:.+@example\.org$ — this will match a SIP URI that contains "example.org" in the domain part
• Reject code: optional; a SIP status code that will be sent as a response to an INVITE request that
does not match the pattern; example: 403
• Reject reason: optional; an arbitrary text that will be included in the SIP response sent with the reject
code
• Enabled: a flag to enable / disable the particular inbound peering rule
Both of the properties Reject code and Reject reason must be left empty if a peering
server (i.e. a specific IP address) is part of more peering groups. Such a configuration is
NOTE useful when an incoming SIP INVITE request needs to be treated differently in the
affected peering groups, based on its content, and that’s why if the INVITE message
only partly matches an inbound peering rule it should not be rejected.
Inbound peering rules support POSIX regular expressions, that are different from PCRE
regular expressions. So, for instance, an expression like ^3910[0-9]{5}$ can be written
TIP as ^3910\d{5}$ in PCRE and ^3910{5}$ in POSIX. The kind of regexp used depends on
the underlying technology that uses that expression. Since ranges such as [0-9] are always
correct, we suggest using that syntax.
When all settings for a peering group are done the details of the group look like:
The selection of peering groups and peering servers for outgoing calls is done in the following way:
1. All peering groups that meet the following criteria configured in the outbound peering rule are
added to the list of routes for a particular call:
◦ Callee’s username matches callee prefix
◦ Callee’s URI matches callee pattern
◦ Caller’s URI matches caller pattern
2. When all matching peering groups are selected, they are ordered by callee prefix according to the
longest match basis (sometimes referred to as the longest pattern match or maximum pattern
length match). One or more peering group with longest callee prefix match will be given first
positions on the list of routes.
3. Peering groups with the same callee prefix length are further ordered by Priority. Peering group(s)
with the higher priorities will occupy higher positions.
4. All peering servers in the peering group with the highest priority (e.g. priority 1) are tried one-by-one
starting from the highest server weight. Peering groups with lower priorities or with shorter callee
prefix will be used only for fail-over.
The weight of the peering servers in the selected peering group will influence the order in which
the servers within the group will be tried for routing the outbound call. The weight of a server can
be set in the range from 1 to 127.
Opposite to the peering group priority, a peering server with a higher weight
value has a higher precedence, but the server weight rather sets a probability
IMPORTANT than a strict order. E.g. although a peering server with weight 127 has the highest
chance to be the first in the list of routes, another server with a lower weight (e.g.
100) sometimes will be selected first.
In order to find out this probability knowing the weights of peering servers, use the following script:
#!/usr/bin/perl
$num_args = $#ARGV + 1;
if ($num_args < 1) {
print "Usage: lcr_weight_test.pl <list of weights (integers 1-
254)>\n";
exit 0;
}
my $iters = 10000;
my @rands;
my @counts;
for (my $j=0; $j < $num_args; $j++) {
$counts["$j"] = 0;
}
Let us say you have 2 peering servers, one with weight 1 and another with weight 2. At the end — running
the script as below — you will have the following traffic distribution:
# lcr_weight_test.pl 1 2
If a peering server replies with SIP codes 408, 500 or 503, or if a peering server doesn’t respond at all,
the next peering server in the current peering group is tried as a fallback. All the servers within the
group are tried one after another until the call succeeds. If no more servers are left in the current
peering group, the next group which matches the outbound peering rules is used.
The Sipwise C5 may use a slightly different approach in selecting the appropriate
NOTE peering server if the peer probing feature is enabled. See the details in Peer Probing of
the handbook.
The default call routing uses statically configured peering group priorities to decide where to send the
calls. This solution is useful when you have an external SBC that makes all the routing decisions and is
described in the Routing Order Selection section. The Sipwise C5 also allows you routing calls to the
cheapest SIP peers saving your termination cost.
• Upload the billing fees provided by your peers to the corresponding peering billing profiles
• Enable the LCR module in config.yml (kamailio.proxy.perform_peer_lcr: yes)
When the LCR routing is enabled, the selection of peering groups would be the following:
1. All peering groups that meet the following criteria configured in the outbound peering rule are
added to the list of routes for a particular call (for pure LCR you might want to omit these filters
leaving them blank):
◦ Callee’s username matches callee prefix
◦ Callee’s URI matches callee pattern
◦ Caller’s URI matches caller pattern
2. When all matching peering groups are selected, the longest matching callee prefix is selected from
each of them. And the peering groups are temporary ordered according to the longest matching
prefix and priority.
3. Then, the LCR module re-orders the peering groups starting from the lowest termination cost to the
highest (ignoring the prefix length and peering group priorities).
4. The platform will first route the call to the servers of the first peering group in this list. If no peering
server can terminate the call, the call would fail-over to the second peering group from the list and
so on.
The peering servers in every peering group are sorted and tried according to their
NOTE
weight as described in the previous section.
Let us consider a short example. There are two peering groups (PG1 and PG2) that can deliver calls to
New York (e.g. 12121234567) and they have the following rates:
PG1 has only one rate that matches the dialed number, so that it will be taken into account, PG2 has two
rates and the longest will be selected. The call will be routed to PG1 servers first as it has a cheaper
price and can fail-over to PG2 servers.
The Sipwise C5 LCR feature together with the codec filtering, media transcoding, header manipulations,
SIP, and RTP encryption and other SBC features make an external SBC unnecessary. This simplifies
your VoIP network and cuts deployment and operation costs.
If a peering server requires Sipwise C5 to authenticate for outbound calls (by sending a 407 as response
to an INVITE), then you have to configure the authentication details in the Preferences view of your peer
host.
To configure this setting, open the Remote Authentication tab and edit the following four preferences:
Before the 10.1 version Sipwise C5 used to only have the /etc/ngcp-
config/templates/etc/ngcp-sems/etc/reg_agent.conf.tt2 configuration file to
provide outbound registrations for SIP peering(s). Beginning from 10.1 you can
choose, whether you want to initiate an outbound registration for your SIP
peering using the web administration interface or using the /etc/ngcp-
config/templates/etc/ngcp-sems/etc/reg_agent.conf.tt2 configuration file. The
IMPORTANT recommended way however is to create registrations using the web
administration interface. Keep in mind, in case you want to use the web
administration interface for that, then you have to remove similar configuration
entries from the /etc/ngcp-config/templates/etc/ngcp-
panel/etc/reg_agent.conf.tt2, so that the web administration interface does not
duplicate the same registration information (this can lead to several registration
sessions created for the same SIP peering host, which is not desired).
If you do NOT authenticate against a peer host, then the caller CLI is put into the
From and P-Asserted-Identity headers, e.g. "+4312345"
<sip:[email protected]>. If you DO authenticate, then the From
header is "+4312345"
<sip:your_peer_auth_user@your_peer_auth_realm> (the CLI is in the
IMPORTANT Display field, the peer_auth_user in the From username and the
peer_auth_realm in the From domain), and the P-Asserted-Identity header is as
usual like <sip:[email protected]>. So for presenting the correct
CLI in CLIP no screening scenarios, your peering provider needs to extract the
correct user either from the From Display-Name or from the P-Asserted-Identity
URI-User.
If peer_auth_realm is set, the system may overwrite the Request-URI with the
peer_auth_realm value of the peer when sending the call to that peer or peer_auth_realm
value of the subscriber when sending a call to the subscriber. Since this is rarely a desired
TIP
behavior, it is disabled by default starting with Sipwise C5 release 3.2. If you need the
replacement, you should set set_ruri_to_peer_auth_realm: 'yes' in /etc/ngcp-
config/config.yml.
A registration process for the SIP peering is quite simple, but since currently this functionality is present
both in the web administration interface and in the /etc/ngcp-config/templates/etc/ngcp-
sems/etc/reg_agent.conf.tt2 the last one is an inheritance and will be deprecated in the future), it’s
worth to dedicate a separate section with an additional description. So that it remains clear for the user
of the Sipwise C5 how to properly handle that.
The first and a recommended way to do that - is the web administration interface. It’s simple as that,
you need to tick a check-box 'peer_auth_register', and if previously all needed authentication data has
been provided (user, password and realm) the registration process will start right away.
IMPORTANT Be aware that this will force SEMS to restart, which will drop all calls.
Sipwise C5 supports outbound registrations via UDP, TCP and TLS. Please see
NOTE /etc/ngcp-config/templates/etc/ngcp-sems/etc/reg_agent.conf.tt2 to see examples
how to enable it using needed transport.
By default TCP/IP stack implementation in linux kernel uses so called ephemeral ports
for TCP transport, when it comes to originating a brand new TCP session towards
remote side. This is usually in the range of 32768 – 60999. This also applies to TLS.
However Sipwise C5 can and will always reuse already existing TCP sessions with
NOTE
subscribers, in order to send them out-of-dialog requests (for e.g. INVITE). It works so,
because subscribers which register at Sipwise C5, initiate and constantly support a TCP
session with Sipwise C5 (either with TCP keepalive mechanisms, or constantly sending
new re-registrations or/and OPTIONS).
You can force the Load-Balancer to use a fixed port for sending outbound registrations
from your Sipwise C5 platform, by enabling option 'tcp_reuse_port' (config.yml →
kamailio.lb.tcp_reuse_port: yes). This will force the Load-Balancer to use the same socket
descriptor(s), for establishing outbound sessions, as used for listening (this only relates to
TIP
TCP and TLS). With UDP you can by default initiate sessions from Sipwise C5 using a
constant port (usually 5060). Remember enabling 'tcp_reuse_port' will force all sessions
(not only REGISTER) initiated from behalf of Sipwise C5 be established over local port
engaged for listening (TCP or TLS).
There is a possibility to define a specific value for the "username" parameter of the
Authorization header, in case you want to have another username for the Digest process,
TIP than the one used in From/To headers. In order to do that, you have to define the option
'auth_user' for a desired registration entity. It’s being defined separately for each
registration entity.
As from the image above, following the arrows, you will have an idea about which type of Rewrite Rules
are applied during a call. In general:
• Call from local subscriber A to local subscriber B: Inbound RR from local Domain/Subscriber A and
Outbound Rewrite Rules from local Domain/Subscriber B.
• Call from local subscriber A to the peer: Inbound RR from local Domain/Subscriber A and Outbound
Rewrite Rules from the peer.
• Call from peer to local subscriber B: Inbound RR from the Peer and Outbound Rewrite Rules from
local Domain/Subscriber B.
You would normally begin with creating a Rewrite Rule Set for your SIP domains. This is used to control
what an end user can dial for outbound calls, and what is displayed as the calling party on inbound
calls. The subscribers within a domain inherit Rewrite Rule Sets of that domain, unless this is overridden
by a subscriber Rewrite Rule Set preference.
You can use several special variables in the Rewrite Rules, below you can find a list of them. Some
examples of how to use them are also provided in the following sections:
• ${caller_cc} : This is the value taken from the subscriber’s preference CC value under Number
Manipulation
• ${caller_ac} : This is the value taken from the subscriber’s preference AC value under Number
Manipulation
• ${caller_emergency_cli} : This is the value taken from the subscriber’s preference
emergency_cli value under Number Manipulation
• ${caller_emergency_prefix} : This is the value taken from the subscriber’s preference
emergency_prefix value under Number Manipulation
• ${caller_emergency_suffix} : This is the value taken from the subscriber’s preference
emergency_suffix value under Number Manipulation
To create a new Rewrite Rule Set, go to Settings→Rewrite Rule Sets. There you can create a Set identified
by a name. This name is later shown in your peer-, domain- and user-preferences where you can select
the rule set you want to use.
Click Create Rewrite Rule Set and fill in the form accordingly.
To view the Rewrite Rules within a set, hover over the row and click the Rules button.
The rules are ordered by Caller and Callee as well as direction Inbound and Outbound.
To create the following rules, click on the Create Rewrite Rule for each of them and fill them with the
values provided below.
Strip leading 00 or +
• Field: Caller
Normalization for national and local calls is possible with special variables ${caller_cc} and
${caller_ac} that can be used in Replacement Pattern and are substituted by the country and area
code accordingly during the call routing.
These variables are only being filled in when a call originates from a subscriber
(because only then the cc/ac information is known by the system), so you can
IMPORTANT
not use them when a calls comes from a SIP peer (the variables will be empty in
this case).
When routing a call, the rewrite processing is stopped after the first match of a rule,
starting from top to bottom. If you have two rules (e.g. a generic one and a more specific
TIP
one), where both of them would match some numbers, reorder them with the up/down
arrows into the appropriate position.
Strip leading 00 or +
Our provided rules will only match if the caller dials a numeric number. If he dials an
alphanumeric SIP URI, none of our rules will match and no rewriting will be done. You can
TIP however define rules for that as well. For example, you could allow your end users to dial
support and rewrite that to your support hotline using the match pattern ^support$ and
the replace pattern 43800999000 or whatever your support hotline number is.
Note that both of the rules would match a number starting with 43, so reorder the national
TIP
rule to be above the international one (if it’s not already the case).
• Simple emergency number handling: inbound rewrite rules append an emergency tag to the called
number, this will be recognised by NGCP’s call routing logic and the call is routed directly to a peer.
Please read the next section for details of simple emergency number handling.
• An emergency number mapping is applied: a dedicated emergency number mapping database is
consulted in order to obtain the most appropriate routing number of emergency services. This logic
ensures that the caller will contact the geographically closest emergency service. Please visit the
Emergency Mapping section of the handbook for more details.
For Emergency Calls from a subscriber to the platform, you need to define an Inbound Rewrite Rule For
Callee, which adds a prefix emergency_ to the number (and can rewrite the number completely as well
at the same time). If the proxy detects a call to a SIP URI starting with emergency_, it will enter a special
routing logic bypassing various checks which might make a normal call fail (e.g. due to locked or
blocked numbers, insufficient credits or exceeding the max. amount of parallel calls).
To route an Emergency Call to a Peer, you can select a specific peering group by adding a peering rule
with a callee prefix set to emergency_ to a peering group.
In order to normalize the emergency number to a valid format accepted by the peer, you need to
assign an Outbound Rewrite Rule For Callee, which strips off the emergency_ prefix. You can also use
the variables ${caller_emergency_cli}, ${caller_emergency_prefix} and
${caller_emergency_suffix} as well as ${caller_ac} and ${caller_cc}, which are all
configurable per subscriber to rewrite the number into a valid format.
PIDF-LO format
It can use different location encodings but there are two mandatory elements that need a special value
in order to be replaced by Sipwise C5 at the moment of initiating the emergency call:
• timestamp
• retention-expiry
<retention-expiry>$$expiry$$</retention-expiry>
<timestamp>$$ts$$</timestamp>
cirpack format
You can do the same in the Preferences of your subscribers to override the rule on a subscriber basis.
That way, you can finely control down to an individual user the dial-plan to be used. Go to Settings
→Subscribers, click the Details button on the subscriber you want to edit, the click the Preferences button.
If your peering servers don’t send numbers in E.164 format <cc><ac><sn>, you need to create Inbound
Rewrite Rules for each peering server to normalize the numbers for caller and callee to this format, e.g.
by stripping leading + or put them from national into E.164 format.
Likewise, if your peering servers don’t accept this format, you need to create Outbound Rewrite Rules for
each of them, for example to append a '+' to the numbers.
The Call Routing Verification utility performs only basic number processing and does not invoke the full
number manipulation logic applied on real calls. The goal is to enable testing of rewrite rules, rather
than validate the complete number processing.
You can access the utility following the path on Admin web interface: Tools → Call Routing Verification.
Examples
◦ Result:
◦ Result:
Chapter 6. Billing
This chapter describes the steps necessary to rate calls and export rated CDRs (call detail records) to
external systems.
Each profile may have call destinations (usually based on E.164 number prefix matching) with
configurable fees attached. Call destination fees each support individual intervals and rates, with a
different duration and/or rate for the first interval. (e.g.: charge the first minute when the call is opened,
then every 30 seconds, or make it independent of the duration at all) It is also possible to specify
different durations and/or rates for peak and off-peak hours. Peak time may be specified based on
weekdays, with additional support for manually managed dates based on calendar days. The call
destinations can finally be grouped for an overview on user’s invoices by specifying a zone in two detail
levels. (E.g.: national landline, national mobile, foreign 1, foreign 2, etc.)
To set up billing fees, click on the Fees button of the billing profile you want to configure. Billing fees
may be uploaded using a configurable CSV file format, or entered directly via the web interface by
clicking Create Fee Entry. To configure the CSV field order for the file upload, rearrange the entries in
the www_admin→fees_csv→element_order array in /etc/ngcp-config/config.yml and execute the command
ngcpcfg apply 'changed fees element order'. The following is an example of working CSV file to upload
(pay attention to double quotes):
".","^1",out,"EU","ZONE
EU",5.37,60,5.37,60,5.37,60,5.37,60,0,0,regex_longest_pattern
"^01.+$","^02145.+$",out,"AT","ZONE
Test",0.06250,1,0.06250,1,0.01755,1,0.01733,1,0,regex_longest_pattern,30
,0.01,30,0.01
For input via the web interface, fill in the text fields accordingly.
A billing fee record essentially defines the rate per interval to charge the customer when calling a
particular destination number. The properties below outline supported options in detail:
• Zone: A zone for a group of fees. May be used to group fees for simplified display, e.g. on invoices.
(e.g. foreign zone 1)
• Match Mode: The mode for matching a fee’s source and destination patterns against a CDR’s source
fields (the caller given by <source_cli>@<source_domain> or <source_cli> only) and
destination fields (the callee given by <destination_user_in>@<destination_domain> or
<destination_user_in> only). Each of the currently supported modes below provide different
flexibility and speed:
1. Exact string (destination): The destination string has to match the destination from the CDR
exactly. Fastest, O(log(#fees)). In csv files, this match mode is specified by
exact_destination.
2. Prefix string: The fee‘s source/destination represent strings which both the source/destination
from the CDR have to start with. The fee with the longest destination prefix is picked. If there are
multiple, the one with the longest source prefix is picked. In contrast to regular-expression
based match modes, this algorithm uses database index lookups instead of SQL REGEXP table
scans. The performance boundary is O(length(cdr src) * length(cdr dest) * log(#fees)), hence this
will be the preferred mode for tens of thousands of fees in place or high throughput (LCR, rating
peer-to-peer calls). In csv files, this match mode is specified by prefix.
3. Regular expression - longest match: The fee‘s source/destination patterns represent PCREs
which both have to match the source/destination from the CDR. The fee with the longest match
within the destination string is picked. If there are multiple, the one with the longest match within
the source string is picked. In csv files, this match mode is specified by regex_longest_match.
4. Regular expression - longest pattern: The fee‘s source/destination represent PCREs which both
have to match the source/destination from the CDR. The fee with the longest (most distinctive)
destination pattern is picked. If there are multiple, the one with the longest (most distinctive)
source pattern is picked. In csv files, this match mode is specified by
regex_longest_pattern.
If fees with different match mode are in place and matching, the precedence is given by above
order. When omitted in file uploads, the legacy default regex_longest_pattern is used.
There are several internal services (vsc, conference, voicebox) which will need a
specific destination entry with a domain-based destination. If you don’t want to
charge the same (or nothing) for those services, add a fee for destination
\.local$ there. If you want to charge different amounts for those services,
IMPORTANT
break it down into separate fee entries for @vsc\.local$,
@conference\.local$ and @voicebox\.local$ with the according fees.
NOT CREATING EITHER THE CATCH-ALL FEE OR THE SEPARATE FEES FOR
THE .local DOMAIN WILL BREAK YOUR RATING PROCESS!
• Onpeak init rate: The rate for the first rating interval in cent (of whatever currency, represented as a
floating point number) per second. Applicable to calls during onpeak hours.
• Onpeak init interval: The duration of the first billing interval, in seconds. Applicable to calls during
onpeak hours.
• Onpeak follow rate: The rate for subsequent rating intervals in cent (of whatever currency,
represented as a floating point number) per second. Applicable to calls during onpeak hours.
Defaults to onpeak init rate.
• Onpeak follow interval: The duration of subsequent billing intervals, in seconds. Applicable to calls
during onpeak hours. Defaults to onpeak init interval.
• Offpeak init rate: The rate for the first rating interval in cent (of whatever currency, represented as a
floating point number) per second. Applicable to calls during off-peak hours. Defaults to onpeak init
rate.
• Offpeak init interval: The duration of the first billing interval, in seconds. Applicable to calls during
off-peak hours. Defaults to onpeak init interval.
• Offpeak follow rate: The rate for subsequent rating intervals in cent (of whatever currency,
represented as a floating point number) per second. Applicable to calls during off-peak hours.
Defaults to offpeak init rate if that one is specified, or to onpeak follow rate otherwise.
• Offpeak follow interval: The duration of subsequent billing intervals, in seconds. Applicable to calls
during off-peak hours. Defaults to offpeak init interval if that one is specified, or to onpeak follow
interval otherwise.
• Onpeak use free time: Specifies whether free time minutes may be used when calling this
destination during onpeak hours. Specified in the file upload as 0, n[o], f[alse] and 1, y[es], t[rue]
respectively.
• Offpeak use free time: Specifies whether free time minutes may be used when calling this
destination during off-peak. Specified in the file upload as 0, n[o], f[alse] and 1, y[es], t[rue]
respectively.
• Onpeak extra second: If defined, an extra rate will be charged at the given second of call time for
post-paid calls. Applicable to calls started during onpeak hours.
• Onpeak extra rate: The rate to charge if the call time exceeds extra second in cent (of whatever
currency, represented as a floating point number). Applicable to calls started during onpeak hours.
• Offpeak extra second: See onpeak extra second. Applicable to calls started during offpeak hours.
• Offpeak extra rate: See onpeak extra rate. Applicable to calls started during offpeak hours.
To set off-peak times for a weekday, click on Edit next to the according weekday. You will be presented
with two input fields which both receive a timestamp in the form of hh:mm:ss specifying a time of day
for the start and end of the off-peak period. If any of the fields is left empty, the system will
automatically insert 00:00:00 (start field) or 23:59:59 (end field). Click on Add to store the setting in the
database. You may create more than one off-peak period per weekday. To delete a range, click Delete
next to the entry. Click the close icon when done.
To specify off-peak ranges based on calendar dates, click on Create Special Off-Peak Date. Enter a date
in the form of YYYY-MM-DD hh:mm:ss into the Start Date/Time input field and End Date/Time input field
to define a range for the off-peak period.
As soon as call costs of a CDR are determined by rate-o-mat, database tables for bookkeeping daily
and monthly sums are updated. Fraud lock levels will be applied instantly in case of a fraud event - that
is when either the fraud monthly limit or fraud daily limit got exceeded. If fraud lock is set to anything
other than none, it will lock the account’s subscribers accordingly (e.g. if fraud lock is set to outgoing,
the account will be locked for all outgoing calls).
A background script (managed by cron daemon, running every 10 minutes by default) automatically
checks recent fraud events. An email will be sent to the address given by fraud notify, if set. The email
will contain information about which account is affected, which subscribers within that account are
affected, the current account balance and the configured fraud limit, and also whether or not the
account was locked in accordance with the fraud lock setting. It should be noted that this email is
meant for the administrators or accountants etc., and not necessarily for the customer.
You can override fraud detection and locking settings of a billing profile on a
IMPORTANT
per-account basis via REST API or the Admin interface.
Accounts that were automatically locked by the fraud detection feature will not be
automatically unlocked (eg. if either a limit is lowered or the next day/month starts).
CAUTION
This has to be done manually through the administration panel or through the
provisioning interface.
It is possible to fetch the list of fraud events and thus get fraud status of Customers by
NOTE
using the REST API and referring to the resource: /api/customerfraudevents.
Customers with a post-paid billing profile may have a positive account cash balance value. This is the
regular case when using a post-paid billing profile showing a free cash greater than '0'.
You can set the free cash (and the free time) in the billing profile. The account balance will
TIP be set and managed (i.e. refilled or carried over) automatically for subsequent balance
intervals.
In case the account has a positive cash balance, the cost of the call will be deducted from that balance
and not considered as additional cost of that particular call for the customer.
The rating engine (ngcp-rate-o-mat) in Sipwise C5 will write '0' instead of the real
cost of a call in the CDR, if the source customer’s (who initiated the call) account
IMPORTANT
has a positive cash balance! The purpose of this is to reflect the usage of free
cash in the CDR for the particular call.
It might happen, for instance, that a customer’s billing profile is changed from pre-paid
NOTE to post-paid, and the customer already had a positive cash balance on his account. In
that case the same call rating mechanism is involved as for the free cash.
There are two types of exports. One is CDR (Call Detail Records) used to charge for calls made by
subscribers, and the other is EDR (Event Detail Records) used to charge for provisioning events like
enabling certain features.
• Account: the customer’s account that is charged for calls of its subscriber(s)
• Carrier: a SIP peer that sends incoming calls to, or receives outgoing calls from NGCP. A carrier may
charge fees for the outgoing calls from Sipwise C5 (outbound billing fee), or for the incoming calls
to Sipwise C5 (inbound billing fee).
• Contract: the service contract that represents a customer, a reseller or a SIP peer; a contract on
Sipwise C5 contains the billing profile (billing fees) too
• Customer: the legal entity that represents any number of subscribers; this entity receives the bills
<prefix><separator><version><separator><timestamp><separator><sequence
number><suffix>
A valid example filename for a CDR billing file created at 2012-03-10 14:30:00 and being the 42nd file
exported by the system, is:
sipwise_007_20130310143000_0000000042.cdr
The billing file header is one single line, which is constructed by the following fields:
<version>,<number of records>
007,0738
The body of a CDR consists of a minimum of zero and a default maximum of 5000 lines. The platform
operator can configure the maximum number of lines kept in a file by updating the
cdrexport.max_rows_per_file parameter in /etc/ngcp-config/config.yml file. Each line holds one call
detail record in CSV format and is constructed by a configurable set of fields, all of them enclosed in
single quotes.
The following table defines the default set of fields that are inserted into the CDR file, for exports
related to system scope. The list of fields is defined in /etc/ngcp-config/config.yml file,
cdrexport.admin_export_fields parameter.
A valid example of one body line of a rated CDR is (line breaks added for clarity):
'15','2013-03-26 22:09:11','a84508a8-d256-4c80-a84e-
820099a827b0','1','','1','',
'2','testuser1','192.168.51.133','4311001','0','192.168.51.1',
'94d85b63-8f4b-43f0-b3b0-221c9e3373f2','1','','3','','4','testuser3',
'192.168.51.133','testuser3','192.168.51.133','testuser3','','','call','
ok','200',
'2013-03-25 20:24:50.890','2013-03-25 20:24:51.460','10.880','44449842',
'ok','2013-03-25 20:25:27','0.00','24.00','onnet','testzone','platform
internal',
'testzone','0','0','0.00','200.00','','foo','','foo','0','0',
'0.00','','','0','0.00','','','0'
The format of the CDR export files generated for resellers (as opposed to the complete system-wide
export) is identical except for a few missing fields.
Please check the description of fields in the table above, in order to see which fields are
NOTE
omitted for reseller related CDR exports.
The list of fields for reseller CDR export is defined in /etc/ngcp-config/config.yml file,
cdrexport.reseller_export_fields parameter.
Supplementary Data
There are fields in CDR database that contain supplementary data related to subscribers. This data is
not used by Sipwise C5 for CDR processing but rather provides the system administrator with a
possibility to include supplementary information in CDRs.
This informational section is meant for problem solving / debugging purpose: The
NOTE supplementary data listed in following table is stored in
provisioning.voip_preferences database table.
There are fields in CDR database that show changes in cash or free time balance. In addition to that, a
history of billing packages / profiles may also be present, since Sipwise C5 vouchers, that are used to
top-up, may also be set up to cause a transition of profile packages. (Which in turn can result in
changing the billing profile/applicable fees). Therefore the billing package and profile valid at the time
of the CDR are recorded and exposed as fields for CDR export.
TIP Such fields may also be required to integrate Sipwise C5 with legacy billing systems.
Please be aware that pre-paid billing functionality is only available in Sipwise C5 PRO
NOTE
and Sipwise C5 CARRIER products.
The name of CDR data field consists of the elements listed below:
1. source|destination: decides if the data refers to calling (source) or called (destination) party
2. carrier|reseller|customer: the account owner, whose billing data is referred
3. data type:
Examples:
• source_customer_cash_balance_before
• destination_customer_profile_package_id
For calls spanning multiple balance intervals, the latter one will be selected, that
IMPORTANT
is the balance interval where the call ended.
On-net calls (made only between devices on your network) are sometimes treated differently from off-
net calls (terminated to or received from a peer) in external billing systems.
To distinguish between on-net and off-net calls in such a billing systems, check the source_user_id
and destination_user_id fields. For on-net calls, both fields will have a different from zero value
(actually, a UUID).
The body of an EDR consists of a minimum of zero and a maximum of 5000 lines. The platform operator
can configure the maximum number of lines kept in a file by updating the
eventexport.max_rows_per_file parameter in /etc/ngcp-config/config.yml file. Each line holds one call
detail record in CSV format and is constructed by the fields as per the subsequent table.
The following table defines the default set of fields that are inserted into the EDR file, for exports
related to system scope. The list of fields is defined in /etc/ngcp-config/config.yml file,
eventexport.admin_export_fields parameter.
start_profile: Empty.
start_huntgroup: Empty.
end_huntgroup: Empty.
start_ivr: Empty.
end_ivr: Empty.
NEW_PROFILE_NAME 0-255 string The new status of the event. Depending on the
event_type:
end_profile: Empty.
start_huntgroup: Empty.
end_huntgroup: Empty.
start_ivr: Empty.
end_ivr: Empty.
TIMESTAMP 23 timestamp Timestamp of event. Includes date, time with
milliseconds (3 decimals).
RESELLER_ID 1-11 uint Internal ID of the reseller which the event belongs
to.
A valid example of one body line of an EDR is (line breaks added for clarity):
"1","start_profile","sipwise_ext_customer_id_4","Sipwise GmbH",
"sipwise_ext_subscriber_id_44","436667778","","1","2014-06-19
11:34:31","1"
The format of the EDR export files generated for resellers (as opposed to the complete system-wide
export) is identical except for a few missing fields.
Please check the description of fields in the table above, in order to see which fields are
NOTE
omitted for reseller related EDR exports.
The list of fields for reseller EDR export is defined in /etc/ngcp-config/config.yml file,
eventexport.reseller_export_fields parameter.
There are fields in EDR database that contain supplementary data related to subscribers, for example
subscriber phone numbers are such data.
The billing file trailer is one single line, which is constructed by the following fields:
<md5 sum>
The <md5 sum> is a 32 character hexadecimal MD5 hash of the Header and Body.
To validate the billing file, one must remove the Trailer before computing the MD5 sum of the file. The
ngcp-cdr-md5 program included in the ngcp-cdr-exporter package can be used to validate the
integrity of the file.
$ ngcp-cdr-md5 sipwise_001_20071110123000_0000000004.cdr
/tmp/ngcp-cdr-md5.sipwise_001_20071110123000_0000000004.cdr.oqkd4P2zXI:
OK
If the file has been altered during transmission, the output of the integrity check would be:
$ ngcp-cdr-md5 sipwise_001_20071110123000_0000000004.cdr
/tmp/ngcp-cdr-md5.sipwise_001_20071110123000_0000000004.cdr.hUtuhtKEn1:
FAILED
md5sum: WARNING: 1 of 1 computed checksum did NOT match
CDR and EDR files are fetched by a 3rd party billing system using SFTP or SCP with either public key or
password authentication using the username cdrexport.
If public key authentication is chosen, the public key file has to be stored in the file
.ssh/authorized_keys below the home directory of the cdrexport user (i.e.
/home/jail/home/cdrexport/.ssh/authorized_keys). Otherwise, a password has to be set for
the user.
The 3rd party billing system is responsible for deleting CDR files after fetching them.
The cdrexport user is kept in a jailed environment on the system, so it has only access
NOTE
to a very limited set of commandline utilities.
Chapter 7. Features
The Sipwise C5 provides plenty of subscriber features to offer compelling VoIP services to end
customers, and also to cover as many deployment scenarios as possible. In this chapter, we provide the
features overview and describe their function and use cases.
The previous example shows what happens if you type a search string in the Search textbox. The
search string will be applied to all visible columns of the datatable as a filter and all matching records
are kept displayed.
The * is prepended and appended implicitly to the string entered in Search textbox to
NOTE
make filtering easier, for almost all datatables / lists.
While the search pattern is typically matched to values of all columns visible in the datatable, in some
cases (i.e. unindexed columns) may be excluded from searching.
The Call History datatable behaves slightly differently when it comes to wildcard usage. The * wildcard
needs to be entered explicitly by the user if needed.
Be aware that acceptable response times of the administrative web interface rely
on utilizing available database indexes, which is impossible with a leading wildcard
CAUTION
in the search string. Wildcards at the end of the search pattern do not impact
performance.
Administrators, as user accounts, are also used for client authentication on the REST API of NGCP.
There is a single administrator (username: "administrator"), whose account is enabled by default and
who belongs to the default reseller. This user is the superuser of Sipwise C5 administrative web interface
(the so-called "admin panel"), and he has the right to modify administrators of other Resellers as well.
• If you’d like to create a new administrator user press Create Administrator button.
• If you’d like to update an existing administrator user press Edit button in its row.
There are some generic attributes that have to be set for each administrator:
• Reseller: each administrator user must belong to a Reseller. There is always a default reseller (ID: 1,
Name: default), but the administrator has to be assigned to his real reseller, if such an entity (other
than default) exists.
• Login: the login name of the administrator user
• Password: the password of the administrator user for logging in the admin panel, or for
authentication on REST API
• Email: the email of the administrator user, used for resetting password.
Due to the fact that administrators can request a password reset via email, no
administrator is able to change a password or API key other than to himself.
NOTE Administrators with is_system, is_superuser and is_master flags are the only ones that
can change the username and email of other administrators, while the ones without
those flags can only change their own email and password.
The second set of attributes is a list of access rights that are discussed in subsequent section of the
handbook.
* For the web interface this means that Create… and Edit
buttons will be hidden or disabled. * For the REST API this
means that only GET, HEAD, OPTIONS HTTP request
methods are accepted, and Sipwise C5 will reject those
targeting data modification: PUT, PATCH, POST, DELETE.
Show Passwords Show passwords The user sees subscriber passwords (in plain text) on the
web interface.
Block Lists are separated into Administrative Block Lists (adm_block_*) and Subscriber Block Lists (
block_*). They both have the same behaviour, but Administrative Block Lists take higher precedence.
Administrative Block Lists are only accessible by the system administrator and can thus be used to
override any Subscriber Block Lists, e.g. to block certain destinations. The following break-down of the
various block features apply to both types of lists.
Block Modes
Block lists can either be whitelists or blacklists and are controlled by the User Preferences
block_in_mode, block_out_mode and their administrative counterparts.
• The blacklist mode (option is not checked tells the system to allow anything except the entries in
the list. Use this mode if you want to block certain numbers and allow all the rest.
• The whitelist mode indicates to reject anything except the entries in the list. Use this mode if you
want to enforce a strict policy and allow only selected destinations or sources.
You can change a list mode from one to the other at any time.
Block Lists
The list contents are controlled by the User Preferences block_in_list, block_out_list and their
administrative counterparts. Click on the Edit button in the Preferences view to define the list entries.
In block list entries, you can provide shell patterns like * and []. The behavior of the list is controlled by
the block_xxx_mode feature (so they are either allowed or rejected). In our example above we have
block_out_mode set to blacklist, so all calls to US numbers and to the Austrian number +431234567 are
going to be rejected.
Click the Close icon once you’re done editing your list.
For incoming call, the User Preference block_in_clir and adm_block_in_clir controls whether or not to
reject incoming calls with number suppression (either "[Aa]nonymous" in the display- or user-part of the
From-URI or a header Privacy: id is set). This flag is independent from the Block Mode.
In a case of a conflict, when the Block Lists feature allows a number and NCOS Levels rejects the same
number or vice versa, the call will be rejected.
• The blacklist mode indicates to allow everything except the entries in this level. Use this mode if
you want to block specific destinations and allow all the rest.
• The whitelist mode indicates to reject anything except the entries in this level. Use this mode if
you want to enforce a strict policy and allow only selected destinations.
To create an NCOS Level, go to Settings→NCOS Levels and press the Create NCOS Level button.
Select a reseller, enter a name, select the mode and add a description, then click the Save button.
To define the rules within the newly created NCOS Level, click on the Patterns button of the level.
There are 2 groups of patterns where you can define matching rules for the selected NCOS Level:
• NCOS Number Patterns: here you can define number patterns that will be matched against the
called number and allowed or blocked, depending on whitelist / blacklist mode. The patterns are
regular expressions.
• NCOS LNP Carriers: here you can select predefined LNP Carriers that will be allowed (whitelist
mode) or prohibited (blacklist mode) to route calls to them. For each of them you can restrict the
matching to a predefined number pattern. (See Local LNP Database in the handbook for the
description of LNP functionality)
Sipwise C5 performs number matching always with the dialed number and not with the
NOTE number generated after LNP lookup that is: either the original dialed number prefixed
with an LNP carrier code, or the routing number.
In the NCOS Number Patterns view you can create multiple patterns to define your level, one after the
other. Click on the Create Pattern Entry Button on top and fill out the form.
In this example, we block (since the mode of the level is blacklist) all numbers starting with 439. Click
the Save button to save the entry in the level.
There are 2 options that help you to easily define specific number ranges that will be allowed or
blocked, depending on whitelist / blacklist mode:
• Include local area code: all subscribers within the caller’s local area, e.g. if a subscriber has country-
code 43 and area-code 1, then selecting this checkbox would result in the implicit number pattern:
^431.
• Intra PBX calls within same customer: all subscribers that belong to the same PBX customer as the
caller himself.
In the NCOS LNP Carriers view you can select specific LNP Carriers — i.e. carriers that host the called
ported numbers — that will be allowed or blocked for routing calls to them (whitelist / blacklist mode,
respectively).
In the above example we created a rule that blocks calls to "LNP_Carr1" carrier, supposing we use
blacklist mode of the NCOS Level.
In the LNP NCOS Number Patterns view you can create multiple patterns to restrict NCOS LNP Carrier
matching, one after the other. Click on the Create LNP Pattern Entry Button on top and fill out the form.
Considering the example before and adding the pattern shown in the picture, the rule now blocks only
calls to "LNP_Carr1" carrier that starts with 390.
There might be situations when phone number patterns may not be strictly aligned with
telephony providers, for instance in case of full number portability in a country. In such
TIP cases using NCOS LNP Carriers patterns still allows for defining NCOS levels that allow /
block calls to mobile numbers, for example. In order to achieve this goal you have to list
all LNP carriers in the NCOS patterns that are known to host mobile numbers.
The below table gives an overview of all the possible combinations of NCOS and NCOS LNP Carrier:
Once you’ve defined your NCOS Levels, you can assign them to local subscribers. To do so, navigate to
Settings→Subscribers, search for the subscriber you want to edit, press the Details button and go to the
Preferences View. There, press the Edit button on either the ncos or adm_ncos setting in the Call
Blockings section.
You can assign the NCOS level to all subscribers within a particular domain. To do so, navigate to
Settings→Domains, select the domain you want to edit and click Preferences. There, press the Edit button
on either ncos or admin_ncos in the Call Blockings section.
Note: if both domain and subscriber have same NCOS preference set (either ncos or adm_ncos, or both)
the subscriber’s preference is used. This is done so that you can override the domain-global setting on
In some countries there are regulatory requirements that prohibit subscribers from forwarding their
numbers to special numbers like emergency, police etc. While Sipwise C5 does not deny provisioning
Call Forward to these numbers, the administrator can prevent the incoming calls from being actually
forwarded to numbers defined in the NCOS list: select the appropriate NCOS level in the domain’s or
subscriber’s preference adm_cf_ncos. This NCOS will apply only to the Call Forward from the
subscribers and not to the normal outgoing calls from them.
By default, allowed_ips is an empty list which means that subscriber is not restricted. If you want to
configure a restriction, navigate to Settings→Subscribers→Preferences or Settings→Domains→Preferences, and
search for the allowed_ips preference in the Access Restrictions section.
You can enter multiple allowed IP addresses or IP address ranges one after another. Click the Add
button to save each entry in the list. Click the Delete button if you want to remove some entry.
The restriction is applied to User-Provided Number (UPN) which is obtained from the configurable
source based on the setting of inbound_upn preference in the Number Manipulation section in the
Domain and/or User preferences, after it has been rewritten with Inbound Rewrite Rules for Caller.
In case the inbound_upn preference is set to the "From Display-Name" the UPN value can be
alphanumeric so the access control supports the alphanumeric (caller name) matching as well. If the
incoming message does not have the Display-Name, though, the UPN value will be taken from the
From-Username.
In this particular case the inbound_upn preference only defines which Sip Header must be checked first
and, in case of failure, the check is repeated evaluating the username part of the following headers:
• P-Preferred-Identity
• P-Asserted-Identity
• From
In case of positive result, that value will be used as valid UPN and the subsequent headers will be not
evaluated, otherwise if all additional checks fail, restrictions are applied as described above.
By default, upn_block_list is an empty list which means that subscriber is not restricted. If you want to
configure a restriction, navigate to Settings→Subscribers, search for the subscriber you want to edit, press
Details and then Preferences and press Edit for the upn_block_list preference in the Call Blockings
section to define the list entries.
In block list entries, you can provide shell patterns like * and []. The CLI-based block list can either be
whitelist or blacklist.
• The blacklist mode indicates to allow everything except the entries in this list. This is the default
mode of operation and is effective when the preference upn_block_mode is unset.
• The whitelist mode indicates to reject anything except the entries in this list. In order to switch to
this mode, set the preference upn_block_mode (it is a toggle between whitelist/blacklist).
If separate preference upn_block_clir is enabled, outgoing anonymous calls from this user will be
dropped.
If the caller’s UPN is allowed it is also checked according to allowed_clis preference as usual and can
be rewritten according to allowed_clis_reject_policy for correct calling number presentation on outgoing
calls. This step happens after Access Control.
defines the maximum number of concurrent calls (incoming and outgoing) for a subscriber, while the
option concurrent_max_out_total limits only subscriber’s outbound concurrent calls and the option
concurrent_max_in_total only subscriber’s inbound concurrent calls.
It’s also possible to limit the number of concurrent calls of a subscriber compared to the number of
calls made or received by all subscribers within the same customer (account). The options
concurrent_max_per_account, concurrent_max_out_per_account, concurrent_max_in_per_account permit
to apply this limit. To better understand how they work, suppose we have two subscribers A and B,
owned by the same customer. If we set concurrent_max_per_account=2 on B preferences and A is
placing two calls, then B can not receive or place new calls at the same time. For instance, an
administrator may define this restriction to some non-manager subscribers, in which
concurrent_max_per_account=2. Hence, they will be able to make a maximum of two calls if there are no
other calls in place within the customer. On manager subscribers, the limit can be defined differently, or
even not set at all. In the last case, calls will be always allowed.
When concurrent_max_total limit is reached, announcement set on max_calls_in is played to those who
try to call that subscriber. The same announcement is played for concurrent_max,
concurrent_max_per_account, concurrent_max_in_total, concurrent_max_in,
concurrent_max_in_per_account. When concurrent_max_out_total limit is reached, announcement set on
max_calls_out is played. The same announcement is played for concurrent_max_out or
concurrent_max_out_per_account.
• Call Forward Unconditional (CFU): The call forward is always executed, completely disregarding
the subscriber state.
• Call Forward Busy (CFB): The call forward is executed when the subscriber returns a busy state.
• Call Forward Timeout (CFT): The call forward is executed when no answer is received from the
subscriber before the timeout expiration. Timeout is configurable in ringtimeout subscriber
preference.
• Call Forward Unavailable (CFNA): The call forward is executed when the subscriber has no
endpoint registered.
The Call Forward Unavailable is also executed if the callee responds with 480
CAUTION Temporarily Unavailable, which may be the case when a subscriber’s endpoint (e.g.
an IP-PBX) is registered but the callee user is not available.
• Call Forward SMS (CFS): The SMS forward is always executed, completely disregarding the
subscriber state. SMS service has to be enabled, see the SMS (Short Message Service) subchapter
for a detailed description on how to activate it.
• Call Forward on Response (CFR): The call forward is executed only for particular reply codes
received back from the destination endpoint. The list of the reply codes and the activation mode
can be configured in rerouting_codes and rerouting_mode subscriber’s preferences. Example:
suppose that rerouting_codes is set to 503, rerouting_mode to whitelist and the CFR is configured. If
that subscriber receives a call and it replies back a with code 503, then the call will be re-routed to
the destination configured in the CFR. For all the other reply codes the CFR will be NOT executed.
• Call Forward on Overflow (CFO): The call forward is executed when the new incoming call for the
subscriber exceeds the limit configured in concurrent_max_in_total, concurrent_max_in or
concurrent_max_in_per_account subscriber’s preferences. If none of the preferences is set then the
CFO will be NOT executed.
If you select URI/Number in the Destination field, you also have to set a URI/Number. The timeout
defines for how long this destination should be tried to ring.
• URI/Number: A destination to forward calls to. This option is only valid for the URI/Number
destination type. Specify a valid SIP-URI string or a plain number.
• for (seconds): Sets the ringing time, after which the call is forwarded to the next number on the list
(if configured).
• Custom Announcement: Custom Announcements are created in Sound Sets and must have the
If you want to define such more detailed call forwarding rules, you need to change into the Advanced
View when editing your call forward. There, you can select multiple Destination Set - Time Set - Source
Set - B-Number Set groups that determine all conditions under which the call will be forwarded.
• A Destination Set is a list of destinations where the call will be routed to, one after another,
according to the order of their assigned priorities. See the Destination Sets subchapter for a detailed
description.
• A Time Set is a time period definition, i.e. when the call forwarding has to be active. See the Time
Sets subchapter for a detailed description.
• A Source Set is a list of number patterns that will be matched against the calling party number; if the
calling number matches the call forwarding will be executed. See the Source Sets subchapter for a
detailed description.
• A B-Number Set is a list of number patterns that will be matched against the called party number; if
the callee number matches the call forwarding will be executed. See the B-Number Sets
subchapter for a detailed description.
Click on Manage Destination Sets to see a list of available sets. The quickset_cfu has been implicitly
created during our creation of a simple call forward. You can edit it to add more destinations, or you can
create a new destination set.
When you close the Destination Set Overview, you can now assign your new set in addition or instead of
the quickset_cfu set.
Click on Manage Time Sets in the advanced call-forward menu to see a list of available time sets. By
default there are none, so you have to create one.
You need to provide a Name, and a list of Periods where this set is active. If you only set the top setting
of a date field (like the Year setting in our example above), then it’s valid for only this setting (like the full
year of 2013 in our case). If you provide the bottom setting as well, it defines a period (like our Month
setting, which means from beginning of April to end of September). For example, if a CF is set with the
following timeset: "hour { 10-12 } minute { 20-30 }", the CF will be matched within the following time
ranges:
the period is a through definition, so it covers the full range. If you define an Hour
IMPORTANT definition 8-16, then this means from 08:00 to 16:59:59 (unless you filter the
Minutes down to something else).
If you close the Time Sets management, you can assign your new time set to the call forwards you’re
configuring.
Once the Advanced View of the call forward definition has been opened, you will need to press the
Manage Source Sets button to start defining new Source Sets or managing an existing one. The
following image shows the Source Set definition dialog:
You will need to fill in the Name field first, the Mode: whitelist or blacklist, the is_regex flag and finally in
the Source field you can enter:
You can add more patterns to the Source Set by pressing the Add another source button. When you
finished adding all patterns, press the Save button. You will then see the below depicted list of Source
Sets:
Once the Advanced View of the call forward definition has been opened, you will need to press the
Manage B-Number Sets button to start defining new B-Number Sets or managing an existing one. The
following image shows the B-Number Set definition dialog:
You will need to fill in the Name field first, the Mode: whitelist or blacklist, the is_regex flag and finally in
the B-Number field you can enter:
number of characters), "?" (matches any single character), "[abc]" (matches a single character that is
part of the explicitly listed set: a, b or c) and "[0-9]" (matches a single character that falls in the range
0 to 9) as wildcards, as usual in shell patterns. Examples:
◦ "431*" (all numbers from Vienna / Austria)
◦ "49176[0-5]77*" (German numbers containing fixed digits and a variable digit in 0-5 range in
position 6)
◦ "43130120??" (numbers from Vienna with fixed prefix and 2 digits variable at the end)
• A perl compatible regular expressions (only if is_regex if set). Capturing groups can be formed using
parentheses and referenced in the Destination Set via \\1, \\2,…
You can add more patterns to the B-Number Set by pressing the Add another B-Number button. When
you finished adding all patterns, press the Save button. You will then see the below depicted list of B-
Number Sets:
As additional step you can define a Destination Set as described in Destination Sets subchapter. For our
example, we have defined the following Destination Set:
A final step of defining the call forward settings is selecting a Destination, a Time Set, a Source Set and
a B-Number Set, as shown in the image below. Please note that there is no specific Time Set selected in
our example, that means the call forward rule is valid (as shown) <always>.
Figure 36. Definition of a Call Forward with Source and Destination Sets
Once all the settings have been defined and the changes are saved, you will see the call forward entry
(in our example: Call Forward Unconditional), with the names of the selected Destination, Time Set,
Source Sets and B-Number Set provided, at SubscriberPreferences → Call Forwards location on the web
interface:
Figure 37. List of Call Forward with Source and Destination Sets
If a customer registers multiple devices, Sipwise C5 – once receives a call for that user – send the call
to all the registered devices, in parallel. All the devices will ring at the same time. This is called Parallel
Forking, and this is the default behavior. The Sipwise C5 can also do the so-called Serial Forking, which
means let ring one device first, then after a timeout let ring the next device, and so on and so forth. The
Serial Forking feature can be activated setting subscriber/domain preference serial_forking_by_q_value.
In case the client doesn’t set the q value, Sipwise C5 set a default value of 'q=-1' in the database.
Q value can be also specified during the creation of a subscriber’s permanent registration (Details
→Registered Devices→Create Permanent Registration).
The Sipwise C5 can apply two different type of algorithm to the q values in order to achieve two
different types of serial forking called standard and probability.
In case two or more contacts have the same q value, then they are tried in parallel. This
NOTE
allow to create a very flexible mix of Serial and Parallel forking.
Differently from the standard method there is no possibility to have parallel forking. This
NOTE algorithm can be useful to load-balance the calls in case of endpoints in ACTIVE-
ACTIVE configuration.
Sipwise C5 allows you also to define how long each single device has to ring during a Serial Forking
call. To do that, set the subscriber/domain preference contact_ringtimeout to the desired value.
In case both contact_ringtimeout and Call Forward on Timeout are configured, CFT
timeout has higher priority. To clarify this concept, please take a look at the following
examples: Case 1: CFT timeout lower than the total ringtimeout of the contacts. For
example: CFT timeout = 100, contact_ringtimeout = 40 and 3 devices registered: 1st
NOTE device will ring for 40 seconds, 2nd device will ring for other 40 seconds, 3rd device will
ring only for 20 seconds because of the CFT. Case 2: CFT timeout higher than the total
ringtimeout of the contacts. For example: CFT timeout = 100, contact_ringtimeout = 40
and 2 devices registered: 1st device will ring for 40 seconds, 2nd device will ring till
reaching the CFT timeout (60 seconds in this case).
NOTE Accessing external LNP databases is available for PRO and CARRIER products only.
LNP Carriers
LNP Carriers are defined by an arbitrary Name for proper identification (e.g. British Telecom) and contain
a Prefix which can be used as routing prefix in LNP Rewrite Rules and subsequently in Peering Rules to
route calls to the proper carriers. The LNP prefix is written to CDRs to identify the selected carrier for
post processing and analytics purposes of CDRs. LNP Carrier entries also have an Authoritative flag
indicating that the numbers in this block belong to the carrier operating Sipwise C5 . This is useful to
define your own number blocks, and in case of calls to those numbers reject the calls if the numbers
are not assigned to local subscribers (otherwise they would be routed to a peer, which might cause call
loops). Finally the Skip Rewrite flag skips executing of LNP Rewrite Rules if no number manipulation is
desired for an LNP carrier.
LNP Numbers
LNP Carriers contain one or more LNP Numbers. Those LNP Numbers are defined by a Number entry in
E164 format (<cc><ac><sn>) used to match a number against the LNP database. Number matching is
performed on a longest match, so you can define number blocks without specifying the full subscriber
number (e.g. a called party number 431999123 is going to match an entry 431999 in the LNP Numbers).
For an LNP Numbers entry, an optional Routing Number can be defined. This is useful to translate e.g.
premium 900 or toll-free 800 numbers to actual routing numbers. If a Routing Number is defined, the
called party number is implicitly replaced by the Routing Number and the call processing is continued
with the latter. For external billing purposes, the optional Type tag of a matched LNP number is
recorded in CDRs.
An optional Start Date and End Date makes it possible to schedule porting work-flows up-front by
populating the LNP database with certain dates, and the entries are only going to become active with
those dates. Empty values for start indicate a start date in the past, while empty values for end indicate
an end time in the future during processing of a call, allowing to define infinite date ranges. As intervals
can overlap, the LNP number record with a start time closest to the current time is selected.
In order to activate Local LNP during routing, the feature must be activated in config.yml. Set kamailio
→proxy→lnp→enable to yes and kamailio→proxy→lnp→type to local.
When a call arrives at the system, the calling and called party numbers are first normalized using the
Inbound Rewrite Rules for Caller and Inbound Rewrite Rules for Callee within the rewrite rule set assigned
to the calling party (a local subscriber or a peer).
If the called party number is not assigned to a local subscriber, or if the called party is a local subscriber
and has the subscriber/domain preference lnp_for_local_sub set, the LNP lookup logic is engaged,
otherwise the call proceeds without LNP lookup. The further steps assume that LNP is engaged.
If the call originated from a peer, and the peer preference caller_lnp_lookup is set for this peer, then an
LNP lookup is performed using the normalized calling party number. The purpose for that is to find the
LNP prefix of the calling peer, which is then stored as source_lnp_prefix in the CDR, together with the
selected LNP number’s type tag (source_lnp_type). If the LNP lookup does not return a result (e.g. the
calling party number is not populated in the local LNP database), but the peer preference
default_lnp_prefix is set for the originating peer, then the value of this preference is stored in
source_lnp_prefix of the CDR.
Next, an LNP lookup is performed using the normalized called party number. If no number is found
(using a longest match), no further manipulation is performed.
If an LNP number entry is found, and the Routing Number is set, the called party number is replaced by
the routing number. Also, if the Authoritative flag is set in the corresponding LNP Carrier, and the called
party number is not assigned to a local subscriber, the call is rejected. This ensures that numbers
allocated to the system but not assigned to subscribers are dropped instead of routed to a peer.
If the system is serving a local subscriber with only the routing number assigned
(but not e.g. the premium number mapping to this routing number), the
subscriber will not be found and the call will either be rejected if the called party
premium number is within an authoritative carrier, or the call will be routed to a
IMPORTANT peer. This is due to the fact that the subscriber lookup is performed with the
dialled number, but not the routing number fetched during LNP. So make sure to
assign e.g. the premium number to the local subscriber (optionally in addition to
the routing number if necessary using alias numbers) and do not use the LNP
routing number mechanism for number mapping to local subscribers.
Next, if the LNP carrier does not have the Skip Rewriting option set, the LNP Rewrite Rules for Callee are
engaged. The rewrite rule set used is the one assigned to the originating peer or subscriber/domain via
the rewrite_rule_set preference. The variables available in the match and replace part are, beside the
standard variables for rewrite rules:
Typically, you would create a rewrite rule to prefix the called party number with the callee_lnp_prefix by
matching ^([0-9]+)$ and replacing it by ${callee_lnp_prefix}\1.
Once the LNP processing is completed, the system checks for further preferences to finalize the
number manipulation. If the terminating local subscriber or peer has the preference lnp_add_npdi set,
the Request URI user-part is suffixed with ;npdi. Next, if the preference lnp_to_rn is set, the Request
URI user-part is suffixed with ;rn=LNP_ROUTING_NUMBER, where LNP_ROUTING_NUMBER is the
Routing Number stored for the number entry in the LNP database, and the originally called number is
kept in place. For example, if lnp_to_rn is set and the number 1800123 is called, and this number has a
routing number 1555123 in the LNP database, the resulting Request-URI is
sip:1800123;[email protected].
Finally, the destination_lnp_prefix in the CDR table is populated either by the prefix defined in the Carrier
of the LNP database if a match was found, or by the default_lnp_prefix preference of the destination
peer or subscriber/domain.
The Sipwise C5 provides means to allow or block calls towards ported numbers that are hosted by
particular LNP carriers. Please visit Creating Rules per NCOS Level in the handbook to learn how this
can be achieved.
If a call originated from a peer and the peer preference force_outbound_calls_to_peer is set to
force_nonlocal_lnp (the if callee is not local and is ported selection in the panel), the call is routed back
to a peer selected via the peering rules.
This ensures that if a number once belonged to your system and is ported out, but other carriers are
still sending calls to you (e.g. selecting you as an anchor network), the affected calls can be routed to
the carrier the number got ported to.
CSV Format
The LNP database can be exported to CSV, and in the same format imported back to the system. On
import, you can decide whether to drop existing data prior to applying the data from the CSV.
The CSV file format contains the fields in the following order:
Name Description
Carrier Name The Name in the LNP Carriers table (string, e.g. My
Carrier)
Carrier Prefix The Prefix in the LNP Carriers table (string, e.g.
DD55)
Number The Number in the LNP Numbers table (E164
number, e.g. 1800666)
Routing Number The Routing Number in the LNP Numbers table
(E164 number or empty, e.g. 1555666)
Start The Start in the LNP Numbers table (YYYY-MM-
DD or empty, e.g. 2016-01-01)
End The End in the LNP Numbers table (YYYY-MM-DD
or empty, e.g. 2016-12-30)
Authoritative The Authoritative flag in the LNP Carriers table (0
or 1)
Skip Rewrite The Skip Rewrite flag in the LNP Carriers table (0 or
1)
Name Description
Type The Type tag in the LNP Numbers table
(alphanumeric string, e.g. mobile)
If a match in the local LNP table is found corresponding LNP Carrier code will be stored in CDR data.
Additionally two dedicated headers can be added to the outgoing SIP message:
This feature is not enabled by default, but can be activated with the following parameters:
• kamailio->proxy->lnp->add_reply_headers->enable : no
• kamailio->proxy->lnp->add_reply_headers->number : P-NGCP-LNP-Number
• kamailio->proxy->lnp->add_reply_headers->status : P-NGCP-LNP-Status
7.7. P-Early-Media
The Sipwise C5 platform supports P-Early-Media Sip Header according to RFC5009.
7.7.1. Implementation
The Sipwise C5 platform tries to find a P-Early-Media SIP header on every INVITE message coming
from peers or subscribers. If the header is found, it tries to parse the content, in particular it looks for the
following parameters:
• sendonly
• recvonly
• inactive
• sendrecv
• supported
• gated
The first four parameters are also known as directional parameters and they will influence how the
Sipwise C5 platform will behave when a service, potentially producing early media, is involved during
the call. The P-Early-media header will be also transparently sent to the b leg of the call and to the
callee which must honour the contents of the header before playing early media.
A typical example is when a subscriber with an announce preference activated is called, under normal
conditions the early media with the announce is played before connecting to the callee. The early
media however wont be played if the caller is not willing to receive the early audio stream (inactive and
sendonly directional parameters set in P-Early-Media).
There are cases when Sipwise C5 produces an early media to alert the user of an error (typical
examples are when the callee is offline or pstn termination is not available). In this situations, if the caller
is not willing to receive the early audio stream, Sipwise C5 will just return a SIP error without playing the
early media announce.
The presence of the supported parameter forces the Sipwise C5 platform to send back P-Early-Media in
18X replies even if the callee user agent does not include it. This will help the caller user agent to
understand that we are going to send early media and an audio channel must be allocated and opened.
The Sipwise C5 platform will add the missing P-Early-Media back from the callee towards the caller,
according to the following schema:
• if caller sends P-Early-Media: sendonly Sipwise C5 will reply with P-Early-Media: recvonly
• if caller sends P-Early-Media: recvonly Sipwise C5 will reply with P-Early-Media: sendonly
• if caller sends P-Early-Media: sendrecv Sipwise C5 will reply with P-Early-Media: sendrecv
• if caller sends P-Early-Media: inactive Sipwise C5 will reply with P-Early-Media: inactive
The gated parameter is recognized by Sipwise C5 but it doesn’t affect its mode of operation. This
parameter, if present, is just passed transparently to the callee.
7.7.2. Configuration
It’s possible to alter how Sipwise C5 manages P-Early-Media just changing the following parameters
inside the config.yml file:
The following figure shows the overview of emergency call processing when using emergency mapping
feature:
The geographic location is referenced by a location ID, which has to be populated by a north-bound
provisioning system. No towns, areas or similar location data is stored on Sipwise C5 platform. The
locations are called Emergency Containers on NGCP.
The actual emergency number mapping is done per location (per Emergency Container), using the so-
called Emergency Mapping entries. An Emergency Mapping entry assigns a routing prefix, valid only in a
geographic area, to a generic emergency number (for example '112' in Europe, '911' in the U.S.A.) or a
country specific one (for example '133').
Emergency Containers may be assigned to various levels of the client hierarchy within NGCP. The
following list shows such levels with each level overriding the settings of the previous one:
1. Customer or Domain
2. Customer Location, which is a territory representing a subset of the customer’s subscribers, defined
as one or more IP subnets.
3. Subscriber
Please be aware that Customer Location is not necessarily identical to the "location"
NOTE
identified through an Emergency Container.
Once the emergency routing prefix has been retrieved from the emergency mapping table, call
processing continues in the same way as in case of simple emergency call handling.
An Emergency Container must be created, before the mapping entries can be defined. Press Create
Emergency Container to start this. An example of a container is shown here:
You have to select a Reseller that this container belongs to, and enter a Name for the container, which
is an arbitrary text.
The platform administrator has to create as many containers as the number of different
TIP
geographic areas (locations) the subscribers are expected to be in.
As the second step of emergency mapping provisioning, the Emergency Mapping entries must be
created. Press Create Emergency Mapping to start this step. An example is shown here:
Once all the necessary emergency mappings have been defined, the platform administrator will see a
list of containers and mapping entries:
The emergency number mapping is now defined. As the next step, the platform administrator has to
assign the emergency containers to Customers / Domains / Customer Locations or Subscribers. We’ll
take an example with a Customer: select the customer, then navigate to Details → Preferences → Number
Manipulations. In order to assign a container, press the Edit button and then select one container from
the drop-down list:
Once emergency containers and emergency mapping entries are defined, Sipwise C5 administrator has
to ensure that the proper number manipulation takes place, before initiating any emergency call
towards peers.
Please don’t forget to define the rewrite rules for peers — particularly: Outbound
IMPORTANT Rewrite Rules for Callee — as described in Normalize Emergency Calls for Peers
section of the handbook.
There is a special case when the dialed number is recognized as an emergency number, but the
emergency number is not available for the geographic area the calling party is located in.
In such a case the emergency mapping lookup will return an emergency prefix, but the value of this will
be NULL. Therefore the call is rejected and an announcement is played. The announcement is a newly
defined sound file referred as emergency_geo_unavailable.
It is possible to configure the rejection code and reason in /etc/ngcp-config/config.yml file, the
parameters are: kamailio.proxy.early_rejects.emergency_invalid.announce_code and
kamailio.proxy.early_rejects.emergency_invalid.announce_reason.
The Sipwise C5 offers the possibility to upload / download emergency mapping entries in form of CSV
files. This operation is available for each reseller, and is very useful if a reseller has many mapping
entries.
One has to navigate to Settings → Emergency Mapping menu and then press the Download CSV button to
get the list of mapping entries in a CSV file. First the reseller must be selected, then the Download
button must be pressed. As an example, the entries shown in "Emergency Mapping List" picture above
would be written in the file like here below:
EmergCont_1,133,E1_133_
EmergCont_1,144,E1_144_
EmergCont_2,133,E2_133_
The CSV file has a plain text format, each line representing a mapping entry, and contains the following
fields:
Uploading a CSV file with emergency mapping entries may be started after pressing the Upload CSV
button. The following data must be provided:
The CSV file for the upload has the same format as the one used for download.
Such an exceptional condition is called emergency mode and it can be activated for all domains on the
system, or only for selected domains.
Once emergency mode is activated, Sipwise C5 will immediately apply the following restrictions on
new SIP requests or existing calls:
• Any SIP requests (calls, registrations etc.) from subscribers within the affected domains, who are not
marked as privileged, are rejected.
• Any calls from peers not targeting privileged subscribers are rejected.
• Any active calls which do not have a privileged subscriber involved are terminated.
The examples do not show details of SIP messages, but rather give a high-level overview of the call-
flows.
1. A non-privileged subscriber makes a call to another non-privileged subscriber. Result: the call will
be rejected.
2. A non-privileged subscriber makes a call to an external subscriber (via peer). Result: the call will
be rejected.
3. A non-privileged subscriber makes a call to a privileged subscriber. Result: the call will be
accepted.
4. A non-privileged subscriber makes a call to an emergency number. Result: the call will be
accepted.
5. A privileged subscriber makes a call to a non-privileged subscriber. Result: the call will be
accepted.
6. A privileged subscriber makes a call to an external subscriber (via peer). Result: the call will be
accepted.
1. System-level Configuration
The emergency priorization function must be enabled for the whole system, otherwise emergency
mode can not be activated. The platform operator has to set
kamailio.proxy.emergency_priorization.enabled configuration parameter value to "yes" in the main
configuration file /etc/ngcp-config/config.yml. Afterwards changes have to be applied in the usual
way, with the command: ngcpcfg apply "Enabled emergency priorization"
In order to learn about other parameters related to emergency priorization please refer to kamailio part
of the handbook.
2. Subscriber-level Configuration
The platform operator (or any administrator user) has the capability to declare a subscriber privileged,
so that the subscriber can initiate and receive calls when emergency mode has been activated on the
NGCP. In order to do that the administrator has to navigate to Settings → Subscribers → select the subscriber →
Details → Preferences → Internals → emergency_priorization on the administrative web interface, and press
the Edit button.
The checkbox emergency_priorization has to be ticked and then press the Save button.
The same privilege can be added via the REST API for a subscriber: a HTTP PUT/PATCH request must
be sent on /api/subscriberpreferences/id resource and the emergency_priorization
property must be set to "true".
The interruption of ongoing calls is only possible with the command-line tool!
IMPORTANT Activating emergency mode for domains via the web interface or REST API will
only affect upcoming calls.
1. Activate emergency mode via web interface: this way of activation is more appropriate if only a
single (or just a few) domain is affected. Please navigate to Settings → Domains → select a domain →
Preferences → Internals → emergency_mode_enabled → Edit.
The checkbox emergency_mode_enabled has to be ticked and then press the Save button.
2. Activate emergency mode via REST API: this way of activation is more appropriate if only a single (or
just a few) domain is affected.
3. Activate emergency mode using a command-line tool: Sipwise C5 provides a built-in script that
may be used to enable/disable emergency mode for some particular or all domains.
/etc/ngcp-config/templates/etc/ngcp-sems/etc/ngcp.sbcprofile.conf.tt2.
header_filter=whitelist
header_list=[%IF kamailio.proxy.debug == "yes"%]P-NGCP-CFGTEST,[%END%]
P-R-Uri,P-D-Uri,P-Preferred-Identity,P-Asserted-
Identity,Diversion,Privacy,
Allow,Supported,Require,RAck,RSeq,Rseq,User-Agent,History-Info,Call-Info
[%IF kamailio.proxy.presence.enable == "yes"%],Event,Expires,
Subscription-State,Accept[%END%][%IF kamailio.proxy.allow_refer_method
== "yes"%],Referred-By,Refer-To,Replaces[%END%]
By default the system will remove from the second leg all the SIP headers which are not in the above
list. If you want to keep some additional/custom SIP headers, coming from the first leg, into the second
leg you need to add them at the end of the header_list= list. After that, as usual, you need to apply the
changes. In this way the system will keep your headers in the INVITE sent to the destination
subscriber/peer.
WARNING DO NOT TOUCH the list if you don’t know what you are doing.
sdp_filter:
codecs: PCMA,PCMU,telephone-event
enable: yes
mode: whitelist
In the example above, the system is removing all the audio CODECS from the initial INVITE except G711
alaw,ulaw and telephone-event. In this way the callee will be notified that the caller is able to talk only
PCMA. Another example is the blacklist mode:
sdp_filter:
codecs: G729,G722
enable: yes
mode: blacklist
In this way the G729 and G722 will be removed from the SDP payload. In order to apply the changes,
run
Codec filtering feature applies to SDP attributes and it does not remove a whole
WARNING SDP media session in case all the related attributes match a filter rule. For
example, this SDP video media session:
in combination with:
sdp_filter:
codecs: PCMA,PCMU,telephone-event
enable: yes
mode: whitelist
will result in no filtering at all because both codecs id 96 97 are not whitelisted and an empty media
session is not allowed.
• codecs_list
• codecs_filter
• codecs_id_filter
• codecs_id_list
These preferences offer an alternative way to filter codecs without updating the configuration file and
restarting the kamailio-proxy service. Since they can be applied at domain/peer/subscriber
preferences level, they feature a more granular management compared when configuration is set via
config.yml file, which is system wide.
The "codecs_list" preference allows you to enter a list of codecs names, valid names are G722, PCMU,
PCMA, speex, GSM, G723, DVI4, L16, QCELP, CN, MPA, G728, DVI4, G729, AMR, AMR*WB, opus,
telephone*event, CelB, JPEG, H261, H263, H263*1998, MPV, MP2T, nv, vp8, vp9, h264.
The "codecs_id_list" preference allows you to achieve the same result but in this case you will have to
enter the corresponding CODEC-ID(s) payload type.
Once the list is filled, you have to specify if the codecs are going to be blacklisted or whitelisted by
kamailio-proxy.This is done through the codecs_filter or the codecs_id_filter preferences.
If "codecs_list" and "codecs_id_list" are set (and the corresponding codecs_list/codec_id_list), both
filters will be applied sequentially: the list of codecs resulting from "codecs_list" filtering will be used as
input for the second "codecs_id_list" filtering.
By default, the codecs filter preferences are cleared (blacklisted) causing all codecs listed inside the
codecs lists preferences to be filtered out. Differently, if the codecs filters are set, only the ones inside
the codecs list will be retained causing the others to be filtered out.
Examples:
• Example1
◦ codecs_list: "G729"
◦ codecs_filter: unset (false)
◦ SDP IN:
◦ SDP OUT:
◦ SDP OUT:
◦ Codec G729 is retained because whitelisted, PCMA PCMU have been filtered out because they
are not whitelisted.
kamailio:
lb:
block_useragents:
action: reject
block_empty: no
block_absent: no
enable: yes
mode: whitelist
ua_patterns:
- Yealink.*
In the example above, the system allows all the requests, which have the User-Agent header beginning
with 'Yealink' value. All other UACs will be rejected with the 403 Forbidden message. To silently drop
the received message, it is possible to specify the drop action instead of the default reject.
kamailio:
lb:
block_useragents:
action: drop
block_empty: no
block_absent: no
enable: yes
mode: blacklist
ua_patterns:
- friendly-scanner
In the example above Sipwise C5 drops all requests, which have the User-Agent header equal to
'friendly-scanner'. Because of the drop action these messages will be dropped silently, without
providing a response to the sender.
kamailio:
lb:
block_useragents:
action: reject
block_empty: yes
block_absent: yes
enable: yes
mode: whitelist
ua_patterns: []
In the example above Sipwise C5 rejects all requests, which have the User-Agent header absent or the
User-Agent header with no value. Such requests will be rejected with a 403 Forbidden message. It’s
possible to set only one of the options (block_empty: / block_absent:) to 'yes'. As well as it’s possible to
keep both of them enabled.
Please remember that the applying of the changes require a restart of the LB
IMPORTANT
component, which is recommended to be done only during non-working hours.
Regardless of the system-wide configuration (UA filtering enabled globaly or not), it is possible to
define a specific User-Agent filtering for each Domain or Subscriber. In order to do so, you should
configure the following fields in Domain’s or Subscriber’s Preferences section:
• ua_filter_list: Contains wildcard list of allowed or denied SIP User-Agents matched against the User-
Agent header.
• ua_filter_mode: Specifies the operational mode of the SIP User-Agent Filter List: Blacklist or
Whitelist.
• Subscriber username - any SIP username that forms an "email-style" SIP URI.
• Subscriber Aliases - numbers in the global E.164 format without leading plus.
To configure the Subscriber, go to Settings→Subscribers and click Details on the row of your subscriber.
There, click on the Preferences button on top.
You should look into the Number Manipulations and Access Restrictions sections in particular, which
control the calling and called number presentation.
Fallback behaviours
Sipwise C5 can enhance pbx integration providing three different extended dialing modes:
• Strict number matching: dialing arbitrary extension behind subscriber number is not allowed
• Extended matching, send dialed number with extension: the system will locate the subscriber by
longest matching prefix, only the whole dialied number (base number + extension) will be written
inside the Request uri user part.
• Extended matching, send base matching number: the system will locate the subscriber by longest
matching prefix, only the base number or subscriber username will be written inside the Request uri
user part.
• Extended matching, send primary number with extension: the system will locate the subscriber by
longest matching prefix, the new Request uri user part will be equal to the primary number with
appended the extension (calculated using the exceeding part of the callee).
Fallback procedure is on by default and usually applies to extended matching or e164_to_ruri modes. If
the callee UAC replies with a 404 not found error, the fallback feature triggers the generation of a new
INVITE. In this case the new Request URI will be set accordingly to the extended_dialing_mode and
e164_to_ruri values.
The whole 404 fallback procedure can however be disabled activating the no_404_fallback option
under subscriber’s or domain’s preferences.
Rewrite rules
The SIP PBX by default inherits the domain dialplan which usually has rewrite rules applied to normal
Class 5 subscribers with inbound rewrite rules normalizing the dialed number to the E.164 standard. If
most users of this domain are Class 5 subscribers the dialplan may supply calling number in national
format - see Configuring Rewrite Rule Sets. While the SIP-PBX trunk configuration can be sometimes
amended it is a good idea in sense of SIPconnect recommendation to send only the global E.164
numbers.
Moreover, in mixed environments with Sipwise C5 Cloud PBX sharing the same domain with SIP
trunking (SIP-PBX) customers the subscribers may have different rewrite rules sets assigned to them.
The difference is caused by the fact that the dialplan for Cloud PBX is fundamentally different from the
dialplan for SIP trunks due to extension dialing, where the Cloud PBX subscribers use the break-out
code to dial numbers outside of this PBX.
The SIPconnect compliant numbering plan can be accommodated by assigning Rewrite Rules Set to
the SIP-PBX subscriber. Below is a sample Rewrite Rule Set for using the global E.164 numbers with
plus required for the calling and called number format compliant to the recommendation.
Outbound Rewrite Rules for Callee shall NOT be applied to the calls to normal SIP
WARNING UAs like IP phones since the number with plus does not correspond to their SIP
username.
User parameter
The following configuration is needed for your platform to populate the From and To headers and
Request-URI of the INVITE request with "user=phone" parameter as per RFC 3261 Section 19.1.1 (if the
user part of the URI contains telephone number formatted as a telephone-subscriber).
Forwarding number
The following is our common configuration that covers the calling number presentation in a variety of
use-cases, including the incoming calls, on-net calls and Call Forward by the platform:
The above parameters can be tuned to operator specifics as required. You can override these settings
in the Subscriber Preferences if particular subscribers need special settings.
On outgoing call from SIP-PBX subscriber the Network-Provided Number (NPN) is set to
TIP the cli preference prefilled with main E.164 number. In order to have the full alias number
as NPN on outgoing call set preference extension_in_npn = Y.
If the call forward takes place inside the SIP-PBX it can use one of the following specification for
signaling the diversion number to the platform:
Allowed CLIs
• For correct calling number presentation on outgoing calls, you should include the pattern matching
all the alias numbers of SIP-PBX or each individual alias number under the allowed_clis preference.
• If the signalling calling number (usually taken from From user-part, see inbound_upn preferences)
does not match the allowed_clis pattern, the user_cli or cli preference (Network-Provided Number)
will be used for calling number presentation.
7.11.4. Registration
SIP-PBX can use either Static or Registration Mode. While SIPconnect 1.1 continues to require TLS
support at MUST strength, one should note that using TLS for signaling does not require the use of the
SIPS URI scheme. SIPS URI scheme is obsolete for this purpose.
Static Mode
While SIPconnect 1.1 allows the use of Static mode, this poses additional maintenance overhead on the
operator. The administrator should create a static registration for the SIP-PBX: go to Susbcribers, Details
→Registered Devices→Create Permanent Registration and put address of the SIP-PBX in the following format:
sip:username@ipaddress:5060 where username=username portion of SIP URI and ipaddress = IP
address of the device.
Registration Mode
It is recommended to use the Registration mode with SIP credentials defined for the SIP-PBX
subscriber.
The use of RFC 6140 style "bulk number registration" is discouraged. The SIP-
IMPORTANT PBX should register one AOR with email-style SIP URI. The Sipwise C5 will take
care of routing the aliases to the AOR with e164_to_ruri preference.
Trusted Sources
If a SIP-PBX cannot perform the digest authentication, you can authenticate it by its source IP address in
Sipwise C5. To configure the IP-based authentication, go to the subscriber’s preferences (Details→
Preferences→Trusted Sources) and specify the IP address of the SIP-PBX in the Source IP field.
To authenticate multiple subscribers from the same IP address, use theFrom field to distinguish these
subscribers.
When this feature is configured for a subscriber, Sipwise C5 authenticates all calls that arrive from the
If the same IP address and the FROM field are mistakenly specified as trusted for
IMPORTANT different subscribers, Sipwise C5 will not know which subscriber to charge for
the call and will randomly select one.
In order to make a regular subscriber trusted, perform the following extra steps:
This way, all SIP messages coming from the device IP will be considered trusted (and get authenticated
only by the source IP). All the SIP messages forwarded to the devices will be sent to the SIP URI
specified in the subscriber’s permanent registration.
This chapter provides information on the peer probing feature of Sipwise C5 that is available since the
mr5.4.1 release.
Even if this timer is set much lower, like 3 sec, the call setup time is increased significantly. This is even
more true if multiple peering servers fail at the same time, which will sum up the individual timeouts,
finally causing call setup times reach the order of tens of seconds.
To optimize the call setup time in such scenarios, a new feature is implemented to continuously probe
peering servers via SIP messages, and mark them as unavailable on timeout or when receiving
unexpected response codes. Appropriate SIP response codes from the peering servers will mark them
as available again.
Peering servers marked as unavailable are then skipped during call routing in the peering selection
process, which significantly shortens the call setup times if peering servers fail.
1. System-level configuration enables the peer probing feature in general on the Sipwise C5 and
determines the operational parameters, such as timeouts, the SIP method used for probing
requests, etc.
2. Peering server configuration will add / remove a peering server to the list of probed endpoints.
System-level Configuration
The parameters of peer probing are found in the main system configuration file /etc/ngcp-
config/config.yml. You can see the complete list of configuration parameters in kamailio of the
handbook, while the most significant ones are discussed here.
The SIP method used for probing requests can be defined through
kamailio.proxy.peer_probe.method parameter. Allowed values are: OPTIONS (default) and INFO.
The system administrator, in most of the cases, will not need to modify the default
TIP
configuration values other than that of timeout and interval.
If no available peering server is found, the call is rejected with the response code and reason
configured in kamailio.proxy.early_rejects.peering_unavailable.announce_code and
kamailio.proxy.early_rejects.peering_unavailable.announce_reason. If a sound file is
configured within the system sound set assigned to the calling party, an announcement is played as
early media before the rejection.
When the peer probing feature is enabled on system-level, it is possible to add each individual peering
server to the list of probed endpoints. You can change the probed status of a server in two ways:
1. Open the properties panel of a peering server: Peerings → select a peering group → Details → select a
peering server → Edit
2. Tick the checkbox Enable Probing
3. Save changes
• when you create a new peering server you will use an HTTP POST request and the target URL:
https://<IP_of_NGCP>:1443/api/peeringservers
• when you update an existing peering server you will use an HTTP PUT or PATCH request and the
target URL:
https://<IP_of_NGCP>:1443/api/peeringservers/id
In all cases you have to set the 'probe' property to true in order to enable probing, and to false in
order to disable probing. Default value is false and this property may be omitted in a create/update
request, which ensures backward compatibility of the /api/peeringservers API resource.
This subchapter of the handbook is targeted on advanced system operators and Sipwise
TIP engineers and is not necessary to read in order to properly manage peer probing feature
of NGCP.
Each kamailio-proxy instance on the proxy nodes performs the probing individually for performance
reasons. Each proxy holds its result in its cache to avoid central storage and replication of the probing
results.
Each peering server is cross-checked against the hash table filled during outbound probing requests
and is skipped by call routing logic, if a match is found.
On start or restart of the kamailio-proxy instance, the probing will start after the first interval, and NOT
immediately after start. In the first probing interval the proxy will always try to send call traffic to
peering servers until the first probing round is finished, and will only then start to skip unavailable
peering servers.
Database Changes
A peer status change will populate the kamailio.dispatcher table, inserting the SIP URI in format
sip:$ip:$port;transport=$transport in dispatcher group 100, which defines the probing group
for peering servers.
Since access might need to be provided from external networks like PSTN/Mobile, and since certain
SIP phones do not support calling alphanumeric numbers to dial voicebox, you can map any number to
the voicebox URIs using rewrite rules.
To do so, you can provision a match pattern e.g. ^(00|\+)12345$ with a replace pattern voicebox,
voiceboxpass or voiceboxpin to map a number to either password-less for the first one or
password-based IVR access for the other two. Create a new rewrite rule with the Inbound direction
and the Callee field in the corresponding rewrite rule set.
For inbound calls from external networks, assign this rewrite rule set to the corresponding incoming
peer. If you also need to map numbers for on-net calls, assign the rewrite rule set to subscribers or the
whole SIP domain.
When reaching voiceboxpass, the subscriber is prompted for her mailbox number and a password. All
numbers assigned to a subscriber are valid input (primary number and any alias number). By default,
the required format is in E.164, so the subscriber needs to enter the full number including country code,
for example 4912345 if she got assigned a German number.
While reaching for voiceboxpin, the subscriber is only prompted for the PIN.
You can globally configure a rewrite rule in config.yml using asterisk.voicemail.normalize_match and
asterisk.voicemail.normalize_replace, allowing you to customize the format a subscriber can enter, e.g.
having ^0([1-9][0-9]+)$ as match part and 49$1 as replace part to accept German national format.
Unavailable Message
The standard voice mail greeting is the "unavailable" greeting. This is used if you don’t answer the
phone and so the call is directed to your voice mailbox.
Busy Message
If you wish, you can record a custom greeting used when someone calls you and you are currently on
the phone. This is called your "Busy" greeting.
Temporary Greeting
You can also record a temporary greeting. If it exists, a temporary greeting will always be played
instead of your "busy" or "unavailable" greetings. This could be used, for example, if you are going on
vacation or will be out of the office for a while and want to inform people not to expect a return call
anytime soon. Using a temporary greeting avoids having to change your normal unavailable greeting
when you leave and when you come back.
7.14.4. Folders
The Voicemail system allows you to save and organize your messages into folders. There can be up to
ten folders.
• 0 - New Messages
• 1 - Old Messages
• 2 - Work Messages
• 3 - Family Messages
• 4 - Friends Messages
When a caller leaves a message for you,the system will put the message into the "New Messages"
folder. If you listen to the message, but do not delete the message or save the message to a different
folder, it will automatically move the message to the "Old Messages" folder. When you first log into your
mailbox, the Voicemail System will make the "New Messages" folder the current folder if you have any
new messages. If you do not have any new messages the it will make the "Old Messages" folder the
current folder.
Mailbox Options
Leaving a Message
The Sipwise C5 provides the pre-installed prompts for the Voicemail in the English, Spanish, French and
Italian languages and the pre-installed prompts for the Vertical Service Codes IVRs in English only.
The other IVRs such as the Conference system and the error announcements use the Sound Sets
configured in Sipwise C5 Panel and uploaded by the administrator in his language of choice.
As soon as the first audio files (for the sound sets) are uploaded, they will be stored
using the SQL backend and will be not available in the filesystem (as usual files). But, as
soon as these files are first time played for a caller, they will be stored (cached) in the
NOTE '/ngcp-data/cache' directory. This is done so in order to reduce the time needed to
retrieve them (on a routine basis). Anyway, this data will always be stored in the SQL
backend as well for redundancy reasons. So your Sipwise C5 will always be able to
retrieve them from SQL and cache them again if needed.
NOTE You may use 8 or 16 bit mono WAV audio files for all of the voice prompts.
• Contract_Sound_Set is a customer-specific sound set used for the Cloud PBX features. It can be
assigned only to a PBX customer.
• Sound_Set contains general prompts, e.g. for the Conference, Music on Hold, Early Rejects, etc.
The Music on Hold and Digit prompts can be uploaded to both Contract_Sound_Set and Sound_Set. In
this case, the one from the Contract_Sound_Set will take precedence.
The call error announcements are played to the user in early media hence the name "Early Reject". If
you don’t provide the sound files for any handles they will not be used and Sipwise C5 will fallback to
sending the error response code back to the user.
The exact error status code and text are configurable in the /etc/ngcp-config/config.yml file, in
kamailio.proxy.early_rejects section. Please look for the announcement handle listed in below table in
order to find it in the configuration file.
There are some early reject scenarios when either no voice announcement is played, or a fixed
announcement is played. In either case a SIP error status message is sent from Sipwise C5 to the
calling party. It is possible to configure the exact status code and text for such cases in the /etc/ngcp-
config/config.yml file, in kamailio.proxy.early_rejects section. The below table gives an overview of
those early reject cases.
Handle Description
block_admin Caller blocked by adm_block_in_list,
adm_block_in_clir and callee blocked
by adm_block_out_list (customer or
subscriber preference)
block_callee Callee blocked by subscriber
preference block_out_list
block_caller Caller blocked by subscriber preference
block_in_list, block_in_clir
block_contract Caller blocked by customer preference
block_in_list, block_in_clir and callee
blocked by customer preference
block_out_list
callee_tmp_unavailable_gp Callee is a PBX group with 0 members.
Announcement callee_tmp_unavailable
is played; status code and text can be
configured.
callee_tmp_unavailable_tm Callee is a PBX group and we have a
timeout (i.e. no group member could be
reached). Announcement
callee_tmp_unavailable is played; status
code and text can be configured.
emergency_invalid PLEASE NOTE: This handle refers to the
same early reject case as
emergency_geo_unavailable, but is
labeled differently in the configuration
file.
To activate this feature, first create a system Sound Set, or use an already existing one, and then assign
it to the callee subscriber. Upload in the Sound Set one or more announcements. Once the Sound Set is
configured, the subscriber’s preference announce_error_codes_enable must be enabled under
Subscriber → Preferences → NAT and Media Flow Control menu. Last step is to list in the subscriber’s
preference announce_error_codes_list the announcements that will be played to the caller in case a
particular error code is returned back from the callee. Each entry of the list has to be a string composed
in the following way: <error_code>;<announcement_name>, where error_code is the SIP return code
and announcement_name is name of the announcement taken from the sound_set list. Returning to the
example above, to play callee_unknown message in case of 404 returned from the callee, the entry
'404;callee_unknown' has to be added in announce_error_codes_list preference.
You should select Conference option in the Destination field and leave the URI/Number empty. The
timeout defines for how long this destination should be tried to ring.
Then set the preference sound_set on the Domain or Subscriber level in order to assign the Sound Set
you have just created to the subscriber (as usual the subscriber preference overrides the domain one).
In case the PIN protection for the conference is activated, when someone calls the subscriber who has
enabled the conference, the caller is prompted to enter the PIN of the conference. Upon the successful
entry of the PIN the caller hears the announcement that he is going to be placed into the conference
and at the same time this is announced to all participants already in the conference.
7.18.1. Setup
To enable the feature first edit config.yml and enable there apps: malicious_call: yes and kamailio:
store_recentcalls: yes. The latter option enables kamailio to store recent calls per subscrbriber UUID in
the redis DB (the amount of stored recent calls will not exceed the amount of provisionined
subscribers).
Next step is to create a system sound set for the feature. In Settings→Sound Sets either use your already
existing Sound Set or create a new Sound Set and then assign it to your domain or subscribers. In the
Sound Set there is a fileset malicious_call_identification→mailicious_call_report for that purpose.
Once the Sound Set is created the Subscriber’s Preferences Malicious Call Identification must be
enabled under Subcriber → Preferences → Applications menu. The same parameter can be set in the
Customer’s preferences to enable this feature for all its subscribers.
The final step is to create a new Rewrite Rule and to route calls to, for instance *123 -> MCID application.
For that you create a Calee Inbound rewrite rule ^(\*123)$ → malicious_call
Finally you run ngcpcfg apply "Enabling MCID" to recreate the templates and automatically restart
depended services.
7.18.2. Usage
As a subscriber, to report a malicious call you call to either malicious_call or to your custom number
assigned for that purpose. Please note that you can report only your last received call. You will hear the
media reply from the Sound Set you have previously configured.
To check reported malicious calls as the plafrom operator open Settings→Malicious Calls tab where you
will see a list of registered calls. You can selectively delete records from the list and alternatively you
can manage the reported calls by using the REST API.
Profile Sets can be defined in Settings→Subscriber Profiles. To create a new Profile Set, click Create
Subscriber Profile Set.
To create Profiles within a Profile Set, hover over the Profile Set and click the Profiles button.
Profiles within a Profile Set can be created by clicking the Create Subscriber Profile button.
Checking the Default Profile option causes this profile to get assigned automatically to all subscribers,
who have the profile set assigned. Other options define the user preferences which should be made
available to the subscriber.
When the platform administrator selects Preferences of the Subscriber Profile he will
NOTE get an empty page like in the picture below, if none or only certain options are selected
in the Subscriber Profile.
Some of the options, like ncos (NCOS level), will enable the definition of that preference within the
Subscriber Profile Preferences. Thus all subscribers who have this profile assigned to will have the
preference activated by default. The below picture shows the preferences linked to the sample
Subscriber Profile:
The system operator or a third party application can also generate, list, retrieve and delete
TIP
invoices via the REST API. Please read further details here.
To request invoice generation for the particular customer and period press "Create invoice" button. On
the invoice creation form following parameters are available for selection:
• Template: any of existent invoice template can be selected for the invoice generation.
• Customer: owner of the billing account, recipient of the invoice.
• Invoice period: billing period. Can be specified only as one calendar month. Calls with start time
between first and last second of the period will be considered for the invoice
The subsequent sections describe the available operations for invoice management with API requests
in details. All operations work on the Invoices resource and use the /api/invoices base path. The
authentication method is username/password in the examples given below, however it is
recommended to use a TLS client certificate for authentication on the REST API.
The prerequisite for generating a new invoice is that the customer has to have an invoice template
assigned to him.
The following example shows a CURL command that will request generation of an invoice:
Please note that in this operation we used the /api/invoices path (the invoices collection) and a
POST request on it to create a new invoice item.
In case of a successful operation, Sipwise C5 will reply with **201 Created** HTTP status and send the
ID of the invoice in Location header. In our example the new invoice item may be directly referred as
/api/invoices/3 (ID = 3).
In case of a failed operation, e.g. when we request an invoicing period that is invalid for the customer,
Sipwise C5 will reply with **422 Unprocessable Entity** or **500 Internal Server Error** HTTP status.
You can download properties / data of a specific invoice by selecting the item by its ID, using an HTTP
GET request.
The above request will return a JSON data structure containing invoice properties:
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 15 Nov 2017 12:13:04 GMT
Content-Type: application/hal+json;
profile="http://purl.org/sipwise/ngcp-api/"; charset=utf-8
Content-Length: 759
Connection: close
Link: </api/invoices/>; rel=collection
Link: <http://purl.org/sipwise/ngcp-api/>; rel=profile
Link: </api/invoices/3>; rel="item self"
Link: </api/invoices/3>; rel="item http://purl.org/sipwise/ngcp-
api/#rel-invoices"
Link: </api/customers/79>; rel="item http://purl.org/sipwise/ngcp-
api/#rel-customers"
Set-Cookie: ngcp_panel_session=219feccbee4fa936defd1ee511c84efe7b5a6d6a;
path=/; expires=Wed, 15-Nov-2017 13:13:03 GMT; HttpOnly
Strict-Transport-Security: max-age=15768000
{
"_links" : {
"collection" : {
"href" : "/api/invoices/"
},
"curies" : {
"href" : "http://purl.org/sipwise/ngcp-api/#rel-{rel}",
"name" : "ngcp",
"templated" : true
},
"ngcp:customers" : {
"href" : "/api/customers/79"
},
"ngcp:invoices" : {
"href" : "/api/invoices/3"
},
"profile" : {
"href" : "http://purl.org/sipwise/ngcp-api/"
},
"self" : {
"href" : "/api/invoices/3"
}
},
"amount_net" : 0,
"amount_total" : 0,
"amount_vat" : 0,
"id" : 3,
"period_end" : "2017-11-30T23:59:59+00:00",
"period_start" : "2017-11-01T00:00:00+00:00",
"sent_date" : null,
"serial" : "INV2017110000003"
}
It is also possible to query the complete invoices collection and use a filter (e.g. invoicing period,
customer ID, etc.) to get the desired invoice item. In the example below we request all available
invoices that belong to the customer with ID "79".
The returned dataset is now slightly different because it is represented as an array of items, although in
our example the array consist of only 1 item:
{
"_embedded" : {
"ngcp:invoices" : [
{
"_links" : {
"collection" : {
"href" : "/api/invoices/"
},
"curies" : {
"href" : "http://purl.org/sipwise/ngcp-api/#rel-
{rel}",
"name" : "ngcp",
"templated" : true
},
"ngcp:customers" : {
"href" : "/api/customers/79"
},
"ngcp:invoices" : {
"href" : "/api/invoices/3"
},
"profile" : {
"href" : "http://purl.org/sipwise/ngcp-api/"
},
"self" : {
"href" : "/api/invoices/3"
}
},
"amount_net" : 0,
"amount_total" : 0,
"amount_vat" : 0,
"id" : 3,
"period_end" : "2017-11-30T23:59:59+00:00",
"period_start" : "2017-11-01T00:00:00+00:00",
"sent_date" : null,
"serial" : "INV2017110000003"
}
]
},
"_links" : {
"curies" : {
"href" : "http://purl.org/sipwise/ngcp-api/#rel-{rel}",
"name" : "ngcp",
"templated" : true
},
"ngcp:invoices" : {
"href" : "/api/invoices/3"
},
"profile" : {
"href" : "http://purl.org/sipwise/ngcp-api/"
},
"self" : {
"href" : "/api/invoices/?page=1&rows=10"
}
},
"total_count" : 1
}
You can download a specific invoice as a PDF file in the following way:
• selecting the item by its ID (as in our example, but you can also use a filter and query the complete
invoices collection)
• using an HTTP GET request
• adding "Accept: application/pdf" header to the request
Please note that in the example above we do not add the "-i" option that would also include the
headers of the HTTP response in the output file. The output of the CURL command, i.e. the PDF file, is
saved as "result.pdf" locally.
Delete an Invoice
In order to delete an invoice item you have to send a DELETE request on the specific item:
In case of successful deletion Sipwise C5 should send HTTP status 204 No Content as a response:
Invoice templates can be searched, created, edited and deleted in the invoice templates management
interface.
On the invoice template meta information form following parameters can be specified:
• Reseller: reseller who owns this invoice template. Please note, that it doesn’t mean that the
template will be used for the reseller customers by default. After creation, invoice template still
need to be linked to the reseller customers.
• Name: unique invoice template name to differentiate invoice templates if there are some.
• Type: currently Sipwise C5 supports only svg format of the invoice templates.
After registering new invoice template you can change invoice template structure in WYSIWYG SVG
editor and preview result of the invoice generation based on the template.
Invoice template is a XML SVG source, which describes content, look and position of the text lines,
images or other invoice template elements. The Sipwise C5 provides embedded WYSIWYG SVG editor
svg-edit 2.6 to customize default template. The Sipwise C5 svg-edit has some changes in layers
management, image edit, user interface, but this basic introduction still may be useful.
Template refers to the owner reseller contact ("rescontact"), customer contract ("customer"), customer
contact ("custcontact"), billing profile ("billprof"), invoice ("invoice") data as variables in the "[%%]" mark-up
with detailed information accessed as field name after point e.g. [%invoice.serial%]. During invoice
generation all variables or other special tokens in the "[% %]" mark-ups will be replaced by their
database values.
Press on "Show variables" button on invoice template content page to see full list of variables with the
fields:
You can add/change/remove embedded variables references directly in main svg-edit window. To
edit text line in svg-edit main window double click on the text and place cursor on desired position in
the text.
After implementation of the desired template changes, invoice template should be saved.
To return to Sipwise C5 invoice template default content you can press on the "Discard changes"
button.
Layers
Default template contains three groups elements (<g/>), which can be thinked of as pages, or in terms
of svg-edit - layers. Layers are:
• Background: special layer, which will be repeated as background for every other page of the
invoice.
• Summary: page with a invoice summary.
• CallList: page with calls made in a invoice period. Is invisible by default.
To see all invoice template layers, press on "Layers" vertical sign on right side of the svg-edit interface:
One of the layers is active, and its element can be edited in the main svg-edit window. Currently active
layer’s name is bold in the layers list. The layers may be visible or invisible. Visible layers have "eye" icon
left of their names in the layers list.
To make a layer active, click on its name in the layers list. If the layer was invisible, its elements became
visible on activation. Thus you can see mixed elements of some layers, then you can switch off visibility
of other layers by click on their "eye" icons. It is good idea to keep visibility of the "Background" layer on,
so look of the generated page will be seen.
Sometimes it may be convenient to edit svg source directly and svg-edit makes it possible to do it.
After press on the <svg> icon in the top left corner of the svg-edit interface:
When edit svg xml source, please change very carefully and thinkfully things
inside special comment mark-up "<!--{ }-→". Otherwise invoice generation may be
broken. Please be sure that document structure repeats default invoice
IMPORTANT
template: has the same groups (<g/>) elements on the top level, text inside
special comments mark-up "<!--{ }-→" preserved or changed appropriately, svg xml
structure is correct.
To save your changes in the svg xml source, first press "OK" button on the top left corner of the source
page:
You can copy and keep the svg source of your template as a file on the disk before
NOTE start experimenting with the template. Later you will be able to return to this version
replacing svg source.
You will see message about successfully saved template. You can preview your invoice look in PDF
format. Press on "Preview as PDF" button.
• Web password reset requested. Email will be sent to the subscriber, whom password was
requested for resetting. If the subscriber doesn’t have own email, letter will be sent to the customer,
who owns the subscriber.
• Administrator password reset requested. Email will be sent to the administrator, whom password
was requested for resetting. If the administrator doesn’t have an email, an error message will appear
when requesting the password reset.
• New subscriber created. Email will be sent to the newly created subscriber or to the customer, who
owns new subscriber.
• Letter with the invoice. Letter will be sent to the customer.
Each email template refers to the values from the database using special mark-ups "[%" and "%]". Each
email template has fixed set of the variables. Variables can’t be added or changed without changes in
Sipwise C5 Panel code.
Template
name passreset_default_email
From [email protected]
Subject Password reset email
Body Dear Customer,
--
This is an automatically generated message. Do not reply.
• [%url%]: specially generated url where subscriber can define his new password.
• [%subscriber%]: username@domain of the subscriber, which password was requested for reset.
Template
name admin_passreset_default_email
From [email protected]
Subject Password reset email
Body Dear Customer,
--
This is an automatically generated message. Do not reply.
• [%url%]: specially generated url where administrator can define his new password.
• [%admin%]: username@domain of the administrator, which password was requested for reset.
By default email content template is addressed to the customer. Please consider this
NOTE
when create the subscriber with an email.
Template
name subscriber_default_email
From [email protected]
Subject Subscriber created
--
This is an automatically generated message. Do not reply.
• [%url%]: specially generated url where subscriber can define his new password.
• [%subscriber%]: username@domain of the subscriber, which password was requested for reset.
Template
name invoice_default_email
From [email protected]
Subject Invoice #[%invoice.serial%] from [%invoice.period_start_obj.ymd%] to
[%invoice.period_end_obj.ymd%]
Body Dear Customer,
--
This is an automatically generated message. Do not reply.
Invoice fields
• [%invoice.serial%]
• [%invoice.amount_net%]
• [%invoice.amount_vat%]
• [%invoice.amount_total%]
NOTE • [%invoice.period_start_obj%]
• [%invoice.period_end_obj%]
man DateTime
• [%provider%]: container variable for the reseller contact. All database contact values will be
available.
• [%client%]: container variable for the customer contact.
Contact fields example for the "provider". Replace "provider" to client to access proper
"customer" contact fields.
• [%provider.gender%]
• [%provider.firstname%]
• [%provider.lastname%]
• [%provider.comregnum%]
• [%provider.company%]
• [%provider.street%]
• [%provider.postcode%]
• [%provider.city%]
NOTE • [%provider.country%]
• [%provider.phonenumber%]
• [%provider.mobilenumber%]
• [%provider.email%]
• [%provider.newsletter%]
• [%provider.faxnumber%]
• [%provider.iban%]
• [%provider.bic%]
• [%provider.vatnum%]
• [%provider.bankname%]
• [%provider.gpp0 - provider.gpp9%]
C5 .
• Subject: Template of the email subject. Subject will be processed with the same template variables
as the email body.
• Body: Email text template. Will be processed with appropriate template variables.
The value user input is normalized using the Rewrite Rules Sets assigned to
IMPORTANT
domain as described in Configuring Rewrite Rule Sets.
By default, the following codes are configured for setting features. The examples below assume that
there is a domain rewrite rule normalizing the number format 0<ac><sn> to <cc><ac><sn> using 43 as
country code.
• 72 - enable Call Forward Unconditional e.g. to 431000 by dialing *72*01000, and disable it by
dialing #72.
• 90 - enable Call Forward on Busy e.g. to 431000 by dialing *90*01000, and disable it by dialing #90.
• 92 - enable Call Forward on Timeout e.g. after 30 seconds of ringing to 431000 by dialing
*92*30*01000, and disable it by dialing #92.
• 93 - enable Call Forward on Not Available e.g. to 431000 by dialing *93*01000, and disable it by
dialing #93.
• 96 - disable at once all the Call Forwards previously configured using VSC, e.g. disable all the CFs
by dialing #96.
• 50 - set Speed Dial Slot, e.g. set slot 1 to 431000 by dialing *50*101000, which then can be used by
dialing *1. There is no code to disable a speed dial slot. When a slot is no longer necessary, it can
be ultimately removed using the web interface or can be ignored, because it is not impacting the
calls from and to this subscriber.
• 55 - set One-Shot Reminder Call e.g. to 08:30 by dialing *55*0830.
• 31 - set Calling Line Identification Restriction for one call, e.g. to call 431000 anonymously dial
*31*01000.
• 32 - enable Block Incoming Anonymous Calls by dialing 32, and disable it by dialing #32.
• 80 - call using Call Block Override PIN, number should be prefixed with a block override PIN
configured in admin panel to disable the outgoing user/admin block list and NCOS level for a call.
For example, when override PIN is set to 7890, dial *80*789001000 to call 431000 bypassing block
lists.
• 95 - allow to redial the last dialed number by the subscriber. Note: the feature has to be enabled for
the subscriber/domain using preference last_number_redial.
• 71 - allow to hear a voice announcement of the last caller’s number, after the announcement dial
the key defined in sems→vsc→callback_last_caller_confirmation_key to return the call. Note: it is not
possible return a call if the caller’s number is unavailable.
• 74 - allow to return the call to the last caller’s number who called you without hearing the last call
ID announcement. Note: it is not possible return a call if the caller’s number is unavailable.
• 20 - allow to remove the records of the recent calls to and from you.
In order to use the feature codes related to recent calls (95, 71, 74, 20) the
kamailio→proxy→store_recentcalls preference in /etc/ngcp-config/config.yml has to
IMPORTANT be set to yes. Additionally, to handle caller numbers coming from Peers (e.g.
PSTN), set the kamailio→proxy→foreign_domain_via_peer preference to yes in
/etc/ngcp-config/config.yml file.
If you have the EMTAs under your control, make sure that the specified VSCs don’t
CAUTION overlap with EMTA-internal VSCs, because the VSC calls must be sent to Sipwise
C5 via SIP like normal telephone calls.
• Call Recording function can store both unidirectional (originating either from caller, or from callee)
or bidirectional (combined) streams from calls, resulting in 1, 2 or 3 physical files as output
• The location and format of the files is configurable.
• File storage is planned to occur on an NFS shared folder.
• Activation of call recording may happen generally for a Domain / Peer / Subscriber through Sipwise
C5 admin web interface.
NGCP’s Call Recording function is not meant for individual call interception
IMPORTANT
purpose! Sipwise provides its Lawful Interception solution for that use case.
• Querying or deletion of existing recordings may happen through the REST API.
• Listing recordings of a subscriber is possible on NGCP’s admin web interface.
There are 2 rtpengine daemons employed when call recording is enabled and active.
The main rtpengine takes care of forwarding media packets between caller and callee,
NOTE
as usual, while the secondary rtpengine (recording) daemon is responsible for storing
call data streams in the file system.
Call Recording is disabled by default. Enabling and configuration of Call Recording takes place in 2
steps:
1. Enabling the feature on Sipwise C5 by setting configuration parameters in the main config.yml
configuration file.
2. Activating the feature for a Domain / Peer / Subscriber.
Since call data amount may be huge (depending on the number and duration of
calls), it is strongly not recommended to store recorded streams on NGCP’s local
IMPORTANT disks. However if you have to store recorded streams as files in the local
filesystem, please contact Sipwise Support team in order to get the proper
configuration of Call Recording function.
The NFS share gets mounted during startup of the recording daemon. If the NFS share cannot be
mounted for some reason, the recording daemon will not start.
There might be 1, 2 or 3 files produced as recorded streams. The number of files depends on the
configuration:
7.25.3. Configuration
The Call Recording function can be enabled and configured on Sipwise C5 by changing the following
configuration parameters in config.yml file:
rtpproxy:
...
recording:
enable: no
mp3_bitrate: '48000'
nfs_host: 192.168.1.1
nfs_remote_path: /var/recordings
output_dir: /var/lib/rtpengine-recording
output_format: wav
output_mixed: yes
output_single: yes
resample: no
resample_to: '16000'
spool_dir: /var/spool/rtpengine
Enabling the function requires changing the value of rtpproxy.recording.enable parameter to “yes”. In
order to make the new configuration active, it’s necessary to do:
• enable: when set to “yes” Call Recording function is enabled; default: “no”
• mp3_bitrate: the bitrate used when recording happens in MP3 format; default: "48000"
• nfs_host: IP address of the NFS host that provides storage space for recorded streams; default:
"192.168.1.1"
• nfs_remote_path: the remote path (folder) where files of recorded streams are stored on the NFS
share; default: "/var/recordings"
• output_dir: is the local mount point for the NFS share, and thus where the final audio files will be
written; default: "/var/lib/rtpengine-recording"
Normally you don’t need to change the default setting. If you do change the
CAUTION value, please be aware that recorded files will be written by root user in that
directory.
• output_format: possible values are “wav” (Wave) or “mp3” (MP3); default: “wav”
• output_mixed: “yes” means that there is a file that contains a mixed stream of caller and callee voice
data; default: "yes"
• output_single: “yes” means that there is a separate file for each stream direction, i.e. for the streams
originating from caller and callee; default: "yes"
• resample: when set to “yes” the call data stream will be resampled before storing it in the file;
default: “no”
• resample_to: the sample rate used for resampling output; default: "16000"
• spool_dir: is the place for temporary metadata files that are used by the recording daemon and the
main rtpengine daemon for their communication; default: "/var/spool/rtpengine"
You should not change the default setting unless you have a good reason to do
CAUTION so! Sipwise has thoroughly tested the Call Recording function with the default
setting.
If Call Recording is enabled you can see 2 rtpengine processes running when checking Sipwise C5
system state with ngcp-service tool:
Activating Call Recording for e.g. a Subscriber: please use NGCP’s admin web interface for this purpose.
On the web interface one has to navigate as follows: Settings → Subscribers → select subscriber Details →
Preferences → NAT and Media Flow Control. Afterwards the record_call option has to be enabled by
pressing the Edit button and ticking the checkbox.
The call recording function may be activated for a single Subscriber, a Domain and a
Peer server in the same way: Preferences → NAT and Media Flow Control → record_call.
NOTE When activating call recording for a Domain or Peer this effectively activates the
function for all subscribers that belong to the selected domain, and for all calls with a
local endpoint going through the selected peer server, respectively.
Once the call recording is active it’s also possible to play a pre recording announcement to the caller
before the call is established. In order to do this set Preferences → Applications →
play_announce_before_recording to "Always" or "External/Internal calls only" depending if you want to
play the message only for calls coming from PSTN or only for calls coming from local subscribers. In
order to play the message it’s mandatory to upload an audio file into early_media →
announce_before_recording inside the corresponding Sound Set. The play_announce_before_recording
preference can be activated hierarchically at domain, customer and subscriber level.
It is possible to list existing call recordings of a Subscriber through the admin web interface of NGCP.
In order to do so, please navigate to: Settings → Subscribers → select subscriber Details → Call Recordings
If you select an item in the list, besides the main properties such as the time of call and the SIP Call-ID,
you can retrieve the details of the related call (press the Call Details button), get the list of recorded files
(press the Recorded Files button) or Delete the recorded call.
When selecting Call Details you will see the most important accounting data of the call. Furthermore
you can see the SIP Call Flow or the complete Call Details if you press the respective buttons.
When navigating to Recorded Files of a call you will be presented with a list of files. For each file item:
• type of stream is shown, that can be either "mixed" (combined voice data), or "single" (voice data of
caller or callee)
• file format is shown, that can be either "wav", or "mp3"
• you can download the file by pressing the Play button
The following API methods are provided for managing Call Recordings:
• CallRecordings:
◦ Provides information about the calls recorded in the system; can also be used to delete a
recording entry
◦ accessible by the path: /api/callrecordings (collection) or /api/callrecordings/id (single item)
◦ Supported HTTP methods: OPTIONS, GET, DELETE
• CallRecordingStreams:
◦ Provides information about recorded streams, such as start time, end time, format, mixed/single
type, etc.; can also be used to delete a recorded stream
◦ accessible by the path: /api/callrecordingstreams (collection) or /api/callrecordingstreams/id
(single item)
◦ Supported HTTP methods: OPTIONS, GET, DELETE
• CallRecordingFiles:
◦ Provides information about recorded streams, such as start time, end time, format, mixed/single
type, etc.; additionally returns the file content too
◦ accessible by the path: /api/callrecordingfiles (collection) or /api/callrecordingfiles/id (single
item)
◦ Supported HTTP methods: OPTIONS, GET
First create a system sound set for the feature. In Settings → Sound Sets either use your already existing
Sound Set or create a new Sound Set and then assign it to your domain or subscribers. In the Sound Set
there is an announcement early_media → announce_before_recording for that purpose.
Once the Sound Set is created the subscriber’s preference play_announce_before_recording of the
callee must be enabled under Subscriber → Preferences → Applications menu. The same parameter can be
set in the Domain’s or Customer’s preferences to enable this feature for all its subscribers.
NOTE The announcement will be played to caller before the call is routed to the callee.
Some codecs operate at different sampling rates than other codecs. If transcoding happens between
two such codecs, the audio will be resampled as necessary. Similarly, if transcoding happens between
a mono (1-channel) and a stereo (2-channel) codec, the audio will be up-mixed and down-mixed as
necessary.
7.26.3. Configuration
Transcoding can be engaged for individual subscribers, peers, or domains on their respective
preferences page in the Sipwise C5 admin web interface.
Setting any of the transcoding options for a domain makes it affect all the subscribers in this domain.
ptime
Packetisation time in milliseconds. Normally Sipwise C5 lets the RTP endpoints select and negotiate the
packetisation time they want to use. Setting this option to anything other than unchanged will engage
transrating via the transcoding engine towards this subscriber or peer even if none of the other
transcoding options are set, in which case the media will be transrated (repacketised).
For example, setting this to 40 ms would mean that each RTP packet sent towards this subscriber or
peer would contain 40 milliseconds worth of audio, even if the other side of the call sends media that is
packetised differently. It would also make Sipwise C5 indicate towards this subscriber or peer that it
would prefer to receive audio in 40 millisecond packets (through the a=ptime SDP attribute).
transcode_…
Enabling one of these options adds the selected codecs to the list of codecs offered to this subscriber
or peer, even if the original list of offered codecs did not include it. If this additional codec ends up
being accepted by this subscriber or peer, then it will be transcoding to the first supported codec that
was originally offered.
For example, if a calling RTP client A indicates support for PCMA (G.711 a-Law) as well as G.722, and
calls a subscriber B that is configured for transcoding to G.729, then subscriber B would be offered
PCMA, G.722, and G.729 by Sipwise C5. If subscriber B then accepts G.729 and starts sending G.729,
Sipwise C5 would engage its transcoding engine and transcode the audio to PCMA (because PCMA and
not G.722 was the codec preferred by A) before forwarding it to A. Vice versa, PCMA arriving from A
would be transcoded to G.729 before being sent to B. (If B were to reject G.729 and instead starts to
send PCMA or G.722, no transcoding would happen.)
• AMR is available in both narrowband (AMR operating at 8 kHz) and wideband (AMR-WB operating at
16 kHz) variants. These are distinct codecs and can be configured for transcoding separately or
together.
• Opus always operates at 48 kHz, but is supported in both mono and stereo (1 and 2 audio channels
respectively). Both can be offered at the same time if so desired.
• Speex is supported at sampling rates of 8, 16, and 32 kHz. These can be configured separately for
transcoding, or together.
• DTMF is not an actual audio codec, but rather represents transcoding between DTMF event packets
and in-band DTMF audio tones. This is described in more detail below.
• CN refers to comfort noise payloads. More information about this is below.
…_bitrate
Some codecs (Opus and G.723.1 in particular) can be configured for different bitrates, which would
impact the amount of network bandwidth they use, as well as the audio quality produced. For Opus,
different bitrates can be selected for their mono and stereo instances. Selecting a bitrate has no effect if
transcoding to the respective codec is not engaged.
AMR-specific Options
AMR and AMR-WB support dynamic mode switching (adapting the bitrate) during runtime. The
configurable bitrate therefore is only the initial bitrate at which the encoder is started, and is further
constrained by the mode-set option.
The mode-set is a list of comma-separated AMR modes, e.g. 0,1,2,3. If a mode-set is received from a
remote peer, then only the modes (bitrates) given in the list will be used for the encoder. If a specific
bitrate is also configured, then this bitrate will be used as the highest possible starting bitrate. If this
bitrate is not allowed by the mode-set, then the next lower bitrate will be used. If no lower bitrates are
permitted, then the next higher bitrate will be used.
For outgoing AMR offers, a mode-set can be configured in the preferences page, and it will be
honoured just like a mode-set that is received from a remote peer. A remote AMR peer may support
only a specific subset of AMR modes, which would need to be configured in the mode-set. The Sipwise
C5 supports encoding and decoding all possible AMR modes.
AMR has two basic payload variants: bandwidth-efficient and octet-aligned. A remote AMR peer may
support only one of them, in which case the correct one must be configured in the preferences. The
default is bandwidth-efficient. The Sipwise C5 supports sending and receiving both and will honour
the request made by a remote AMR peer for one or the other.
Further options that may be required by a remote AMR peer to restrict permissible mode changes are:
mode-change-period restricts mode changes to be made only every other packet if set to 2 (the
default is 1); mode-change-capability advertises the capability to restrict the modes changes as such
without actually restricting them; and mode-change-neighbor restricts mode changes to be made only
to neighbouring modes if enabled (the default is disabled).
AMR supports requesting specific encoder modes from the remote peer via Codec Mode Requests
(CMR). The Sipwise C5 will honour a CMR received from the remote peer and switch encoder mode
accordingly. Then optionally, if no further CMRs are received from the peer, the Sipwise C5 can then try
to increase encoder bitrate again to improve audio quality. This can be enabled by setting the mode
change interval preference to non-zero. It specifies an interval in milliseconds at which to switch to a
higher encoder bitrate if no CMR was received during that time, and if a higher bitrate is available and
allowed by the mode-set.
In the opposite direction, the Sipwise C5 can optionally request higher bitrates from the remote peer by
sending CMRs out. This can be enabled by setting the CMR interval preference to non-zero. It specifies
an interval in milliseconds at which the Sipwise C5 will request a higher bitrate from the remote
encoder if a higher bitrate is available and it was not being used during that time.
always_transcode
Setting this flag instructs Sipwise C5 to always engage transcoding to the first (preferred) codec
indicated by an RTP endpoint, even if another codec is available that is supported by both parties to a
call. Enabling this flag can potentially engage the transcoding engine for a call even if none of the other
transcoding options are set.
For example: Subscriber A is calling subscriber B. Subscriber A is indicating support for PCMA and
G.722. Subscriber B answers the call, rejects PCMA but accepts G.722, and starts sending G.722 to A.
Normally Sipwise C5 would not get involved and would let G.722 pass between A and B. But if
subscriber B has the always_transcode flag set, Sipwise C5 would now start transcoding the G.722 sent
by B into PCMA before forwarding it to A, because PCMA was indicated as the preferred codec by A.
Vice versa, PCMA arriving from A would be transcoded into G.722 and then forwarded to B.
DTMF transcoding
Sipwise C5 supports transcoding between DTMF event packets (using the RTP telephone-event type
payload) and DTMF tones carried in-band in the audio stream. DTMF transcoding is supported in both
directions: transcoding DTMF event packets to DTMF tones, and DTMF tones in an audio stream and
transcoding them to DTMF event packets.
• Enabling the setting transcode_dtmf for a subscriber, peer, or domain. This is useful if the
subscriber, peer, or domain requires support for DTMF event packets, but the calling entity might
only support DTMF tones carried in-band in the audio stream.
• Enabling the setting always_transcode for a subscriber, peer, or domain. This is useful for the
reverse case: if the subscriber, peer, or domain might only support DTMF tones carried in-band in
the audio stream, but the calling entity requires support for DTMF event packets.
Enabling DTMF transcoding for any call requires that all audio passes through the transcoding engine,
as well as a DSP for detecting DTMF tones in one direction. This carries an additional performance
impact with it, and so DTMF transcoding should only be enabled when really necessary.
Sipwise C5 supports the conversion of SIP INFO messages with application/dtmf-relay payload to
DTMF event or PCM DTMF inband tone, depending on whether the destination participant supports the
telephone-event RTP payload type or not. DTMF conversion of INFO messages works only in one way
direction: DTMF events or PCM DTMF inband tones are not converted back to DTMF INFO messages.
Enabling DTMF conversion of INFO messages for any call requires that all audio passes through the
transcoding engine, as well as a DSP for detecting DTMF tones in one direction. This carries an
additional performance impact with it, and so it should only be enabled when really necessary.
At the moment this feature is for internal use only. External generated INFO messages
NOTE
will be not converted but passed through.
Comfort Noise
RTP supports a special payload format for carrying comfort noise (CN) audio without having to encode
it as actual audio. Support for CN is optional and negotiation is normally left up to the endpoints. If CN
transcoding is enabled, Sipwise C5 can transcode CN payloads to audio noise and vice versa.
When active and when CN is supported by one endpoint but not the other, any received CN payloads
are converted to audio noise and this noise is then inserted into the audio stream. In the reverse
direction, Sipwise C5 can optionally detect silence audio frames and then convert these to predefined
CN payloads.
To enable silence detection, the setting rtpproxy.silence_detect in config.yml must be set to a non-zero
value. This value denotes the silence detection threshold in percent and therefore must be between 0.0
and 100.0. Any audio samples that are lower than the configured threshold will be as silence, and if all
audio samples in an audio frame are detected as silence, then that frame will be replaced by a CN
frame. To only replace audio frames that contain complete silence with CN frames, a very low but non-
zero value can be used here, such as 0.1%.
Certain audio codecs always leave a residual DC offset in the audio samples, even
NOTE when encoding complete silence. G.711 a-Law (PCMA) is one such example, for which
the minimum silence detection threshold is 0.013%.
When a silence audio frame is replaced by a CN frame, the generated CN payload is not based on the
audio that is being replaced, but rather taken from the static and predefined setting
rtpproxy.cn_payload in config.yml. This is a list of comfort noise parameters according to RFC 3389. The
first value in the list is mandatory and denotes the volume of the noise payload in negative dBov
(meaning larger values result in quieter audio, with zero being the loudest), while all subsequent values
are optional and denote spectral information about the noise. The default is the single value 32, which
describes noise with a volume of -32 dBov without any spectral information.
Two settings to control T.38 transcoding are available for subscribers, peers, and domains:
• The setting t38_decode instructs Sipwise C5 to accept an offered T.38 session towards the
subscriber, peer, or domain, and translate it into a regular audio call carrying T.30 fax data. By
default, G.711 (both µ-Law and a-Law) will be offered. If any other codecs are selected through the
transcode_... options, then only those codecs will be offered and the G.711 default will be omitted.
Non-T.38 offers are not affected by this settings.
• The setting t38_force forces any audio call towards this subscriber, peer, or domain to be translated
to a T.38 session, regardless of whether the audio media actually carries T.30 fax data or not. This is
useful if it is known that the remote destination is a fax endpoint supporting T.38.
By default the Sipwise C5 will not attempt to correct such a DTX behaviour and will simply pass through
any DTX gaps untouched. However, for any call with active audio transcoding, the Sipwise C5 can be
configured to enable a DTX jitter buffer in order to fill in DTX gaps with comfort noise to produce a
steady output RTP stream.
Configuration
The master switch to enable the DTX jitter buffer is found in config.yml under the setting
rtpproxy.dtx_delay. This value denotes the processing delay in milliseconds (i.e. the length of the jitter
buffer) and should be set to just slightly higher than the highest expected ingress jitter. The default
value of zero disables the DTX buffer.
When a DTX event is detected, the gap will be filled in using an RFC 3389 compliant comfort noise
generator. The parameters for this generator are set under rtpproxy.dtx_cn_params. The default is just a
single value of 35, specifying white noise at -35 dBov. Higher numbers lead to quieter noise.
Subsequent numbers (i.e. from the second number onward) are optional spectral parameters.
The maximum duration for which comfort noise should be generated can be set using
rtpproxy.max_dtx in seconds. The default is unlimited (zero).
If an incoming RTP stream experiences a timer drift (i.e. the RTP clock runs slower or faster than
expected), then the timer handling the DTX buffer will be shifted forward or backward by
rtpproxy.dtx_shift milliseconds (default 5). Timer drifts can lead to DTX buffer overflows, which are
detected if more than rtpproxy.dtx_buffer packets with an RTP delay of more than rtpproxy.dtx_lag
milliseconds are held in the buffer (defaults 10 and 100, respectively).
AMR and AMR-WB explicitly support DTX and provide their own comfort noise format (called SID) to fill
in DTX gaps. If rtpproxy.amr_dtx is set to native (the default) then the native AMR SID/CN generator will
be used to produce the noise to fill in DTX gaps. If this setting is set to CN then the generic CN
generator (which is used for other codecs) is used instead.
The configuration of the announcement is similar to the activation of Pre-Recording Announcement and
it requires few simple steps.
First create a system sound set for the feature. In Settings → Sound Sets either use your already existing
Sound Set or create a new Sound Set and then assign it to your domain or subscribers. In the Sound Set
there is an announcement early_media → announce_before_call_setup for that purpose.
Once the Sound Set is created the subscriber’s preference play_announce_before_call_setup must be
enabled under Subscriber → Preferences → Applications menu. The same parameter can be set in the
Domain’s or Customer’s preferences to enable this feature for all its subscribers.
NOTE The announcement will be played to caller before the call is routed to the callee.
This feature and Pre-Recording Announcement can be activated at the same time. In this case the
Announcement Before Call Setup will be played as first.
To overcome this problem the Sipwise C5 makes it possible to play a pre-recorded ringback tone to the
caller party in early media mode. This feature can be activated on the caller Subscriber or Peer where
the tone has to be played. The emulated ringback is played in a loop and it is stopped if one of the
following conditions happens:
• a '183 Progress' message is sent back by the callee, this because the callee most likely would like to
play an announcement in early media mode
• a '200 OK' message is sent back by the callee
• the call fails
The configuration of the announcement is similar to the activation of Pre-Recording Announcement and
it requires few simple steps.
First create a system sound set for the feature. In Settings → Sound Sets either use your already existing
Sound Set or create a new Sound Set and then assign it to your domain or subscriber. In the Sound Set
there is an announcement early_media → ringback_tone for that purpose.
Once the Sound Set is created the caller subscriber’s preference play_emulated_ringback_tone must be
enabled under Subscriber → Preferences → Applications menu. The same parameter can be set in the
Domain’s or Customer’s preferences to enable this feature for all its subscribers. It can also be enabled
on Peer’s preferences to activate the feature when the call is coming from the peer.
By default the callee’s soundset is used to generate the emulated ringback tone. If you prefer to use
the ringback tone uploaded in the caller soundset you have to set config.yml preference
kamailio.proxy.play_ringback_tone_of_caller to 'yes'.
The same feature can be used to play back to the caller a music on hold or other announcements while
the callee endpoint is ringing. To do that just upload the media you prefer instead of a ringback tone.
The callee has to send a '180 Ringing' message to trigger the emulated ring back
IMPORTANT
tone to start.
The generation of the emulated ringback tone is currently limited to two specific
NOTE scenarios: in the one specified above after a pre-call announcement and in a TPCC
initiated call where the caller is already in conversation.
Each subscriber can interact with his own personal stored records using Vertical Service Codes (see
VSC). In particular a subscriber can:
• redial last dialed number (this feature has to be enabled for the each subscriber/domain using
preference last_number_redial)
• hear a voice announcement of the last caller’s number, then press the key defined in sems→vsc
→callback_last_caller_confirmation_key preference of /etc/ngcp-config/config.yml to return the call
• return the call to the last caller’s number without hearing the number announcement
• delete the personal stored records of any recent calls to and from him
NOTE it is not possible return a call if the caller’s number is unavailable (e.g. anonymous calls).
Then set the preference sound_set on the Domain or Subscriber level in order to assign the Sound Set
(as usual the subscriber preference overrides the domain one).
Supported fields, input and output format are based on iCalendar EVENT specification.
Not all iCalendar and EVENT properties are supported, but those that are used for time points and
periods definition or stated mandatory by specification:
Important to mention that current implementation does not support these EVENT properties:
• DTSTAMP ( UID is used in generated calendar ics file, both UID and DTSTAMP are ignored during
uploading calendar file );
• DURATION ( DTEND is used );
• RDATE
• EXDATE
• PRIORITY
Main EVENT property, that is used for time points and periods definition is RRULE. Current time sets
implementation supports all properties described in the RRULE specification except WKST.
Time set can be created using creation form. On time sets management interface press button "Create
Time Set Entry":
"Name" field should be defined, if iCalendar (ics) file is not going to be uploaded or file doesn’t have
NAME property for the CALENDAR entry.
If both NAME in the uploaded iCalendar (ics) file and form field "Name" aren’t empty then value from the
form field will be taken.
or deleted:
If calendar ics file will be uploaded to edit time set, all presented events will be deleted
NOTE
and events from the uploaded file will be added after it.
To manage time set events press "Events" button against proper time set.
"Start" field reflects DTSTART property of the EVENT. "Start" is mandatory and by default is set to the
start of the current day. "Start" value format is datetime.
"Stop" field reflects DTEND property of the EVENT. For the events within recurrence "Stop" will define
To return "Stop" field to the empty value press button "None". Value in the form fields will be preserved,
but newly created EVENT will have empty DTEND property.
Other fields in the form are optional. Most of them aren’t visible by default and will be shown if
RRULE property of the EVENT is a recurrence rule and defines set of the iterations for the EVENT.
To customize recurrence rule for the EVENT select proper repetition unit for the "Repeat" form field.
Input field for the recurrence interval will appear left to the frequency select.
According to the selected unit, FREQ property of the EVENT RRULE will be set to one of the:
SECONDLY, MINUTELY, HOURLY, DAYLY, WEEKLY, MONTHLY, YEARLY.
To specify end of the EVENT iterations, select "Series stop" value. For the "at date" option will be shown
input for the date and time that will define UNTIL property of the EVENT RRULE.
"after" option, respectively, will put entered value to the COUNT property of the EVENT RRULE.
Form fields "By hour", "By week day", "By month", "By month day", "By set position", "By week number",
"By year day", "By second" and "By minute" aren’t shown by default. To enter value to any of these fields
press according button on the left. Button with field name is grayed off when corresponding EVENT
property is empty.
When gray button with field name is pressed, field input control appears on the right. In the same time
button with field name becomes orange, indicating that field value will be saved for the EVENT.
Fields with checkboxes controls have auxiliary button "Invert selection". When button "Invert selection"
is pressed currently empty checkboxes become selected and currently selected checkboxes become
empty.
When form data will be saved, checkboxes values will be saved as coma separated numbers.
BYxxx RRULE properties expand or limit behavior of the FREQ according to the table in the RRULE
specification.
Field "By week day" has two variants of the input: checkbox for each week day and text input. Text input
can be used, if "By week day" value is more complex than list of week days, separated by coma, for
example for FREQ MONTHLY value "2TH,-3FR" in the "By week day" will mean second Thursday from
the month start and third Friday from the month end in every month. Such value can’t be presented as
checkboxes selection.
Fields "By set position" and "By year day" are text inputs. Value format for these fields is set of the [+/-
]NUMBER values, separated by comma.
For the "By year day" minus sign in front of year day number means that this day should be taken by
number from the end of the year.
For the "By set position" minus sign in front of the position of the iteration means that the iteration
should be taken by number from the end of the generated iterations sequence.
After new event created, event will appear in time set event list. It will have column with rrule text
description, buttons to request event edit form or event deletion.
In events list section all events can be redefined uploading ics iCalendar file:
If "Purge existing" option is selected, all existing time set events will be removed before creation of the
events from the uploaded file.
To download iCalendar ics file of the time set, press "Download iCalendar".
In difference to the main time set interface, iCalendar ics file for the time set can be downloaded from
the time set list pressing "Download" button.
Creation form doesn’t have "Reseller" field and is processed in context of the current reseller.
Time sets API has possibility to get and return information both as "application/json" data and as
"text/calendar" file.
To create time set with events full specification of the all fields in json format can be used:
Also time set and events can be uploaded as ics iCalendar file:
Output of the GET request to the time set item can be text/calendar:
or application/json:
BEGIN:VEVENT
UID:sipwise19@sipwise15
SUMMARY:unique_name event 19
DTSTART:19710101T000001
DTEND:20201231T235959
END:VEVENT
END:VCALENDAR+
• A SIP-URI of an NGCP subscriber, which may have one or more endpoints registered to it.
• Remote peering destinations.
The feature can be set within subscriber preferences, via Admin Panel or REST API.
By the definition of one ore more location entries on a subscriber, it is possible to generate separate call
branches for each destination when an incoming call is received on that subscriber.
(b) Set Triggering Conditions and Mode for Each Call Branch.
In order to trigger a call branch, conditions can be defined for both caller and callee numbers via
regular expressions, as well as the definition of the call branch behavior to be applied.
Number manipulations can be applied on the username part of the Request-URI (RURI) or the To field in
a SIP INVITE message.
Example Scenarios
There may be different scenarios in which the feature can be considered. Some examples, as follows:
Scenario Description
• Incoming calls on an NGCP subscriber are (also) delivered to another
NGCP subscriber.
NGCP Subscriber
• Two cases are possible: re-routed or multiplied calls.
The following sections will provide more details about the feature.
7.31.2. Fields
Location mappings fields are summarized in the following table.
Field Description
This field has two possible value options:
A regular expression pattern to match the From field of the INVITE (After
Caller Pattern
Inbound Rewrite Rules). If left empty, it defaults to the .+ pattern.
A regular expression pattern to match the R-URI/To of the INVITE (After
Callee Pattern
Inbound Rewrite Rules). If left empty, it defaults to the .+ pattern.
Field Description
Defines the behavior of the matched entry during the call termination:
Replaces the username part of the RURI/To in a SIP INVITE with the value
RURI/To Username defined on this field. Useful for cases when the remote username is different
than the one used for the location mapping.
An arbitrary string name (e.g. an identifier of a 3rd party provisioning/billing
External ID
system). This is an optional attribute, which can be kept as empty.
Enabled Enable/Disable the entry.
The location mappings “Forward” mode works differently when compared to the others:
• This mode does not require the Location SIP-URI field, since it applies outbound peering logic to
select the correct peer and automatically calculates the final destination.
• It creates a new parallel branch meant for peers only and it will behave like a Call Forward
Unconditional (CFU). (NOTE: If you need to generate an internal call to local subscribers, use the
Add mode instead.)
• The remote peer will receive the original caller as the source of the call (NOTE: User Provided
Redirecting Number is intentionally disabled for this particular mode). Also, two different Call Detail
Records (CDR) will be created: the first one from ‘A’ to ‘B’ (in which the CDR call_type field equals
to 'call'), and the second one from the original callee subscriber to the peer (with call_type = 'cfu').
• To prevent the call to be looped back, the new parallel branch is terminated if the inbound peer
belongs to the same peer group of the outbound peer. However, it is possible to disable this check
by activating the allow_lm_forward_loop peer preference (“Internals” section) of the outgoing
peer.
For creation, press on the “Create” button, which will pop-up a new window.
As shown in the example below, data can be entered and saved to create the new entry.
Practical Example
Let us assume that an administrator will use Admin Panel to provision some location mappings on a
selected subscriber. The following Subscriber Details are considered:
Field Value
SIP URI sip:[email protected]
Primary Number 4312521523
Alias Numbers 4312521523001 4312521523002
Then, on Subscriber Preferences, within the Location Mappings section, the following entries are defined:
Logic Result
• An incoming call to the subscriber • The call will ring on the registered devices of
number 4312521523 will be sip:[email protected].
additionally sent to the devices
• The call will ring on the registered devices of
registered with
sip:[email protected].
sip:[email protected].
• The call will ring on the registered devices of sip:gw-
[email protected].
• When a device takes the call, the call will be
cancelled on the rest of devices.
• An incoming call to the subscriber • The call will NOT ring on the registered devices of
number 4312521523001 will replace sip:[email protected].
the current subscriber SIP-URI as
• The call will ring on the registered devices of
destination (i.e. the call will not be
sip:[email protected] with the number 990001.
terminated at the devices registered
with subscriber • The call will ring on the registered devices of sip:gw-
sip:[email protected]). [email protected].
• Instead, the call will be sent to the • When a device takes the call, the call will be
registered devices with location entry cancelled on the rest of devices.
sip:[email protected] with the
"username" part of the INVITE replaced
with number 990001.
Logic Result
• An incoming call to the subscriber • If sip:[email protected] is offline, then the call will
number 4312521523002 will be ring on the registered devices of
additionally sent to the devices sip:[email protected] with the number 990002.
registered with
• The call will ring on the registered devices of sip:gw-
sip:[email protected] only if there
[email protected].
are NO active registrations under this
subscriber (i.e. sip:[email protected] • When a device takes the call, the call will be
is offline). cancelled on the rest of devices.
• Any incoming call to the subscriber • When a device takes the call, the call will be
sip:[email protected] will be cancelled on the rest of devices.
additionally sent to the devices
registered with sip:gw-
[email protected].
7.32. STIR/SHAKEN
7.32.1. Overview
What does STIR/SHAKEN stand for?
This technology gives an opportunity to make sure that the calling side (caller’s number) is not spoofed,
hence can help during the common work/inter-cooperation between ITSPs, in terms of call spoofing
detection. Therefore when it is massively used by ITSPs, it decreases the amount of robo-calls.
ITSP - Internet Telephony Service Provider. Is a general abbreviation for VoIP service
NOTE providers, which can use IP-based technologies/protocols such as SIP protocol or
H.323 stack of protocols to provide telephony services.
The Sipwise C5 is currently compliant with the list of general RFC standards:
• RFC8224 - Authenticated Identity Management in the Session Initiation Protocol (SIP) (this RFC
obsoletes RFC 4474) ;
• RFC8588 - Personal Assertion Token (PaSSporT) Extension for signature-based handling of
Asserted information using toKENs (SHAKEN) ;
The fact of the matter is that as the VoIP world is growing and extending proposed technologies, new
security mechanisms come into play, which can give you a good protection level on different layers of
VoIP. STIR/SHAKEN is one of them and it works as a superstructure over the VoIP system. It can be
considered as the Application layer of TCP/IP stack (in common with SIP).
This standard has been developed by IETF, in order to propose a new way to detect spoofed calls and
to help ITSPs to protect their customers. Hence decrease the amount of fraud events/bot calls. The
strong side of this technology is that it not only works within the scope of your VoIP system, but it is also
dependent on other intermediary/termination ITSPs. Therefore it can bring a good quality improvement
for a protection from undesired calls (bot-calling).
NOTE The SIP header declared for this purpose is called literally “Identity:” .
The “Identity-Info:” header is deprecated by RFC 8224 and now is stored as the
IMPORTANT
";info=" parameter within the "Identity:" header.
• Originating service provider - a system which performs an authentication (IP based, digest over MD5
etc.) of the calling party (SIP). It has to support all the needed RFC regulations to add/manipulate
the Identity header. This entity does all the work to prepare the "Identity" header before sending a
call out ;
• Terminating service provider - a remote VoIP system (call termination ITSP), which verifies if the call
is compliant with the STIR/SHAKEN technology, then verifies it before to accept and send to the
edge subscriber. As well as with the Originating service provider, it has to support all the needed
functionality to manipulate the Identity header. This entity does all the work on the Identity header
of the received request, such as: decryption of the JWT token stored inside the "Identity" header
and an attestation level verification ;
• Authentication service - is a superstructure/standalone authority used by the originating ITSP to
obtain certificates/keys needed to encrypt the "Identity" header’s value (JWT token). It is only used
for work with certificates and keys ;
• Verification service - is a superstructure/standalone authority used by a terminating ITSP to obtain
certificates/keys needed to decrypt the "Identity" header’s value (JWT token). The same as with the
Authentication service, it’s only used for work with certificates and keys ;
• Originating service provider - when Sipwise C5 sends a call out to PSTN networks
• Terminating service provider - when Sipwise C5 is a recipient of the call coming from PSTN
networks
This technology assumes that there is some centralized authority or a list of them,
NOTE
which will be used both by the originating and the terminating service providers.
• Firstly a SIP call is originated and obtained by certain ITSP (let’s call it ITSP A) ;
• ITSP A verifies the call source and its number, in order to define how to confirm validity (full, partial
or gateway attestation) ;
• ITSP A creates a SIP Identity header that contains the information on the calling number, called
number, attestation level and call origination, along with the certificate (important). All information in
the Identity header gets encrypted into the JWT token, with the following list of parameters ;
• The call (INVITE request) is sent out with the SIP Identity header (which has a reference to the
certificate) to certain destination ITSP (let’s call it ITSP B) ;
• ITSP B verifies the identity of the header and the certificate itself ;
• ITSP B makes sure the attestation level is complaint with local security standards (A, B or C) ;
• ITSP B sends a call to the edge subscriber (with possibly added parameters to the PAI header -
verstat) ;
To sum up, essentially this technology gives a way for the destination user/service provider to verify
that the original caller (calling side) is the one that it pretends to be.
• Full attestation ( A ) - SP authenticates the calling party and confirms it is authorized to use this
particular number. An example - SIP registration (we say that originating ITSP recognizes the entire
phone number as being registered with the originating subscriber) ;
• Partial attestation ( B ) - SP verifies the call origin, but cannot fully confirm that the source of the call
is authorized to use this number. An instance - a calling party (number) from behind a remote PBX
(you give a block of numbers to the customer and trust this customer entirely, but you cannot verify
directly individuals that use those numbers) ;
• Gateway attestation ( C ) - SP authenticates the call’s origin, but there is no way to verify the source.
An instance - a call received from an international gateway (you have a legal interconnection, but
you don’t know who is sitting behind and using source numbers, which you let to pass through your
network) ;
In most case scenarios, the attestation level which will appear in calls involving Sipwise
NOTE C5 - will be “A”. Unless you don’t use a subscriber preference "trusted source" or/and a
domain preference "unauth_inbound_calls".
Signature - is some encoded string (binary data) in Base64 URL, where its syntax is:
Base64URL( ES256 (Base64URL(JWT header).Base64URL(JWT payload)) ) Firstly the Base64
TIP
URL is built, then also the signature with the private key is built, and a URL to the public
key certificate corresponding to that key is added (as a value in the “;info=“ parameter).
The Receiving party will have to download the certificate and perform a signature
verification. In case the check passes, it will trust the value stored in the attestation level
NOTE parameter. And of course the value of caller/callee ( “orig“ / “dest”) has to match the
actual data (in SIP headers) to be sure it’s not an attack and is not a call which reuses a
value from another INVITE not related to the current one.
The secsipid module relies on libsecsipid from the Secsipidx project. Link to the
NOTE
SecSIPIDx project at Github: https://github.com/asipto/secsipidx
Secsipid - is a first implementation of STIR/SHAKEN IETF extensions (RFC8224, RFC8588) for asserting
caller identity in Kamailio. The module is being developed further, and is reliable enough to be included
in the Sipwise C5.
The configuration of the STIR/SHAKEN is done with /etc/ngcp-config/config.yml (at least in the current
implementation of Sipwise C5), with the section: kamailio.proxy.stir . To see how it’s being configured,
please take a look at kamailio (Appendix "Configuration Overview" → "config.yml Overview").
Domain preferences:
1. Make sure which authorities you would like to get in contact with, in order to grab the needed
certificates/keys ;
2. Your certificates should be prepared for work with a needed domain (your SIP domain), then you
upload the given private key(s) to your Sipwise C5 system ;
3. Basically a general parameter (in the config.yml) you need to take care of is 'domains', and of course
the given keys to it. The rest can be left untouched, unless you have some preferences for your
domain(s) ;
4. Don’t forget to define the related domain preferences (via the web panel) 'stir_pub_url' and
'stir_check' to enable SHAKEN for your domain(s);
5. After you’re done with the configuration part, you need to apply changes with: ngcpcfg apply
"added stir-shaken support" ;
Applying the changes will imply a restart of the Proxy service, therefore it’s
IMPORTANT
strongly recommended to apply the changes outside of business hours.
Remember that the kamailio user needs read permissions on the private-key
IMPORTANT
files, otherwise it will not be able to consume them.
The CA authority which provides you the needed certificates, should be something well
TIP
known and widely used by other operators in your area.
Keep in mind that you can have multiple domains and hence keys for them stored in
NOTE the Sipwise C5. This depends on the amount of SIP domains you actually have, which
use STIR/SHAKEN.
The fact that you enabled support for STIR/SHAKEN on your platform, does not mean
all of the present domains will have to use it. Checks/manipulations will be only
NOTE
enabled for those domains that are defined in kamailio.proxy.stir.domains of /etc/ngcp-
config/config.yml
For now the Sipwise C5 supports 'A' and 'B' attestation levels when sending outbound calls:
As soon as you enable STIR/SHAKEN for a certain domain served by the Sipwise C5 system, calls
coming to this domain will be challenged according to RFC standards dedicated to processing of the
Identity header.
For now the Sipwise C5 supports the following list of 4XX response codes:
• 428 - indicates an absence of the Identity header or wrong extension added into the ';ppt='
parameter ;
• 436 - indicates an inability to acquire the credentials needed by the verification service for validating
the signature in an Identity header field ;
• 438 - indicates that no Identity header field with a valid and supported PASSporT object has been
received ;
Normally, in case of the incoming call to a SIP domain with enabled STIR/SHAKEN, the "Identity"
header’s content will be decrypted, verified and the call will be sent further according to the logic of the
Sipwise C5 system setup.
7.33. Fileshare
7.33.1. Overview
Fileshare is a REST API endpoint, /api/fileshare, that provides NGCP users with a way to share data
among other NGCP users or external users.
This feature is primarily used by the NGCP SIP::App and comes as a replacement for the ComX based
fileshare component which is no longer supported by NGCP.
This feature can be provided to clients directly or integrated into own applicaton services.
7.33.3. Configuration
Fileshare is disabled by default and requires basic configuration in the config.yml
config.yml
fileshare:
enable: no
limits:
quota: 10737418240
upload_size: 10485760
user_files: 10
user_quota: 20971520
public_links: no
ttl: 86400
7.33.4. Approach
File Upload
To upload a file the client must use POST and the file attached into the form named "file"
one of the available authorization methods is required for the file upload (Basic
NOTE
Authentication or JWT)
There is an optional upload body parameter 'ttl', that can be provided to override the default ttl for the
uploaded file.
Once a file is successfully uploaded a JSON response is returned with the following data:
{
"id": "b994894d-882b-4672-a152-ff1e68ab7ee0",
"name": "sample_image.png",
"mime_type": "image/png",
"ttl": "3600",
"created_at": "2021-12-14T20:58:13.483Z",
"expires_at": "2021-12-14T21:58:13.483Z",
"size": 198791,
"_links": {
"self": {
"href": "/api/fileshare/b994894d-882b-4672-a152-ff1e68ab7ee0"
},
"collection": {
"href": "/api/fileshare"
}
}
}
File Download
If fileshare.public_links is enabled in the config.yml, then there is no authorization required for the link to
work, otherwise an authorization is required for the link to be used (any authenticated NGCP subscriber
(or admin) user can use the link).
Files Collection
As a subscriber (or an admin) you can retrieve all your uploaded files list as:
{
"_links": {
"self": {
"href": "/api/fileshare?page=1&rows=10"
},
"ngcp:fileshare": [
{
"href": "/api/fileshare/1ec51a35-92e7-46be-aa98-db69f11483a7"
},
{
"href": "/api/fileshare/58f417bb-4d28-47cf-9673-0a9453b79cc5"
}
],
"collection": {
"href": "/api/fileshare"
}
},
"total_count": 2,
"_embedded": {
"ngcp:fileshare": [
{
"id": "1ec51a35-92e7-46be-aa98-db69f11483a7",
"name": "doc.pdf",
"mime_type": "application/pdf",
"ttl": 86400,
"created_at": "2021-12-11T11:46:39.000Z",
"expires_at": "2021-12-12T11:46:39.000Z",
"size": 10
},
{
"id": "58f417bb-4d28-47cf-9673-0a9453b79cc5",
"name": "sample_text.txt",
"mime_type": "text/plain",
"ttl": 3600,
"created_at": "2021-12-14T18:17:15.000Z",
"expires_at": "2021-12-14T19:17:15.000Z",
"size": 10
}
]
}
{
"id": "1ec51a35-92e7-46be-aa98-db69f11483a7",
"name": "doc.pdf",
"mime_type": "application/pdf",
"ttl": 86400,
"created_at": "2021-12-11T11:46:39.000Z",
"expires_at": "2021-12-12T11:46:39.000Z",
"size": 10
},
{
"id": "58f417bb-4d28-47cf-9673-0a9453b79cc5",
"name": "sample_text.txt",
"mime_type": "text/plain",
"ttl": 3600,
"created_at": "2021-12-14T18:17:15.000Z",
"expires_at": "2021-12-14T19:17:15.000Z",
"size": 10
}
File Removal
Files are removed automatically by the server based on their expiraton time or manually per request.
Batch provisioning allows to define provisioning templates, in which specific subscriber settings can be
set. A template allows to define different types of input fields, parameters for internal calculations, and
the setting of subscriber-related parameters.
Provisioning templates allows the definition of code snippets for parameter calculations. Code can be
based on Javascript or Perl programming languages.
Batch provisioning is based on transactional processing. If provisioning fails at a specific point, it will
rollback what was created up to that point, in order to avoid residual data in the database.
Batch provisioning allows to process a large number of subscriber data with a considerable gain in
processing speed.
The following sections will provide more details about these features.
fields:
#Structure that contains several input fields.
contract_contact:
#Structure that contains several provisioning fields
#for the contact of the customer.
contract:
#Structure that contains several provisioning fields
#for the customer.
contract_preferences:
#Structure that contains several provisioning fields
#for customer preferences.
subscriber:
#Structure that contains several provisioning fields
#for subscriber details.
subscriber_preferences:
#Structure that contains several provisioning fields
#for subscriber preferences.
registrations:
#Structure that contains several provisioning fields
#for permanent registrations.
trusted_sources:
#Structure that contains several provisioning fields
#for trusted sources.
cf_mappings:
#A structure that contains several provisioning fields
#for call forward mappings.
The fields key allows to define input hierarchical structures by providing additional key-value pair
parameters. The supported attribute names are the ones defined in the Comprehensive Perl Archive
Network (CPAN) HTML::FormHandler::Field Modules.
Parameters must contain a name and data type. For the latter, some basic type values are: Integer,
Float, Text, Boolean, Checkbox and Select. Additional attributes can be appended as well.
The following example aims to show how to declare different parameters within the fields key. Let us
assume that an administrator wants to:
• Declare a parameter named “my_field1”, which will be a mandatory input text labeled as “This is field
1 (Text)”.
• Declare a parameter named “my_field2”, which will be an optional integer input labeled as “This is
field 2 (Integer)”.
• Declare a parameter named “my_field3”, which will be optional Boolean input labeled as “This is field
3 (Boolean)”.
• Declare a parameter named “my_field4”, which will be a mandatory dropdown list labeled as “This is
field 4 (Select)” with two sub-options labeled “optA-label”, “optB-label” with the static values “optA-
value”, “optB-value”, respectively.
fields:
- name: my_field1
label: "This is Field 1 (Text)"
type: Text
required: 1
- name: my_field2
label: "This is Field 2 (Integer)"
type: Integer
- name: my_field3
label: "This is Field 3 (Boolean)"
type: Boolean
- name: my_field4
label: "This is Field 4 (Select)"
type: Select
options:
- label: optA-label
value: optA-value
- label: optB-label
value: optB-value
required: 1
The purge attribute name is a reserved word that can be declared within the fields tag, as a Boolean
type. When set to 1, and if there is an existing subscriber with the same data to be provisioned (e.g.
same username, number or alias), then the existing subscriber will be terminated before the new one is
created. On the opposite, if set to 0, that row will be skipped.
The engine will not terminate anything other than a subscriber (Including its child items
NOTE such as preferences, trusted sources, call forwards, etc.). Thus, the contract or contact
is not terminated/deleted.
There is a special attribute type named calculated, which is not visible on form elements. It is declared
for internal use to: (a) Store static values on attributes; (b) Store the output of computed operations
coming from code snippets. As defined in HTML::FormHandler, the former requires declaring the
value attribute name to store the data. The latter requires declaring the value_code attribute in order
to store the data in the value attribute. Next sections will describe further details about this.
The rest of the template keys can contain any of the NGCP settings, as detailed in the table below.
The identifier field is a comma-separated list composed by one or more JSON/SQL properties. It
can be specified within any of the template keys of the table above. It is a string list that the batch
processing engine uses for data lookup in the database.
For instance, let us assume that the following declaration has been defined:
contract_contact:
identifier: "firstname, lastname, status"
reseller: default
firstname_code: "function() { return row.first_name; }"
lastname_code: "function() { return row.last_name; }"
status: "active"
contract:
identifier: contact_id
contact_id_code: "function() { return contract_contact.id; }"
product: "Basic SIP Account"
billing_profile: "Default Billing Profile"
Firstly, a Contract refers to a customer (i.e. a PBX). When the engine processes a CSV file (or a Web
form), it will search for a contract contact with the names specified in the firstname and lastname
fields (e.g. "John, Doe"), and with the status field equals to “active”.
If the contact entry does not yet exist, it will be created. At this stage, there are two situations:
(a) Contact does not yet exist: A new one is created, with some new contact_id value.
(b) Contact already exists: It is looked up and returns some existing contact_id value.
Regarding the contract tag, its identifier is the contact_id field. Again, the engine will try to look up
for a contract with the contact_id previously obtained:
• When the contract contact was just created (Case (a) above), then there will neither be an existing
contract. Hence, the contract is also created.
• In case (b), there is already a contact (e.g. “John Doe”, which is active), then possibly also already a
contract linked to it. Hence, the engine will not create another contract, but it looks up the existing
one.
• Finally, the engine proceeds with creating subscribers and their corresponding settings.
• Within the fields key, the value attribute name needs to be used to store static data. Hence, the
value_code attribute name must be declared in the template if a code snippet is put in place to
calculate such data. When the data is computed, it will be stored in the value attribute.
• Within the contract key, contact_id is one of the several available attributes for a customer that
can be declared in that section. If the value of this attribute needs to be computed, then the
contact_id_code attribute name needs to be declared, along with the corresponding code
snippet. Then, when the data is computed, it will be stored in the contact_id attribute.
The following directives must be declared to use code snippets in templates, for both Javascript and
Perl, respectively:
"function() {
//Javascript code logic
...
return ... ; //Output to be stored in a *_code attribute name.
}”
"sub {
#Perl code logic
...
return ... ; #Output to be stored in a *_code attribute name.
}”
Native Javascript/Perl directives can be used as part of the code logic, such as string concatenations,
number stripping, etc. Furthermore, there are reserved variable names and special functions that can
be used in a code. These are detailed in the following sections.
Reserved variable names can be used in the definition of code snippets, summarized as follows.
Special Functions
Apart from using native Javascript/Perl functions, there are special utility functions available,
summarized as follows.
fields:
- name: cc_ac_map
type: calculated
value:
- CC1:
- AC1:
split_number() String - AC2:
...
- CC2:
- AC1:
- AC2:
...
Where:
For Perl, the following core functions are disabled to prevent harmful code
injection: binmode(), close(), closedir(), dbmclose(), dbmopen(), eof(), fileno(), flock(),
format(), getc(), read(), readdir(), rewinddir(), say(), seek(), seekdir(), select(), syscall(),
sysread(), sysseek(), syswrite(), tell(), telldir(), truncate(), write(), print(), printf(), chdir(),
chmod(), chown(), chroot(), fcntl(), glob(), ioctl(), link(), lstat(), mkdir(), open(), opendir(),
readlink(), rename(), rmdir(), stat(), symlink(), sysopen(), umask(), unlink(), utime(),
alarm(), exec(), fork(), getpgrp(), getppid(), getpriority(), kill(), pipe(), setpgrp(),
setpriority(), sleep(), system(), times(), wait(), waitpid(), accept(), bind(), connect(),
IMPORTANT getpeername(), getsockname(), getsockopt(), listen(), recv(), send(), setsockopt(),
shutdown(), socket(), socketpair(), msgctl(), msgget(), msgrcv(), msgsnd(), semctl(),
semget(), semop(), shmctl(), shmget(), shmread(), shmwrite(), endgrent(),
endhostent(), endnetent(), endpwent(), getgrent(), getgrgid(), getgrnam(), getlogin(),
getpwent(), getpwnam(), getpwuid(), setgrent(), setpwent(), endprotoent(),
endservent(), gethostbyaddr(), gethostbyname(), gethostent(), getnetbyaddr(),
getnetbyname(), getnetent(), getprotobyname(), getprotobynumber(), getprotoent(),
getservbyname(), getservbyport(), getservent(), sethostent(), setnetent(),
setprotoent(), setservent(), exit(), goto().
Code-Snippet Example.
fields:
- name: cc
label: "Country Code:"
type: Text
required: 1
- name: ac
label: "Area Code:"
type: Text
required: 1
- name: sn
label: "Subscriber Number:"
type: Text
required: 1
- name: sip_username
type: calculated
value_code: "function() {
return row.cc.concat(row.ac).concat(row.sn);
}"
Here, the text input fields cc, ac and sn along with the internal field sip_username are declared. It is
required for this case that sip_username must be a string concatenation of the cc, ac and sn fields,
respectively. Therefore, sip_username type is declared as calculated and its value must be
declared through the value_code attribute name. This attribute shows a code snippet which contains a
Javascript function that performs the string concatenation. The row variable refers to the CSV file row,
or the form input when filling out the data through Admin Panel. Finally, when the data is computed, it
will be stored in the value attribute.
When set, the Batch Provisioning page can be accessed through the Tools → Batch Provisioning menu
entry. The interface will offer the option to create a new provisioning template, or edit an existing one.
For creation, press on the 'Create Provisioning Template' button. This will pop-up a new window, as
shown below.
Once a template has been defined, there are two options available for data input:
This option is available when clicking on the 'Open Form' button. A new window will be displayed to
enter the variable data of the subscriber in several form fields:
The fields displayed will depend of what is defined on the provisioning template. If the default built-in
template is in use, then parameters are as follows:
• First Name: The given name of the customer in which the subscriber will belong to.
• Last Name: The surname of the customer in which the subscriber will belong to.
• Country Code (CC): Country code of the subscriber telephone number.
• Area Code (AC): Area code of the subscriber telephone number.
• Subscriber Number (SN): Telephone number of the subscriber.
• Terminate subscriber, if exists: If ticked, it will terminate any existing subscriber with that name.
This option is available when clicking on the 'Upload CSV' button, which allows to upload a CSV file that
contains a line of data for each subscriber. A new window will be displayed to enter the data:
• CSV: The CSV file to upload. The file has to follow the format defined in the template.
• Purge Existing: If ticked, it will terminate any existing subscribers with that name. This checkbox is
equivalent to specify the value 1 in each row of the CSV file.
Usage:
ngcp-provisioning-template "reseller-name/provisioning-template-name"
[options]
For templates defined in database, different resellers could each have a provisioning
NOTE
template with the same name.
The form fields can be passed as command line options, as described below.
Option Description
--help Prints a brief help message and exits.
The host of the ngcp database to connect to. If omitted, the
--db-host=db-host-IP-address
database connection settings of ngcp-panel will be used.
Option Description
The port of the ngcp database to connect to. Only relevant if
--db-port=db-host-port
--db-host is specified.
The database user for the ngcp database to connect to. Only
--db-user=db-username
relevant if --db-host is specified.
The the database user password (if any) for the ngcp
--db-password=db-password database to connect to. Only relevant if --db-host is
specified.
Specify a CSV filename to process. Each row represents
--file=csv-filename
form values for one subscriber to create.
Provide an input attribute name and its value, as defined
--[input-attribute within the fields tag in the template (Attribute must not be
-name]=[attribute-value] internal, but form visible). Only relevant if no --file is
specified.
Terminate an existing subscriber with duplicate
--purge
number/aliases first.
Verbosity level of printed messages while processing (
--log-level
error, warn, info, debug).
If no CSV file is specified with the --file option, each of the non-internal input parameters defined in
the template (within the fields tag) can be provided as part of the command line options. For instance, if
first_name input variable is declared in the template, then such option can be entered as
--first_name (e.g. --first_name=John).
Batch provisioning is based on transactional processing. If provisioning fails at a specific point, it will
rollback what was created up to that point, in order to avoid residual data in the database.
The following sub-sections aim to highlight common use cases. Let us assume the following template
base data will be used.
Field Value
Reseller default
Reseller ID 1
SIP Domain mydomain.com
Product Basic SIP Account
Template Name My API Provisioning Template
Template Language js (Javascript)
Template Content Same as Built-in Template
API IP <Address:Port> 127.0.0.1:1443
API Key File ./apiclient.pem
Template Creation
For template creation, the HTTP POST method is available. Template metadata can be specified in
JSON notation using the name, description, reseller_id, and lang attributes. Template definition
can be provided in JSON notation within the template attribute, as shown below.
Template Request
For template request, the HTTP GET method is available. A specific template can be fetched according
the id value of the template, which corresponds to the concatenation of reseller name, the / symbol
and the template name. Based on the previous example creation, the corresponding value is
“default/My API Provisioning Template”.
GET method will output the template definition within the template attribute, which output format can
be controlled by using the ?format=[value] directive. The available values are: yml, yaml or json.
Example:
Additionally, as templates can be stored on database or in config.yml file, it is possible to use the
Boolean editable parameter to list: (a) Database-stored templates only (true); or (b) Templates defined
on config.yml file only (false). Example:
Templates defined on config.yml will be displayed on Admin Panel, but they cannot be
NOTE
edited.
Template Update
For template update, the HTTP PUT and PATCH methods are available.
For PUT, it is possible to set the whole template at once only. Let us assume that the gpp0 attribute
(located within the subscriber_preferences tag) will be modified to other value, meanwhile the rest
of template properties will remain the same.
{
"name" : "last_name",
"label" : "Last Name:",
"type" : "Text",
"required" : "1"
},
{
"label" : "Country Code:",
"name" : "cc",
"type" : "Text",
"required" : "1"
},
{
"name" : "ac",
"label" : "Area Code:",
"type" : "Text",
"required" : "1"
},
{
"name" : "sn",
"label" : "Subscriber Number:",
"type" : "Text",
"required" : "1"
},
{
"name" : "sip_username",
"type" : "calculated",
"value_code" : "function() { return
row.cc.concat(row.ac).concat(row.sn); }"
},
{
"name" : "purge",
"label" : "Terminate subscriber, if exists:",
"type" : "Boolean"
}
],
"contract_contact" : {
"identifier" : "firstname, lastname, active",
"reseller" : "default",
"firstname_code" : "function() { return row.first_name; }",
"lastname_code" : "function() { return row.last_name; }",
"status" : "active"
},
"contract" : {
"product" : "Basic SIP Account",
"billing_profile" : "Default Billing Profile",
"identifier" : "contact_id",
"contact_id_code" : "function() { return contract_contact.id; }"
},
"subscriber" : {
"domain" : "mydomain.com",
"primary_number" : {
For PATCH, it is possible to modify main template attributes at once only. Sub-attributes belonging to a
section will need to be replaced as a whole. Let us assume that the description attribute and the
gpp0 attribute (located within the template.subscriber_preferences section) will be updated to
different values, respectively.
"type" : "Text",
"required" : "1"
},
{
"name" : "sn",
"label" : "Subscriber Number:",
"type" : "Text",
"required" : "1"
},
{
"name" : "sip_username",
"type" : "calculated",
"value_code" : "function() { return
row.cc.concat(row.ac).concat(row.sn); }"
},
{
"name" : "purge",
"label" : "Terminate subscriber, if exists:",
"type" : "Boolean"
}
],
"contract_contact" : {
"identifier" : "firstname, lastname, status",
"reseller" : "default",
"firstname_code" : "function() { return row.first_name; }",
"lastname_code" : "function() { return row.last_name; }",
"status" : "active"
},
"contract" : {
"product" : "Basic SIP Account",
"billing_profile" : "Default Billing Profile",
"identifier" : "contact_id",
"contact_id_code" : "function() { return contract_contact.id; }"
},
"subscriber" : {
"domain" : "mydomain.com",
"primary_number" : {
"cc_code" : "function() { return row.cc; }",
"ac_code" : "function() { return row.ac; }",
"sn_code" : "function() { return row.sn; }"
},
"username_code" : "function() { return row.sip_username; }",
"password_code" : "function() { return row.sip_password; }"
},
"subscriber_preferences" : {
"gpp0" : "My new gpp0 value"
}
}
}
]'
Template Deletion
For template deletion, the HTTP DELETE method is available. It is required to provide the id value
(String) of the template. Based on the examples, the value is “default/My API Provisioning Template”.
A POST can be requested to provision a single subscriber by using JSON. Let us assume that the
following single subscriber data will be provisioned:
To bulk-upload subscribers, it is required to specify the Content-Type as text/csv and POST the CSV
file in the request body. Let us assume that the following subscriber data will be provisioned in the
bulk.csv file:
Low level management of the configuration framework might be required by advanced users though.
This chapter explains the architecture and usage of Sipwise C5 configuration framework. If the basic
usage explained above fits your needs, feel free to skip this chapter and return to it when your
requirements change.
A more detailed workflow of the configuration framework for creating a configuration file consists of 7
steps:
There are different types of files in this template framework, which are described below.
Example: Let’s say we are changing the IP used by kamailio load balancer on interface eth0 to IP 1.2.3.4.
This will change kamailio’s listen IP address, when the configuration file is generated. A quick look to
After applying the changes with the ngcpcfg apply 'my commit message' command, a new configuration
file will be created under /etc/kamailio/lb/kamailio.cfg with the proper values taken from the main
configuration files (in this case network.yml):
listen=udp:1.2.3.4:5060
All the low-level configuration is provided by these .tt2 template files and the corresponding config.yml
file. Anyway, advanced users might require a more particular configuration.
Instead of editing .tt2 files, the configuration framework recognises .customtt.tt2 files. These files are the
same as .tt2, but they have higher priority when the configuration framework creates the final
configuration files. If you need to introduce changes in a template, you must always copy the required
.tt2 file to .customtt.tt2, make changes in the latter file one and leave the .tt2 file untouched. This way,
the system will use the new custom configuration allowing you to switch back to the original one
quickly.
cd /etc/ngcp-config/templates/etc/kamailio/lb
cp kamailio.cfg.tt2 kamailio.cfg.customtt.tt2
echo '# This is my last line comment' >> kamailio.cfg.customtt.tt2
ngcpcfg apply 'my commit message'
The ngcpcfg command will generate /etc/kamailio/lb/kamailio.cfg from our custom template instead
of the general one:
tail -1 /etc/kamailio/lb/kamailio.cfg
# This is my last line comment
users have to upgrade all .customtt.tt2 manually every time .tt2 is upgraded, as
WARNING
ngcpcfg completely ignores new code in .tt2 received from new package version.
The huge drawback of .customtt.tt2 files are necessity to keep them up-to-date manually. Keeping
them outdated will cause the system misbehaviour as different components will use different code
version (as new .tt2 version will be overwritten by old .customtt.tt2).
The .patchtt.tt2 concept should help users here. It will minimise the manual efforts by using linux "patch"
utility. The ngcpcfg tool is searching for .patchtt.tt2 files every time 'ngcpcfg build' has been called. If
.patchtt.tt2 is detected, the ngcpcfg tool will try to apply .patchtt.tt2 on .tt2 and store result in
.customtt.tt2 if no conflicts noticed during patching. Further building process happens in a common
way. Example:
To convert some/all the current .customtt.tt2 users can use command ngcpcfg patch --from-customtt
[<customtt_file>]:
# vim: ft=cfg
+# This is my last line comment
root@spce:~#
The .tt2 files use the Template Toolkit language. Therefore you can use all the feature this
TIP
excellent toolkit provides within ngcpcfg’s template files (all the ones with the .tt2 suffix).
A better way is to handle custom modifications using .patchtt.tt2 files (e.g. /etc/ngcp-
config/templates/etc/cron.d/cleanup-tools.patchtt.tt2). In this case, on every "ngcpcfg patch", a
.patchtt.tt2 file will be applied on top of the .tt2 file and the result will be saved into the customtt file and
used commonly as described in the previous section. "ngcpcfg patch" is the first step on "ngcpcfg build"
that guarantees the latest upstream templates with the availability of the necessary local changes on
every configuration apply.
The patch to be applied to the corresponding .tt2 template file is selected in the following
TIP order (highest to lowest): *.patchtt.tt2.$HOSTNAME *.patchtt.tt2.$PAIRNAME
*.patchtt.tt2.$HA_NODE *.patchtt.tt2
If a suitable patchtt file is found for a template, then the ngcpcfg patch command will
NOTE
overwrite the corresponding customtt file, if any.
Let us see how to introduce custom changes into a template through a patchtt file. For example, we
need to change the accounting records cleanup time, which is defined in cleanup-tools.tt2. Here is how
to do this:
cd /etc/ngcp-config/templates/etc/cron.d/
cp ./cleanup-tools.tt2 ./cleanup-tools.customtt.tt2
vim ./cleanup-tools.customtt.tt2
• Create the patchtt file from your customtt file and recheck it:
You will notice that the "ngcpcfg apply" command has generated the customtt file for the
corresponding template:
root@web01a:/etc/ngcp-config/templates/etc/cron.d# ls -l ./cleanup-
tools*
-rw------- 1 root root 932 Jan 4 11:11 ./cleanup-tools.customtt.tt2
-rw-r--r-- 1 root root 630 Jan 4 11:08 ./cleanup-tools.patchtt.tt2
-rw-r--r-- 1 root root 932 Dec 18 15:09 ./cleanup-tools.tt2
Now, even if cleanup-tools.tt2 slightly changes after a software upgrade, "ngcpcfg apply" will still
preserve your custom changes.
If in a new release the .tt2 file gets changed in the same lines where you had introduced
custom changes (e.g. your changes were temporary until a feature is implemented
NOTE properly in a new software release), the apply process will fail and ask you to review the
corresponding .patchtt.tt2 file. Then, check it and either correct if it is still required or
remove it.
To convert all existing customtt files to patchtt files use the command: ngcpcfg patch
TIP
--from-customtt
• They have to be placed in a .prebuild or .postbuild file in the same path as the original .tt2 file.
• The file name must be the same as the configuration file, but having the mentioned suffixes.
• The commands must be bash compatible.
• The commands must return 0 if successful.
• The target configuration file is matched by the environment variable output_file.
• The particular one, with the same name as the configuration file it is associated to.
Example: /etc/ngcp-config/templates/etc/asterisk/sip.conf.services is associated to
/etc/asterisk/sip.conf
• The general one, named ngcpcfg.services that is associated to every file in its target directory.
Example: /etc/ngcp-config/templates/etc/asterisk/ngcpcfg.services is associated to every file
under /etc/asterisk/
When the services step is triggered all .services files associated to a changed configuration file will be
executed. In case of the general file, any change to any of the configuration files in the directory will
trigger the execution of the commands.
If the service script has the execute flags set (chmod +x $file) it will be invoked directly. If it
TIP doesn’t have execute flags set it will be invoked under bash. Make sure the script is bash
compatible if you do not set execute permissions on the service file.
These commands are usually service reload/restarts to ensure the new configuration has been loaded
by running services.
The configuration files mentioned in the following example usually already exist on the
NOTE platform. Please make sure you don’t overwrite any existing files if following this
example.
Example:
In this example we created two .services files. Now, each time we trigger a change to /etc/mysql.my.cnf
or to /etc/asterisk/* we’ll see that MySQL or Asterisk services will be restarted by the ngcpcfg system.
The /etc/ngcp-config/constants.yml file provides configuration options for the platform that aren’t
supposed to be edited by the user. Do not manually edit this file unless you really know what you’re
doing.
The /etc/ngcp-config/network.yml file provides configuration options for all interfaces and IP
addresses on those interfaces. You can use the ngcp-network tool for conveniently change settings
without having to manually edit this file.
The /etc/ngcp-config/ngcpcfg.cfg file is the main configuration file for ngcpcfg itself. Do not manually
edit this file unless you really know what you’re doing.
8.3.1. apply
The apply option is a short-cut for the options "check && build && services && commit" and also
executes etckeeper to record any modified files inside /etc. It is the recommended option to use the
ngcpcfg framework unless you want to execute any specific commands as documented below.
8.3.2. build
The build option generates (and therefore also updates) configuration files based on their configuration
(config.yml) and template files (.tt2). Before the configuration file is generated a present .prebuild will be
executed, after generation of the configuration file the according .postbuild script (if present) will be
executed. If a file or directory is specified as argument the build will generate only the specified
configuration file/directory instead of running through all present templates.
Example: to generate all the files located inside the directory /etc/nginx/ you can execute:
8.3.3. commit
The commit option records any changes done to the configuration tree inside /etc/ngcp-config. The
commit option should be executed when you’ve modified anything inside the configuration tree.
8.3.4. decrypt
Decrypt /etc/ngcp-config-crypted.tgz.gpg and restore configuration files, doing the reverse operation
of the encrypt option. Note: This feature is only available if the ngcp-ngcpcfg-locker package is
installed.
8.3.5. diff
Show uncommitted changes between ngcpcfg’s Git repository and the working tree inside /etc/ngcp-
config. Iff the tool doesn’t report anything it means that there are no uncommitted changes. If the
--addremove option is specified then new and removed files (iff present) that are not yet (un)registered
to the repository will be reported, no further diff actions will be executed then. Note: This option is
available since ngcp-ngcpcfg version 0.11.0.
8.3.6. encrypt
Encrypt /etc/ngcp-config and all resulting configuration files with a user defined password and save
the result as /etc/ngcp-config-crypted.tgz.gpg. Note: This feature is only available if the ngcp-
ngcpcfg-locker package is installed.
8.3.7. help
The help options displays ngcpcfg’s help screen and then exits without any further actions.
8.3.8. initialise
The initialise option sets up the ngcpcfg framework. This option is automatically executed by the
installer for you, so you shouldn’t have to use this option in normal operations mode.
8.3.9. services
The services option executes the service handlers for any modified configuration file(s)/directory.
8.3.10. status
The status option provides a human readable interface to check the state of the configuration tree. If
you are unsure what should be done as next step or if want to check the current state of the
configuration tree, invoke ngcpcfg status.
If everything is OK and nothing needs to be done the output should look like:
# ngcpcfg status
Checking state of ngcpcfg:
OK: has been initialised already (without shared storage)
Checking state of configuration files:
OK: nothing to commit.
Checking state of /etc files
OK: nothing to commit.
If the output doesn’t say "OK", follow the instructions provided by the output of 'ngcpcfg status'.
Further details regarding the ngcpcfg tool are available through 'man ngcpcfg' on the Sipwise Next
Generation Platform.
hosts:
self:
role:
- proxy
- lb
- mgmt
interfaces:
- eth0
- lo
eth0:
ip: 192.168.51.213
netmask: 255.255.255.0
type:
- sip_ext
- rtp_ext
- web_ext
- web_int
lo:
ip: 127.0.0.1
netmask: 255.255.255.0
type:
- sip_int
- ha_int
Some more complete, sample configuration is shown in network.yml Overview section of the
handbook.
The file contains all configuration parameters under the main key: hosts
In Sipwise C5 systems there is only one host entry in the file, and it is always named self.
• role: The role setting is an array defining which logical roles a node will act as. Possible entries for
this setting are:
◦ mgmt: This entry means the host is acting as management node for the platform. In a Sipwise C5
system this option must always be set. The management node exposes the admin and CSC
panels to the users and the APIs to external applications and is used to export CDRs.
◦ lb: This entry means the host is acting as SIP load-balancer for the platform. In a Sipwise C5
system this option must always be set. The SIP load-balancer acts as an ingress and egress
point for all SIP traffic to and from the platform.
◦ proxy: This entry means the host is acting as SIP proxy for the platform. In a Sipwise C5 system
this option must always be set. The SIP proxy acts as registrar, proxy and application server and
media relay, and is responsible for providing the features for all subscribers provisioned on it.
◦ db: This entry means the host is acting as the database node for the platform. In a Sipwise C5
system this option must always be set. The database node exposes the MySQL and Redis
databases.
◦ rtp: This entry means the host is acting as the RTP relay node for the platform. In a Sipwise C5
system this option must always be set. The RTP relay node runs the rtpengine Sipwise C5
component.
• interfaces: The interfaces setting is an array defining all interface names in the system. The actual
interface details are set in the actual interface settings below. It typically includes lo, eth0, eth1
physical and a number of virtual interfaces, like: bond0, vlanXXX
• <interface name>: After the interfaces are defined in the interfaces setting, each of those interfaces
needs to be specified as a separate set of parameters.
• dbnode: the sequence number (unique ID) of the node in the database cluster; not used in Sipwise
C5 CE systems.
• status: one of 'online', 'offline', 'inactive'. 'inactive' means that the node is up but is not ready to work
in the cluster (installing process). 'offline' means that the node is not reachable. 'online' is a normal
working node.
◦ api_int: internal, API-based communication interface. It is used for the internal communication of
such services as faxserver, fraud detection and others.
◦ aux_ext: interface for potentially insecure external components like remote system log
collection service.
◦ rtp_ext: main (external) interface for media traffic
◦ sip_ext: main (external) interface for SIP signalling traffic between NGCP and other SIP endpoints
◦ sip_ext_incoming: additional, optional interface for incoming SIP signalling traffic
◦ sip_int: internal SIP interface used by Sipwise C5 components (lb, proxy, etc.)
◦ ssh_ext: command line (SSH) remote access interface
◦ web_ext: interface for web-based or API-based provisioning and administration
◦ web_int: interface for the administrator’s web panel, his API and generic internal API
communication
◦ ha_int: HA (High Availability) communication interface between the services
Please note that, apart from the standard ones described so far, there might be other
NOTE
types defined for a particular Sipwise C5 system.
post_up:
- route add -host 1.2.3.4 gw 192.168.1.1 dev vlan70
- route add -net 10.11.12.0/21 gw 192.168.1.2 dev vlan300
- route del -host 1.2.3.4 gw 192.168.1.1 dev vlan70
- route del -net 10.11.12.0/21 gw 192.168.1.2 dev vlan300
• bond_XY: specific to "bond0" interface only; these contain Ethernet bonding properties
• etc_hosts_global_extra_entries at the host level, which overrides the global one if for some reason
the whole content is undesired for a particular host (e.g. to have some but not all of the "default"
global entries)
• etc_hosts_local_extra_entries at the host level, which are added only to the hosts where this entry is
present, if for some reason it is desired to have extra entries only visible in some subset of the hosts
The behaviour is the same in all cases, to append the entries directly to /etc/hosts.
---
hosts_common:
etc_hosts_global_extra_entries:
- 10.100.1.1 server-1 server-1.internal.example.com
- 10.100.1.2 server-2 server-2.internal.example.com
hosts:
db01b:
etc_hosts_local_extra_entries:
- 127.0.1.1 local-alias-1.db01b
- 127.0.2.1 local-alias-2.db01b
- 172.30.52.180 db01b.example.com
...
web01a:
etc_hosts_local_extra_entries:
- 127.0.1.1 local-alias-1.web01a
- 127.0.2.1 local-alias-2.web01a
- 172.30.52.168 web01a.example.com
etc_hosts_global_extra_entries:
- 10.100.1.1 server-1 server-1.internal.example.com
...
With this, the additional output in /etc/hosts for db01b will be:
and in web01a:
extra_sockets:
port_5064: udp:10.15.20.108:5064
test: udp:10.15.20.108:6060
The label is shown in the outbound_socket peer preference (if you want to route calls to the specific
peer out via specific socket); the value must contain a transport specification as in example above (udp,
tcp or tls). After adding execute ngcpcfg apply:
The direction of communication through this SIP extra socket is incoming+outgoing. The Sipwise C5 will
answer the incoming client registrations and other methods sent to the extra socket. For such incoming
communication no configuration is needed. For the outgoing communication the new socket must be
selected in the outbound_socket peer preference. For more details read the next section Extra SIP and
RTP Sockets that covers peer configuration for SIP and RTP in greater detail.
In this section you have just added an extra SIP socket. RTP traffic will still use
IMPORTANT
your rtp_ext IP address.
Suppose we need to add a new SIP socket and a new RTP socket on VLAN 100. You can use the ngcp-
network tool for adding interfaces without having to manually edit this file:
..
..
eth0.100:
hwaddr: ff:ff:ff:ff:ff:ff
ip: 192.168.1.3
netmask: 255.255.255.0
type:
- sip_ext_incoming
- rtp_int_100
..
..
interfaces:
- lo
- eth0
- eth0.100
- eth1
..
..
As you can see from the above example, extra SIP interfaces must have type sip_ext_incoming. While
sip_ext should be listed only once per host, there can be multiple sip_ext_incoming interfaces. The
direction of communication through this SIP interface is incoming only. The Sipwise C5 will answer the
incoming client registrations and other methods sent to this address and remember the interfaces used
for clients' registrations to be able to send incoming calls to him from the same interface.
In order to use the interface for the outbound SIP communication it is necessary to add it to
extra_sockets section in /etc/ngcp-config/config.yml and select in the outbound_socket peer
preference. So if using the above example we want to use the vlan100 IP as source interface towards a
peer, the corresponding section may look like the following:
extra_sockets:
port_5064: udp:10.15.20.108:5064
test: udp:10.15.20.108:6060
int_100: udp:192.168.1.3:5060
After applying the changes, a new SIP socket will listen on IP 192.168.1.3 and this socket can now be
used as source socket to send SIP messages to your peer for example. In above example we used
label 'int_100'. So the new label "int_100" is now shown in the outbound_socket peer preference.
Also, RTP socket is now listening on 192.168.1.3 and you can choose the new RTP socket to use by
setting parameter rtp_interface to the Label "int_100" in your Domain/Subscriber/Peer preferences.
The same 'rtp_' interface type can be configured on multiple interfaces. If this is the case, and if ICE
('Interactive Connectivity Establishment') is enabled for a Domain/Subscriber/Peer, it is possible to use
ICE to automatically negotiate which interface should be used for RTP communications. ICE must be
supported by the remote client for this to work.
..
..
eth0.100:
type:
- rtp_ext
..
eth0.150:
type:
- rtp_ext
..
eth1:
type:
- rtp_ext
..
..
In this example, the RTP interface 'ext' will be available for selection in the Domain/Subscriber/Peer
preferences. If selected and if ICE is enabled, the addresses of all three interfaces will be presented to
the remote client, and ICE will be used to negotiate which one of them will be used for
communications. This can be useful in multi-homed environments, or when remote clients are on
private networks.
To enable this, multiple interfaces with different addresses must be configured, and interface types of
the format 'rtp_NAME:SUFFIX' must be assigned to them. For example, if the RTP interface named 'ext'
should be load-balanced across three interfaces, they can be configured like so (abbreviated):
..
..
eth0.100:
type:
- rtp_ext:1
..
eth0.150:
type:
- rtp_ext:2
..
eth1:
type:
- rtp_ext:3
..
..
In this example, all three given RTP interface types will be available for selection in the
Domain/Subscriber/Peer preferences individually (as 'ext:1' and so on), but in addition to that, an
interface named just 'ext' will also be available for selection. If 'ext' is selected, only one of the three
RTP interfaces will be selected in a round-robin fashion, thus increasing the number of available RTP
ports threefold. The round-robin algorithm only selects an interface if it actually has RTP ports available.
ngcp-upgrade requires a special partitioning schema of disk subsystem. The server has 3 separate
partitions:
ngcp-root and ngcp-fallback - they are equal size and contain the software, OS files and NGCP
packages. One of them is the current root '/' partition, the another one is mounted as /ngcp-fallback
directory.
During the upgrade the second partition is formatted and the target version is installed into it. After the
reboot the system will be started from this partition and previous one becomes the /ngcp-fallback
directory.
Please, pay particular attention that this partitioning schema is mandatory and if
WARNING
your system doesn’t have it - create it beforehand.
This is the only supported upgrade schema. The old, in-place upgrade is not
WARNING
supported and technically not possible.
• Russian language/prompts have been removed from NGCP. Sipwise against Russian aggression in
Ukraine: https://war.ukraine.ua/ [TT#166550]
• Run the media/RTP proxy service (rtpengine) as unprivileged non-root user by default. A new
option was introduced to 'config.yml' ('rtpproxy.run_as_root') to run the service as fully privileged
root user anyway, which can be necessary for certain features (e.g. directly managing firewall rules
through an iptables chain). If any such features are enabled then the setting 'rtpproxy.run_as_root'
must be set to 'yes'. If call recording with a non-standard output directory is in use, then care must
be taken about the permissions as well. [TT#157800]
• Internal NGCP communications between rtpengine instances now uses by default rtpc-mux. Audio
streams now have a data protocol RTP and control protocol RTCP multiplexed, this allows to save
some ports especially in case of call forking scenarios. [TT#158652]
• Reworked ngcp-io-scheduler behavior:
◦ support for multiple disks was added, e.g. for usage in Software RAID setups
◦ new I/O scheduler default (uses none by default, for rotational/spinning disks deadline
scheduler is used, in virtualized environments the default scheduler doesn’t get modified)
◦ ngcp-io-scheduler behavior can be customized via /etc/default/io-scheduler
[TT#160100]
• As mentioned in the important changes, the kamailio usrloc db_mode parameter has been switched
from 1 to 3 for Pro and CE systems. This parameter controls how and where the usrloc (subscriber
locations) are stored: kamailio cache or database. Here the link to the official kamailio
documentation: https://www.kamailio.org/docs/modules/stable/modules/usrloc.html#
usrloc.p.db_mode. Starting from now the locations are only stored in the database and not kept in
the internal kamailio cache. Administrators can switch back the config.yml parameter to the
previous value, but this could prevent the possibility of using future new features. [TT#139455]
• Added Grandstream User/Password options into ngcp-insert-pbx-devices script [TT#160200]
Deprecation notice:
Please find the complete changelog in our release notes on our WEB site.
10.2. Overview
The Sipwise C5 software upgrade procedure to mr10.4.1 will perform several fundamental tasks:
Please make sure to have remote access to the system via out-of-band
WARNING
management (like IPMI, iLO, IMM, iDRAC, KVM, etc)
screen -S my_screen_name_for_ngcp_upgrade
sudo -s
ngcp-status
If you directly change the working configuration (e.g. add custom templates or
change the existing ones) for some reason, then the system must be thoroughly
WARNING
tested after these changes have been applied. Continue with the software upgrade
preparation only if the results of the tests are acceptable.
ngcp-customtt-diff-helper
The script will also ask you if you would like to download the templates for your target release. To
download the new templates separately, execute:
ngcp-customtt-diff-helper -d
In the tmp folder provided by the script, you can review the patchtt files or merge the current customtt
with the new tt2 templates, creating the new customtt.tt2 files. Once you do this, archive the new
patchtt/customtt files to reapply your custom modifications after the software upgrade:
ngcp-customtt-diff-helper -t
ngcp-status --integrity
ngcpcfg status
Run "apt-get update" and ensure that you do not have any warnings and errors in the output.
If the installation uses locally specified mirrors, then the mirrors must be switched
to the Sipwise APT repositories (at least for the software upgrade). Otherwise, the
WARNING
public Debian mirrors may not provide packages for old Releases anymore or at
least provide outdated ones!
If there is an error during the upgrade, the ngcp-upgrade script will request you to
NOTE solve it. Once you’ve fixed the problem, execute ngcp-upgrade again and it will
continue from the previous step.
The upgrade script will ask you to confirm that you want to start. Read the given information carefully,
and if you agree, proceed with y.
The upgrade process will take several minutes, depending on your network connection and server
performance. After everything has been updated successfully, it will finally ask you to reboot your
system. Confirm to let the system reboot (it will boot with an updated kernel).
• --step-by-step: confirm before proceeding to next step. With this option the upgrade operation
is performed confirming every step before execution, with the possibility to instruct to continue
without confirming further steps until the end (if confirmation is only needed for some steps at the
beginning).
• --pause-before-step STEP_NAME: pause execution before step, given by the name of the script
(e.g. "backup_mysql_db"). This option can be useful in several scenarios, for example:
◦ to help to debug problems or work around known problems during upgrades. In this case the
operator can pause at a given step known to be problematic or right before a problematic set,
perform some manual checks or changes, then continue the upgrade until another step (with
confirmation like with the recent option --step-by-step), or continue without stop until the
end
◦ another use might be to help to speed up upgrades when it involves several nodes: they can all
proceed in parallel when it’s known to be safe to do so; then perform some parts in lock-step
(some nodes waiting until others finish with some stage); then continue in parallel until the end
• --skip-db-backup: This will speed-up the process in cases where it’s deemed unnecessary, and
this is very likely in the upgrade of nodes other than the first.
Public Debian mirrors may not provide packages for old Debian releases anymore. Also, they might be
outdated. Consider using Sipwise repositories for the time of the upgrade.
ngcp-prepare-upgrade mr10.4.1
ngcp-upgrade
There is "stop" step in upgrade scenario, upgrader stops there. At this time the new system in fallback
partition is ready so you can reboot the server to boot from mr10.4.1 system.
After reboot run ngcp-upgrade again with the same parameters so upgrade will continue with post-
upgrade steps.
Once up again, double-check your config file /etc/ngcp-config/config.yml (sections will be rearranged
now and will contain more parameters) and your domain/subscriber/peer configuration and test the
setup.
You can find a backup of some important configuration files of your existing installation
under /ngcp-data/backup/ngcp-mr10.4.1-\* (where \* is a place holder for a
NOTE
timestamp) in case you need to roll back something at any time. A log file of the
upgrade procedure is available at /ngcp-data/ngcp-upgrade/$FROM-mr10.4.1/logs/.
Execute all steps as described in Pre-upgrade checks. They include the system checks,
customtt/patchtt preparation and others. It is important to execute all the steps from the above
chapter.
ngcp-update
This is the most important data in the system. All subscriber and billing information, CDRs, user
preferences, etc. are stored in the MySQL server. It is strongly recommended to have up-to-date
dumps of all the databases .
• System configuration
The system configuration folder /etc/ngcp-config/ must be included in the backup as well. It contains
the system specific configuration (like SSL keys). Also you might have some local modifications. We
suggest backing up the whole /etc folder to preserve the etckeeper history to be able to answer when
and who changed particular configuration files in the past.
The /home/jail/home/cdrexport directory contains the exported CDRs. It depends on your call data
retention policy whether or not to remove these files after exporting them to an external system.
11.2. Recovery
In the worst case scenario, when the system needs to be recovered from a total loss, you only need 4
steps to get the services back online:
To reset database to its original state you can use a script provided by CE: * Execute ngcp-reset-db. It
will assign new unique passwords for Sipwise C5 services and reset all services. The script will also
create dumps for all Sipwise C5 databases.
In case the system administrator needs to modify some configuration value, the new configuration
must be activated in the usual way, by running the following commands:
As a result new configuration files will be generated for the accounting database and the exported CDR
cleanup tools. Please read detailed description of those tools in subsequent sections of the handbook.
The Sipwise C5 system administrator can also select the time when cleanup scripts are run, by
modifying the schedule here: /etc/cron.d/cleanup-tools
############
batch = 10000
archive-target = /ngcp-data/backup/cdr
compress = gzip
username = dbcleaner
password = rcKamRdHhx7saYRbkJfP
host = localhost
port = 3306
redis-batch = 10000
redis-port = 6379
connect accounting
keep-months = 2
use-partitioning = yes
timestamp-column = cdr_start_time
backup cdr_cash_balance_data
backup cdr_time_balance_data
backup cdr_relation_data
backup cdr_tag_data
backup cdr_mos_data
backup cdr_export_status_data
backup cdr_group
timestamp-column = first_cdr_start_time
backup cdr_period_costs
timestamp-column = start_time
backup cdr
archive-months = 2
archive cdr_cash_balance_data
archive cdr_time_balance_data
archive cdr_relation_data
archive cdr_tag_data
archive cdr_mos_data
archive cdr_export_status
archive cdr_group
archive cdr_period_costs
archive cdr
cleanup-days = 1
use-partitioning = no
timestamp-column = cdr_start_time
cleanup int_cdr_cash_balance_data
cleanup int_cdr_time_balance_data
cleanup int_cdr_relation_data
cleanup int_cdr_tag_data
cleanup int_cdr_group
cleanup int_cdr_export_status
timestamp-column = start_time
cleanup int_cdr
connect kamailio
time-column = time
cleanup-days = 90
cleanup acc
connect-redis 21
connect kamailio
time-column = time_hires
cleanup-days = 3
cleanup-mode = mysql
cleanup-redis acc:entry::*
maintenance = no
The configuration file itself contains a detailed description of how database cleanup script works. It
consists of a series of statements, one per line, which are going to be executed in sequence. A
statement can either only set a variable to some value, or perform an action.
There are 4 types of actions the database cleanup script can take:
The database cleanup tool can create monthly backups of data in the accounting database tables by
moving old records to separate tables named: cdr_YYYYMM. The instruction in the configuration file
looks like: backup <table name>, by default and typically it is: backup cdr
• time-column: The name of the column in the table to use for determining which month a record
belongs to. Must be a "datetime" column.
• timestamp-column: The name of the column in the table to use for determining which month a
record belongs to. Must be a "decimal(13,3)" column.
• use-partitioning: If a table is partitioned using the time-column (timestamp-column) and the value is
set to "yes", then moving/deleting records are instant operations, done by managing the partitions.
Otherwise the usual method is used to delete/move records by chunks.
• batch: How many rows to include per transaction when processing in chunks. If unset or ⇐ 0, it does
them all at once.
• keep-months: How many months worth of records to keep in the table and not move into the
monthly backup tables.
IMPORTANT: Months are always processed as a whole and this specifies how many months to keep
AT MOST. In other words, if the script is started on December 15th and this value is set to "2", then all
of December and November is kept, and all of October will be moved out.
The database cleanup tool can archive (dump) old monthly tables. The statement used for this purpose
is: archive <table name>, by default and typically it is: archive cdr
This creates an SQL dump out of older tables created by the backup statement and drop them from
database afterwards. Archiving uses the following configuration values:
• archive-months: Uses the same logic as the "keep-months" variable. If set to "12" and the script was
started on December 15th, it will start archiving with the December table of the previous year.
Archiving continues month by month, going backwards in time, until the script encounters a missing
table.
• archive-target: Target directory for writing the SQL dump files. If explicitly specified as "/dev/null",
then no actual archiving will be performed, but instead the tables will only be dropped.
• compress: If set to "gzip", then gzip the dump files after creation. If unset, do not compress.
• host, "username" and "password": As dumping is performed by an external command, those
variables are reused from the "connect" statement.
The database cleanup tool may do database table cleanup without performing backup. In order to do
that, the statement: cleanup <table name> is used. Typically this has to be done in kamailio database,
examples:
• cleanup acc
• cleanup acc_trash
• cleanup acc_backup
The cleanup statement works exactly like the backup statement, but doesn’t actually backup anything,
but rather only deletes old records. Additional configuration parameters required by the cleanup
procedure:
• cleanup-days: Any record older than these many days will be deleted.
With the advent of persisting kamailio.acc record data in a redis keystore, a separate cleanup-redis
<key pattern> statement was introduced. It will remove old redis entries, whose keys match the given
redis SCAN pattern. Typically this has to be done for the redis 21 database (acc records), eg.:
• cleanup-redis acc:entry::*
connect-redis <redis database number> has to be used instead of connect +<mariadb database name>,
which is needed to initially connect before any <backup>, <archive> and <cleanup> operations.
The cleanup-redis statement works similar to the cleanup statement, with some additional options
below:
• time-column: The name of the field in a redis entry denoting the record timestamp in epoch
seconds.
• cleanup-mode: If set to "delete", aged entires will be simply removed. If set to "mysql", they will be
inserted into a database table first. The latter requires connect to open the database additionally.
• redis-batch: Chunk size of redis entries with matching keys to look at. Note that redis processing
always works in chunks, there is no partitioning.
• cleanup-days: Any entry older than these many days will be deleted.
The configuration file used by exported CDR cleanup script is: /etc/ngcp-cleanup-tools/cdr-files-
cleanup.yml
enable: no
max_age_days: 30
paths:
-
path: /home/jail/home/*/20[0-9][0-9][0-9][0-9]/[0-9][0-9]
wildcard: yes
remove_empty_directories: yes
max_age_days: ~
-
path: /home/jail/home/cdrexport/resellers/*/20[0-9][0-9][0-9][0-
9]/[0-9][0-9]
wildcard: yes
remove_empty_directories: yes
max_age_days: ~
-
path: /home/jail/home/cdrexport/system/20[0-9][0-9][0-9][0-9]/[0-
9][0-9]
wildcard: yes
remove_empty_directories: yes
max_age_days: ~
The exported CDR cleanup tool deletes CDR files in the directories provided in the configuration file, if
those have already expired.
To completely remove Sipwise access to your system, please execute as user root:
NOTE you have to execute the command above on each node of your Sipwise C5 system!
If you need to restore Sipwise access to the system, please execute as user root:
12.2. Firewalling
12.2.1. Firewall framework
The Sipwise C5 runs a wide range of services. In order to secure the platform while allowing access to
Sipwise C5 , Sipwise C5 configuration framework provides a set of predefined network zones. Services
are aggregated into appropriate zones by default. Zones are assigned to network interfaces (and
VLANs if applicable) in /etc/ngcp-config/network.yml.
Additional custom zones may be configured, but will not be automatically integrated
NOTE
into the firewall configuration.
To facilitate firewall functionality, Sipwise C5 uses the Kernel’s 'netfilter' facility and 'iptables-persistent'
as an interface to 'netfilter'. 'Netfilter' is using 'tables' and within that 'chains' to store rules in this
hierarchy: 'table' → 'chain' → 'rule'. Default firewall setups of Sipwise C5 do not use netfilter tables 'nat' and
'raw', but only default table 'filter'.
Custom 'nat' rules for IPv4 and IPv6 may be added in file /etc/ngcp-config/config.yml
NOTE
in sections 'security→firewall→nat_rules4' and 'security→firewall→nat_rules6'.
Each 'chain' deploys a 'default policy' handling packets which did not trigger and rule in a prticular
'chain'.
Firewall configuration is applied by running ngcpcfg apply. However, this will not activate new rules
automatically to avoid inadvertent self-lockout. To finally activate new firewall rules run iptables-apply.
This will prompt for another system logon to verify access remains available. If the prompt is not
confirmed, firewall rules will automatically be reverted to the previous state re-enabling access to the
command line.
sip_ext INPUT ACCEPT -p udp --dport Set of rules for all 'sip_ext'
'<kamailio.lb.port>' -j ACCEPT interfaces accepting all
packets on the loda balancer’s
SIP signalling port defined in
'/etc/ngcp-config/config.yml'
with key 'kamailio.lb.port' (UDP)
sip_ext INPUT ACCEPT -p tcp --dport Set of rules for all 'sip_ext'
'<kamailio.lb.port>' -j ACCEPT interfaces accepting all
packets on the loda balancer’s
SIP signalling port defined in
'/etc/ngcp-config/config.yml'
with key 'kamailio.lb.port' (TCP)
sip_ext INPUT ACCEPT -p tcp --dport Set of rules for all 'sip_ext'
'<kamailio.lb.tls.port>' -j interfaces accepting all
ACCEPT packets on the loda balancer’s
SIP signalling port defined in
'/etc/ngcp-config/config.yml'
with key 'kamailio.lb.tls.port'
(TCP/TLS)
sip_ext INPUT ACCEPT -p tcp --dport 5222 -j ACCEPT Set of rules for all 'sip_ext'
interfaces accepting all
packets on TCP port 5222
(XMPP client)
sip_ext INPUT ACCEPT -p tcp --dport 5269 -j ACCEPT Set of rules for all 'sip_ext'
interfaces accepting all
packets on TCP port 5269
(XMPP server)
sip_ext INPUT ACCEPT -p tcp --dport '<pushd.port>' -j Set of rules for all 'sip_ext'
ACCEPT interfaces accepting all
packets incoming for the
'pushd' server port configured
in '/etc/ngcp-
config/config.yml' with key
'pushd.port'
ssh_ext INPUT ACCEPT -A INPUT -i List of rules to accept
'<ssh_ext_interface>' -p tcp -s incoming packets for SSH on
'<sshd.permit_support_from>' all 'ssh_ext' interfaces from
--dport 'sshd.port' -j ACCEPT hosts configured in
'/etc/ngcp-config/config.yml'
with key
'sshd.permit_support_from'
To function correctly, the rtpengine requires an additional iptables rule installed. This
rule (with a target of RTPENGINE) is automatically installed and removed when the
rtpengine starts and stops, so normally you don’t need to worry about it. However,
any 3rd party firewall solution can potentially flush out all existing iptables rules
before installing its own, which would leave the system without the required
CAUTION
RTPENGINE rule and this would lead to decreased performance. It is imperative
that any 3rd party firewall solution either leaves this rule untouched, or installs it
back into place after flushing all rules out. The complete parameters to install this
rule (which needs to go into the INPUT chain of the filter table) are: -p udp -j
RTPENGINE --id 0
Some of the parameters used to populate the firewall rules automatically may contain
hostnames instead of IP addresses. Since firewall rules need to be configured based on
IP addresses by design, Sipwise C5 configuration framework will lookup such
hostnames during 'ngcpcfg apply' and expand them to the IP addresses as returned by
NOTE
'gethostbyname'. If DNS resolving changes for such hostnames due to changes to DNS
the rules will not update automatically. Another run of 'ngcpcfg apply' will be needed to
reperform the lookup and update the rules to reflect changes in DNS. If this step is
omitted, clients may be locked out of the system.
By default, the rules for the 'rtp_ext' zone are created with a target of ACCEPT. It is
optionally possible to create these rules with another iptables chain as target, and
instruct the RTP proxy to dynamically manage individual rules for each running call in
this chain. If this is enabled, the chain with the name given in the /etc/ngcp-
config/config.yml key rtpproxy->firewall_iptables_chain will be created as empty,
leaving the effective target for UDP packets within the RTP port range as the table’s
NOTE
default policy (normally DROP). The RTP proxy will then dynamically created one
ACCEPT rule for each open RTP media port in the given chain when a call starts, and
delete it when the call is finished. It should be noted that dynamically creating and
deleting iptables rules can incur a singificant performance overhead, especially in
scenarios with high call volumes, and it is therefore not recommended to enable this
feature in such cases.
Example custom rule to whitelist all IPv4 traffic from network interface eth1.301 effectively making
VLAN 301 a trusted network:
rules4:
- '-A INPUT -i eth1.301 -j ACCEPT'
Example custom rule to accept incoming traffic from monitoring station 203.0.113.93 for an optionally
installed check_mk agent:
rules4:
- '-A INPUT -p tcp -s 203.0.113.93 --dport 6556 -j ACCEPT'
To add hosts or networks to the SSH whitelist they can be either added to key
'sshd.permit_support_from' in '/etc/ngcp-config/config.yml' or a custom rule may be used:
rules4:
- '-A INPUT -s 198.51.100.0/24 --dport 22 -j ACCEPT'
- '-A INPUT -s 203.0.113.93 --dport 22 -j ACCEPT'
security:
firewall:
enable: yes
logging:
enable: yes
file: '/var/log/firewall.log'
tag: 'NGCPFW'
policies:
input: 'DROP'
forward: 'DROP'
output: 'ACCEPT'
rules4:
- '-A INPUT -i eth0 -j ACCEPT'
Many Sipwise C5 services use MySQL backend. Users and passwords for these
services are created during the installation. These passwords are unique for each
IMPORTANT
installation, and the connections are restricted to localhost. You should not
change these users and passwords.
To change the root password log into the freshly deployed system as "root" using the preconfigured
password and execute:
root@myserver:~# passwd
The Vagrant/VirtualBox/VMWare Sipwise C5 images come with more default credentials which should
be changed immediately:
• The default password of the system account root is sipwise. A password must be changed
immediately using command passwd root.
• SSH authorized_keys for users root and sipwise should be wiped out using command rm
\~root/.ssh/sipwise_vagrant_key ~sipwise/.ssh/sipwise_vagrant_key for VirtualBox/VMWare images
(skip the step if you use Vagrant).
The password for the "administrator" account can be changed via the Web-interface.
For system setup purposes, the default setting on the Sipwise C5 is to permit
WARNING remote 'root' logins via SSH. It is strongly recommended to change this default
setting as soon as possible.
Once you’ve created a user account for yourself that can be used to gain 'root' privileges, remote 'root'
logins can be disabled via the config switch sshd→permit_root_login in /etc/ngcp-config/config.yml.
sshd:
permit_root_login: yes
The logs are saved in directories with a special structure, the numbers are for a so-called "session" or
sequence:
$BASE_DIR/$USERNAME/00/00/00
For example:
/var/log/sudo-io/root/00/00/00
and within them, several files for tty input and output, stdin/stdout/stderr, and other ancillary files.
This is disabled by default, but can be configured in /etc/ngcp-config/config.yml with the following
options:
sudo:
logging:
enable: no
exclude_users: []
max_sessions: 0
This sudo plugin saves all input and output including passwords typed in shell
WARNING prompts (even when they are not echoed to the screen), and this is unencrypted,
so please consider the security implications.
Even if in some versions the compression of these files is enabled (releases mr9.5
and after), some commands can use huge amounts of data and fill-up the available
disk space very quickly, and full disk will cause serious problems (failures in
WARNING services, or even preventing external access to the system to fix the problems).
Please consider setting up monitoring of free space, or mitigating measures like
setting a small amount of sessions saved, taking data out the system often for
preservation and deleting sessions from previous days, etc.
Additionally, this has a performance impact (both CPU and I/O) on every command
WARNING run with sudo that triggers logging, negligible for most commands but significant
when the input or output is large.
• Generate the certificates. The customer self care interface certificate should be signed by a
certification authority to avoid browser warnings.
• Upload the certificates to the system
• Set the path to the new certificates in /etc/ngcp-config/config.yml:
◦ ossbss→apache→autoprov→sslcertfile and ossbss→apache→autoprov→sslcertkeyfile for the provisioning
interface.
◦ ossbss→apache→restapi→sslcertfile and ossbss→apache→restapi→sslcertkeyfile for the REST interface.
◦ www_admin→http_admin→sslcertfile and www_admin→http_admin→sslcertkeyfile for the admin
interface.
◦ www_admin→http_csc→sslcertfile and www_admin→http_csc→sslcertkeyfile for the customer self care
interface.
• Apply the configuration changes with ngcpcfg apply 'added web ssl certs'.
The Sipwise C5 also provides the self-signed SSL certificates for SIP over TLS services. The system
administrator should replace them with certificates signed by a trusted certificate authority if he is
going to enable it for the production usage (config.yml section: kamailio→lb→tls (TLS is enabled by default
and uses self-signed SSL certificates)).
• Apply the configuration changes with ngcpcfg apply 'added kamailio certs'.
kamailio:
lb:
security:
dos_ban_enable: yes
dos_ban_time: 3600
dos_reqs_density_per_unit: 50
dos_sampling_time_unit: 2
dos_whitelisted_ips: []
dos_whitelisted_subnets: []
As soon as Sipwise C5 receives more than 50 messages from the same IP in a time window of 2
seconds, that IP will be blocked for 3600 sec, and you will see in the kamailio-lb.log a line saying:
The banned IP will be stored in kamailio memory, you can check the list via web interface or via the
following command:
There may be some SIP endpoints that send a huge traffic towards Sipwise C5 from a specific IP
address. A typical example is a SIP Peering Server.
Sipwise C5 supports handling such situations by excluding all defined SIP Peering
CAUTION
Servers from DoS protection mechanism.
The Sipwise C5 platform administrator may also add whitelisted IP addresses manually in /etc/ngcp-
config/config.yml at kamailio.lb.security.dos_whitelisted_ips and
kamailio.lb.security.dos_whitelisted_subnets parameters.
kamailio:
lb:
security:
failed_auth_attempts: 3
failed_auth_ban_enable: yes
failed_auth_ban_time: 3600
It may be required to increase the number of failed attempts by adjusting the ban time (e.g. some users
can be banned accidentally because they are not writing the right password). If a user tries to
authenticate an INVITE/REGISTER (or more in general, any request containing an Authorization or
Proxy-Authorization SIP header) and if it fails more than 3 times, the user@domain (not the IP as for
Denial of Service attack) will be blocked for 3600 seconds (see failed_auth_ban_time on /etc/ngcp-
config/config.yml). In this case, you will see the following lines in /var/log/ngcp/kamailio-lb.log file:
Both the banned IPs and banned users will be shown in the Admin web interface by accessing the
Settings→Security Bans menu. To retrieve the same information from Kamailio memory, use the following
command:
In a typical SIP session the mandatory headers may carry that sensitive information, for example:
Contact, Via, Record-Route, To, From, Call-ID. An SBC applying topology hiding will mangle the content
of those headers.
Record-Route: <sip:127.0.0.8;line=sr-NvaAlWtecghucEhu6WtAcu...>
Contact: <sip:127.0.0.8;line=sr-NvaAli-1VeL.kRxLcbN86W...>
The load-balancer element of Sipwise C5 has an SBC role, from the SIP peers point of view. The LB
offers topology masking function that can be activated through a configuration change. By default the
function is disabled.
Activating topology masking function is possible through the modification of the following configuration
parameters in /etc/ngcp-config/config.yml file (shown below with default values of parameters):
kamailio:
lb:
security:
topoh:
enable: no
mask_callid: no
mask_ip: 127.0.0.8
Any valid, preferably private network address can be used. The suggestion is however
TIP to use an address that is not used by any other SIP endpoint or intermediary element
in the network.
Although masking sensitive information about a VoIP provider’s network is desired, there are some
potential side effects caused by topology masking.
The most common example is the consequence that SIP message size may grow when applying
topology masking. The fact that SIP messages become larger may even prevent Sipwise C5 from
communicating successfully with another SIP entity (a peer SBC, for example). This can be expected
under following circumstances:
In such a case the IP packets carrying SIP messages with encoded headers will have a size exceeding
the MTU, that will cause loss of data in some networks.
The recommended solution in such a case is to use TCP transport for SIP messages.
This mechanism offers some benefits over the older topology masking approach:
• It enables the Sipwise C5 to interconnect with SIP endpoints that are not capable of operating
through a SIP proxy.
• The message size is decreased because of stripping the SIP Record-Route, Route and Via header
fields.
• It solves the interoperability issues with SIP ALG in some cases.
• It retains also the lightweight nature and the efficient operation.
The module uses the auto-expiration of the Redis keys so it can cause temporary spikes in the memory
usage and redis keys count until produced data is cleaned up by redis.
Activation of the topology hiding function is done through the modification of the following
configuration parameters in /etc/ngcp-config/config.yml file (shown below with default values of
parameters):
topos:
enable: no
redis_db: 24
In order to activate the function, you should set enable: 'yes' in /etc/ngcp-config/config.yml and leave
the Redis DB number unchanged, then execute ngcpcfg apply "activated topos".
If you have performance issues with regards to disk I/O please consider enabling the
NOTE 'noatime' mount option for the root filesystem. Sipwise recommends the usage of
'noatime', though remove it if you use software which conflicts with its presence.
In this section some parameters will be explained to allow Sipwise C5 administrator tune the system
requirements for optimum performance.
In case of using virtualized environment with limited amount of hardware resources, you
TIP can use the script ngcp-toggle-performance-config to adjust Sipwise C5 configuration for
high/low performance:
root@spce:~# /usr/sbin/ngcp-toggle-performance-config
/usr/sbin/ngcp-toggle-performance-config - tool to adjust Sipwise C5
configuration for low/high performance
root@spce:~#
12.10. Troubleshooting
The Sipwise C5 platform provides detailed logging and log files for each component included in the
system via rsyslog. The main folder for log files is /var/log/ngcp/, it contains a list of self explanatory
log files named by component name.
The Sipwise C5 is a high performance system which requires compromise between traceability
(maximum amount of debug information being written to hard drive) and productivity (minimum load on
IO subsystem). This is the reason why different log levels are configured for the provided components
by default.
Most log files are designed for debugging Sipwise C5 by Sipwise operational team while main log files
for daily routine usage are:
it is highly NOT recommended to change default log levels as it can cause system
WARNING
IO overloading which will affect call processing.
the exact size of log files depend on system type, system load, system health status
and system configuration, so cannot be estimated with high precision. Additionally
NOTE
operational network parameters like ASR and ALOC may impact the log files' size
significantly.
The above line shows the SIP information you can find in a general line contained in
/var/log/ngcp/kamailio-*:
In order to collect the full log related to a single call, it’s necessary to "grep" the
/var/log/ngcp/kamailio-proxy.log using the ID= string, for example:
# grep "[email protected]"
/var/log/ngcp/kamailio-proxy.log
# ngrep-sip b
# man ngrep-sip
The ngrep debian tool can be used in order to make a SIP trace and save it into a .pcap file :
The sngrep debian graphic tool as well can be used to visualize SIP trace and save them in a .pcap file :
# sngrep
The platform uses various monitoring backend services to monitor many aspects of the system,
including CPU, memory, swap, disk, filesystem, network, processes, NTP, Nginx, Redis and MySQL.
The gathered information is stored in VictoriaMetrics which is a long-term storage backend for
Prometheus. NOTE: Both VictoriaMetrics and Prometheus can act as the prometheus server
implementation, and are mutually exclusive in their execution.
The gathered information is stored in VictoriaMetrics in the ngcp namespace on its time-series database.
Some of the data gathering can be disabled (most are enabled by default) through the
config.yml file, and those data points will then either be missing from the database or be
TIP initialized with a stub value. This will then cascade into other subsystems using this
monitoring information, such as Grafana dashboards. The enable/disable flags can be
found in the witnessd.gather section.
The monitoring data can also be accessed directly by various means. On new installations by using the
promtool command-line tool; or by using the HTTP API with curl (or other HTTP fetchers), or with the
NGCP::Prometheus::HTTP perl module.
Monitoring metrics
See Prometheus monitoring metrics for detailed information about the list of ngcp namespaced metrics
stored in the Prometheus monitoring database.
PromQL
To get the list of all metrics for a specific namespace the following query can be used
TIP
{__name__=~"^namespace_.+"}.
The anonymous usage statistics is enabled by default but you can disable it. In order to do that you
have to edit the main configuration file '/etc/ngcp-config/config.yml' and set
general.anonymous_usage_statistics parameter to no. Then apply the new configuration with
the usual command: ngcpcfg apply "Disabled anon. usage stat"
If Sipwise C5 operator does not want to have the license client package (ngcp-license-
client and ngcp-license-module) on his system at all, it is possible to replace it with a
TIP
dummy package: ngcp-license-client-dummy. This dummy package does not contain
any licensing software, and is available from mr5.5.2 Sipwise C5 release.
The new CSC UI is technically a Single Page Application, that is fully client side rendered and builds on
top of the NCGP REST API as part of a Service Oriented Architecture. The new CSC UI source code is
published under a GPL license on https://github.com/sipwise/ngcp-csc-ui and can be used as an
example for the customised CSC UI development if necessary (using the same REST API methods).
NOTE it is impossible to have both new and old CSC UI enabled simultaneously.
As an operator (as well as a Reseller), you can change the branding logo of the Customer Self-Care
(CSC) panel and the available languages on the CSC panel. This is possible via the admin web interface.
For changing the branding logo on a reseller’s admin web page and on the CSC panel you need to
access the web interface as Administrator and navigate to Reseller menu. Once there click on the
Details button for your selected reseller, finally select Branding.
In order to do the same as Reseller, login on the admin web interface with the reseller’s web
credentials, then access the Panel Branding menu.
7. Now the new logo is already visible on the admin / CSC panel. If you want to hide the Sipwise
copyright notice at the bottom of the web panels, add a line of CSS code as shown here:
The layout and style of NGCP’s admin and CSC web panel is determined by a single CSS file:
/usr/share/ngcp-panel/static/css/application.css
More complex changes, like replacing colour of some web panel components, is possible via the
modification of the CSS file.
Only experienced users with profound CSS knowledge are advised to change web
WARNING panel properties in the main CSS file. Sipwise does not recommend and also does
not support the modification of the main CSS file.
You can also enable/disable specific languages a user can choose from in the CSC panel. Currently,
English (en), German (de), Italian (it) and Spanish (es) are supported, and the default language is the
same as the browser’s preferred one.
You can select the default language provided by CSC by changing the parameter
www_admin.force_language in /etc/ngcp-config/config.yml file. An example to set the English
language as default:
The CSC panel allows your users to listen to voicemail messages from the web browser, delete them
and call back the user who left the voice message. User can setup voicemail forwarding to the external
email and the PIN code needed to access the voicebox from any telephone also from the CSC panel.
To manage the voice messages from SIP phone: dial internal voicemail access number 2000.
To change the access number: look for the parameter voicemail_number in /etc/ngcp-
config/config.yml in the section sems→vsc. After the changes, execute ngcpcfg apply 'changed voicebox
number'.
To let the callers leave a voice message when user is not available he should enable Call
Forward to Voicebox. The Call Forward can be provisioned from the CSC panel as well as
by dialing Call Forward VSC with the voicemail number. E.g. when parameter
TIP
voicemail_number is set to 9999, a Call Forward on Not Available to the Voicebox is set if
the user dials *93*9999. As a result, all calls will be redirected to the Voicebox if SIP
phone is not registered.
• As an operator, you can setup some DID number as external voicemail access number: for that, you
should add a special rewrite rule (Inbound Rewrite Rule for Callee, see Configuring Rewrite Rule
Sets.) on the incoming peer, to rewrite that DID to "voiceboxpass". Now when user calls this number
the call will be forwarded to the voicemail server and he will be prompted for mailbox and
password. The mailbox is the full E.164 number of the subscriber account and the password is the
PIN set in the CSC panel.
• The user can also dial his own number from PSTN, if he setup Call Forward on Not Available to the
Voicebox, and when reaching the voicemail server he can interrupt the "user is unavailable"
message by pressing '*' key and then be prompted for the PIN. After entering PIN and confirming
with '#' key he will enter own voicemail menu. PIN is random by default and must be kept secret for
that reason.
The subsection "Company Hours" under the CSC UI "Call Forward" allows the user to specify Call
Forwarding Rules for a specific period of time. The time defined in this subsection represents the office
hours of the company. The first step is to define the actual days and the according times. Each time
entry consists of day, start-time, and end-time. You can define multiple times for the same day, to get a
different behavior with the breaks and the office hours. If the current times are not in one of the defined
periods, the system falls back to the subsection "Always". Specific dates or date ranges can not be
defined. The functionality is limited to weekdays and its timing.
The feature "Company Hours" is a virtual Sipwise C5 function which is based on Sipwise C5 core
functionality Subscribers "Unconditional Call Forwarding" which is enhanced with the "Time sets" and
"Sounds set" to achieve the necessary functionality.
The feature "Company Hours" can be managed using REST API methods CFDestinationSet, CFMapping,
CFSourceSet and CFTimeSet. Please check all available options for those methods in a public REST API
documentation.
The Sipwise C5 provides a REST API to provision various functionality of the platform. The entry point -
and at the same time the official documentation - is at https://<your-ip>:1443/api. It allows both
administrators and resellers (in a limited scope) to manage the system.
You can either authenticate via username and password of your administrative account you’re using to
access the admin panel, or via SSL client certificates. Find out more about client certificate
authentication in the online API documentation.
The boiler-plate to access the REST API is described in the online API documentation at /api/#auth. A
simple example in Perl using password authentication looks as follows:
#!/usr/bin/perl -w
use strict;
use v5.10;
use LWP::UserAgent;
use JSON qw();
my $uri = 'https://ngcp.example.com:1443';
my $ua = LWP::UserAgent->new;
my $user = 'myusername';
my $pass = 'mypassword';
$ua->credentials('ngcp.example.com:1443', 'api_admin_http', $user,
$pass);
my ($req, $res);
For each customer you create, you need to assign a billing profile id. You either have the ID stored
somewhere else, or you need to fetch it by searching for the billing profile handle.
my $billing_profile_handle = 'my_test_profile';
$req = HTTP::Request->new('GET',
"$uri/api/billingprofiles/?handle=$billing_profile_handle");
$res = $ua->request($req);
if($res->code != 200) {
die "Failed to fetch billing profile: ".$res->decoded_content."\n";
}
my $billing_profile = JSON::from_json($res->decoded_content);
my $billing_profile_id = $billing_profile->{_embedded}-
>{'ngcp:billingprofiles'}->{id};
say "Fetched billing profile, id is $billing_profile_id";
A customer is mainly a billing container for subscribers without a real identification other than the
external_id property you might have stored somewhere else (e.g. the ID of the customer in your CRM).
To still easily identify a customer, a customer contact is required. It is created using the
/api/customercontacts/ resource.
To get the ID of the recently created resource, you need to parse the Location
header. In future, this approach will be changed for POST requests. The response
IMPORTANT
will also optionally return the ID of the resource. It will be controlled via the
Prefer: return=representation header as it is already the case for PUT and PATCH.
The example above implies the fact that you access the API via a reseller user. If
WARNING you are accessing the API as the admin user, you also have to provide a reseller_id
parameter defining the reseller this contact belongs to.
Once you have created the customer contact, you can create the actual customer.
Once you have created the customer, you can add subscribers to it. One customer can hold multiple
subscribers, up to the max_subscribers property which can be set via /api/customers/. If this property is
not defined, a virtually unlimited number of subscribers can be added.
A domain must exist before creating a subscriber. You can create the domain via
IMPORTANT
/api/domains/.
At that stage, the subscriber can connect both via SIP and XMPP, and can be reached via the primary
number, all alias numbers, as well as via the SIP URI.
If you want to set call forwards for the subscribers, then perform an API call as follows.
$req = HTTP::Request->new('PUT',
"$uri/api/callforwards/$subscriber_id");
$req->header('Content-Type' => 'application/json');
$req->header('Prefer' => "return=minimal"); # use return=representation
to get full json response
$req->content(JSON::to_json({
cfna => { # set a call-forward if subscriber is not registered
destinations => [
{ destination => "4366610001", timeout => 10 }, # ring this
for 10s
{ destination => "4366710001", timeout => 300 }, # if no
answer, ring that for 300s
],
times => undef # no time-based call-forward, trigger cfna always
}
}));
$res = $ua->request($req);
if($res->code != 204) { # if return=representation, it's 200
die "Failed to set cfna for subscriber: ".$res-
>decoded_content."\n";
}
You can set cfu, cfna, cfb, cft, cfs, cfr and cfo via this API call, also all at once. Destinations can be
hunting lists as described above or just a single number. Also, a time set can be provided to trigger call
forwards only during specific time periods.
To provision certain features of a subscriber, you can manipulate the subscriber preferences. You can
find a full list of preferences available for a subscriber at /api/subscriberpreferencedefs/.
$req = HTTP::Request->new('GET',
"$uri/api/subscriberpreferences/$subscriber_id");
$res = $ua->request($req);
if($res->code != 200) {
die "Failed to fetch subscriber preferences: ".$res-
>decoded_content."\n";
}
my $prefs = JSON::from_json($res->decoded_content);
delete $prefs->{_links}; # not needed in update
Modifying numbers assigned to a subscriber, changing the password, locking a subscriber, etc. can be
done directly on the subscriber resource.
At the end of a subscriber life cycle, it can be terminated. Once terminated, you can NOT recover the
subscriber anymore.
$req = HTTP::Request->new('DELETE',
"$uri/api/subscribers/$subscriber_id");
$res = $ua->request($req);
if($res->code != 204) {
die "Failed to terminate subscriber: ".$res->decoded_content."\n";
}
say "Terminated subscriber";
Note that certain information is still available in the internal database to perform billing/rating of calls
done by this subscriber. Nevertheless, the data is removed from the operational tables of the database,
so the subscriber is not able to connect to the system, login or make calls/chats.
Resources modification can be done via the GET/PUT combination. Alternatively, you can add, modify
or delete single properties of a resource without actually fetching the whole resource. See an example
below where we terminate the status of a customer using the PATCH method.
1. An HTTP timeout at the gateway may occur. The default timeout limit is set to 60s. You can change
it by creating a patchtt file for the following template: /etc/ngcp-config/templates/etc/nginx/sites-
available/ngcp-panel_admin_api.tt2.
2. Other parts of the system might become unresponsive due to mysql table locks. This especially
applies to endpoints related to the Customers entity.
Appendix
Appendix A: Corosync/Pacemaker
The Corosync/Pacemaker pair is the successor of the long obsolete and unsupported Heartbeat v2
software package. While Heartbeat v2 was playing the role of both the Group Communication System
(GCS) and the Cluster Resource Manager (CRM), these roles are split under the new system. Corosync
is the GCS and in charge of communication, while Pacemaker sits on top of the GCS and plays the role
of the CRM, managing the resources and responding to changes in the cluster status.
Migration
An existing cluster under Heartbeat v2 can be migrated to Corosync/Pacemaker using the script ngcp-
migrate-ha-crm. This script automates the following steps:
The script must be run on the standby node, and the steps described above are first performed locally
(on the standby node), followed by the node’s peer (the active node). This is to minimise resource
downtime.
Switching the values of ha.gcs or ha.crm is not enough to actually effect any
CAUTION change. These values are merely reflective of which software is installed and must
not be modified without also altering the underlying software.
The migration needs to be run on non-migrated pairs of nodes, from the standby node of each pair, and
the services need to be all in a good state (from 'ngcp-service summary' point of view). The program
will perform these sanity checks before making it possible to proceed. The user will also be prompted
for confirmation, which can be skipped for non-interactive use with the FORCE environment variable.
For a Carrier system the configuration settings will be set per pair, so that it does not affect the entire
cluster. Once the whole cluster has been migrated these configuration files should be merged into the
global one. If the switch does not need to be staged, then the 'ngcp-parallel-ssh(8)' command can help
with that, with its inactive host selector, such as 'ngcp-parallel-ssh inactive "FORCE=yes ngcp-migrate-
ha-crm"'.
Rollback
Rollback can be done by using ngcp-migrate-ha-crm --rollback, which involves reversing the
steps outlined above: Removal or corosync and pacemaker, installation of the downloaded
heartbeat-2 Debian package, and reverting ha.gcs and ha.crm to their previous values
heartbeat-2.
Corosync
Corosync is the Group Communication System (GCS). Its configuration resides in
/etc/corosync/corosync.conf and describes the following details:
Quorum
Corosync uses a voting system to determine the state of the cluster. Each configured node in the
cluster receives one vote. A quorum is defined as a majority presence within the cluster, meaning at
least 50% of the configured nodes plus one, or q = n / 2 + 1. For example, if 8 nodes were
configured, a quorum would be present if at least 5 nodes are communicating with each other. In this
state, the cluster is said to be quorate, which means it can operate normally. (Any remaining nodes, 3 in
the worst case, would see the cluster as inquorate and would relinquish all their resources.)
A two-node cluster is a special case as under the formula above, a quorum would consist of 2
functioning nodes. The Corosync config setting two_node: 1 overrides this and artificially sets the
quorum to 1. This means that under a split-brain scenario (each node seeing only 1 vote), both nodes
would see the cluster as quorate and try to become active, instead of both nodes going standby.
In addition to this, Pacemaker itself also uses an internal scoring system for individual resources. This
mechanism is described below and not directly related to the quorum.
Pacemaker
Pacemaker uses the communication service provided by Corosync to manage local resources. All
status and configuration information is shared between all Pacemaker instances within the cluster as
long as communication is up. This means that any configuration change done on any node will
immediately and automatically be propagated to all other nodes in the cluster.
Pacemaker internally uses an XML document to store its configuration, called "CIB" stored in
/var/lib/pacemaker/cib/cib.xml. However, this XML document must never be edited or
modified directly. Instead, a shell-like interface crm is provided to talk to Pacemaker, query status
information, alter cluster state, view and modify configuration, etc. Any configuration change done
through crm is immediately reflected in the CIB XML, locally as well as on all other nodes.
As an added bonus, to make things more awkward, the syntax used by crm is not XML at all, but rather
uses a Cisco-like hierarchy.
Commands can be issued to crm either directly from the shell as command-line arguments, or
interactively by entering a Cisco-like shell. So for example, the current config can be viewed either from
the shell with:
Or interactively, as either:
root@sp1:~# crm
crm(live/sp1)# config
crm(live/sp1)configure# show
...
or
root@sp1:~# crm
crm(live/sp1)# config show
...
Interactive online help is provided by the ls command to list commands valid in the current context, or
using the help command for a more verbose help output.
Query Status
The current cluster status can be viewed with the top-level status command:
crm(live/sp1)# status
Stack: corosync
Current DC: sp2 (version unknown) - partition with quorum
Last updated: Fri Nov 22 18:38:06 2019
Last change: Fri Nov 22 18:25:28 2019 by hacluster via crmd on sp1
2 nodes configured
7 resources configured
If the status is queried from sp2 instead, the output will be the same. Most importantly, the resources
will not show up as "stopped" on sp2 but instead will be reported as running on sp1.
Config Management
The NGCP templates do not operate on Pacemaker’s CIB XML directly, but instead produce a file in
CRM syntax in /etc/pacemaker/cluster.crm. This file is not handled by Pacemaker directly, but
instead is loaded into Pacemaker via the crm command config load replace. It shouldn’t be
necessary to do this manually, as the script ngcp-ha-crm-reload handles this automatically, which is
called from the config file’s postbuild script.
Changes to the config don’t need to be saved explicitly. This is done automatically by Pacemaker, as
well as sharing any changes with all other members of the cluster.
In crm, changes made to the config are cached until made active with commit, or discarded with
refresh. Changes to resource status can be avoided by enabling maintenance mode (see below).
However, since our config is loaded from a template, any changes done to the
IMPORTANT config through crm manually are transient and will be lost the next time a config
reload happens.
The currently active config can be shown with config show and should be logically identical to the
contents of /etc/pacemaker/cluster.crm:
General Concepts
• The configuration consists of a collection of objects of various types with various attributes.
• Each object has a unique identifying name that can be used to refer to it.
• Usually the type of the object is the first word and the identifying name is the second. For example,
clone c_ping p_ping defines a clone type object with the name c_ping.
• The unique name is used e.g. when deleting an object (config del …), when starting or stopping a
resource, when referring to resources from a group, etc.
Resources
Resources are the primary type of objects that Pacemaker handles. A resource is anything that can be
started or stopped, and a resource is normally allowed to run on one node only. A resource is defined
as a primitive type object.
Pacemaker supports many types of resources, all of which have different options that can be given to
them. The config syntax defines that options given to a resource itself are prefixed with params, while
options that influence how a resource should be managed are prefixed with meta. Options that are
relevant to operations that can be performed on a resource are prefixed with op.
Resources are grouped into classes, providers, and types. Details about them (e.g. which options they
support) can be obtained through the ra menu.
Shared IP Addresses
This defines a resource of type IPaddr with name p_vip_eth1_v4_1 and the given parameters
(address, netmask, interface). Pacemaker will check for the existence of the address every 5 seconds,
with an action timeout of 60 seconds. If the monitor action fails, the resource is restarted.
System Services
While Pacemaker has support for native systemd services, for the time being we’re still relying on monit
to manage our services. Therefore, services are defined in Pacemaker virtually identical to how they
were defined in Heartbeat v2, through a monit-services start/stop script. The old Heartbeat script
was /etc/ha.d/resource.d/monit-services and the new script used by Pacemaker is
/etc/ngcp-ocf/monit-services.
The primary difference between the two scripts is the support for a monitor action for
Pacemaker, which can be configured via the config.yml variable
ha.monitor_services. It can be set to 'full' to periodically use the output of ngcp-
NOTE
service summary to determine whether all services are running or not. The default
value is 'none', which preserves backwards compatibility with the behavior of Heartbeat
v2, by performing no periodic checks of the status of the services.
• meta migration-threshold=20 means that the resource will be migrated away (instead of
restarted) after 20 failures. See the discussion on failure counts below.
• meta failure-timeout=800 means that the failure count should be reset to zero if the last failure
occurred more than 800 seconds ago. (However, the actual timer depends on the cluster-
recheck-interval.)
• Run the monitor action every 20 seconds with a timeout of 60 seconds and restart the resource on
failure.
Ping Nodes
The builtin pingd service, using a resource name that intelligently is not named pingd but rather ping,
replaces Heartbeat’s ping nodes. It supports multiple ping backends, and uses fping by default.
Each configured ping node (each entry in host_list) produces a score of 1 if that ping node is up. The
scores are summed up and multiplied by the multiplier. So in the example above, a score of 2000 is
generated if both ping nodes are up. Pacemaker will then prefer the node which produces the higher
score.
• dampen=5s means to wait 5 seconds after a change occurred to prevent transient glitches from
causing service flapping.
• Other options are the same as described above.
Fencing/STONITH
Pacemaker will generate a warning if no fencing mechanism is configured, therefore we configure the
null fencing mechanism.
Pacemaker supports several proper fencing mechanism and these might eventually get supported in
the future.
Groups
To manage, control, and restrict multiple resources at the same time, resources can be grouped into
single objects. The group g_ngcp is pointless for the time being (it contains only a single other
resource) but will become useful once native systemd resources are in use. The group g_vips ensures
that all shared IP addresses are active at the same time.
Clones
Since a single resource normally only runs on one node, a clone can be defined to allow a resource to
run on all nodes. We want the pingd service and the fencing service to always run on all nodes.
Constraints
This tells Pacemaker that we want to force the g_ngcp resource on the same node that is running the
g_vips resource.
This tells Pacemaker that these resources depend on the pingd service being healthy. If pingd fails on
one node (ping nodes are unavailable), then Pacemaker will shut down the constrained resources.
This tells Pacemaker that the shared IP addresses must be up and running before the system services
can be started.
Cluster Options
property cib-bootstrap-options: \
have-watchdog=false \
cluster-infrastructure=corosync \
cluster-name=sp \
stonith-enabled=yes \
no-quorum-policy=ignore \
startup-fencing=yes \
maintenance-mode=false \
last-lrm-refresh=1574443528
Failure Counts
Pacemaker keeps a failure count for each resource, which is somewhat hidden from view, but can
largely influence its behaviour. Each time a service fails (either during runtime or during startup), the
failure count is increased by one. If the failure count exceeds the configured migration-threshold,
Pacemaker will cease trying to start the service and will migrate the service away to another node. In
crm status this shows up as stopped.
Failure counts can be cleared automatically if the failure-timeout setting is configured for a
resource. This timeout is counted after the last time the resource has failed, and is checked periodically
according to the cluster-recheck-interval. In other words, a very short failure timeout won’t have
any effect unless the recheck interval is also very short.
The failure count for a resource can be checked from the shell via crm_failcount, for example:
root@sp1:~# ngcp-ha-show-failcounts
p_vip_eth1_v4_1:
sp1: 0
sp2: 0
p_vip_eth2_v4_1:
sp1: 0
sp2: 0
p_monit_services:
sp1: 0
sp2: 0
Analogous to checking a failure count, it can be cleared using any one of these methods:
In addition, the crm command resource cleanup also resets failure counts.
Resource Scores
Pacemaker uses an internal scoring system to determine which resources to run where. A resource will
be run on the node on which it received the highest score. If a resource has a negative score, that
resource will not be run at all. If a resource has the same score on multiple nodes, then the resource
will be run on any one of those nodes. Scores can be calculated and acted upon through various config
settings.
A score value of infinity (and negative infinity) to force certain states is provided, which evaluates to
not infinity at all, but rather to a static value of one million. This can be used to artificially manipulate
resource scores to force running a resource on a particular node, or forbid a resource from running on
particular nodes.
Common Tasks
The commands ngcp-make-active and ngcp-make-standby work normally. Under Pacemaker, they
function through the crm command resource move to create a temporary location constraint on
g_vips. This can be done manually through:
The lifetime of 30 seconds is needed because g_ngcp depends on the location of g_vips, and
therefore g_ngcp needs to be stopped before g_vips can be stopped. The location constraint must
remain active until g_ngcp has been completely and successfully stopped.
These commands only effect the status of the running resources, and not the status of
the node itself. This means that after going standby, Pacemaker will immediately be
NOTE
ready to take over the resources again if needed. See below for a discussion on node
status.
Similarly, ngcp-check-active uses the output of crm resource status g_vips to determine
whether the local node is active or not.
In addition to the status and location of individual resources, nodes themselves can also go into
standby mode. The submenu node in crm has the relevant options.
A node in standby mode will not only give up all of its resources, but will also refuse to take them over
until it’s back online. Therefore, it’s possible to set both nodes to standby mode and shut down all
resources on both nodes.
A node in standby mode will still participate in GCS communications and remain visible
NOTE
to the rest of the cluster.
Use crm node standby to set the local node to standby mode. A remote node can be set to standby
By default, the standby mode remains active until it’s cancelled manually (a lifetime of forever).
Alternatively, a lifetime of reboot can be specified to tell Pacemaker that after the next reboot, the
node should automatically come back online. Example: crm node standby sp2 reboot
To cancel standby mode, use crm node online, optionally followed by the node name.
To show the current status of all nodes, use crm node show. The top-level crm status also shows
this.
Maintenance Mode
If Pacemaker’s maintenance mode is enabled, it will continue to operate normally, i.e. continue to run
and monitor resources, but will refuse to stop or start any resources. This is useful to make changes to
the running config, and is done automatically by ngcp-ha-crm-reload.
crm maintenance on
crm maintenance off
CLI Alternatives
Several of the commands available through crm are also available through standalone CLI tools, such
as crm_failcount, crm_standby, crm_resource, etc. They generally have less friendly syntax and
so researching them is left as an exercise to the reader.
Sipwise C5 performs the following checks when processing a call coming from a subscriber and
terminated at a peer:
• Checks if the IP address where the request came from is in the list of trusted IP addresses. If yes,
this IP address is taken as the identity for authentication. Otherwise, Sipwise C5 performs the digest
authentication.
• When the subscriber is authorized to make the call, Sipwise C5 applies the Inbound Rewrite Rules
for the caller and the callee assigned to the subscriber (if any). If there are no Rewrite Rules
assigned to the subscriber, the ones assigned to the subscriber’s domain are applied. On this stage
the platform normalises the numbers from the subscriber’s format to E.164.
• Matches the callee (called number) with local subscribers.
◦ If it finds a matching subscriber, the call is routed internally. In this case, Sipwise C5 applies the
Outbound Rewrite Rules associated with the callee (if any). If there are no Rewrite Rules
assigned to the callee, the ones assigned to the callee’s domain are applied.
◦ If it does not find a matching subscriber, the call goes to a peer as described below.
• Queries the LNP database to find out if the number was ported or not.For details of LNP queries
refer to the Local Number Porting chapter.
◦ If it was ported, Sipwise C5 applies the LNP Rewrite Rules to the called number.
• Based on the priorities of peering groups and peering rules (see Routing Order Selection for details),
Sipwise C5 selects peering groups for call termination and defines their precedence.
• Within every peering group the weight of a peering server defines its probability to receive the call
for termination. Thus, the bigger the weight of a server, the higher the probability that Sipwise C5
will send the call to it.
• Applies the Outbound Rewrite Rules for the caller and the callee assigned to a peering server when
Endpoint Registration
The subscriber endpoint starts sending a REGISTER request, which gets challenged by a 401. After
calculating the response of the authentication challenge, it sends the REGISTER again, including the
authentication response. The SIP proxy looks up the credentials of the subscriber in the database,does
the same calculation, and if the result matches the one from the subscriber, the registration is granted.
The SIP proxy writes the content of the Contact header (e.g. sip:[email protected]:1234;transport=UDP) into its
location table (in case of NAT the content is changed by the SIP load-balancer to the IP/port from
where the request was received), so it knows where to reach a subscriber in case on an inbound call to
this subscriber (e.g. sip:[email protected] is mapped to sip:[email protected]:1234;transport=UDP and
sent out to this address).
If NAT is detected, the SIP proxy sends a OPTIONS message to the registered contact every 30
seconds, in order to keep the NAT binding on the NAT device open. Otherwise, for subsequent calls to
this contact, Sipwise C5 wouldn’t be able to reach the endpoint behind NAT (NAT devices usually drop
a UDP binding after not receiving any traffic for ~30-60 seconds).
By default, a subscriber can register 5 contacts for an Address of Record (AoR, e.g.
sip:[email protected]).
Basic Call
The calling party sends an INVITE (e.g. sip:[email protected]) via the SIP load-balancer to the SIP
proxy. The proxy replies with an authorization challenge in the 407 response, and the calling party
sends the INVITE again with authentication credentials. The SIP proxy checks if the called party is a
local user. If it is, and if there is a registered contact found for this user, then (after various feature-
related tasks for both the caller and the callee) the Request-URI is replaced by the URI of the registered
contact (e.g. sip:[email protected]:1234;transport=UDP). If it’s not a local user but a numeric user, a proper PSTN
gateway is being selected by the SIP proxy, and the Request-URI is rewritten accordingly (e.g.
sip:[email protected]:5060).
Once the proxy has finished working through the call features of both parties involved and has selected
the final destination for the call, and - optionally - has invoked the Media Relay for this call, the INVITE is
sent to the SIP B2BUA. The B2BUA creates a new INVITE message from scratch (using a new Call-ID
and a new From-Tag), copies only various and explicitly allowed SIP headers from the old message to
the new one, filters out unwanted media capabilities from the SDP body (e.g. to force audio calls to use
G.711 as a codec) and then sends the new message back to the SIP proxy that forwards it to the SIP
load-balancer to reach to the called party.
SIP replies from the called party are passed through the elements back to the calling party (replacing
various fields on the B2BUA to match the first call leg again). If a reply with an SDP body is received by
the SIP proxy (e.g. a 183 or a 200), the Media Relay is invoked again to prepare the ports for the media
stream.
Once the 200OK is routed from the called party to the calling party, the media stream is fully
negotiated, and the endpoints can start sending traffic to each other (either end-to-end or via the Media
Relay). Upon reception of the 200OK, the SIP proxy writes a start record for the accounting process. The
200OK is also acknowledged with an ACK message from the calling party to the called party, according
to the SIP 3-way handshake.
Either of the parties can tear down the media session at any time by sending a BYE, which is passed
through to the other party. Once the BYE reaches the SIP proxy, it instructs the Media Relay to close the
media ports, and it writes a stop record for accounting purposes. Both the start- and the stop-records
are picked up by the ngcp-mediator service in a regular interval and are converted into a Call Detail
Record (CDR), which will be rated by the ngcp-rate-o-mat process and can be billed to the calling party.
Session Keep-Alive
The SIP B2BUA acts as refresher for the Session-Timer mechanism as defined in RFC 4028. If the
endpoints indicate support for session timers during call-setup, then the SIP B2BUA will use an
UPDATE or re-INVITE message if enabled per peer, domain or subscriber via Provisioning to check if
the endpoints are still alive and responsive. Both endpoints can renegotiate the timer within a
configurable range. All values can be tuned using the Admin Panel or the APIs using Peer-, Domain-
and Subscriber-Preferences.
Keep in mind that the values being used in the signaling are always half the value being
TIP configured. So if you want to send a keep-alive every 300 seconds, you need to provision
sst_expires to 600.
If one of the endpoints doesn’t respond to the keep-alive messages or answers with 481
Call/Transaction Does Not Exist, then the call is torn down on both sides. This mechanism prevents
excessive over-billing of calls if one of the endpoints is not reachable anymore or "forgets" about the
call. The BYE message sent by the B2BUA triggers a stop-record for accounting and also closes the
media ports on the Media Relay to stop the call.
Beside the Session-Timer mechanism to prevent calls from being lost or kept open, there is a
maximum call length of 21600 seconds per default defined in the B2BUA. This is a security/anti-fraud
mechanism to prevent overly long calls causing excessive costs.
Voicebox Calls
Calls to the Voicebox (both for callers leaving a voicemail message and for voicebox owners managing
it via the IVR menu) are passed directly from the SIP proxy to the App-Server without a B2BUA. The
App-Server maintains its own timers, so there is no risk of over-billing or overly long calls.
In such a case where an endpoint talks via the Media Relay to a system-internal endpoint, the Media
Relay bridges the media streams between the public in the system-internal network.
In case of an endpoint leaving a new message on the voicebox, the Message-Waiting-Indication (MWI)
mechanism triggers the sending of a unsolicited NOTIFY message, passing the number of new
messages in the body. As soon as the voicebox owner dials into his voicebox (e.g. by calling
sip:[email protected] from his SIP account), another NOTIFY message is sent to his devices,
resetting the number of new messages.
The Sipwise C5 does not require your device to subscribe to the MWI service by
sending a SUBSCRIBE (it would rather reject it). On the other hand, the endpoints
IMPORTANT
need to accept unsolicited NOTIFY messages (that is, a NOTIFY without a valid
subscription), otherwise the MWI service will not work with these endpoints.
apps
This section contains parameters for the additional applications that may be activated on Sipwise C5.
apps:
malicious_call: no
• malicious_call: If set to 'yes', the Malicious Call Identification (MCID) application will be enabled.
asterisk
asterisk:
log:
facility: local6
rtp:
maxport: 20000
minport: 10000
sip:
bindport: 5070
dtmfmode: rfc2833
voicemail:
enable: no
fromstring: 'Voicemail server'
greeting:
busy_custom_greeting: '/home/user/file_no_extension'
busy_overwrite_default: no
busy_overwrite_subscriber: no
unavail_custom_greeting: '/home/user/file_no_extension'
unavail_overwrite_default: no
unavail_overwrite_subscriber: no
mailbody: 'You have received a new message from ${VM_CALLERID} in
voicebox ${VM_MAILBOX} on ${VM_DATE}.'
mailsubject: '[Voicebox] New message ${VM_MSGNUM} in voicebox
${VM_MAILBOX}'
max_msg_length: 180
maxgreet: 60
maxmsg: 30
maxsilence: 0
min_msg_length: 3
normalize_match: '^00|\+([1-9][0-9]+)$'
normalize_replace: '$1'
serveremail: [email protected]
autoprov
autoprov:
hardphone:
skip_vendor_redirect: no
server:
bootstrap_port: 1445
ca_certfile: '/etc/ngcp-config/ssl/client-auth-ca.crt'
host: localhost
port: 1444
server_certfile: '/etc/ngcp-config/ssl/myserver.crt'
server_keyfile: '/etc/ngcp-config/ssl/myserver.key'
ssl_enabled: yes
softphone:
config_lockdown: 0
webauth: 0
• autoprov.skip_vendor_redirect: Skip phone vendor redirection to the vendor provisioning web site.
sems-b2b (some paramenters are only used with additional Cloud PBX module activated)
b2b:
bindport: 5080
dialog_publish_expires: 3600
enable: yes
highport: 19999
lowport: 15000
media_processor_threads: 10
moh_codecs:
codecs_list: PCMA,PCMU,telephone-event
enable: no
mode: whitelist
permit_ext_dial_when_no_prompt_exists: no
session_processor_threads: 10
xmlrpcport: 8090
backuptools
backuptools:
cdrexport_backup:
enable: no
etc_backup:
enable: no
mail:
address: [email protected]
error_subject: '[ngcp-backup] Problems detected during daily backup'
log_subject: '[ngcp-backup] Daily backup report'
send_errors: no
send_log: no
mysql_backup:
enable: no
exclude_dbs: 'syslog sipstats information_schema'
replicas:
peer: yes
mgmt: no
rotate_days: 7
storage_dir: '/ngcp-data/backup/ngcp_backup'
temp_backup_dir: '/ngcp-data/backup/ngcp_backup/tmp'
cdrexport
cdrexport:
daily_folder: yes
export_failed: no
export_incoming: no
export_nodes:
roles:
- mgmt
hosts:
exportpath: '/home/jail/home/cdrexport'
full_names: yes
monthly_folder: yes
• cdrexport.daily_folder: Set 'yes' if you want to create a daily folder for CDRs under the configured
path.
• cdrexport.export_failed: Export CDR for failed calls.
• cdrexport.export_incoming: Export CDR for incoming calls.
• cdrexport.export_nodes: Export CDRs to specific nodes based on role or hostnames.
• cdrexport.exportpath: The path to store CDRs in .csv format.
• cdrexport.full_names: Use full namen for CDRs instead of short ones.
• cdrexport.monthly_folder: Set 'yes' if you want to create a monthly folder (ex. 201301 for January
2013) for CDRs under configured path.
cleanuptools
cleanuptools:
acc_cleanup_days: 90
archive_targetdir: '/ngcp-data/backups/cdr'
binlog_days: 15
cdr_archive_months: 2
cdr_backup_months: 2
cdr_backup_retro: 3
compress: gzip
delete_old_cdr_files:
enable: no
max_age_days: 30
paths:
-
max_age_days: ~
path: '/home/jail/home/*/20[0-9][0-9][0-9][0-9]/[0-9][0-9]'
remove_empty_directories: yes
wildcard: yes
-
max_age_days: ~
path: '/home/jail/home/cdrexport/resellers/*/20[0-9][0-9][0-
9][0-9]/[0-9][0-9]'
remove_empty_directories: yes
wildcard: yes
-
max_age_days: ~
path: '/home/jail/home/cdrexport/system/20[0-9][0-9][0-9][0-
9]/[0-9][0-9]'
remove_empty_directories: yes
wildcard: yes
sql_batch: 10000
trash_cleanup_days: 30
• cleanuptools.acc_cleanup_days: CDR records in acc table in kamailio database will be deleted after
this time
• cleanuptools.binlog_days: Time after MySQL binlogs will be deleted.
• cleanuptools.cdr_archive_months: How many months worth of records to keep in monthly CDR
backup tables, instead of dumping them into archive files and dropping them from database.
• cleanuptools.cdr_backup_months: How many months worth of records to keep in the current cdr
table, instead of moving them into the monthly CDR backup tables.
• cleanuptools.cdr_backup_retro: How many months to process for backups, going backwards in
time and skipping cdr_backup_months months first, and store them in backup tables. Any older
record will be left untouched.
• cleanuptools.delete_old_cdr_files:
◦ enable: Enable (yes) or disable (no) exported CDR cleanup.
◦ max_age_days: Gives the expiration time of the exported CDR files in days. There is a general
value which may be overridden by a local value provided at a specific path. The local value is
valid for the particular path only.
For the description of cleanuptools please visit Cleanuptools Description section of the handbook.
cluster_sets
cluster_sets:
default:
dispatcher_id: 50
default_set: default
type: central
• cluster_sets.<label>: an arbitrary label of the cluster set; in the above example we have default
• cluster_sets.<label>.dispatcher_id: a unique, numeric value that identifies a particular cluster set
• cluster_sets.default_set: selects the default cluster set
• cluster_sets.type: the type of cluster set; can be central or distributed
database
database:
bufferpoolsize: 24768M
faxserver
faxserver:
enable: yes
fail_attempts: '3'
fail_retry_secs: '60'
mail_from: 'Sipwise C5 FaxServer <[email protected]>'
general
general:
adminmail: [email protected]
companyname: sipwise
lang: en
maintenance: no
production: yes
timezone: localtime
heartbeat
heartbeat:
hb_watchdog:
action_max: 5
enable: yes
interval: 10
transition_max: 10
• heartbeat.hb_watchdog.enable: Enable heartbeat watchdog in order to prevent and fix split brain
scenario.
• heartbeat.hb_watchdog.action_max: Max errors before taking any action.
intercept
intercept:
enable: no
kamailio
kamailio:
lb:
block_useragents:
action: reject
block_empty: no
block_absent: no
enable: no
mode: blacklist
ua_patterns: []
cfgt: no
debug:
enable: no
modules:
- level: '1'
name: core
- level: '3'
name: xlog
debug_level: '1'
debug_uri:
enable: no
redis_db: 27
htable_idx_size: 4
dns:
dns_sctp_pref: 1
dns_tcp_pref: 1
dns_tls_pref: 1
dns_try_naptr: no
dns_udp_pref: 1
use_dns_cache: on
external_sbc: []
extra_sockets: ~
max_forwards: '70'
mem_log: '1'
mem_summary: '12'
max_inv_lifetime: '180000'
nattest_exception_ips:
- 1.2.3.4
- 5.6.7.8
nattest_exception_nets:
- 192.168.10.0/24
- 192.168.11.0/24
pkg_mem: '16'
port: '5060'
remove_isup_body_from_replies: no
sdp_line_filter:
enable: no
remove_line_startswith: []
security:
dos_ban_enable: yes
dos_ban_time: '300'
dos_reqs_density_per_unit: '50'
dos_sampling_time_unit: '5'
dos_whitelisted_ips: []
dos_whitelisted_subnets: []
failed_auth_attempts: '3'
failed_auth_ban_enable: yes
failed_auth_ban_time: '3600'
topoh:
enable: no
mask_callid: no
mask_ip: 127.0.0.8
topos:
enable: no
redis_db: 24
shm_mem: '64'
skip_contact_alias_for_ua_when_tcp:
enable: no
user_agent_patterns: []
start: yes
strict_routing_safe: no
syslog_options: yes
tcp_children: 1
tcp_max_connections: '2048'
tls:
enable: no
port: '5061'
sslcertfile: /etc/ngcp-config/ssl/myserver.crt
sslcertkeyfile: /etc/ngcp-config/ssl/myserver.key
udp_children: 1
proxy:
allow_cf_to_itself: no
allow_info_method: no
allow_msg_method: no
allow_peer_relay: no
allow_refer_method: no
always_anonymize_from_user: no
authenticate_bye: no
cf_depth_limit: '10'
cfgt: no
check_prev_forwarder_as_upn: no
children: 1
decode_utu_header: no
debug:
enable: no
modules:
- level: '1'
name: core
- level: '3'
name: xlog
debug_level: '1'
default_expires: '3600'
default_expires_range: '30'
dlg_timeout: '43200'
early_rejects:
block_admin:
announce_code: '403'
announce_reason: Blocked by Admin
block_callee:
announce_code: '403'
announce_reason: Blocked by Callee
block_caller:
announce_code: '403'
announce_reason: Blocked by Caller
block_contract:
announce_code: '403'
announce_reason: Blocked by Contract
block_in:
announce_code: '403'
announce_reason: Block in
block_out:
announce_code: '403'
announce_reason: Blocked out
block_override_pin_wrong:
announce_code: '403'
announce_reason: Incorrect Override PIN
callee_busy:
announce_code: '486'
announce_reason: Busy Here
callee_offline:
announce_code: '480'
announce_reason: Offline
callee_tmp_unavailable:
announce_code: '480'
announce_reason: Temporarily Unavailable
callee_tmp_unavailable_gp:
announce_code: '480'
announce_reason: Unavailable
callee_tmp_unavailable_tm:
announce_code: '408'
announce_reason: Request Timeout
callee_unknown:
announce_code: '404'
announce_reason: Not Found
cf_loop:
announce_code: '480'
announce_reason: Unavailable
emergency_invalid:
announce_code: '404'
announce_reason: Emergency code not available in this region
emergency_unsupported:
announce_code: '403'
announce_reason: Emergency Calls Not Supported
invalid_speeddial:
announce_code: '484'
announce_reason: Speed-Dial slot empty
locked_in:
announce_code: '403'
announce_reason: Callee locked
locked_out:
announce_code: '403'
announce_reason: Caller locked
max_calls_in:
announce_code: '486'
announce_reason: Busy
max_calls_out:
announce_code: '403'
announce_reason: Maximum parallel calls exceeded
no_credit:
announce_code: '402'
announce_reason: Insufficient Credit
peering_unavailable:
announce_code: '503'
announce_reason: PSTN Termination Currently Unavailable
reject_vsc:
announce_code: '403'
announce_reason: VSC Forbidden
relaying_denied:
announce_code: '403'
announce_reason: Relaying Denied
unauth_caller_ip:
announce_code: '403'
announce_reason: Unauthorized IP detected
emergency_priorization:
enable: no
register_fake_200: yes
register_fake_expires: '3600'
reject_code: '503'
reject_reason: Temporary Unavailable
retry_after: '3600'
enum_suffix: e164.arpa.
expires_range: '30'
filter_100rel_from_supported: no
filter_failover_response: 408|500|503
foreign_domain_via_peer: no
fritzbox:
enable: no
prefixes:
- 0$avp(caller_ac)
- $avp(caller_cc)$avp(caller_ac)
- \+$avp(caller_cc)$avp(caller_ac)
- 00$avp(caller_cc)$avp(caller_ac)
special_numbers:
- '112'
- '110'
- 118[0-9]{2}
ignore_auth_realm: no
ignore_subscriber_allowed_clis: no
keep_original_to: no
lcr_stopper_mode: 0
latency_limit_action: '100'
latency_limit_db: '500'
latency_log_level: '1'
latency_runtime_action: 1000
lnp:
add_reply_headers:
enable: no
number: P-NGCP-LNP-Number
status: P-NGCP-LNP-Status
api:
add_caller_cc_to_lnp_dst: no
invalid_lnp_routing_codes:
- ^EE00
- ^DD00
keepalive_interval: '3'
lnp_request_blacklist: []
lnp_request_whitelist: []
port: '8991'
reply_error_on_lnp_failure: no
request_timeout: '1000'
server: localhost
tcap_field_fci: end.components.0.invoke.parameter
tcap_field_lnp: ConnectArg.destinationRoutingAddress.0
tcap_field_opcode: end.components.0.invoke.opCode
enable: no
execute_ncos_block_out_before_lnp: no
skip_callee_lnp_lookup_from_any_peer: no
strictly_check_ncos: no
type: api
lookup_peer_destination_domain_for_pbx: no
loop_detection:
enable: no
expire: '1'
max: '5'
max_expires: '43200'
max_gw_lcr: '128'
max_registrations_per_subscriber: '5'
mem_log: '1'
mem_summary: '12'
min_expires: '60'
nathelper:
sipping_from: sip:[email protected]
nathelper_dbro: no
natping_interval: '30'
natping_processes: 1
nonce_expire: '300'
pbx:
hunt_display_fallback_format: '[H %s]'
hunt_display_fallback_indicator: $var(cloud_pbx_hg_ext)
hunt_display_format: '[H %s]'
hunt_display_indicator: $var(cloud_pbx_hg_displayname)
hunt_display_maxlength: 8
ignore_cf_when_hunting: no
skip_busy_hg_members:
enable: no
redis_key_name: totaluser
peer_probe:
available_treshold: '1'
enable: yes
from_uri_domain: probe.ngcp.local
from_uri_user: ping
interval: '10'
method: OPTIONS
reply_codes: class=2;class=3;code=403;code=404;code=405
timeout: '5'
unavailable_treshold: '1'
perform_peer_failover_on_tm_timeout: yes
perform_peer_lcr: no
pkg_mem: '32'
port: '5062'
presence:
enable: yes
max_expires: '3600'
reginfo_domain: example.org
proxy_lookup: no
push:
apns_alert: New call
apns_sound: incoming_call.xaf
code_18x: 180
reason_18x: 'Ringing'
reply_18x: 'no'
report_mos: yes
set_ruri_to_peer_auth_realm: no
shm_mem: '125'
skip_pbx_loop: no
start: yes
stir:
cache_dir: /var/cache/kamailio/stir/
cache_expire: 3600
domains:
- name: <domain_name>
private_key: <path_to_a_private_key_related_to_domain>
enable: yes
expire: 300
libopt: []
shaken:
attestation_name: verstat
attestation_values:
failed: TN-Validation-Failed
no_validation: No-TN-Validation
not_present: TN-Validation-Not-Present
passed: TN-Validation-Passed
passed_A: TN-Validation-Passed-A
passed_B: TN-Validation-Passed-B
passed_C: TN-Validation-Passed-C
timeout: 5
store_recentcalls: no
syslog_options: yes
tcp_children: 1
tm:
fr_inv_timer: '180000'
fr_timer: '9000'
max_inv_lifetime: '180000'
treat_600_as_busy: yes
use_enum: no
usrloc_dbmode: '1'
voicebox_first_caller_cli: yes
xfer_other_party_from: no
In order to learn about details of emergency priorization function of NGCP please refer
TIP
to Emergency Priorization part of the handbook.
• kamailio.proxy.filter_failover_response: Specify the list of SIP responses that trigger a failover on the
next available peering server.
• kamailio.proxy.foreign_domain_via_peer: Enable/disable of routing of calls to foreign SIP URI via
peering servers.
• kamailio.proxy.fritzbox.enable: Enable detection for Fritzbox special numbers. Ex. Fritzbox add some
prefix to emergency numbers.
• kamailio.proxy.fritzbox.prefixes: Fritybox prefixes to check. Ex. '0$avp(caller_ac)'
• kamailio.proxy.fritzbox.special_numbers: Specifies Fritzbox special number patterns. They will be
checked with the prefixes defined. Ex. '112', so the performed check will be
'sip:0$avp(caller_ac)112@' if prefix is '0$avp(caller_ac)'
• kamailio.proxy.ignore_auth_realm: Ignore SIP authentication realm.
• kamailio.proxy.ignore_subscriber_allowed_clis: Set to 'yes' to ignore the subscriber’s
allowed_clis preference so that the User-Provided CLI is only checked against customer’s
allowed_clis preference.
• kamailio.proxy.lcr_stopper_mode: 0, default mode first rule to match will stop the gw matching
process. 1, lcr will keep matching gws even if the rule has stopper value and after ordering gws by
priority it will obey the first stopper value and discard the rest.
• kamailio.proxy.latency_limit_action: Limit of runtime in ms for config actions. If a config action
executed by cfg interpreter takes longer than this value, a message is printed in the logs.
• kamailio.proxy.latency_limit_db: Limit of runtime in ms for DB queries. If a DB operation takes longer
than this value, a warning is printed in the logs.
• kamailio.proxy.latency_log_level: Log level to print the messages related to latency. Default is 1
(INFO).
• kamailio.proxy.latency_runtime_action: Limit of runtime in ms for SIP message processing cycle. If
the SIP message processing takes longer than this value, a warning is printed in the logs.
• kamailio.proxy.keep_original_to: Not used now.
• kamailio.proxy.lnp.add_reply_headers.enable: Enable/disable dedicated headers to be added after
LNP lookup.
• kamailio.proxy.lnp.add_reply_headers.number: Name of the header that will contain the LNP
number.
• kamailio.proxy.lnp.add_reply_headers.status: Name of the header that will contain the LNP return
code (200 if OK, 500/480/… if an error/timeout is occurred).
• kamailio.proxy.lnp.api.add_caller_cc_to_lnp_dst: Enable/disable adding of caller country code to
LNP routing number of the result ('no' by default, LNP result in E.164 format is assumed).
• kamailio.proxy.lnp.api.invalid_lnp_routing_codes [only for api type]: number matching pattern for
routing numbers that represent invalid call destinations; an announcement is played in that case
and the call is dropped.
• kamailio.proxy.lnp.api.keepalive_interval: Not used now.
• kamailio.proxy.lnp.api.lnp_request_whitelist [only for api type]: list of matching patterns of called
numbers for which LNP lookup must be done.
• kamailio.proxy.lnp.api.lnp_request_blacklist [only for api type]: list of matching patterns of called
numbers for which LNP lookup must not be done.
• kamailio.proxy.lnp.api.port: Not used now.
• kamailio.proxy.nathelper_dbro: Default is "no". This will be "yes" on CARRIER in order to activate the
use of a read-only connection using LOCAL_URL
• kamailio.proxy.natping_interval: Sets the NAT ping interval in seconds.
• kamailio.proxy.natping_processes: Set the number of NAT ping worker processes.
• kamailio.proxy.nonce_expire: Nonce expire time in seconds.
• kamailio.proxy.pbx.hunt_display_fallback_format: Default is '[H %s]'. Sets the format of the hunt
group indicator that is sent as initial part of the From Display Name when subscriber is called as a
member of PBX hunt group if the preferred format defined by the hunt_display_format and
hunt_display_indicator can not be used (as in the case of not provisioned subscriber settings).
The '%s' part is replaced with the value of the hunt_display_fallback_indicator variable.
• kamailio.proxy.pbx.hunt_display_fallback_indicator: The internal kamailio variable that sets the
number or extension of the hunt group. Default is $var(cloud_pbx_hg_ext) which is populated
during call routing with the extension of the hunt group.
• kamailio.proxy.pbx.hunt_display_format: Default is '[H %s]'. Sets the format of hunt group indicator
that is sent as initial part of the From Display Name when subscriber is called as a member of PBX
hunt group. This is the preferred (default) indicator format with Display Name, where the '%s' part is
replaced with the value of the hunt_display_indicator variable.
• kamailio.proxy.pbx.hunt_display_indicator: The internal kamailio variable that contains the preferred
identifier of the hunt group. Default is $var(cloud_pbx_hg_displayname) which is populated
during call routing with the provisioned Display Name of the hunt group.
• kamailio.proxy.pbx.hunt_display_maxlength: Default is '8'. Sets the maximum length of the variable
used as the part of hunt group indicator in Display Name. The characters beyond this limit are
truncated in order for hunt group indicator and calling party information to fit on display of most
phones.
• kamailio.proxy.pbx.ignore_cf_when_hunting: Default is 'no'. Whether to disregard all individual call
forwards (CFU, CFB, CFT and CFNA) of PBX extensions when they are called via hunt groups. Note
that call forwards configured to local services such as Voicebox or Conference are always skipped
from group hunting.
• kamailio.proxy.pbx.skip_busy_hg_members.enable: Default is 'no'. Whether to skip the subscribers
that have busy status when routing the calls to huntgroups.
• kamailio.proxy.pbx.skip_busy_hg_members.redis_key_name: one of [totaluser, activeuser] -
Sets the internal redis key name that contains the number of active calls for the user.
• kamailio.proxy.peer_probe.enable: Enable the peer probing, must be also checked per individual
peer in the panel/API.
• kamailio.proxy.peer_probe.interval: Peer probe interval in seconds.
• kamailio.proxy.peer_probe.timeout: Peer probe response wait timeout in seconds.
• kamailio.proxy.peer_probe.reply_codes: Defines the response codes that are considered successful
response to the configured probe request, e.g.
class=2;class=3;code=403;code=404;code=405, with class defining a code range.
• kamailio.proxy.peer_probe.unavailable_treshold: Defines after how many failed probes a peer is
considered unavailable.
• kamailio.proxy.peer_probe.available_treshold: Defines after how many successful probes a peer is
considered available.
• kamailio.proxy.peer_probe.from_uri_user: From-userpart for the probe requests.
You can find more information about peer probing configuration in Configuration of
TIP
Peer Probing of the handbook.
ngcp-mediator
mediator:
interval: 10
modules
modules:
- enable: no
name: dummy
options: numdummies=2
monitoring
monitoring:
backend: prometheus
filesystems:
- /
- /ngcp-data
- /ngcp-fallback
- /mnt/glusterfs
interval: 10
prometheus_server: victoria-metrics
retention_policy_long_duration: 12
retention_policy_short_duration: 15
retrospect_interval: 30
threshold:
cpu_idle_min: '0.1'
disk_used_max: '0.9'
kamailio_lb_pkgmem_min: 1048576
kamailio_lb_shmem_min: '1048576'
kamailio_proxy_pkgmem_min: 1048576
kamailio_proxy_shmem_min: '1048576'
load_long_max: '2'
load_medium_max: '2'
load_short_max: '3'
mem_used_max: 0.98
mta_queue_len_max: '15'
mysql_replication_delay_max: 60
sip_responsiveness_max: '15'
sslcert_timetoexpiry: '30'
sslcert_whitelist: []
swap_free_min: 0.02
timeout: 10
• monitoring.backend: The monitoring implementation backend to use. Valid value is: 'prometheus'
(default).
• monitoring.filesystems: The filesystem mount points to monitor.
• monitoring.interval: The number of seconds between each data gathering iteration.
• monitoring.prometheus_server: The prometheus server implementation to use. Either 'victoria-
metrics' (default) or 'prometheus'.
• monitoring.retention_policy_long_duration: The long term retention policy for metrics in the
monitoring database in months.
• monitoring.retention_policy_short_duration: The short term retention policy for metrics in the
nginx
nginx:
status_port: 8081
xcap_port: 1080
ntp
ntp:
servers:
- 0.debian.pool.ntp.org
- 1.debian.pool.ntp.org
- 2.debian.pool.ntp.org
- 3.debian.pool.ntp.org
ossbss
ossbss:
apache:
port: 2443
proxyluport: 1080
restapi:
sslcertfile: '/etc/ngcp-panel/api_ssl/api_ca.crt'
sslcertkeyfile: '/etc/ngcp-panel/api_ssl/api_ca.key'
serveradmin: [email protected]
servername: "\"myserver\""
ssl_enable: yes
sslcertfile: '/etc/ngcp-config/ssl/myserver.crt'
sslcertkeyfile: '/etc/ngcp-config/ssl/myserver.key'
frontend: no
htpasswd:
-
pass: '{SHA}w4zj3mxbmynIQ1jsUEjSkN2z2pk='
user: ngcpsoap
logging:
apache:
acc:
facility: daemon
identity: oss
level: info
err:
facility: local7
level: info
ossbss:
facility: local0
identity: provisioning
level: DEBUG
web:
facility: local0
level: DEBUG
provisioning:
allow_ip_as_domain: 1
allow_numeric_usernames: 0
auto_allow_cli: 1
carrier:
account_distribution_function: roundrobin
prov_distribution_function: roundrobin
credit_warnings:
-
domain: example.com
recipients:
- [email protected]
threshold: 1000
faxpw_min_char: 0
log_passwords: 0
no_logline_truncate: 0
pw_min_char: 6
routing:
ac_regex: '[1-9]\d{0,4}'
cc_regex: '[1-9]\d{0,3}'
sn_regex: '[1-9]\d+'
tmpdir: '/tmp'
• ossbss.frontend: Enable disable SOAP interface. Set value to 'fcgi' to enable old SOAP interface.
• ossbss.htpasswd: Sets the username and SHA hashed password for SOAP access. You can
generate the password using the following command: htpasswd -nbs myuser mypassword.
• ossbss.provisioning.allow_ip_as_domain: Allow or not allow IP address as SIP domain (0 is not
allowed).
• ossbss.provisioning.allow_numeric_usernames: Allow or not allow numeric SIP username (0 is not
allowed).
• ossbss.provisioning.faxpw_min_char: Minimum number of characters for fax passwords.
• ossbss.provisioning.pw_min_char: Minimum number of characters for sip passwords.
• ossbss.provisioning.log_password: Enable logging of passwords.
• ossbss.provisioning.routing: Regexp for allowed AC (Area Code), CC (Country Code) and SN
(Subscriber Number).
pbx:
enable: no
prosody
prosody:
ctrl_port: 5582
log_level: info
pushd
pushd:
apns:
enable: yes
endpoint: api.push.apple.com
endpoint_port: 0
extra_instances:
- certificate: '/etc/ngcp-config/ssl/PushCallkitCert.pem'
enable: yes
key: '/etc/ngcp-config/ssl/PushCallkitKey.pem'
type: callkit
http2_jwt:
ec_key: '/etc/ngcp-config/ssl/AuthKey_ABCDE12345.pem'
ec_key_id: 'ABCDE12345'
enable: yes
issuer: 'VWXYZ67890'
tls_certificate: ''
tls_key: ''
topic: 'com.example.appID'
legacy:
certificate: '/etc/ngcp-config/ssl/PushChatCert.pem'
feedback_endpoint: feedback.push.apple.com
feedback_interval: '3600'
key: '/etc/ngcp-config/ssl/PushChatKey.pem'
socket_timeout: 0
domains:
- apns:
endpoint: api.push.apple.com
extra_instances:
- certificate: '/etc/ngcp-config/ssl/PushCallkitCert-
example.com.pem'
enable: no
key: '/etc/ngcp-config/ssl/PushCallkitKey-example.com.pem''
type: callkit
http2_jwt:
ec_key: '/etc/ngcp-config/ssl/AuthKey_54321EDCBA.pem'
ec_key_id: '54321EDCBA'
issuer: '09876ZYXWV'
tls_certificate: ''
tls_key: ''
topic: 'com.example.otherAppID'
legacy:
certificate: '/etc/ngcp-config/ssl/PushChatCert-example.com.pem'
feedback_endpoint: feedback.push.apple.com
key: '/etc/ngcp-config/ssl/PushChatKey-example.com.pem'
domain: example.com
enable: yes
android:
key: 'google_api_key_for_example.com_here'
enable: yes
android:
enable: yes
key: 'google_api_key_here'
priority:
call: high
groupchat: normal
invite: normal
message: normal
muc:
exclude: []
force_persistent: 'true'
owner_on_join: 'true'
one_device_per_subscriber: no
port: 45060
processes: 4
ssl: yes
sslcertfile: /etc/ngcp-config/ssl/CAsigned.crt
sslcertkeyfile: /etc/ngcp-config/ssl/CAsigned.key
unique_device_ids: no
qos
The QoS section allows configuring the ToS (Type of Service) feature:
qos:
tos_rtp: 184
tos_sip: 184
The ToS byte includes both DSCP and ECN bits. So, specify the DSCP value multiplied by
TIP
four (46x4=184) and, optionally, add the required ECN value to it (1, 2 or 3).
ngcp-rate-o-mat
rateomat:
enable: yes
loopinterval: 10
splitpeakparts: 0
redis
redis:
database_amount: 16
port: 6379
syslog_ident: redis
reminder
reminder:
retries: 2
retry_time: 60
sip_fromdomain: voicebox.sipwise.local
sip_fromuser: reminder
wait_time: 30
weekdays: '2, 3, 4, 5, 6, 7'
• reminder.retries: How many times the reminder feature have to try to call you.
rsyslog
rsyslog:
external_logging:
- address: 192.168.32.1
enable: no
loglevel: warning
port: '514'
proto: udp
ngcp_logs_max_size: 2G
ngcp_logs_preserve_days: '93'
rtpproxy
rtpproxy:
allow_userspace_only: yes
cdr_logging_facility: ''
control_tos: 0
delete_delay: 30
dtls_passive: no
enable: yes
final_timeout: 0
firewall_iptables_chain: ''
graphite:
interval: 600
prefix: rtpengine.
server: ''
log_level: '6'
maxport: '40000'
minport: '30000'
num_threads: 0
prefer_bind_on_internal: no
recording:
enable: no
mp3_bitrate: '48000'
log_level: '6'
nfs_host: 192.168.1.1
nfs_remote_path: /var/recordings
output_dir: /var/lib/rtpengine-recording
output_format: wav
output_mixed: yes
output_single: yes
resample: no
resample_to: '16000'
spool_dir: /var/spool/rtpengine
rtcp_logging_facility: ''
rtp_timeout: '60'
rtp_timeout_onhold: '3600'
• rtpproxy.allow_userspace_only: Enable/Disable the user space failover for rtpengine ('yes' means
enable). By default rtpengine works in kernel space.
• rtpproxy.cdr_logging_facility: If set, rtpengine will produce a CDR-like syslog line after each call
finishes. Must be set to a valid syslog facility string (such as 'daemon' or 'local0').
• rtpproxy.control_tos: If higher than 0, the control messages port uses the configured ToS (Type of
Service) bits. See the QoS section below for details.
• rtpproxy.delete_delay: After a call finishes, rtpengine will wait this many seconds before cleaning up
resources. Useful for possible late branched calls.
• rtpproxy.dtls_passive: If enabled, rtpengine will always advertise itself as a passive role in DTLS
setup. Useful in WebRTC scenarios if used behind NAT.
• rtpproxy.final_timeout: If set, any calls lasting longer than this many seconds will be terminated, no
matter the circumstances.
• rtpproxy.firewall_iptables_chain: If set, rtpengine will create an iptables rule for each individual
security
The following is the security section. Usage of the firewall subsection is described in Firewalling:
security:
firewall:
enable: no
logging:
days_kept: '7'
enable: yes
file: /var/log/firewall.log
tag: NGCPFW
nat_rules4: ~
nat_rules6: ~
policies:
forward: DROP
input: DROP
output: ACCEPT
rules4: ~
rules6: ~
• security.firewall.enable: Enable/disable iptables configuration and rule generation for IPv4 and IPv6
(default: no)
• security.firewall.logging.days_kept: Number of days logfiles are kept on the system before being
deleted (log files are rotated daily, default: 7)
• security.firewall.logging.enable: Enables/disables logging of all packets dropped by Sipwise C5
firewall (default: yes)
• security.firewall.logging.file: File firewall log messages go to (default: /var/log/firewall.log)
• security.firewall.logging.tag: String prepended to all log messages (internally DROP is added to any
tag indicating the action triggering the message, default: NGCPFW)
• security.firewall.nat_rules4: Optional list of IPv4 firewall rules added to table nat using iptables-
persistent syntax (default: undef)
• security.firewall.nat_rules6: Optional list of IPv6 firewall rules added to table nat using iptables-
persistent syntax (default: undef)
• security.firewall.policies.forward: Default policy for iptables FORWARD chain (default: DROP)
• security.firewall.policies.input: Default policy for iptables INPUT chain (default: DROP)
• security.firewall.policies.output: Default policy for iptables OUTPUT chain (default: ACCEPT)
• security.firewall.rules4: Optional list of IPv4 firewall rules added to table filter using iptables-
persistent syntax (default: undef)
• security.firewall.rules6: Optional list of IPv6 firewall rules added to table filter using iptables-
persistent syntax (default: undef)
sems
sems:
bindport: 5080
conference:
enable: yes
max_participants: 10
debug: no
highport: 50000
lowport: 40001
media_processor_threads: 10
prepaid:
enable: yes
sbc:
calltimer_enable: yes
calltimer_max: 3600
outbound_timeout: 6000
profile:
- custom_header: []
name: ngcp
- custom_header: []
name: ngcp_cf
sdp_filter:
codecs: PCMA,PCMU,telephone-event
enable: yes
mode: whitelist
session_timer:
enable: yes
max_timer: 7200
min_timer: 90
session_expires: 300
session_processor_threads: 10
vsc:
block_override_code: 80
cfb_code: 90
cfna_code: 93
cft_code: 92
cfu_code: 72
clir_code: 31
directed_pickup_code: 99
enable: yes
park_code: 97
reminder_code: 55
speedial_code: 50
unpark_code: 98
voicemail_number: 2000
xmlrpcport: 8090
sms
This section provides configuration of Short Message Service on the NGCP. Description of the SMS
module is provided earlier in this handbook here.
In the below example you can see the default values of the configuration parameters.
sms:
core:
admin_port: '13000'
smsbox_port: '13001'
enable: no
loglevel: '0'
sendsms:
max_parts_per_message: '5'
port: '13002'
smsc:
dest_addr_npi: '1'
dest_addr_ton: '1'
enquire_link_interval: '58'
host: 1.2.3.4
id: default_smsc
max_pending_submits: '10'
no_dlr: yes
password: password
port: '2775'
source_addr_npi: '1'
source_addr_ton: '1'
system_type: ''
throughput: '5'
transceiver_mode: '1'
username: username
• sms.core.admin_port: Port number of admin interface of SMS core module (running on LB nodes).
• sms.core.smsbox_port: Port number used for internal communication between bearerbox module
on LB nodes and smsbox module on PRX nodes. This is a listening port of the bearerbox module
(running on LB nodes).
• sms.enable: Set to yes if you want to enable SMS module.
• sms.loglevel: Log level of SMS module; the default '0' will result in writing only the most important
information into the log file.
• sms.sendsms.max_parts_per_message: If the SM needs to be sent as concatenated SM, this
parameter sets the max. number of parts for a single (logical) message.
• sms.sendsms.port: Port number of smsbox module (running on PRX nodes).
• sms.smsc. : Parameters of the connection to an SMSC
◦ dest_addr_npi: Telephony numbering plan indicator for the SM destination, as defined by
standards (e.g. '1' stands for E.164)
◦ dest_addr_ton: Type of number for the SM destination, as defined by standards (e.g. '1' stands
for "international" format)
◦ enquire_link_interval: Interval of SMSC link status check in seconds
◦ host: IP address of the SMSC
◦ id: An arbitrary string for identification of the SMSC; may be used in log files and for routing SMs.
◦ max_pending_submits: The maximum number of outstanding (i.e. not acknowledged) SMPP
operations between Sipwise C5 and SMSC. As a guideline it is recommended that no more than
10 (default) SMPP messages are outstanding at any time.
◦ no_dlr: Do not request delivery report; when sending an SM and this parameter is set to yes,
Sipwise C5 will not request DR for the message(s). May be required for some particular SMSCs,
in order to avoid "Incorrect status report request parameter usage" error messages from the
SMSC.
◦ password: This is the password used for authentication on the SMSC.
◦ port: Port number of the SMSC where Sipwise C5 will connect to.
◦ source_addr_npi: Telephony numbering plan indicator for the SM source, as defined by
standards (e.g. '1' stands for E.164)
◦ source_addr_ton: Type of number for the SM source, as defined by standards (e.g. '1' stands for
"international" format)
◦ system_type: Defines the SMSC client category in which Sipwise C5 belongs to; defaults to
"VMA" (Voice Mail Alert) when no value is given. (No need to set any value)
◦ throughput: The max. number of messages per second that Sipwise C5 will send towards the
SMSC. (Value type: float)
◦ transceiver_mode: If set to 1 (yes / true), Sipwise C5 will attempt to use a TRANSCEIVER mode
connection to the SMSC. It uses the standard transmit port of the SMSC for receiving SMs too.
◦ username: This is the username used for authentication on the SMSC.
sshd
sshd:
listen_addresses:
- 0.0.0.0
• sshd: specify interface where SSHD should run on. By default sshd listens on all IPs found in
network.yml with type 'ssh_ext'. Unfortunately sshd can be limited to IPs only and not to interfaces.
The current option makes it possible to specify allowed IPs (or all IPs with 0.0.0.0).
sudo
sudo:
logging: no
max_log_sessions: 0
• logging: enable/disable the I/O logging feature of sudo. See man page of 'sudoreplay(8)'.
• max_log_sessions: when I/O logging is enabled, specifies how many log sessions per individual
user sudo should keep before it starts overwriting old ones. The default '0' means no limit.
ngcp-witnessd
witnessd:
debug: no
interval: ~
gather:
asr_ner_statistics: yes
kamailio_concurrent_calls: yes
kamailio_dialog_active: yes
kamailio_dialog_early: yes
kamailio_dialog_incoming: yes
kamailio_dialog_local: yes
kamailio_dialog_outgoing: yes
kamailio_dialog_relay: yes
kamailio_shmem: yes
kamailio_usrloc_regdevices: yes
kamailio_usrloc_regusers: yes
peering_groups: yes
mta_queue_len: yes
mysql_global_status: yes
mysql_slave_status: yes
oss_provisioned_subscribers: yes
sip_responsiveness: yes
sip_stats_num_packets: yes
sip_stats_num_packets_perday: yes
sip_stats_partition_size: yes
• witnessd.interval: The number of seconds between each data gathering iteration, when the value is
undefined, the code will fallback to use monitoring.interval.
• witnessd.gather.asr_ner_statistics: Enable ASR/NER statistics data.
• witnessd.gather.kamailio_*: Enable Kamailio statistics data.
• witnessd.gather.mta_queue_len: Enable MTA (exim4) queue length data.
• witnessd.gather.mysql_global_status: Enable global MySQL data.
• witnessd.gather.mysql_slave_status: Enable salave (replication) MySQL data.
• witnessd.gather.oss_provisioned_subscribers: Enable OSS provisioned subscribers count data.
• witnessd.gather.sip_*: Enable SIP statistics data.
www_admin
www_admin:
apache:
autoprov_port: 1444
callingcard_features: 0
callthru_features: 0
conference_features: 1
contactmail: [email protected]
fastcgi_workers: 2
fax_features: 1
fees_csv:
element_order:
- source
- destination
- direction
- zone
- zone_detail
- onpeak_init_rate
- onpeak_init_interval
- onpeak_follow_rate
- onpeak_follow_interval
- offpeak_init_rate
- offpeak_init_interval
- offpeak_follow_rate
- offpeak_follow_interval
- use_free_time
http_admin:
autoprov_port: 1444
port: 1443
serveradmin: [email protected]
servername: "\"myserver\""
ssl_enable: yes
sslcertfile: '/etc/ngcp-config/ssl/myserver.crt'
sslcertkeyfile: '/etc/ngcp-config/ssl/myserver.key'
http_csc:
autoprov_bootstrap_port: 1445
autoprov_port: 1444
port: 443
serveradmin: [email protected]
servername: "\"myserver\""
ssl_enable: yes
sslcertfile: '/etc/ngcp-config/ssl/myserver.crt'
sslcertkeyfile: '/etc/ngcp-config/ssl/myserver.key'
logging:
apache:
acc:
facility: daemon
identity: oss
level: info
err:
facility: local7
level: info
security:
password_allow_recovery: 0
password_max_length: 40
password_min_length: 6
password_musthave_digit: 0
password_musthave_lowercase: 1
password_musthave_specialchar: 0
password_musthave_uppercase: 0
password_sip_autogenerate: 0
password_sip_expose_subadmin: 1
password_web_autogenerate: 0
password_web_expose_subadmin: 1
speed_dial_vsc_presets:
vsc:
- '*0'
- '*1'
- '*2'
- '*3'
- '*4'
- '*5'
- '*6'
- '*7'
- '*8'
- '*9'
constants.yml Overview
/etc/ngcp-config/constants.yml is one of the main configuration files that contains important
(static) configuration parameters, like Sipwise C5 system-user data.
network.yml Overview
/etc/ngcp-config/network.yml is one of the main configuration files that contains network-related
configuration parameters, like IP addresses and roles of the node(s) in Sipwise C5 system.
The next example shows a part of the network.yml configuration file. Explanation of all the configuration
parameters is provided in Network Configuration section of the handbook.
self:
dbnode: '1'
eth0:
ip: 10.0.2.15
netmask: 255.255.255.0
type:
- web_ext
- web_int
- ssh_ext
eth1:
ip: 10.15.20.143
netmask: 255.255.255.0
type:
- ssh_ext
- web_ext
- web_int
- sip_ext
- rtp_ext
interfaces:
- lo
- eth0
- eth1
lo:
cluster_sets:
- default
ip: 127.0.0.1
netmask: 255.255.255.0
shared_ip: []
shared_v6ip: []
type:
- sip_int
- ha_int
- aux_ext
- ssh_ext
- api_int
v6ip: '::1'
role:
- proxy
- lb
- mgmt
- rtp
- db
status: 'online'
hosts_common:
etc_hosts_global_extra_entries:
- 10.100.1.1 server-1 server-1.internal.example.com
- 10.100.1.2 server-2 server-2.internal.example.com
The administrator can create new entries in network.yml to specify extra entries for the file /etc/hosts.
One entry is global and two per-host, one of which is local only for the host, and the other overrides
global for this host. These entries will be appended without further processing.
Global is useful if the entries are to be added to all hosts. These probably make more sense in most
set-ups.
Per-host local is useful if the entries are only to be added to some node, but not needed or convenient
to add to all of them.
Per-host override of the global config is useful if the global entries are to be added to a potentially
large number of nodes and to be excluded only in a few of them, to not have to do the contrary
(duplicate entries in many hosts except a couple).
hosts_common:
etc_hosts_global_extra_entries:
- 10.100.1.1 server-1 server-1.internal.example.com
- 10.100.1.2 server-2 server-2.internal.example.com
hosts:
db01b:
etc_hosts_local_extra_entries:
- 127.0.1.1 local-alias-1.db01b
- 127.0.2.1 local-alias-2.db01b
- 172.30.52.180 db01b.example.com
...
web01a:
etc_hosts_local_extra_entries:
- 127.0.1.1 local-alias-1.web01a
- 127.0.2.1 local-alias-2.web01a
- 172.30.52.168 web01a.example.com
etc_hosts_global_extra_entries:
- 10.100.1.1 server-1 server-1.internal.example.com
...
Configuration
There are new options in constants.yml
mysql:
encryption:
enable: yes
encrypt_binlog: yes
key:
1;a356c82422a9031f2e472047ad8220eeea257d611849fbdc9f75b49933f75241
threads: 1
NOTE: all changes in the configuration section will cause the MariaDB server to restart when ngcpcfg
templates are applied.
• mysql.encryption.enable: Switch encryption on/off. Values: 'yes','no', Default: 'yes'. When enabled,
all tables are being encrypted, it takes from a few seconds to several minutes for MariaDB to
encrypt all the data (depending on the overall size) and the encryption procedure is performed in
the background, while all the data continutes to be fully accessible. Also all new tables are created
encrypted by default and it is not possible to disable encryption for specific tables as the encryption
is 'forced'.
• mysql.encryption.encrypt_binlog: Encrypt binlogs. Values: 'yes','no', Default: 'yes'. While it is
preferred to have this option enabled by default, for scenarios where binlog files need to be parsed,
this option can be turned off. It is also possible to use mysqlbinlog with --read-from-remote-server
option to read encrypted binlogs.
• mysql.encryption.key: Encryption key. The value is randomly generated during the cfg-schema
upgrade when the option is added into constants.yml. The key is located in /etc/mysql/keyfile and
normally MUST NOT be changed. Changing or losing the key permanently will render all the
MariaDB tablespaces data (databases/tables) unusable.
• mysql.encryption.threads: Amount of encryption threads. Default: 1 How many MariaDB encryption
threads should be running, this value depends on how many tables are created/removed or the
encryption keys are rotated.
Supported IO drives
At the moment the following drives are supported: HDD, SSD, and NVMe. We recommend installing
NVMe type SSD storage for the best performance. Otherwise, install SATA SSDs for an average
performance as SATA hard disks are a good option only for test/development purpose.
The exact model and size depend on the type of the system and the load. We recommend running the
initial performance test on the selected hardware before going into production.
The new partitioning logic is simple. The 'code' of services (e.g., kamailio, MariaDB) is separated from
the 'data' (e.g., databases, CDR files) generated and processed by the 'code', and is located in a different
partition of the disk. Additionally, there are two partitions for 'code' with different services versions. This
way, the version of the code can be switched very quickly, by rebooting the system. The 'data' partition
will be the same for both versions of the 'code', and it will always be mounted and ready to be used
before the services start.
The installer can only boot from GPT and does not support ms-dos partitions anymore.
NOTE The legacy 'BIOS' systems can also boot from GPT, while (U)EFI systems can only boot
from GPT (and not from BIOS/legacy boot).
UEFI
UEFI installation is supported. The dedicated UEFI partition has been created on the disk during the
installation (being the second partition in the list).
The Swap partition is no longer in use. The Sipwise C5 has been migrated to the Swap file on the 'data'
partition. It gives the following benefits:
• more space is now available for the 'root', 'rollback' and 'data' partitions.
• the Swap file size can be easily changed on the fly (if necessary).
• the Swap file can be migrated to a new location easily: create a new Swap file with the necessary
size and location using the 'mkswap' command and activate the new Swap file with 'swapon'. Add
the new location to /etc/fstab. Now, you can deactivate the old swapfile with 'swapoff' and remove
it to release the disk space.
• The main reason for the Swap partition usage, used to be 'data fragmentation' on hard disk drives
(HDDs) and old types of filesystems. For modern SSD drives, the fragmentation issue is irrelevant
and the 'ext4' filesystem does not require manual defragmentation either. The free space on fast
SSDs is more important nowadays, as it allows storing more 'data'.
Redis id constants
The list of current Sipwise C5 Redis DB IDs:
The Prometheus monitoring database contains time series metrics of several monitoring sources. The
following are some of the current metrics namespaces:
NGCP Preferences
Tables
The following tables contain user data and depend on voip_preferences and optionally on
voip_preferences_enum:
Columns
Enum
So called "enum preferences" allow a fixed set of possible values, an enumeration, for preferences.
Following the differences between other preferences are described.
Setting the attribute "data_type" of table "voip_preferences" to "enum" marks a preferences as an enum.
The list of possible options is stored in table "voip_preferences_enum".
id primary key
Relevant triggers:
Module overview
This new module enables storing all headers in XAVP to freely modify them in the kamailio logic and
only apply them once when it’s time for the packet to be routed outside. The main goal of the module is
to offload the intermediate header processing into the XAVP dynamic container as well as provide with
high level methods and pseudovariables to simplify SIP message header modifications.
In few words:
• as soon as a SIP message enters the proxy, kamailio reads all the headers (using the function
"pv_collect_headers()") and stores them in an XAVP called "headers".
• starting from this point all the header changes are directly performed on the "headers" XAVP. For
example the From header is available at '$xavp(headers[0]⇒From[0])'.
• right before the SIP message leaves the proxy, kamailio writes back all the headers changes (using
the function "pv_apply_headers()").
RURI and the headers listed in the module parameter "skip_headers" are left untouched and not saved
in the XAVP. Therefore they should be handled in the usual way.
Template changes
As described before in the upgrade procedures, the module is enabled by default in kamailio proxy and
all the templates have been already updated to use this new logic. Before proceeding with the
upgrade, it is essential that the customtt/patchtt files you have in place are updated to this new format.
Here some few examples of what has been changed in the proxy templates:
• variables $fu, $fU, $fd, $fn, $ft have been substituted by $x_fu, $x_fU, $x_fd, $x_fn, $x_ft
• variables $tu, $tU, $td, $tn, $tt have been substituted by $x_tu, $x_tU, $x_td, $x_tn, $x_tt
• variables $rr, $rs have been substituted by $x_rr, $x_rs
• variables $ua have been substituted by $x_hdr(User-Agent)
• variables $ai have been substituted by $x_hdr(P-Asserted-Identity)
• variables $pU, $pd have been substituted by $x_hdr(P-Preferred-Identity)
• variables $re have been substituted by $x_hdr(Remote-Party-ID)
• variables $di have been substituted by $x_hdr(Diversion)
• variables $ct have been substituted by $x_hdr(Contact)
• $hdr("name") has been substituted by $x_hdr("name")
• is_present_hf("name") has been sustituted by $x_hdr(name)!= $null
• remove_hf("name") has been substituted by pv_remove_header("name") function or
$(x_hdr(name)[*]) = $null
• append_hf("name: value\r\n") has been substituted by pv_append_header("name", "value") /
Module documentation
Parameters
xavp_name (string)
Default: headers
Result:
$xavp(headers[0]=>From)
$xavp(headers[0]=>To)
$xavp(headers[0]=>Call-ID)
....
skip_headers (string)
A comma separated headers list that must be excluded from processing (they are skipped when
pv_apply_headers() changes the sip message headers). If the parameter is not set then the "Default" list
is used. If the parameter is set to an empty string then all the sip message headers are processed.
Default: Record-Route,Via,Route,Content-Length,Max-Forwards
split_headers (string)
A comma separated headers list that must be split into multi headers if their value is a comma
separated list. If the parameter is not set then the "Default" is used. If the parameter is set to an empty
string then no headers are split.
Default: None
Result:
Received Diversion header:
Diversion:
<[email protected]>,<[email protected]>,<[email protected]>
After split:
Diversion: <[email protected]>
Diversion: <[email protected]>
Diversion: <[email protected]>
Becomes handy if used together with pv_modify_header() or
pv_remove_header()
to change or remove value 2 for instance.
Functions
pv_collect_headers()
This function collects all headers from the message into the XAVP. It should be used preferably just
when the sip message is reveived by kamailio.
Returns:
• 1 - on success
• -1 - if there were errors
pv_apply_headers()
This function applies the current XAVP headers state to the real headers and should be called only
once per branch when the message is about to leave kamailio.
• all headers in the XAVP except for ones provided in the "skip_headers" parameter and From/To are
recreated in the sip message.
• From/To headers are processed by the uac module if it is loaded.
• From/To headers are not changed in the reply messages.
• headers with NULL value are removed if exist in the sip message.
• the initial order of the sip headers is preserved.
Usage:
if (pv_apply_headers())
{
"success"
}
else
{
"errors"
}
pv_reset_headers()
This function resets the current XAVP headers list and enables pv_collect_headers() and
pv_apply_headers() to be called again in the same branch.
Usage:
if (pv_reset_headers())
{
"success"
}
else
{
"errors"
}
pv_check_header(hname)
This function checks if the header already exists in the XAVP. It can be freely called from anywere, but
only after pv_collect_headers().
Usage:
if (pv_check_header(hname))
{
"exists"
}
else
{
"does not exist"
}
pv_append_header(hname, hvalue)
This function appends a new header into the XAVP. It can be freely called from anywere, but only after
pv_collect_headers(). Please note that subsequent "pv_append_header" calls will result in multiple
headers. If the provided "hvalue" is $null then the header is added into the XAVP but it is not going to be
added into the message.
Usage:
if (pv_append_header(hname, hvalue))
{
"appended"
}
else
{
"errors"
}
pv_modify_header(hname, hvalue)
This function modifies an existing header in the XAVP. It can be freely called from anywere, but only
after pv_collect_headers(). Please note that if the header does not exist it will be explicitly appended. If
there are multiple headers with the same name only the first one will be affected. If the provided
header value is $null then the header is modified in the XAVP then it is removed from the sip message
when pv_apply_headers() is called.
Usage:
if (pv_modify_header(hname, hvalue))
{
"modified"
}
else
{
"errors"
}
This function works similar to pv_modify_header(hname, hvalue) but should be used when there are
multiple headers with the same name one of them to be modified. Index order is top to bottom.
Usage:
pv_remove_header(hname)
This function removes an existing header from the XAVP. It can be freely called from anywere, but only
after pv_collect_headers(). If there are multiple headers with the same name all of them are removed. It
Usage:
if (pv_remove_header(hname, hvalue))
{
"removed"
}
else
{
"does not exist or errors"
}
This function works similar to pv_remove_header(hname, hvalue) but should be used when there are
multiple headers with the same name one of them to be removed. Index order is top to bottom.
Usage:
Pseudovariables
$x_hdr
This pseudovariable is used to append/modify/remove headers by their name and can be used
instead of the pv_append_header(), pv_modify_header(), pv_remove_header() functions.
Usage:
• append header "X-Header" with value "example". NOTE: It always appends a header, even there is
already one with the same name
$x_hdr(X-Header) = "example";
• modify header "X-Header" with index 0. Returns an error if there is no such index
$(x_hdr(X-Header)[0]) = "example";
• remove all occurrences of header "X-Header" and append one with value "example"
$(x_hdr(X-Header)[*]) = "example";
• remove header "X-Header" with index 2 (if there are multiple headers). Returns an error if there is no
such index
$(x_hdr(X-Header)[2]) = $null;
• remove all occurrences of the header. Does not produce an error if there is no such header
$(x_hdr(X-Header)[*]) = $null;
$var(test) = $x_hdr(X-Header);
$var(test) = $x_hdr(X-Header)[*]);
$var(test) = $(x_hdr(X-Header)[2]);
$x_fu, $x_tu
These pseudovariables are used to modify/retrieve the "From" and "To" headers.
Usage:
$var(test) = $x_fu;
$x_fU, $x_tU
These pseudovariables are used to modify/retrieve the username part of the "From" and "To" headers.
Usage:
$x_fU = "440001";
$var(test) = $x_fU;
$x_fd, $x_td
These pseudovariables are used to modify/retrieve the domain part of the "From" and "To" headers.
Usage:
$x_fd = "example.local";
$var(test) = $x_fd;
$x_fn, $x_tn
These pseudovariables are used to modify/retrieve the display part of the "From" and "To" headers.
Usage:
$x_fn = "User1";
$var(test) = $x_fn;
$x_ft, $x_tt
These pseudovariables are used to retrieve the tag part of the "From" and "To" headers.
Usage:
$var(test) = $x_ft;
$x_rs, $x_rr
These pseudovariables are used to modify/retrieve or change "status" and "code" of the SIP reply
NOTE: Only messages with reply status > 300 can be changed as well as reply status 1xx and 2xx
cannot be set
Usage:
$x_rs = 486
$var(test) = $x_rs;
$var(test) = $x_rr;
In order to troubleshoot/debug/capture a scenario, the "debug proxy" allows defining a list of "debug
subscribers" that will be matched against From/To headers for every SIP message on a specific lb
node. If matched that SIP message will be delivered to the assigned proxy node. In summary, any call
to/from that subscriber will be easily traced since no calls are delivered by default to an inactive
"debug proxy" node. Also, you can enable extra debug levels on the "debug proxy" node which will NOT
affect production traffic on the platform.
The subscribers have to be specified in the same format as they are received on
IMPORTANT
Kamailio LB (before all the rewrite rules applied).
In the following examples both proxy node 'prx99a' and 'prx99b' must be set to
IMPORTANT inactive nodes 'hosts.prx99a.status=inactive' and 'hosts.prx99b.status=inactive' in
network.yml!
And make sure 'prx99' active node has this new config applied.
There’s a command-line tool available to manage the subscriber list. An example of use:
Be aware that the list of debug subscribers belongs to just one lb pair, the info is kept in REDIS 'local'
database, it is necessary to survive LB restarts and/or HA switchovers. To skip saving in REDIS 'local'
database, specifying the option '--no-store' (in this case the information will stay in memory only and
will be void on Kamailio LB restart):
ngcp-debug-subscriber --help
ngcp-debug-subscriber add --help
The "debug subscribers" is kept in a kamailio htable. htable index size value can be changed if
necessary in config.yml using the option 'kamailio.lb.debug_uri.htable_idx_size'. This is not the
maximum size. From Kamailio htable documentation:
size - number to control how many slots (buckets) to create for the hash
table.
A larger value means more slots with a higher probability for fewer
collisions.
The actual number of slots (or buckets) created for the table is 2^size.
The possible range for this value is from 2 to 31, smaller or larger
values
will be increased to 3 (8 slots) or decreased to 14 (16384 slots).
Note that each slot can store more than one item, when there are
collisions of
hash ids computed for keys. The items in the same slot are stored in a
linked list.
In other words, the size is not setting a limit of how many items can be
stored in a hash table, as long as there is enough free shared memory,
new items can be added.
The default value 'kamailio.lb.debug_uri.htable_idx_size=4' is enough for all the use cases in production.
Currently services and daemon executables namespaced too with 'ngcp-' can be found
within PATH, but are not intended for general execution, and might eventually be
NOTE
moved out under /usr/libexec/. These are listed in the table "Internal NGCP
component" below.
• ngcpcfg
• ngcp-loglevel
• ngcp-service
• ngcp-status
Name Description
Configuration tools:
ngcpcfg main NGCP configuration tool
ngcp-initial-configuration configure 'bare' node as NGCP (cluster) member
ngcp-network command line interface to ngcp-config network
configuration settings
ngcp-support-access enable/disable Sipwise Support team access to
NGCP
ngcp-toggle-performance-config switch NGCP performance modes: low/high
Maintenance tools:
ngcp-approx-cache update cached APT metadata in Approx
ngcp-approx-snapshots manage (create/delete/export/import) snapshots
of Approx
ngcp-customtt-diff-helper prepare local customtt/patchtt files for Sipwise
analyses
ngcp-loglevel show/set debug level per component in run-time
ngcp-ppa handle Sipwise PPA APT repositories for NGCP
customization
ngcp-prepare-upgrade prepare NGCP to upgrade to the new
release/build
Name Description
ngcp-reset-db reset MariaDB database. NOTE: think twice before
calling it!
ngcp-update wrapper for the latest hotfixes installations inside
the same release
ngcp-update-cfg-schema update ngcp-config YML files. Safe to re-execute
ngcp-update-db-schema upgrade MariaDB. Safe to re-execute
ngcp-upgrade Sipwise NGCP platform upgrade framework to
upgrade on new release/build. Execute with
caution!
ngcp-upgrade-pre-checks check possible issues/misconfigurations before
the upgrade
Operational tools:
ngcp-active-calls show/drop active calls matching search criteria
ngcp-cdr-md5 validate the integrity of exported CDR files
ngcp-check-active show HA node status (active/standby)
ngcp-check-redis-dialogs script to check stalled Kamailio dialogs in Redis
DB
ngcp-clish CISCO-like CLI on a UNIX system. Provides various
cluster helpers
ngcp-disk-usage disk usage statistic tool (symlink to ncdu)
ngcp-kamcmd Kamailio console debug tool
ngcp-kamctl Kamailio command-line interface
ngcp-location-cleanup Delete expired location entries from Redis
ngcp-log-flow create a call flow of a single Call-ID taking NGCP
logs as input
ngcp-logs search a string in NGCP logs. Useful to retrieve
Kamailio and SEMS logs given a call-id
ngcp-make-active make HA node active (revoke standby HA state
from the peer)
ngcp-make-standby make HA node standby (revoke active HA state
from the peer)
ngcp-memory-usage report processes with the biggest RAM/SWAP
usage
ngcp-mysql-compare-dbs fast compare MariaDB schemas between two
hosts
ngcp-redis-helper easier various data requests from Redis DB
ngcp-service manage NGCP system services. See 'man ngcp-
service' for more details
Name Description
ngcp-status show general overall NGCP status. It is a wrapper
for many NGCP tools
ngcp-support-upload upload files to the ticket on support.sipwise.com
ngcp-system-tests main self-check tool. Safe to execute in
production
ngcp-usr-location show the correct VoIP registrations (from Redis
DB). See 'ngcp-usr-location --help'
REST API tools:
ngcp-api-admins manage NGCP Administrators
ngcp-api-delete send arbitrary DELETE request to NGCP REST API
ngcp-api-get send arbitrary GET request to NGCP REST API
ngcp-api-patch send arbitrary PATCH request to NGCP REST API
ngcp-api-ping fast check for NGCP REST API availability
ngcp-api-post send arbitrary POST request to NGCP REST API
ngcp-api-put send arbitrary PUT request to NGCP REST API
ngcp-create-customer create NGCP Customer
ngcp-create-domain create NGCP Domain
ngcp-create-subscriber create NGCP Subscriber
ngcp-delete-domain delete an NGCP Domain. Execute with caution
(subscribers are deleted with a domain)!
ngcp-get-customer get customer info by the customer ID
ngcp-terminate-customer terminate an NGCP Customer
ngcp-terminate-subscriber terminate an NGCP Subscriber
Deprecated tools (will be removed soon):
ngcp-delete-subscriber backward compatibility symlink to ngcp-
terminate-subscriber
ngcp-delete-voip-account backward compatibility symlink to ngcp-
terminate-customer
ngcp-get-voip-account backward compatibility symlink to ngcp-get-
customer
ngcp-voicemail-table-cleanup backward compatibility symlink to ngcp-cleanup-
voicemail-table
TIP they can be used, but they might be changed without the notification.
Name Description
ngcp-bcrypt-webpassword migration encrypt subscribers' WEB passwords
using bcrypt
ngcp-check-rev-applied check which DB/config revisions have been
executed
ngcp-check-sip-option monitoring tool that sends an OPTIONS request to
a SIP server
ngcp-chroot-shell a suid root program that will take care of securely
opening a shell inside a jail
ngcp-create-testusers developers generate a batch of
customers/subscribers
ngcp-dlgcnt-check check Kamailio dialogs counters in Redis DB
ngcp-dlgcnt-clean remove Kamailio dialogs from Redis DB
ngcp-dlglist-clean remove Kamailio queue dialogs from Redis DB
ngcp-ha-host-state keep HA peers in sync (used by ngcp-config)
ngcp-ha-proc-state keep HA peers in sync (used by ngcp-config)
ngcp-ha-crm print current CRM in use
ngcp-io-scheduler systemd helper to set proper IO scheduler on the
system boot (HDD related only)
ngcp-kamailio-shm-usage developers generate Kamailio shared memory
usage report
ngcp-location-migrate temporary migrate from Kamailio locations from
MariaDB to Redis DB
ngcp-location-sync temporary sync Kamailio locations after migration
from MariaDB to Redis
ngcp-memdbg-csv developers generate Kamailio modules memory
usage
ngcp-network-validator dynamically validates the network.yml file (used
by ngcp-config)
ngcp-nodename print the current NGCP HA node name
ngcp-panel-create-keys generate encryption keys for ngcp-panel
ngcp-peerprobe-status internal NGCP monitoring tool
ngcp-prepare-translations developers tool for NGCP localization files.
Available on 'trunk' systems only
ngcp-screen-check check if the current session is running inside a
screen/tmux
ngcp-ssh NGCP wrapper for SSH. Used inside various NGCP
scripts to access neighbors in the cluster
ngcp-sync-constants sync MariaDB credentials with /etc/ngcp-
config/constants.yml (used by ngcp-config)
Name Description
ngcp-sync-grants sync MariaDB grants with /etc/mysql/grants.yml
(used by ngcp-config)
ngcp-type reports back NGCP type: spce/sppro/carrier
ngcp-upgrade-redis-usrloc move Kamailio locations from MariaDB to Redis in
mr7.5
ngcp-virt-identify check hardware/virtual installation type. See 'man
ngcp-virt-identify' for more details
Name Description
ngcp-backup main executable binary file for backup component
ngcp-cdr-exporter main executable binary file for CDR exporter
component
ngcp-cleanup-acc script responsible for cleaning up accounting
database is by cron
ngcp-cleanup-cdr-files script responsible for cleaning up exported CDR
files by cron
ngcp-cleanup-sems script cleans up SEMS calling card tokens in Redis
by cron
ngcp-cleanup-voicemail-table script cleans up voicemail records on a monthly
basis by cron
ngcp-credit-warning main executable binary file for check for contract
balances above credit warning thresholds
ngcp-emergency-mode main executable binary file for emergency mode
component
ngcp-event-exporter main executable binary file for events exporter
component
ngcp-fraud-notifier sends fraud notifications for customers that
exceed the threshold
ngcp-installer main executable binary file for installer
component
ngcp-int-cdr-exporter main executable binary file for intermediate CDRs
exporter component
ngcp-licensed main executable binary file for licensed
component
ngcp-mediator main executable binary file for mediator
component
Name Description
ngcp-provisioning-template create subscribers with detailed settings
according to provisioning templates
ngcp-rate-o-mat main executable binary file for rate-o-mat
component
ngcp-reminder main executable binary file for reminder
component
ngcp-rtpengine-iptables-setup systemd related helper for rtpengine
ngcp-rtpengine-recording-nfs-setup systemd related helper for rtpengine-recording
ngcp-sems main executable binary file for B2BUA component
ngcp-vmnotify an Asterisk VoiceMail compatible MWI notification
script
ngcp-vmsmsnotify same as ngcp-vmnotify, but for SMS notifications
ngcp-witnessd main executable binary file for witnessd
component
Overview
SIP message '181 - Call Is Being Forwarded' is an optional provisional response that can be sent towards
the caller user to inform it of an ongoing call forward. The message can also contain History-Info
headers necessary to the caller to identify which is the new destination of the call.
How to enable it
By default Sipwise C5 doesn’t generate any 181 message. To enable this feature two steps are required:
The first preference will actually activate the 181 message generation. The second one, instead, allows
SEMS to forward back to caller all the provisional messages even if they contain a different To-Tag.
Without this second preference set, the 181 message is sent towards the caller but all the following 18x
messages are blocked by SEMS.
How it works
When a call forward is triggered in Sipwise C5, Kamailio Proxy stores in the Redis database, which is
selected by 'kamailio.proxy.cf_send_181.redis_db' preference in config.yml, the History-Info headers
that are added to the outgoing INVITE message. Kamailio LB receives the outgoing INVITE and it
generates a '182 - Connecting' message back towards the caller. The 182 message is received by
Kamailio Proxy that converts it in a '181 - Call Is Being Forwarded' message and adds the History-Info
headers previously stored in the Redis DB, if any. The message is then sent back to the caller.
The WebRTC subscriber is a normal subscriber which has just a different configuration in his
Preferences. You need to change the following preferences under Subscribers→Details→Preferences→NAT
and Media Flow Control:
The transport_protocol setting may change, depending on your WebRTC client/browser configuration.
Supported protocols are the following:
In order to have a bridge between normal SIP clients (using plain RTP for example) and WebRTC client,
the normal SIP clients' preferences have to have the following configuration:
This will teach Sipwise C5 to translate between Plain RTP and RTP/SAVPF when you have calls
between normal SIP clients and WebRTC clients.
By default, the built-in template will set the subscriber’s SIP URI as
[CC][AC][SN]@[DOMAIN], where [DOMAIN] is defined within the template as a static
value (in the subscriber.domain attribute). An alpha-numeric string will be generated
NOTE
automatically for the SIP password. Additionally, the contract_contact.reseller
and contract.billing_profile attributes (among others) may need to be adjusted
to particular provisioning needs.
fields:
- name: first_name
label: "First Name:"
type: Text
required: 1
- name: last_name
label: "Last Name:"
type: Text
required: 1
- name: cc
label: "Country Code:"
type: Text
required: 1
- name: ac
label: "Area Code:"
type: Text
required: 1
- name: sn
label: "Subscriber Number:"
type: Text
required: 1
- name: sip_username
type: calculated
value_code: "function() { return
row.cc.concat(row.ac).concat(row.sn); }"
- name: purge
label: "Terminate subscriber, if exists:"
type: Boolean
contract_contact:
identifier: "firstname, lastname, status"
reseller: default
firstname_code: "function() { return row.first_name; }"
lastname_code: "function() { return row.last_name; }"
status: "active"
contract:
product: "Basic SIP Account"
billing_profile: "Default Billing Profile"
identifier: contact_id
contact_id_code: "function() { return contract_contact.id; }"
subscriber:
domain: "example.org"
primary_number:
cc_code: "function() { return row.cc; }"
ac_code: "function() { return row.ac; }"
sn_code: "function() { return row.sn; }"
username_code: "function() { return row.sip_username; }"
password_code: "function() { return row.sip_password; }"
subscriber_preferences:
gpp0: "test"
fields:
- name: first_name
label: "First Name:"
type: Text
required: 1
- name: last_name
label: "Last Name:"
type: Text
required: 1
- name: cc
label: "Country Code:"
type: Text
required: 1
- name: ac
label: "Area Code:"
type: Text
required: 1
- name: sn
label: "Subscriber Number:"
type: Text
required: 1
- name: sip_username
type: calculated
value_code: "sub { return $row{cc}.$row{ac}.$row{sn}; }"
- name: purge
label: "Terminate subscriber, if exists:"
type: Boolean
contract_contact:
identifier: "firstname, lastname, status"
reseller: default
firstname: "sub { return $row{first_name}; }"
lastname: "sub { return $row{last_name}; }"
status: "active"
contract:
product: "Basic SIP Account"
billing_profile: "Default Billing Profile"
identifier: contact_id
contact_id_code: "sub { return $contract_contact{id}; }"
subscriber:
domain: "example.org"
primary_number:
cc_code: "sub { return $row{cc}; }"
ac_code: "sub { return $row{ac}; }"
sn_code: "sub { return $row{sn}; }"
username_code: "sub { return $row{sip_username}; }"
password_code: "sub { return $row{sip_password}; }"
subscriber_preferences:
gpp0: "test"
www_admin:
batch_provisioning_features: 1
provisioning_templates:
"My First Provisioning Template":
description: "Create a contract including contact with firstname
and lastname for a single subscriber."
lang: js
fields:
- name: first_name
label: "First Name:"
type: Text
required: 1
- name: last_name
label: "Last Name:"
type: Text
required: 1
- name: cc
label: "Country Code:"
type: Text
required: 1
- name: ac
label: "Area Code:"
type: Text
required: 1
- name: sn
label: "Subscriber Number:"
type: Text
required: 1
- name: sip_username
type: calculated
value_code: "function() { return
row.cc.concat(row.ac).concat(row.sn); }"
- name: purge
label: "Terminate subscriber, if exists:"
type: Boolean
contract_contact:
identifier: "firstname, lastname, status"
reseller: default
firstname_code: "function() { return row.first_name; }"
lastname_code: "function() { return row.last_name; }"
status: "active"
contract:
product: "Basic SIP Account"
billing_profile: "Default Billing Profile"
identifier: contact_id
contact_id_code: "function() { return contract_contact.id; }"
subscriber:
domain: "example.org"
primary_number:
cc_code: "function() { return row.cc; }"
ac_code: "function() { return row.ac; }"
sn_code: "function() { return row.sn; }"
username_code: "function() { return row.sip_username; }"
password_code: "function() { return row.sip_password; }"
subscriber_preferences:
gpp0: "test"
www_admin:
batch_provisioning_features: 1
provisioning_templates:
"My First Provisioning Template":
description: "Create a contract including contact with firstname
and lastname for a single subscriber."
fields:
- name: first_name
label: "First Name:"
type: Text
required: 1
- name: last_name
label: "Last Name:"
type: Text
required: 1
- name: cc
label: "Country Code:"
type: Text
required: 1
- name: ac
label: "Area Code:"
type: Text
required: 1
- name: sn
label: "Subscriber Number:"
type: Text
required: 1
- name: sip_username
type: calculated
value_code: "sub { return $row{cc}.$row{ac}.$row{sn}; }"
- name: purge
label: "Terminate subscriber, if exists:"
type: Boolean
contract_contact:
identifier: "firstname, lastname, status"
reseller: default
firstname: "sub { return $row{first_name}; }"
lastname: "sub { return $row{last_name}; }"
status: "active"
contract:
product: "Basic SIP Account"
billing_profile: "Default Billing Profile"
identifier: contact_id
contact_id_code: "sub { return $contract_contact{id}; }"
subscriber:
domain: "example.org"
primary_number:
Then, the following cf_mappings section can be appended to the batch provisioning template:
cf_mappings:
cfu: []
cfb:
- enabled: 1
destinationset:
name: "Phone2"
destinations:
- destination: "123456"
priority: 1
timeout: 300
cft:
- enabled: 1
destinationset:
name: "Phone3"
destinations:
- destination: "654321"
priority: 1
timeout: 300
cft_ringtimeout: 15
cfna:
- enabled: 1
destinationset:
name: "VoiceMail"
destinations:
- destination: "voicebox"
priority: 1
timeout: 300
cfs: []
cfr: []
cfo: []