# Introduction

## About DNL Class 4 Switch

Denovolab's Class 4 Fusion is a high performance switching platform developed for both termination and origination traffic.  This platform not only can handle International A-Z termination but also US domestic termatiion, as well as origination traffic.&#x20;

Class 4 Fusion is the only platform that a VoIP operator will need because it is equips with :

* Billing
* Routing
* Switching
* Monitoring
* Rate Generation&#x20;
* CDR/PCAP Backup and Archive

Users of Class 4 Fusion does not need to buy any 3rd part software because all necessary components to run a successful VoIP business is all provided for. &#x20;

We write this cookbook to help our users to install and manage their own DNL Class 4 switch.  We try to put as much as we know in this book without reservation.  If you have any topic that you want us to write about but it is not already covered, please [submit a ticket](http://support.denovolab.com) to us and we will add it asap.

This cookbook is a fast-food type of user manual for users to get started very quickly to deploy and run calls.  It provide the most basic setup and some common questions we normally get asked. &#x20;

However, Class 4 is a very huge platform and have more features than what we are covering here.  You can check all features from our [user manual](https://doc.denovolab.com/display/CLAS4v6/Welcome+to+Denovo+Class4V6) at <https://doc.denovolab.com/display/CLAS4v6/Welcome+to+Denovo+Class4V6>.


# Configure a new Class 4 instance

## First Step

After you install your Class 4 instance, you will need to gain access to the UI portal to start setting up your switch data.&#x20;

You also will need to add VoIP gateway to connect to the UI.&#x20;

This section will go through how to do this two steps.&#x20;


# Setup Admin Access

After you finish installation, you can access to the following URL to configure your admin user and password.

```
http://{your_ip}/setup 
```

You should see the following:

![](/files/-MdtSYJ1UgbhAoEHQzhV)

You can setup your admin user and password.  After you are done, then you can go to the landing page to login.  Your landing page URL is:

```
http://{your_ip}/ 
```

## What if I lost my Admin password

If you lost your admin password, you can remove the admin user in DB using the following command:

```


[root@ns505185 ~]# psql -U postgres
psql (12.5)
Type "help" for help.
postgres=# \l
                                  List of databases
    Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
------------+----------+----------+-------------+-------------+-----------------------
 class4_dnl | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
            |          |          |             |             | postgres=CTc/postgres
 template1  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
            |          |          |             |             | postgres=CTc/postgres
(4 rows)
postgres=# \c class4_dnl ;
You are now connected to database "class4_dnl" as user "postgres".
class4_dnl=# delete from users where user_id =1;
```

Once the admin user is removed, you can get on to the /setup page to reset a new admin user.&#x20;


# First Time Login

The first time you login to Class 4, you will get a pop up box that let you select your standard landing page.  This landing page will be used in the future as the first page to show after you login:

![](/files/-MdtW78u5lkoLBJ39a72)

You can then go to the landing page or use the setup wizard that will guide you to configure your switch for live traffic.&#x20;


# Setup SIP Switch

Each UI can connect to as many SIP Switch as you want.  These SIP Switches can be running in different servers also.  Each Class 4 switch has a telnet port and this telnet port enable the UI to communicate with it.&#x20;

Here is how you need to do to setup the SIP Switch:

![Click on VoIP Gateway on right side](/files/-MdtWTuvXjLYuSEe626Z)

&#x20;In the VoIP Gateway page, you can specify the telnet IP and port to access to the dnl\_softswitch instance:

![](/files/-MdtWnSlXLj0kuFC8m_W)

Each dnlsoftswitch instance can listen to multiple SIP IP:port.  You can click on + to add as many SIP IP:port combination as you need.&#x20;

![](/files/-MdtX0KKeJWX8AKrxfUH)

After you modify the VoIP gateway, you will need to restart dnl\_softswitch instance in order for the change to take place.&#x20;

You can use the following command to check if the SIP port is live or not:

```
[root@ns505183 ~]# netstat -anp |grep 5060
udp        0      0 198.27.82.144:5060      0.0.0.0:*                           27257/dnl_softswitc 
[root@ns505183 ~]# netstat -anp |grep 5080
udp        0      0 198.27.82.144:5080      0.0.0.0:*                           27257/dnl_softswitc 
[root@ns505183 ~]# 
```


# Your First Call with Class 4 Fusion

Class 4 Fusion is a very easy to use softswitch.  Here are the basic steps you need to do to start traffic:

1. Create Vendor Rate Table
2. Create Termination Vendor
3. Create Egress trunk
4. Create Dynamic Routing
5. Create Routing Plan
6. Create Termination Client
7. Create Ingress trunk
8. Execute Call Simulation&#x20;

We are going to go through it here :


# Create Vendor Rate Table

Go to Routing > Rate Table, you can see the list of existing rate tables:

![](/files/-MZp_K_fqdM2bfDBPDY9)

Then, you can click on Create New button to create a new rate table:

![](/files/-MZp_XdGQuKMv8UcGOTO)

After that, you can click on "Submit".

![](/files/-MZp_em_Lhwa_Zf8RrVr)


# Create Termination Vendor

You can create a new Termination Vendor by going into Termination > Vendor&#x20;

![](/files/-MZp_qIsGxOa4joock5Y)

In this Vendor listing page, you can click on "Create New" to create a new vendor:

![](/files/-MZpaCPpd_Bh-TTkmuxf)

All the required fields are marked with \*\*.  Here the company name and Main email address are the two required fields for creating a new terminating vendor.

![](/files/-MZpaSjmKOQAN7BU0E-e)

The Creation wizard will guard you through each step then at the end, you can click on "Submit".

![](/files/-MZpac-w5ZOdJnFFJsm2)

After the process is completed, you can tell Class 4 whether to send a welcome email to your vendor.&#x20;

![](/files/-MZpamROPN4EUPFQ6LqH)

{% hint style="info" %}
You can configure the format of welcome letter and all email templates under Configuration > Email Template.
{% endhint %}


# Create Egress Trunk

After you create a termination vendor, the wizard will prompt you to create a new egress trunk.  Egress trunk defines the IP address and setting of your vendor.

In the New Egress Trunk page, you must provide a trunk name.&#x20;

![](/files/-MZpbNYVyEmsHWb7detE)

{% hint style="info" %}
The Rate Table must be select in order for Class 4 to terminate traffic to this vendor.
{% endhint %}

Then, you must provide IP address to the egress trunk.

![](/files/-MZpbUEgGfPaili2_EsQ)

After you are done, you will see this egress under the terminating vendor's Egress tab.

![](/files/-MZpbY2rwclCP0e3Vpz1)


# Create Dynamic Route

Class 4 is a very flexible and powerful routing engine.  There are many different ways for you to setup routing.  In this quick guide, we will talk about the most basic way of setting up routing.&#x20;

First you go to Routing > Dynamic Routing

![](/files/-MZpwzXy2oXgcY70VXM3)

You can see the list of dynamic routing above.  Then, you can click on "Create New" to create a new dynamic routing.   Here in the dynamic routing, you give it a name and you specify the list of egress trunks that you want to route traffic into within this dynamic routing.&#x20;

![](/files/-MZpx411Bq1ALAQ2pke9)

After you submit, you can see the new dynamic routing created.

![](/files/-MZpx8ydp8UjuwqQrxmm)


# Create Routing Plan

After you create dynamic routing, you can create a routing plan.  Routing plan is en encapsulation of routes based on ANI or DNIS.  For example, you can have one country to route using a specific dynamic routing and another country to route using a static routing.&#x20;

You can also do failover routing within routing plan.  For example, if calls fail to route to a dynamic routing you can send call to anther static routing.&#x20;

You can see dynamic routing and static routing as different ways of selecting vendor trunk and routing plan is a way to assign different static and dynamic routing based on ANI or DNIS of the call.&#x20;

To create a routing plan, you can go to Routing > Routing Plan:

![](/files/-MZq00TU0LTehdt4j4Xv)

In this page, you can see the list of routing plan already created.&#x20;

Then, you can click on "Create New" to create a new routing plan as shown below:

![](/files/-MZq4yS_ueO9hyaOPRF9)

After you create a routing plan, you can click inside the routing plan and add route to it.&#x20;

In this "Add Route" popup, you can specify routing type for each ANI or DNIS combination.

If you just want to simply route all traffic to one dynamic routing, you can leave ANI and DNIS empty.

![](/files/-MZq56osQdoSLRotndef)

After you create the route, you will see the routing rule within the routing plan:

![](/files/-MZq5OBeXllgMTX4FvdE)


# Create Client Rate Table

Before you create a Customer, you need to create Rate Table first for that customer.  The process of creating rate table for customer is same as the process for creating rate table for Vendor. &#x20;

You can refer to [Create Vendor Rate Table](https://cookbook.denovolab.com/your-first-call-with-class-4-fusion/create-termination-vendor) section on how to create a new rate table.


# Create Termination Client

The first step in creating a Termination Client is to go to Termination > Client as shown below:

![](/files/-MZq8-y7GFR8ss35g34M)

In this page, you can see all the existing client.&#x20;

You can click "Create New" to create a new Client.&#x20;

![](/files/-MZq89jK1-nA6GLoX6E9)

The wizard will guide you through each section.  The required fields are marked with \*\*.

Company name is a required fields so you must enter one:

![](/files/-MZq8NH3iQDVBNp7XiOM)

You can setup automatic report pushing to your client:

![](/files/-MZq8TfIybQ4RA70yOW2)

{% hint style="info" %}
You can define email report format under Configuration > Mail Template&#x20;
{% endhint %}

You can setup auto invoicing for the client:

![](/files/-MZq8g3Ctu4-Q2iAeVny)

You can let your client to check traffic via portal:

![](/files/-MZq8oU_loIW_VspCgGK)

When done, you can click on the Submit button in the bottom of the page:

![](/files/-MZq8vNqSKcSqbEUE4bQ)


# Create Ingress Trunk

After you create a new termination client, the guided wizard will lead you to creating a new ingress trunk.  Each client can have many ingress trunks.  Each ingress trunk defines the IP addresses of the client and the routing plan as well as the rate table that is to be applied to the trunk.

If one trunk has multiple rate table and routing, you can use tech-prefix to differentiate them.&#x20;

Here is how the ingress creation page looks:

![](/files/-MZq9KYv_GOrbBxpMsJu)

![](/files/-MZq9OsotnVdh6Mqt5QJ)

You need to fill out the necessary information:

* IP&#x20;
* Rate Table
* Routing Plan

You can then submit, then you will see all the ingress trunks in the Ingress tab of Client.

![](/files/-MZq9Z3-ctcQ_ssxNdcu)


# Simulate Your Call

Before you start making your first calls, you can use Call Simulation to test out the routing to check if it is configured correctly.&#x20;

Call Simulation can be found in Tools > Call Simulation.&#x20;

![](/files/-MZqB443pq-zO9LIqSRW)


# Support Contact

We have multiple support channels for you to get help

| [Google Group  ](https://groups.google.com/g/dnl-class4-user) | All       |
| ------------------------------------------------------------- | --------- |
| <p>Skype Support </p><p>skype account: dnl\_support</p>       | Paid User |
| [Ticketing System](http://support.denovolab.com)              | All       |
| Live Chat                                                     | All       |

If you have found a bug or have feature request, please submit them to our Ticket System.&#x20;

You will get notification when we are done with your request.

If you are using the FREE community edition, but still would like to have live support from DNL, you can pay for a yearly support contract [here](https://buy.stripe.com/fZe5mY0Q99EJdgccMQ).  This support subscription will give you immediate support on a 24/7 basis over skype.&#x20;


# eLearning

DNL provides many video to assist you in using our software.  You can access them from our [Youtube Channel](https://www.youtube.com/channel/UCIVrN4OSdY-r4l_FA4ekIBA).&#x20;

You may want to start with the following:

* [Demo of DNL Class4 ](https://www.youtube.com/watch?v=tgVYjd3UeIA)[Fusion](https://www.youtube.com/watch?v=tgVYjd3UeIA)&#x20;
* [How to install DNL Class 4 Fusion on OVH VM](https://www.youtube.com/watch?v=jIU-bHenFdc\&t=108s)
* [Configuring DNL Class 4 Fusion for live traffic](https://www.youtube.com/watch?v=vK5ybU644cc)


# Bug Reporting Process

If you find bugs, you can come to our [Jira](http://support.denovolab.com) site :

![](/files/-MY2oq7beg0SibxtDu2u)

You can then click on "Report a bug" to submit your bug report:

![](/files/-MY2p3neZDik1qm1lj9e)

Once you submit your bug report, you will receive a confirmation email.  When the issue is resolved, you will be informed via email.  &#x20;


# Hardware Sizing

Class 4 Fusion is built using C and on top of sofia-sip stack.  It is extremely efficient so you don't need a lot of hardware power to run a high volume of traffic.&#x20;

The size of disk depends on CPS and how many days of CDRs you want to keep in DB and in local disk. As you can push CDRs to Google Cloud, you don't need to keep many CDRs in local disk in raw format.  However, you may want to keep more CDRs in DB for UI query. &#x20;

You should estimate about 200 GB of disk space per day of CDR.&#x20;

#### 50000 Ports / 10000 CPS

| Component | Spec                                                    |
| --------- | ------------------------------------------------------- |
| Memory    | 128 GB                                                  |
| Disk Size | 2 X 4 TB                                                |
| CPU       | Intel 2x Xeon Silver 4214 - 24 c / 48 t - 2.2 GHz / 3.2 |

####

#### 10000 Ports / 3000 CPS

| Component | Spec                                                    |
| --------- | ------------------------------------------------------- |
| Memory    | 128 GB                                                  |
| Disk Size | 2 X 4 TB                                                |
| CPU       | Intel 2x Xeon E5-2650v3 - 20 c / 40 t - 2.3 GHz / 3 GHz |

#### 5000 Ports / 1000 CPS

| Component | Spec                                                      |
| --------- | --------------------------------------------------------- |
| Memory    | 128 GB                                                    |
| Disk Size | 2 X 4 TB                                                  |
| CPU       | Intel 2x Intel Xeon-E 2274G - 4 c / 8 t - 4 GHz / 4.9 GHz |


# Licensing

The free community edition of Class 4 Fusion is free for 500 ports.  We provide you different ways of installing your own community edition on your server, VM, AWS/Google Instance.  This cookbook provides you a very detailed step by step instruction on how you can install DNL Class 4 Fusion.  The Community Edition has the same feature as a commercial version, with the exception that only 500 ports is supported.

If you need help from DNL to install for you, you can do the following:

1. Send a $100 USD installation service fee to DNL via this [`link`](https://buy.stripe.com/14kg1CbuN049fokaEE).&#x20;
2. Fill out the installation questionnaire via this [link](https://forms.gle/T5Q9DA74TnkgebAd6).

If you feel 500 ports is not sufficient, then you can purchase additional licensing from [denovo.me](http://denovo.me).


# Install with Tarball

Step 1 Go  to download.denovolab.com

Download  api, database, systemd service files,  falcon\_rest package, ui and switch binaries

Supported OS is Centos7

## First time install:

Run the following commands:

```
yum -y install epel-release
yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
yum -y install centos-release-scl
yum clean expire-cache
yum -y install python3 python3-pip python3-devel libnetfilter_conntrack postgresql12 postgresql12-devel wget lzma openssl-devel xz-devel gcc libjpeg-turbo-devel ntp python-devel tcpdump wireshark make bzip2-devel sqlite-devel zip expect telnet git ntp redis nginx postgresql12-server prefix12 ip4r12 postgresql12-contrib
```

* Check if  selinux is enabled, and if true, set it to permissive or disable it
* Install  NodeJS for the  UI with the following commands:

```
curl --silent --location https://rpm.nodesource.com/setup_12.x | sudo bash -
yum install -y nodejs
create user  webbackend and denovo_v6:
-          useradd  denovo_v6  -d /opt/denovo_v6
-          useradd  -r  webbackend
```

* copy  content of the systemd.tar.gz into  /etc/systemd/system
* initialize postgresql server:

```
/usrl/psql-12/bin/postgresql-12-setup  initdb postgresql

```

* Go  to /opt/pgsql/12/data/, edit pg\_hba.conf:

```
local   all         all                                 trust
# IPv4 local connections:
host all         all         127.0.0.1/32       trust
# IPv6 local connections:
host all         all         ::1/128             trust
```

* Start  Postgres server using the following command:

```
systemctl  start postgresql
```

* Unpack database archive and  prepare  and load db.   In psql command prompt , make database named class4\_dnl.

Here is how you enter into Postgres prompt:

```
psql   -U postgres
```

Here is how you create .a Postgres database:

```
create database class4_dnl;
create user webbackend superuser login;
```

After that, you navigate to the folder where  you unpacked database files

```
psql  -U postgres class4_dnl  <schema.sql
psql  -U postgres  class4_dnl <data.sql
```

Then you can install Python Backend:

```
pip3  install  falcon-rest-1.0.14.tar.gz
```

* In the directory  /opt/denovo\_v6   copy contend of  the switch binaries
* Create directory web and put content of the UI  archive there
* Go to the dir where api\_dnl is and  run  following commands:

```
pip3  install –U pip
pip3 install  filename_api_dnl.tar.gz
```

* Create file  named denovo.conf in the  /etc/nginx/conf.d/ and put following:

```
server {
     listen   80;
        server_name  localhost;
     root               /opt/denovo_v6/web;
             index   index.html index.htm;
        client_max_body_size 320m;
     # Load configuration files for the default server block.
     include /etc/nginx/default.d/*.conf;
     location / {
     try_files $uri $uri/ @rewrites;
     }
     location @rewrites {
     rewrite ^(.+)$ /index.html last;
     }
     error_page 404 /404.html;
         location = /40x.html {
     }
     error_page 500 502 503 504 /50x.html;
         location = /50x.html {
     }
}
```

* Restart nginx.
* Start  all dnl services&#x20;

```
systemctl start dnl_softswitch, dnl_livecall, dnl_tools dnl_webhelper dnl_api_dnl, dnl_api_dnl_worker@0 dnl_api_dnl_worker@1 dnl_api_dnl_worker@2 dnl_api_dnl_beat
```

Also make sure that redis  and nginx is running,  if you have firewall enabled, add port for the web ui into it

For the switch you need  also to open ports in firewall if you are using it:

Default ones are 4319/udp , 5060/udp

After all is started you should be able to open UI on the ip address of your machine, and take rest configuration from there.

You must setup Selinux according to instruction [here](/installation/setup-selinux) in order for UI to show up.


# Install with RPM

You can install Class 4 on any Centos environment using RPM.  We have RPM for fresh install and update.&#x20;

Each install of Class 4 comes with a forever free 500 ports.  If you need more than 500 ports, you can buy a license from <http://www.denovo.me>.

The following instruction is for Rocky 8 edition.

## Installing Class 4 Fusion Version 6

```
yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
dnf module disable postgresql -y
yum -y install postgresql15-server postgresql15-contrib prefix_15 ip4r_15
yum install -y epel-release
yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
dnf module disable postgresql -y
dnf config-manager --set-enabled powertools
yum install -y python3 python3-pip python3-wheel
curl -sL https://rpm.nodesource.com/setup_18.x | sudo -E bash -
yum -y install nodejs
yum install -y http://repo.denovolab.com/rocky/8/noarch/denovolab-rocky-1-1.noarch.rpm
yum -y install dnl-database
yum -y install denovolabv6-software
yum -y install dnl_live_monitor
systemctl restart nginx
systemctl restart dnl_web_helper 
```

{% hint style="info" %}
You must setup Selinux according to instruction [here](/installation/setup-selinux) in order for UI to show up.
{% endhint %}

##


# Step by Step Guide

RPM installation guide

Step 1 ->

Get the SSH key and open the cookbook page where commands are located

{% embed url="<https://cookbook.denovolab.com/installation/install-with-rpm>" %}

Step 2 ->

Enter the commands one by one to install the switch

![](/files/yjFeAjY9y4HyrzVbRphx)

Step 3 ->

Open the website and do the first time setup and enter the Admin Username and Admin Password. Also, add the SIP IP and Port to complete the process

![](/files/89SSPVTbbMWzGkSompsu)

Step 4 ->

Login using the credential as Admin and start to configure the switch as required

![](/files/ZLLTANQns9XBKaGZZ9EN)

Step 5 ->

Set the desired Landing page. This will open the same page after every login\
By default it is set as Dashboard or just click on Go to Landing page

![](/files/NPln3udbnUYlKiPkG5Dz)

Step 6 ->

Now, you can setup the logo,system configuration like Domain URL / default time zone , timeout settings for PDD and ring call duration

Also First time wizard allows default email setup for switch and LRN setting too

![](/files/VdZIjYV8D9rV2u7wjqMT)![](/files/56Nkazfo56YKKFiyyZzU)![](/files/4lOxb0hBKLkDlIDbayDd)![](/files/A4pFfgAeydDr591XHOOG)![](/files/Qycz4QtSIKM57xQz89X2)![](/files/Tb7kWgnusjYcbw65A9kB)

Step 7 ->

Switch is ready to setup Client , vendors and routing

![](/files/p7aI3KhbVZyfLFUaty1Q)


# Install with AWS

## Search for DNL Class4 in AWS Cloud

After you login to your AWS Cloud, you can look up "denovolab" and find the two versions of DNL Class 4 switch.

![](/files/-MY2bpOLbanjwDqwnSFh)

When you click on "Class4 Fusion Version 6.x", you can install a new image.

![](/files/-MY2c0MKM0UwMPs8v9px)

Here is the full URL to access Class4v5 from AWS Marketplace.

```
https://aws.amazon.com/marketplace/pp/prodview-wpvqijjdhllla
```

Here is the full URL to access Class4v6 from AWS Marketplace.

```
https://aws.amazon.com/marketplace/pp/prodview-eiffyd2wstvwg
```

{% hint style="info" %}
You must setup Selinux according to instruction [here](/installation/setup-selinux) in order for UI to show up.
{% endhint %}


# Install with Google Cloud

Class 4  is already available from Google Cloud. You can search for it from within <http://cloud.google.com>

![](/files/-MY2cAo65GUz3HaxlZr4)

Here is the full URL to access Class4v5 from Google Marketplace.

```
https://console.cloud.google.com/marketplace/product/denovolab-public-260121/class4v5 
```

Here is the full URL to access Class4v6 from Google Marketplace.

```
https://console.cloud.google.com/marketplace/product/denovolab-public-260121/class4v6
```


# Distributed Architecture

Each DNL Class 4 Fusion consists of the following three parts:

* Web UI
* Switch Backend
* Database

You can install Web UI, Switch Backend, and Database with multiple servers to enforce redundancy and high availability.&#x20;

This section discusses how you can do build this configuration.&#x20;


# Switch Server

You can install Switch server with the following commands:

```
yum install -y epel-release
yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
yum -y install centos-release-scl
yum install -y http://repo.denovolab.com/centos/7/noarch/denovolab-1-1.noarch.rpm
yum install -y dnlv6-softswitch dnlv6-livecall dnlv6-tools dnlv6_cloud_tool dnlv6-memdb dnl_watchdog dnl_live_monitor

```

There are multiple modules within Switch Server that you will need to run:

* dnl\_livecall
* dnl\_softswitch
* dnl\_watchdog
* dnl\_cloud
* dnl\_tools
* dnl\_live\_monitor
*


# dnl\_live\_monitor

This dnl\_live\_monitor process is responsible for live monitoring of pcap for all traffic in the switches.  It then use websocket to send the live SIP capture to the UI

You need to configure the dnl\_live\_monitor with this config file:

```
cd  /opt/denovo_v6/dnl_live_monitor
vi settings.cfg 

```

Within the config file, you need to specify the Python API server access.  this module will need this access to validate the API token is valid in order for data to be passed back to UI.

```
#no whitespaces before and after assignment sign are allowed
TOKEN_VALIDATION_URL="http://127.0.0.1:8000/api_dnl/v1/auth/check-token"  ← this neds to be changes to the Url of the  where api server is.
```


# dnl\_tool

This dnl\_tool is an assistance module to the Softswitch module.  It handles all the CDR and reports preparation and generation.  Each softswitch instance must have one dnl\_tool running together.

You need to configure the config file for dnl\_tool:

```
cd /opt/denovo_v6/dnl_tools/conf/
vi  dnl_tools.conf

```

balance\_unifie&#x64;*\_*&#x75;pdate should be set to false:

```
#The client balance unifed update featue, default is disable
balance_unified_update = true   ← change this to false

```

dnl\_tool can auto remove CDRs and reports from DB after they are older than certain number of days.&#x20;

```
#Automatic clean the old data of the database, default is false
auto_clean_db = true  ← change this to false
```

```
[create_table]
#Enable or disable create sub-table feature, default is true
#The create sub-table sql in conf/create_table.sql
create_table = true  ← change this to false

```

```
[balance_daily]
#Enable or disable balance daily feature, default is disable
create_balance_daily = yes ← Change this to no
```

```
#Enable or disable generate balance log feature, default is disable

```

In the case of multiple switch instance installation, you need to make sure only one dnl tool instance has balance handling enabled.  By default, it is enabled.  That means you need to turn it off in all dnl\_tool.conf except the one that is enabled.  Here is how you disable balance handling:

```
#The client balance unifed update featue, default is disable
balance_unified_update = true

#Automatic clean the old data of the database, default is false
auto_clean_db = true

[create_table]
#Enale or disable create sub-table feature, default is true
#The create sub-table sql in conf/create_table.sql
create_table = true
#Create sub-table execute hour, default is 23
#create_table_execute_hour = 23

[balance_daily]
#Enable or disable balance daily feature, default is disable
create_balance_daily = yes
balance_daily_execute_hour = 5
using_cdr_report_table = cdr_report_detail
#Enable or disable generate balance log feature, default is disable
generate_balance_log = yes
```


# dnl\_livecall

The purpose of the dnl\_livecall module is to provide a single daemons service that keep track of live calls in each softswitch instances.&#x20;

In the cases you have multiple softswitch running, you still only need to install one instance of dnl\_livecall module. Each softswitch module must be configured to communicate with this dnl\_livecall module.&#x20;

This dnl\_livecall is also responsible for providing call state information to populate the call state in a softswitch that is restarting.  In the case of softswitch restart, softswitch can contact dnl\_livecall to populate its internal call status so that live calls can sustatin under a softswitch restart event.&#x20;

Only one switch should have dnl\_livecall installed.

Here is how you configure the dnl\_livecall module:

```
cd /opt/denovo_v6/dnl_livecall/conf/
vi dnl_livecall.conf
```

Inside livecall.conf, you need to modify the following field to change the DB server access:

```
db_host = 127.0.0.1
```

This section is for configuring the binding IP of the dnl\_livecall module:

```
[HA]
#HA Server UDP address
ha_listen_ip = 127.0.0.1 ← This needs to be changed to the IP address which is available to the other switches, api and ui. (It can be private ip if the servers have private network established)

[web_client]
web_listen_ip = 127.0.0.1 ← Needs to be changed to the IP address same as above one.

[billing]
billing_listen_ip = 127.0.0.1   ← Same as for other two.
```


# dnl\_softswitch

This is the main switch service that you need to configure for call routing.  Here is how you confgure:

```
cd /opt/denovo_v6/dnl_softswitch/conf
vi dnl_softswitch.conf

```

Each one of the dnl\_*softswtich* instance *must have a unique identifier.  This switch\_*&#x6E;ame needs to be changed on every next switch, it can be changed on all, but it is not requirement for first one. it is because each switch on each server needs to have its unique name in order to function properly.

```
switch_name = class4 
```

This following parameter is to be changed to the ip address where database is installed:

```
[db]
db_host = 127.0.0.1

```

This needs to be changed to the ip address accessible to the UI and api ( it may be private ip if servers have private network established).

```
[CLI]
cli_listen_ip = 127.0.0.1

```

This needs to be changed to the ip address on which dnl\_livecall is set to listen to (also can be from private ip range if there is such setup)

```
[livecall] 
livecall_server_ip = 127.0.0.1
```

This username is also unique and needs to be changed on each additional switch. Also for this to work after change is done, new user needs to be inserted into database in the table c4\_livecall\_users.

```
livecall_login_user = class4  
```

After you finish configuring dnl\_softswitch, you can restart it with the following command:

```
systemctl restart dnl_softswitch
```

You can check if the switch is running with the following command:

```
systemctl status dnl_softswitch
```

Then, you should check if dnl\_softswitch is listening on port 5060:

```
netstat -anp |grep 5060
```

## Binding dnl\_softswitch to port 5060&#x20;

When dnl\_softswitch is first started, it does not automatically listen on port 5060 for SIP traffic.  You need to configure it in the UI. &#x20;

To do so, you first go to the VoIP Gateway page:

![](/files/tBZ4TCz0LtlvHJo8qD1E)

Inside VoIP Gateway, you will see the live instance of VoIP switch:

![](/files/Qaka9fa0tKjK0da8xGdB)

You can see in the above image that this setup has one dnl\_softswitch instance running.  You need to add SIP Profile under this instance by clicking on ![](/files/OkRl1kajRyV9eHSbY9zC) icon.   Each SIP Profile represents the SIP IP that dnl\_softswitch is listening on.  Each instance of dnl\_softswitch can be listening to many SIP IP ( SIP Profile ).

![](/files/1iMXJc0OEUpEwKkDApwd)

As you can see, initially, this dnl\_softswitch is not having any SIP Profile.&#x20;

You need to click on the + icon to add SIP Profile in order for this swtich to start listening on the defined SIP IP and port for traffic:

![](/files/snsm3QSSQZyDy0YlqlcY)


# dnl\_watchdog

dnl\_watchdog is a module responsible for monitoring the hardware resources for DNL Class 4 Fusion.  It also provides interface for the UI to start and stop processes.&#x20;

To configure the dnl\_watchdog instance, you need to go to this file below:

```
cd /opt/denovo_v6/dnl_watchdog/conf
vi dnl_watchdog.conf
```

You must specify the correct IP for the database.  The dnl\_watchdog will publish status and events to DB so that UI can display them.&#x20;

```
pgsql_hostaddr  127.0.0.1  ← Ip address of the database server
pgsql_user  	postgres   ← database user

```

The dnl\_watchdog also works as a live daemon.  It can take incoming requests from Ui to start or stop any DNL Class4 Fusion processes.&#x20;

```
# Account password
# Default: none
#pgsql_pass 	password   ← If database is set to password only access then password here, and remove # from the front.

# Server binding address
# Default: 127.0.0.1
server_ip   	127.0.0.1 ← Ip address which is accessible to the api/ui server.

# Default: none - allow all connections
server_ip_whitelist 	127.0.0.1  ← Add server ip of the api /ui server to allow connections.

```


# dnl\_cloud

```
cd /opt/denovo_v6/dnl_cloud_tool/conf/
vi dnl_cloud_tool.conf:

```

```

# (M) String used to identify this server
server_name 	dnl-host-server ← Change this name for each server dnl_software is running on (for switching part and api/ui one) so it identifies every server that is running .
# Default: connect to Unix-domain socket

pgsql_hostaddr  127.0.0.1  ← address of the postgresql server

pgsql_user  	postgres     ← username for database

#pgsql_pass 	password   ← Password if required (also remove # from the line)

```

Dnl\_cloud\_tool also needs to be configured to the ip address accessible to the UI/api part For this at the time of writing this instructions, values in database table needs to be changed: Table name dnl\_cloud\_status, each running instance of dnl\_cloud\_tool will be shown here in the table along with some data, for example:

```
select * from dnl_cloud_status ;
   server_name   |  instance  | operation | is_online |  	upd_time   	| server_ip | server_port | server_use_ssl | switch_list
-----------------+------------+-----------+-----------+---------------------+-----------+-------------+----------------+-------------
 dnl-host-server | search 	|       	| t     	| 2021-12-02 07:05:54 | 127.0.0.1 |   	33502 | f          	| class4
 dnl-host-server | downloader |       	| t     	| 2021-12-02 07:05:54 | 127.0.0.1 |   	33501 | f          	| class4
 dnl-host-server | dbman  	|       	| t     	| 2021-12-02 07:05:54 | 127.0.0.1 |   	33500 | f          	| class4
(3 rows)

```

In this table server ip needs to be changed to the ip address that is accessible from the server which hosts api/UI.

Sql for this is update table dnl\_cloud\_status set server ip = ‘your ip’ where server\_name = ‘server\_name’ ; (in this example dnl-host-server, but this name is defined in the dnl\_cloud\_tool config and it should be different for each dnl\_cloud\_tool instance.


# Web UI

Class4 Fusion uses NGIX as the web server.  You can have multiple web servers to load balance web UI access.&#x20;

Here is how you install the web component in each one of your web servers:

```
yum install dnlv6-webbackend.noarch dnlv6-webui.x86_64

```

The Web component consists of Vue.js Web Ui and Python API server.&#x20;

After web server is installed, you can configure the API server to connect to the database by going to the following directory:

{% hint style="info" %}
cd /opt/denovo\_v6/api\_dnl
{% endhint %}

Then, you need to edit this fiel: **api.ini**

You then change the followign line to  specify what IP or hostname to bind your API server:

{% hint style="info" %}
**api\_host = localhost**
{% endhint %}

You can specify to use HTTP or HTTPS with the following parameter:

{% hint style="info" %}
**api\_schema = http\://**
{% endhint %}

You can specify the DB access with the following parameter:

{% hint style="info" %}
**db\_conn\_string = postgresql://webbackend\@127.0.0.1:5432/class4\_dnl**
{% endhint %}


# dnl\_web\_helper

Each Web server must have dnl\_web helper installed.  The dnl\_web\_helper is responsible for all the asynchronous jobs for the User Interface.&#x20;

You can start the dnl\_web\_helper with the following command:

```
systemctl start dnl_web_helper
```

{% hint style="info" %}
The dnl web help should be installer in the same server where the web server ( NGINX) is running on.
{% endhint %}


# Troubleshoot Your Installation

## Unable to open up UI&#x20;

After your installation, if you are not able to bring up Login page and you see this kind of error in your browser, then it is likely due to Selinux setting.

![](/files/QuBg98EluxtNUCpVIIkd)

Because we put our software in the /opt path, and Selinux policies does not allow to run web app from anything that it is not /var/[www](http://www).

Since we don't want to change system policies on the customer servers, we set it just temporarily and give user a warning to change if he want permanent setting.

When this issue occurs, you will see the following error in nginx.log file:

```
2022/08/10 09:22:47 [crit] 14588#14588: *1 connect() to 127.0.0.1:8000 failed (13: Permission denied) while connecting to upstream, client: 178.223.69.167, server: localhost, request: "GET /api_dnl/v1/swagger.json HTTP/1.1", upstream: "http://127.0.0.1:8000/api_dnl/v1/swagger.json", host: "33.33.170.221"

The command you can use to check the Selinux policy is as follows:
```

You can use the getenforce command to see your SELINUX mode:

```
# getenforce
Enforcing
```

### How to set your system to Permissive Mode

Use the following procedure to permanently change SELinux mode to permissive. When SELinux is running in permissive mode, SELinux policy is not enforced. The system remains operational and SELinux does not deny any operations but only logs AVC messages, which can be then used for troubleshooting, debugging, and SELinux policy improvements. Each AVC is logged only once in this case.

**Prerequisites**

* The `selinux-policy-targeted`, `libselinux-utils`, and `policycoreutils` packages are installed on your system.
* The `selinux=0` or `enforcing=0` kernel parameters are not used.

**Procedure**

1. Open the `/etc/selinux/config` file in a text editor of your choice, for example:

   <pre><code><strong># vi /etc/selinux/config
   </strong></code></pre>
2. Configure the `SELINUX=permissive` option:

   <pre><code># This file controls the state of SELinux on the system.
   # SELINUX= can take one of these three values:
   #       enforcing - SELinux security policy is enforced.
   #       permissive - SELinux prints warnings instead of enforcing.
   #       disabled - No SELinux policy is loaded.
   <strong>SELINUX=permissive
   </strong># SELINUXTYPE= can take one of these two values:
   #       targeted - Targeted processes are protected,
   #       mls - Multi Level Security protection.
   SELINUXTYPE=targeted
   </code></pre>
3. Restart the system:

   <pre><code><strong># reboot
   </strong></code></pre>

**Verification**

After the system restarts, confirm that the `getenforce` command returns `Permissive`:

<pre><code><strong>$ getenforce
</strong>Permissive
</code></pre>

## License Module Initialization Error&#x20;

If you are seeing the following error in /opt/denovo*v6/dnl\_softswitch/log/dnl\_softswitch.log, you should reset your license IP* [*here*](/installation/change-ip-mac-address)*.*&#x20;

```
Aug 21 23:26:18 194-233-170-221.ip.linodeusercontent.com dnl_softswitch[9387]: 2022-08-21 23:26:18 [ERROR] dnl_core.c:1760 Failed to initialize license module
```

## Unable to open Web Portal

When you do "rpm update", the nginx config may get overwritten.&#x20;

![](/files/BS9SNgvQikOERrVkF15H)

In this case, you can rerun the following command to reset the correct nginx config:&#x20;

<pre><code><strong>yum install dnlv6-webbackend.noarch dnlv6-webui.x86_64
</strong></code></pre>

## API is not responding due to Postgres is down

If API is no responding, then you may also want to check if Postgres is running:

```
# systemctl status postgresql.service
● postgresql.service - PostgreSQL 11 database server
   Loaded: loaded (/etc/systemd/system/postgresql.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2022-09-30 02:26:21 UTC; 8s ago
  Process: 14612 ExecStartPre=/usr/pgsql-11/bin/postgresql-11-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
 Main PID: 14618 (postmaster)
   CGroup: /system.slice/postgresql.service
           ├─14618 /usr/pgsql-11/bin/postmaster -D /opt/pgsql/11/data/
           ├─14620 postgres: logger   
           ├─14631 postgres: checkpointer   
           ├─14632 postgres: background writer   
           ├─14633 postgres: walwriter   
           ├─14634 postgres: autovacuum launcher   
           ├─14635 postgres: stats collector   
           ├─14636 postgres: logical replication launcher   
           ├─14643 postgres: class4_user class4_dnl 127.0.0.1(41500) idle
           ├─14645 postgres: webbackend class4_dnl 127.0.0.1(41506) idle
           └─14648 postgres: class4_user class4_dnl 127.0.0.1(41510) idle
```

If it is showing down, then you can start with the following command.  After you restart Postgresql, you can also restart dnl\_api:

```
systemctl start postgresql.service
systemctl restart dnl_api_core
```


# Setup SSL on Web UI

To enable the ssl to web portal, you can use free certificate from letsencrypt.  To use the free letsencrypt ssl certificate, you can user cerbot.  Cerbot is a bot-like plugin which uses letsencrypt to get ssl certificate.  "certbot-nginx" is a plugin for the certbot  for automate renewal of SSL certificate using on nginx.  A standard free letsencrypt expires every 90 days, so the purpose of "cerbot" is to automatically renew the letsencrypt every 90 days.

The package for cerbot is :

```
python2-certbot-nginx.noarch
```

Here is the command:

```
command is yum -y install python2-cerbot-nginx
```

The following config file is an example for the manual ssl setup for using letsencrypt.  If you are  using cerbot, only thing you need is to change/set server\_name in /etc/nginx/conf.d/denovo.conf

{% code title="" %}

```
    server_name  localhost;    <---- change this to your domain name.
```

{% endcode %}

After you edit /etc/nginx/conf.d/denovo.conf and replace domain name with chosen domain name , you should run the command:

`certbot` &#x20;

You will be presented with wizard which will help you setup an letsencrypt account and  create a fre ssl for you.  this is free  ssl certificate which is valid for 90 days so some 2 weeks before certificate expires, you will be able to renew it by using command:

`certbot renew`

If you are not using cerbot, but you manually generate, or buy  SSL certificates you need to modify nginx config and  set it up manually.  This is the config you should refer to.

```
server {

    #listen       80;
    server_name  localhost;      <---- changing domain name to your domain name                      
    root         /opt/denovo_v6/web;
    index       index.html index.htm;
    client_max_body_size 320m;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
    try_files $uri $uri/ @rewrites;
    }

    location @rewrites {
    rewrite ^(.+)$ /index.html last;
    }


    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }

    listen  443 ssl;      <------- Add SSL listen directive
    ssl_certificate /path/to/ssl/certificate.crt ;   <------- Add path to your cert file
    ssl_certificate_key /path/to/ssl/certificate_key;  <------ Add path to your cert key file
}
```

## Next step

After switching to domain name and choosing **https**, you would also need to edit **api.ini** and change schema and hostname there.

{% hint style="info" %}
**The default path for api.ini is /opt/denovo*****v6/api\_dnl/api.ini***
{% endhint %}

The variables to update are:

* **api\_schema**&#x20;
* **api\_host**

/![](/files/pUtwVJ8Ca6fBXrfBuCth)

Then, you can restart api using the following command:

```
systemctl restart dnl_api_dnl
```

## Auto Renew SSL Certificate

The lescrypt SSL certificate expires every 90 days.  You may want to set it to auto renew by using crontab.  The crontab command is as follows:

```
0 0,12 * * * root python3 -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew
```


# LAN IP Setup for Virtual Machine

This section applies to users who are using Google Cloud Marketplace or AWS Marketplace to install DNL Class 4 Fusion Switching Platform.  This may also apply to some other VM providers that use NAT.

Under the top right menu, please click on "VoIP Gateway."&#x20;

![](/files/FIho43qfvOlwnC56vBIq)

Then, you will see the list of VoIP Gateways installed.  VoIP Gateway is a Switch instance and you can have multiple VoIP Gateway for your installation. Each VoIP Gateway can listen to multiple IP addresses.&#x20;

![](/files/sHljK2uwld5YnHCiv3G0)

For AWS and GCP users, you must specify the external SIP IP and port that is allocated to your VM / Instance.  You must also click on "Enabled" under NAT and specify LAN IP and Port.&#x20;

![](/files/fFJBwZUJVRMrhjKYhMfF)


# Change IP/MAC Address

In this section, we will discuss what you should do if you change IP address in your switch installation. &#x20;

if ip is changed for whatever reason, you must do the following:

1 - Modify dnl\_softswitch.conf file to update license ip and lrn local ip.  The following 2 parameters need to be adjusted to current ip address:

![](/files/76sezvd61R4fLSDREhCS)

2 - Delete these 2 files: dnl\_softswitch.key2 and dnl\_softswitch.lic &#x20;

3 - Restart dnl\_softswitch

{% hint style="info" %}
The default location for dnl*softswitch.conf is /opt/denovo/dnl*\_softswitch/conf
{% endhint %}

{% hint style="info" %}
You can restart Class 4 switch with the command : systemctl restart dnl\_softswitch
{% endhint %}


# Validate Your Installation

This sections will talk about multiple ways to validate your Class 4 Fusion installation.

* Make sure port 5060 is listened by dnl\_softswitch

```
netstat -anp |grep 5060
udp        0      0 94.23.45.144:5060       0.0.0.0:*                           1895254/dnl_softswi 
```


# Check dnl\_softswitch log

The location for dnl\_softswitch log is as follows:

> /opt/denovo\_v6/dnl\_softswitch/log/dnl\_softswitch.log

If your dnl\_softswitch is started successfully, you should see the following lines inside this log:

```
2022-12-28 08:57:37  [NOTICE] routing_data.c:11516 Loading table rate data done
2022-12-28 08:57:37  [NOTICE] routing_data.c:11518 Loading table rate done, elapsed 0(s), loaded 1 records
2022-12-28 08:57:37  [WARNING] routing_data.c:11634 ********** All data loading done **********
2022-12-28 08:57:37  [WARNING] routing_data.c:11638 ********** dnl_softswitch Started **********

```

If you see error such as the following, you should go to the config file and modify the correct IP where postgres is listened on:

```
2022-12-28 08:57:10  [NOTICE] dnl_shaken.c:1615 SHAKEN status thread: couldn't connect to the database!
2022-12-28 08:57:11  [WARNING] dnl_call_qos_report.c:326 DB connect failed, PQstatus:1, connection to server at "154.27.74.199", port 5432 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?
```

The path for dnl\_softswitch config is as follows:

> /opt/denovo\_v6/dnl\_softswitch/conf/dnl\_softswitch.conf

To check the IP for your postgres instance, you can use the following command:

```
[root@switch01 log]# netstat -anp |grep postgres
tcp        0      0 127.0.0.1:5432          127.0.0.1:56800         ESTABLISHED 1885/postgres: webb 
tcp        0      0 127.0.0.1:5432          127.0.0.1:49280         ESTABLISHED 2286/postgres: webb 

```

Inside the dnl\_softswitch.conf, you can find the \[db] block to modify the postgres IP accordingly:

```

[db]
db_host = 127.0.0.1
db_listen_port = 5432
db_name = class4_dnl
db_user = class4_user
db_user_password = 123456


```


# Configuring DNL softswitch

The DNL softswitch reads confgiration from dnl\_softswitch.conf.

You can find this file at:

```
/opt/denovo_v6/dnl_softswitch/conf/dnl_softswitch.conf
```

Most of the configuration is pre-defined for you during the RPM install process.   There are some setting you can use to define custom behaviour and we will go through them in this section.

## Media IP Block

The media IPs to be blocked is defined in the spam\_traffic\_ip table.  By default, dnl\_softswitch blocks calls if it sees those IPs in the SIP INVITE ( for ingress traffic ) and SIP 200 OK ( for egress response ).  If you would prefer to use whitelisting mechanism instead of the default blacklisting, you can configure as follows:

```
file: dnl_softswitch.conf
section: [media]
parameter:
# If true, spam_traffic_ip acts as a whitelist. Otherwise as a blacklist (default)
#spam_traffic_ip_whitelist = true
```


# Setup Selinux

You must setup Selinux properly or else UI will not show up.

Use the following procedure to permanently change SELinux mode to permissive. When SELinux is running in permissive mode, SELinux policy is not enforced. The system remains operational and SELinux does not deny any operations but only logs AVC messages, which can be then used for troubleshooting, debugging, and SELinux policy improvements. Each AVC is logged only once in this case.

**Prerequisites**

* The `selinux-policy-targeted`, `libselinux-utils`, and `policycoreutils` packages are installed on your system.
* The `selinux=0` or `enforcing=0` kernel parameters are not used.

**Procedure**

1. Open the `/etc/selinux/config` file in a text editor of your choice, for example:

   Copy

   ```
   # vi /etc/selinux/config
   ```
2. Configure the `SELINUX=permissive` option:

   Copy

   ```
   # This file controls the state of SELinux on the system.
   # SELINUX= can take one of these three values:
   #       enforcing - SELinux security policy is enforced.
   #       permissive - SELinux prints warnings instead of enforcing.
   #       disabled - No SELinux policy is loaded.
   SELINUX=permissive
   # SELINUXTYPE= can take one of these two values:
   #       targeted - Targeted processes are protected,
   #       mls - Multi Level Security protection.
   SELINUXTYPE=targeted
   ```
3. Restart the system:

   Copy

   ```
   # reboot
   ```

**Verification**

After the system restarts, confirm that the `getenforce` command returns `Permissive`:

Copy

```
$ getenforce
Permissive
```

### &#x20; <a href="#license-module-initialization-error" id="license-module-initialization-error"></a>


# Configuring Stir/Shaken

Denovolab signs and verifies calls with built-in Stir/Shaken feature. This section will explain you the step you need to take to configre Stir/Shaken.

## Step 1: Navigate to Stir/Shaken page

&#x20;![](/files/wPXnDa5P51RD0yvEPrl5)&#x20;

Step 2: Upload your Private Keys and specify Certificate URL:

<figure><img src="/files/SujXGpASFcivK8rYQKUy" alt=""><figcaption></figcaption></figure>


# Generating Certificate with Peeringhub.io

Denovolab Class4 fusion supports certificates from any Stir/Shaken CA.  This section will show you how you can integrate Stir/Shaken Certificate from Peeringhub.io

## Step 1: Register at [portal.peeringhub.io ](https://portal.peeringhub.io/register)for only $500 / year

## Step 2: Make sure your subscription is not expired

![](/files/mfEc7LrHtXnITV1ryA41)

## Step 3: Navigate to STI-Certificate > Private Key to view all your Private Keys

<figure><img src="/files/4N4AarswwVkoytJNJnc9" alt=""><figcaption></figcaption></figure>

## Step 4: Generate a new Private Key

Click on the "Create New" button on the top right to create new Private Key.

<figure><img src="/files/AEKD0S7IxOPWgt3PZi0t" alt=""><figcaption></figcaption></figure>

## Step 5: Navigate to STI-Certificate&#x20;

<figure><img src="/files/ujGEkYi9mjBUstjJRVLk" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
The default private key generated by Peeringhub.io portal does not require passphase.
{% endhint %}

## Step 6: Click on Generate New to create a new Certificate

You can select one of the private keys already created, and your iConnectiv Username and Password to generate a new certificate.

<figure><img src="/files/awTQuHCbjBfCztYFvLuc" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If you are getting error when creating certificate, you can test and verify your iConnective STI-PA username/password by logging into <http://authenticateapp.iconectiv.com>
{% endhint %}

## Step 7: Setup in Denovolab Switch

You can copy the **CR URL** from **peeringhub.io** and paste it into the **Certificate URL** field in the **Denovolab Switch**.\
Make sure to also **download the corresponding private key** from Peeringhub and **upload it to the Denovolab Switch**.

Here's how it should appear:

<figure><img src="/files/UZwFoGroLnXyZtJKJUxr" alt=""><figcaption></figcaption></figure>


# Update an Existing Installation

DNL Class 4 Platform is undergoing continuous development.  This section describes how you can update with newer versions.

Depends on whether you are installing from tarball or from RPM, the instruction is different.&#x20;


# Update with Tarball

* Download new version of the components you want to update.
* For the web ui, overwrite content in the web folder with new files.
* For the dnl\_api,  run pip3 install filename\_api.tar.gz , after it is installed, go to the folder /opt/denovo\_V6/api\_dnl/ and  stop all api\_dnl services,
* Run   next command: &#x20;

```
 alembic  or  /usr/local/bin/alembic  -c alembic.ini upgrade head.
```

After that is done, start back  dnl\_api\_dnl  services.

For the upgrade of one of the backend binaries:  unpack  archive, stop running service, and replace binary in its correspondent folder. Then restart all services.<br>


# Update with RPM

To update Web component, you use the following commands:

> yum install dnlv6\_webbackend (for the api )
>
> yum install dnlv6\_webui (for the web ui)

To update Switch backend component, you use the following commands:&#x20;

> yum install dnlv6\_softswitch

If some cases, you may not be able to start up dnl\_api\_core, then you will need to run the following commands to reinstall the API server.

```
rm -rf /usr/lib/python3.6/site-packages/api_dnl*
yum remove  dnlv6-webbackend
yum install  dnlv6-webbackend


```

After RPM packages are installed then run the following command:

> cd /opt/denovo\_v6/api\_dnl&#x20;
>
> alembic -c alembic.ini upgrade head

{% hint style="info" %}
It is recommended that you backup your Class4 DB before you update your installation.  here is the Postgres command you can use to backup the entire database:

pg\_dump -U postgres class4\_dnl > class4\_dnl\_dump.sql
{% endhint %}


# Introduction

Class 4 Fusion supports different kinds of configuration Stir Shaken configuration. &#x20;

1. If you are already an iconnectiv certified SP, then you can use the built-in AS/VS within Class 4
2. If you are not an existing iconnectiv certified SP, you can use an external AS/VS service to sign and verify your calls.
3. If you just simply want to bypass stir shaken signature from ingress to egress, you can configure Class 4 to block calls that don't have valid stir shaken signature.  This setting can be done on a per ingress trunk basis.

## STIR/SHAKEN

### I. Validating incoming requests

STIR/SHAKEN Identity is a JWT with encoded origination ANI and DNIS, signed by a certified STIR/SHAKEN Service Provider, included into the INVITE request.

Ingress and egress trunks may put requirements on incoming and outgoing INVITE requests respectively, using `resource.shaken_vfy_policy` parameter: 0 - Do not check STIR/SHAKEN Identity; 1 - Require STIR/SHAKEN Identity; 2 - Require valid STIR/SHAKEN Identity; 3 - Require STIR/SHAKEN Identity; Try to validate, but bypass if failed.

If the inbound INVITE request does not satisfy ingress verification policy, the call should be blocked with the corresponding reason:

```
 Release cause | SIP code                      | Reason
------------------------------------------------------------------------------------------------------------
            71 | 428 - Use Identity header     | Ingress requires STIR/SHAKEN Identity
            72 | 438 - Invalid Identity Header | Call blocked due to invalid STIR/SHAKEN Identity signature
```

Another set of codes represents errors in the STIR/SHAKEN module, which prevent ingress trunk from validating the Identity:

```
 Release cause | SIP code                  | Reason
-------------------------------------------------------------------------------------
            73 | 503 - Service Unavailable | All SHAKEN providers failed
            74 | 503 - Service Unavailable | No SHAKEN providers configured
            75 | 503 - Service Unavailable | General error in the STIR/SHAKEN module
```

### II. Signing outgoing requests

1. STIR/SHAKEN identity creation

Switch can create STIR/SHAKEN Identity when placing the outbound INVITE, if caller did not provide it. Ingress trunk can regulate the conditions on which switch can generate Identity for the call, using `resource.shaken_sign_policy` parameter: 0 - Do not sign calls; 1 - Sign call, if ANI is a US numbers; 2 - Sign, if ANI is a valid phone number (do not allow URI as ANI); 3 - Sign, if ANI is in the SHAKEN ANI pool.

Since class4 switch has options to alter, replace or randomize ANI, final ANI/DNIS may not match numbers in the original Identity provided by the caller. In such scenarios, switch may re-create Identity using the new ANI and DNIS. This behavior is controlled by `resource.shaken_allow_resign` flag in the ingress trunk configuration. NOTE: New identity creation is allowed only due to ANI/DNIS mismatch. Switch cannot re-sign call, if STIR/SHAKEN Identity did not pass validation.

1. ANI pools and attestation levels

STIR/SHAKEN Identity contains a trust level for the call (attestation level): A - Full attestation B - Partial Attestation C - Gateway Attestation

Client may control attestation levels for each ANI, using SHAKEN ANI groups. Attestation level for numbers outside of the pool can be set with `resource.shaken_default_attest_lvl` ingress parameter.

1. SHAKEN ANI pool creation

Create SHAKEN ANI group:

`INSERT INTO shaken_ani_group (name) VALUES ('my test group') RETURNING id;`

Populate ANI group:

`INSERT INTO shaken_ani_group_rel (group_id, did) VALUES (<shaken_ani_group.id>, <number>);`

Create ANI pool (list of groups):

`INSERT INTO shaken_ani_group_list (name) VALUES ('Trunk X ANI pool') RETURNING id;`

Add created ANI group to the pool, defining the attestation level:

`INSERT INTO shaken_ani_group_list_rel (ani_group_list_id, ani_group_id, attest_lvl) VALUES (<shaken_ani_group_list.id>, <shaken_ani_group.id>, 'B');`

Assign SHAKEN ANI pool ID to the ingress trunk, using `resource.shaken_ani_group_list_id` parameter.

ANI groups and/or pools may be shared between different resources freely.

### III. Routing

Egress trunks may put requirements on STIR/SHAKEN Identity using `resource.shaken_vfy_policy` parameter (see above). If verification policy cannot be satisfied, egress trunk should be removed from routing with the corresponding cause:

```
 Egress cause | Reason
----------------------------------------------------------------------------
           62 | Egress requires STIR/SHAKEN Identity
           63 | Provided STIR/SHAKEN Identity is not valid
           64 | All SHAKEN providers failed
           65 | No SHAKEN providers configured
           66 | General error in the STIR/SHAKEN module
```

If all egress routes failed due to STIR/SHAKEN policy, ingress shall block the call with the regular "No egress found" reason.


# Configure Class 4

The configuration is fully in dnl switch config file right now: /opt/denovo/dnl\_softswitch/conf/dnl\_softswitch.conf

```
 
[shaken]
# Whether to use built-in or remote module. Default: use remote
use_builtin = yes

#
# Built-in STIR/SHAKEN module configuration
# Ignored if set use_builtin = no
#
# Iconectiv API account credentials

iconectiv_user_id = xxx
iconectiv_password = xxx

# Whether to use staging environment (default: use production)
# iconectiv_staging = yes

# Trace HTTP requests to iconectiv API
#iconectiv_trace = yes
# SHAKEN STI-SP key to sign calls with

sti_sp_key_path = /opt/denovo/dnl_softswitch/shaken/sti_sp_813T_ec.pem
sti_sp_key_passphrase = ENfexxx5MbHxppJV

# URL to SHAKEN STI-SP certificate to put in PASSporT
sti_sp_x5u = http://certificates.peeringhub.io/0axxx0b4d93fdb0e628c577020c73b8a5caff750e7e499f80ee2ab362a3f6a.crt

# Log all sign requests into a file
sti_sp_sign_log = yes

# Log all verification errors into a file
sti_sp_verification_error_log = yes

# Certificates cache location (default binary path /shaken_cache)
#cert_cache_path = /opt/denovo/dnl_softswitch/shaken_cache
#
# External STIR/SHAKEN module configuration
# Ignored if set use_builtin = yes
#
# Path to PEM certificate file for TLS connections
#our_cert_file =
# How many times to retry failed requests
max_retry = 3
# Request timeout
req_timeout = 0.5
# Connection failures timeout
conn_timeout = 10
# How often to post status into c4_shaken_status table
# Set 0 to disable.
status_post_interval = 1
# Our bind address for UDP connections
our_ip = 176.31.100.14
our_port = 15889
# Log all incoming and outgoing data (1 - true; 0 - false)
enable_trace = 1



```

After you configure the \[shaken] section, you need to restart the switch to make it effective.

{% hint style="info" %}
Configure built-in SHAKEN module in dnl\_softswitch.conf (use template from c4v7 stash >= v7.1.2-1),
{% endhint %}

\
Explanation of key stir-shaken parameters&#x20;
-----------------------------------------------

\[shaken]

Make switch use built-in module instead of external

```
use_builtin = yes

```

Path to STI-SP private key for calls signing, and its passphrase (if required)

```
sti_sp_key_path = /opt/denovo/dnl_softswitch/certs/sti_sp_XXX.pem
sti_sp_key_passphrase = 12345678
Public URL of STI-SP certificate
sti_sp_x5u = http://certificates.peeringhub.io/XXXXX.crt
```

Log all signing operations and verification errors

```
sti_sp_sign_log = yes
sti_sp_verification_error_log = yes
```

If server does not have access to iconectiv.com, make sure to delete/comment-out the corresponding configuration in the dnl\_softswitch.conf:

```
# Iconectiv API account credentials
#iconectiv_user_id = sp_username
#iconectiv_password = sp_password
```

{% hint style="info" %}
In most cases, you just need to modify these following lines and leave the rest as default:

sti\_sp\_key\_path - path to their private key to sign calls.&#x20;

sti\_sp\_key\_passphrase - password for this key, if it's encrypted.

sti\_sp\_x5u - URL which can be used to download certificates.&#x20;
{% endhint %}


# Configure Stir Shaken in DB

Trunk setting can be defined in Class 4 DB.  The name of the table is "resource."  The resource DB table has fields for configuring stir shaken signing and verificaiton methods.&#x20;

* resource.shaken\_sign\_policy - conditions on which switch is *allowed* sign the call (for ingress trunks):

{% code overflow="wrap" %}

```
0 - Never sign calls 
1 - Sign only US numbers 
2 - Sign any telephone number (URI is not allowed) 3 - Sign only numbers from the pool
```

{% endcode %}

* resource.shaken\_vfy\_policy (for ingress trunks) - conditions to block calls:

```
0 - None: do not block calls based on shaken identity 
1 - Reject the call if Identity is missing 
2 - Reject the call if Identity is missing or invalid 
3 - Pass through: allow all calls (same as 0)
```

* resource.shaken\_vfy\_policy (for egress trunks) - conditions to route the call to egress:

{% code overflow="wrap" %}

```
0 - None: route all calls; do not sign/validate 
1 - Block if missing: route the call if Identity is provided in the inbound INVITE, or if it can be created. Do not perform validation. 
2 - Block if invalid: route the call if inbound INVITE contains a _valid_ identity, or if inbound INVITE does not contain Identity but ingress sign policy allows to create one 
3 - Pass through: if inbound INVITE does not have Identity, try to sign the call, if ingress allows it. Otherwise - pass the call as is, performing signature validation.
```

{% endcode %}

* resource.shaken\_allow\_resign (for ingress trunks):

{% code overflow="wrap" %}

```
If inbound INVITE contains an Identity, inside of which ANI/DNIS do not match outbound INVITE, switch is allowed to create a new signature. This flag takes effect if egress shaken_vfy_policy is "Block if invalid" or "Pass through", and if ingress sign policy allows to sign calls.
```

{% endcode %}

* resource.shaken\_p\_headers - put SHAKEN signature parameters into INVITE headers (for egress trunks):

{% code overflow="wrap" %}

```
0 - None 
1 - Regular: put verstat into P-Asserted-Identity header 
2 - Extended: put verstat into P-Asserted-Identity header; origid into P-Origination-ID; attestation level into P-Attestation-Indicator
```

{% endcode %}

Verstat value contains signature validation status, which should be shown on user's device. Since validation is configurable, the value depends on egress's vfy policy. vfy\_policy - possible verstat values:&#x20;

{% code overflow="wrap" %}

```
0 - No-TN-Validation 
1 - No-TN-Validation 
2 - TN-Validation-Passed 
3 - No-TN-Validation / TN-Validation-Passed / TN-Validation-Failed (depending on signature validation status)
```

{% endcode %}


# Configure Ingress Trunk

Class 4 provides built-in functionalities to verify stir/shaken identity header and sign call using stir/shaken certificate.&#x20;

By default, class 4 automatically pass the stir/shaken identity header from ingress trunk to egress trunk.  Class 4 can also be provisioned to sign calls that don't have stir/shaken header.  To enable Class 4 to sign call, you will need to configure Stir/Shaken in both ingress trunk and egress trunk.&#x20;

Stir/Shaken setting in the ingress trunk defines what attestation is to be used to sign call.  Stir/Shaken setting in the egress trunk defines whether a call should be signed when it is being passed to the egress trunk.&#x20;

## Stir/Shaken setting in Ingress Trunk

The ingress trunk setting for Stir/Shaken is shown as follows:

![](/files/ErSA3sVwyphuwOijyNyq)

Under Signing Policy, you can see the following options:

![](/files/lgwyGf50FIY4jqfhbWbg)

| Signing Policy                                   | Description                                                                                                                                                        |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Do not sign calls                                | This option means the switch should not sign any calls from this ingress trunk.                                                                                    |
| Sign only US numbers                             | This option means that the switch should only sign calls with valid US numbers as the ANI.                                                                         |
| Sign any phone numbers                           | This option means that the switch should sign all calls.                                                                                                           |
| Sign only numbers from the Stir/Shaken ANI group | This options means that the switch should sign calls with ANI defined in the Stir/Shaken ANI Group.  You can create Stir/Shaken ANI Group from Configuration menu. |

### Re-sign calls on ANI/DNIS replacement

In the next option, you can turn on / off "Re-sign calls on ANI/DNIS replacement." &#x20;

![](/files/RKp6q6Iz04cqPNOwAYxN)

When turned on, Class 4 will regenerate a new Identity header if the ANI or DNIS is modified using Digit Manipulation or Digit Replacement.&#x20;

### Attestation  Setting

This section defines what attestation level to use according to the ANI of the call.&#x20;

![](/files/C6Vb9yZdVXuQ8f74VBMh)

You must set a default Attestation if you want to turn on signing of calls.&#x20;

### Stir/Shaken ANI Group

To create new Stir/Shaken ANI Group, you can select Stir/Shaken under Configuration menu:

![](/files/oC5DuFC61mwy7HyZQjiF)

After you create a Stir/Shaken ANI Group, you can click into the ANI Group and then you can upload numbers into the ANI Group.

### Un-sign Call Handling

This option let you define how to handle a call from ingress trunk if there is no Stir/Shaken identity header included in it.&#x20;

![](/files/DnOWgcYDuzpGPgwGJqZH)

If you select Pass Through, it means you want to let the calls to go through and use the other options to define whether to sign and how to sign a call.&#x20;

You can also choose to reject a call if the Stir/Shaken identity header is missing from the ingress side. &#x20;

In some cases, the Stir/Shaken may exist but it is invalid, then you can also choose to reject calls that has invalid Stir/Shaken Identity header.&#x20;


# Configuring Egress Trunk

The Stir/Shaken in the egress trunk defines whether to sign a call or not when passing the calls to Egress trunk.&#x20;

![](/files/WkTK54vnjQSHDV8I3NOL)

| Verification Policy                   | Description                                                                                                                       |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| Disable Stir/Shaken                   | This option means the switch will ignore Stir/Shaken for this egress trunk.                                                       |
| Require Signature or Block Call       | This option means Class 4 will not send call to this egress trunk if it does not has an Identity header.                          |
| Require Valid Signature or Block Call | This option means Class 4 will not send call to this egress trunk if it does not has a valid Identity header.                     |
| Passthur or Sign Call if no signature | This options means Class 4 will attempt to sign calls according to the attestation defined in the ingress trunk to sign the call. |

## P-header setting

By default, Class 4 does not do anything to P-header.  Class 4 supports 2 different p-asserted identity header setting as shown her:

![](/files/a5CQoz4MeLnywif2LPpy)


# Basic Configuration Example

You need to configure both ingress trunk and egress trunk in order for the switch to sign calls with your Stir/Shaken certificate. &#x20;

Ingress Trunk's Stir/Shaken configuration instructs the switch on "HOW" to sign the call.&#x20;

Egress Trunk's Stir/Shaken configuration tells the switch "WHEN" to sign the call.&#x20;

Most of the times, you want to use the most simple configuration, which is to have the switch to sign only incoming calls that are not previously signed by ingress clients.&#x20;

In this case, you will configuration your ingress trunk as shown below:

![](/files/dxkmFetkcU515oykSkJ2)

The above configuration will sign all calls from a valid US caller ID.

Then, you will configure egress trunk to sign only calls that are not already signed.&#x20;

![](/files/HMAeFxrNqsRSnPEexwRI)


# Validation of Stir/Shaken Setup

When the switch is signing calls, you should be able to see the insertion of "Identity" field in your outbound PCAP.&#x20;

<figure><img src="/files/m4fNLoWJhi8QUFxKvGiB" alt=""><figcaption></figcaption></figure>


# Setup External AS/VS connectivity

If you want to use an external AS/VS service, you can setup under Configuration > Setting > Advanced&#x20;

![](/files/-MZqSCmBuS7LVUFxfF_J)


# Integrate Class 4 to Google SMTP

This section provides a guide on integrating Class 4 with the Google SMTP server.

Class 4 supports different type of SMTP server prover but since Google has special process for SMTP setting, we are writing a section here.&#x20;

You can configure Mail Sender under Configuration menu:

<figure><img src="/files/PTc7ui7jafZ8LJgWGbuT" alt=""><figcaption></figcaption></figure>

Then here is what you get:

<figure><img src="/files/wsAqN4NiDf3finMZD63S" alt=""><figcaption></figcaption></figure>

## Configure Google Mail Account

Step 1 Login to your Google Mail Account

<figure><img src="/files/Kt2C6osxWOUGnaOuYMdt" alt=""><figcaption></figcaption></figure>

Step 2 Go to Data & Privacy

<figure><img src="/files/Ef13VhYNiARu7xxp8rGe" alt=""><figcaption></figcaption></figure>

Step 3 Turn off 2-Step Verification&#x20;

<figure><img src="/files/Ts0PBmn7fLOqTCO4iK3m" alt=""><figcaption></figcaption></figure>

Step 4 Google may request you to enter phone number to turn off 2-Step Verification

<figure><img src="/files/iDsWJzs89R8zq9tKEW8Y" alt=""><figcaption></figcaption></figure>

Step 5 Add a Security Key

<figure><img src="/files/Vn0Fisfr5jBuuV4iXfkk" alt=""><figcaption></figcaption></figure>

Step 6 Add a APP Password

To create a APP Password, you go to <https://myaccount.google.com/apppasswords>

You may need to turn on 2-Factor Authenticator to be able to create APP Password.

<figure><img src="/files/AyBzO2XvVS5KNZtbQgR7" alt=""><figcaption></figcaption></figure>

Step 7 Enter a "App name" and generate a APP Password

<figure><img src="/files/U5Nycs7ET42WLNRulRkC" alt=""><figcaption></figcaption></figure>

Step 8 Store the backup code in a safe place

<figure><img src="/files/icAlJetR5gBPMVosfeoS" alt=""><figcaption></figcaption></figure>


# Customize your logo

## Step 1: Customize your logo

You can customize the portal with your logo by first going to System Setting page:

![](/files/-MXTdqThJzY6PE0WuDmt)

Then,  you can upload your logo:

![](/files/-MXTe-T5T0yfsKP5-HVG)


# Customize Domain Name

After you have domain name configured for your portal, you can set it under Configuration > System Setting:

![](/files/-M_82nIrFLdFUbxMKMkg)

If you see issue below, you should update the Base Domains URL as shown in above.&#x20;

![](/files/-M_86HF2fMphEC8Jl-fj)


# Customize email template

## Getting Super Powers

Becoming a super hero is a fairly straight forward process:

```
$ give me super-powers
```

{% hint style="info" %}
&#x20;Super-powers are granted randomly so please submit an issue if you're not happy with yours.
{% endhint %}

Once you're strong enough, save the world:

{% code title="hello.sh" %}

```bash
# Ain't no code for that yet, sorry
echo 'You got to trust me on this, I saved the world'
```

{% endcode %}


# Customize invoice template

## Getting Super Powers

Becoming a super hero is a fairly straight forward process:

```
$ give me super-powers
```

{% hint style="info" %}
&#x20;Super-powers are granted randomly so please submit an issue if you're not happy with yours.
{% endhint %}

Once you're strong enough, save the world:

{% code title="hello.sh" %}

```bash
# Ain't no code for that yet, sorry
echo 'You got to trust me on this, I saved the world'
```

{% endcode %}


# Configuring Payment Gateway

Class 4 supports the following two Payment Gateways:

* Paypal
* Stripe

Class 4 user setup their customer to pay invoice or topup account within the client portal. &#x20;

#### Step 1: To setup paypal gateway, here is the first step:

![Select "Payment Setting" under Configuration](/files/-MXmcsIR2IlrfofIeZOu)

#### Step 2: You can select whether to enable Paypal or Stripe or both

![](/files/-MXmd6kpnYmAkuOLcm5s)


# Stripe Configuration

You need to obtain the API key from Strip.  Here is how you do it:

Step 1: Click on   Developers > API keys in your Strip account

![](/files/-MY2ysyf5TBSnZ-H3jbX)

Step 2: Obtain the API tokens for your account:

![](/files/-MY2zC1Vv9SgLTjj9fIi)

Step 3: Go to Webhooks section&#x20;

![](/files/-MY2zPJImJ8094FTRB62)

Step 4: Add new Webhook

![](/files/-MY2zapJTj2MmGcw5xLw)

In your Stripe setting, you get to see the webhook URL of your switch.  This Webhook URL is what you need to fill in.  Then, you need to select "charge.succeeded."

![](/files/-MY2zm0nO4fCpIMHDT5S)

Step 5: Activate your key for production

![](/files/-MY3-1fBZl1CtK8VPAmZ)

In stripe, you need to activate your account.  Before you do that, your API account is a test sandbox account.   When your account is still in test mode, you can use the following link to get the test credit card numbers to test your setup.&#x20;

```
https://stripe.com/docs/testing    
```

{% hint style="info" %}
When your stripe key is started with "test" keyword, that means this key is a test sandbox key instead of a production key.&#x20;
{% endhint %}


# Paypal Configuration

In this section, we will go through how to configure your Paypal account to work with your Class 4 installation.

Step 1: Go to developer.paypal.com

![](/files/-MXmdUv3vjbaWf37y1ED)

#### Step 2: Go to "My Apps & Credential"

In this section, you need to create an APP.  You can crate either a Sandbox or Live APP.  Sandbox will accept test account and test credit card.  Live APP only accept real paypal account and real credit card.&#x20;

![Create an APP](/files/-MXmdiheZtX6lglhoNT8)

#### Step 3: Fill out APP details

![](/files/-MXme6ht5rUQDMqOSZBs)

#### Step 4: Review your APP information

![](/files/-MXmecixixs4QP8cvFL3)

This Client ID and Secret should be placed inside the Paypal section like below:

![](/files/-MXmerThYM35GtBXu14Z)

Here you can select to charge the total amount that the user paid or the amount that actually got credited to your paypal account after the Paypal fee. &#x20;

If you select "Enable Paypal Test Mode", Class 4 will send query to the Paypal Sandbox URL instead of the Live Paypal URL.

#### Step 5: Specify Webhook and select the events that Class 4 needs

In the APP setting, you also need to setup Webhook.  This webhook is needed for Paypal to tell Class4 when a user has paid.&#x20;

![Webhook Setting](/files/-MXmfUp5hhdsWoKKOIlJ)

In the Paypal Webhook URL, you copy that URL.

![](/files/-MXmfjCJOo9wLdcGZa7P)

Then, you enter that webhook URL to the following:

![](/files/-MXmg3FQk4YhGERIGvCx)

You can set "all" but Class 4 only expects 'PAYMENT.SALE.COMPLETED' in fact.&#x20;

## Troubleshoot

You must use HTTPS and a domain name when setting up webhook in Paypal.  That means your Class 4 portal must be setup with a https domain url.  Otherwise, Paypal will complaint the following error:

![](/files/-MZuh5IyvSgX3bpYSPwe)


# Configuring CDR and PCAP Backup

Class 4 can store backup of your CDR and PCAP to the following storage:

* Google Cloud
* FTP
* Mount Disk

You can specify how many days of CDR or PCAP to keep in local disk and how many days to push to remote storage for cold backup.&#x20;

You can specify how many days of CDR or PCAP you would store locally as compressed format.


# Google Cloud Setup

####

#### Step 1: Create a Google Cloud Project

#### Step 2:  Go to IAM & Admin -> IAM

![](/files/-MXmi3Zb31abxfaOqMu7)

#### Step 3: Find service account, and press "Edit member" (pen button) on the right side of it

![](/files/-MXmiPw5k-lA-bmVnzkI)

#### Step 4: Press "Add condition"

![](/files/-MXmifF7d9HECOsdyjhg)

#### Step 5: Open "Condition Editor" and put the expression, filling the bucket name

![](/files/-MXmiteOj8f_lEIg6nh6)

```
(resource.type != "storage.googleapis.com/Bucket" && resource.type != "storage.googleapis.com/Object") || resource.name.startsWith("projects/_/buckets/<name>/") || resource.name == "projects/_/buckets/<name>"

```

####

#### Step 6: Press Save in both condition editor and permissions editor. Otherwise it will be canceled

#### Step 7: Go To Class 4 and Open the Archive Setting page

![](/files/-MXmjVV3XRDia292hucv)

#### Step 8: Select Server Name

Class 4 platform select using multiple sip switch server.  Each sip switch server has its own directory for storing backup data.&#x20;

![](/files/-MXmk96b7E5540uuj8Q0)

#### Step 9: Select where you want to store the data

![](/files/-MXmkbsTMGjpCgYUQVKN)

Here is a video showing you how can obtain the Google Cloud Service Key json file:

<https://drive.google.com/file/d/1Loon-8jWRZdDiUg0251sODHswqIBIeyf/view?usp=sharing>


# Configuring SIP Registration

You can create SIP user and use this SIP user/password to authenticate your inbound traffic by adding as many SIP User and Password combination in the Ingress Trunk section:

![](/files/ce6sxNw58YBvlz03tsW8)

In the "Authoized" dropdown, select "Authorized by SIP Registration."

Then, you will see the table below with one column for SIP Username and one for SIP Password.  Thisis where you can create as many SIP user as you need.&#x20;

## Setting up a SIP Interface

The standard SIP Interface only supports IP authorization.  To support SIP Registration, you need to create a new SIP Interface.&#x20;

You can click on "VoIP Gateway" to do that.&#x20;

![](/files/Elgv5SpdWnRem0Db0cn0)

By default, you would see one VoIP gateway setup with port 5060 for your SIP traffic.  The default VoIP Gateway has "Require authentication" turned off, meaning that there is no need for SIP Registration. &#x20;

To turn on SIP Register on any one of the Ingress trunk, you need to create another VoIP Gateway that has "Require authentication" set to "true".  Here is an example how it should look:

![](/files/k07bFD4MHdiAPhhQzurW)

With this configuration, your SIP client can point to the same IP but port 5080 to perform SIP registration.&#x20;

{% hint style="info" %}
Setting SIP username and password in SIP trunk does not work unless you also have a VoIP Gateway that can handle "Authorization."
{% endhint %}

## What if you are getting no time out?

If your sip client is getting no response from dnl\_softswitch, then, it is likely that it is firewall issue.  You can use sngrep or Live Call page from UI to check the SIP register signal flow:

![](/files/PY0zBU45z1e6nBlUvGje)

If you see that your SIP Register is not getting response, then you can run the following commands to open up port 5080:

```
firewall-cmd --add-port=5080/udp --permanent

firewall-cmd --reload
```


# Configuring LRN

DeNovoLab provides two LRN server that your dnl\_softswitch can query.&#x20;

You can setup LRN server access via Configuration > System Setting page:

![](/files/Sm0zKdmctlWLVxtSkX9E)

The two LRN IP provided by DeNovoLab are 142.44.212.125 and 149.20.191.167.

In the CDR or in call simulation, if you are getting LRN Not Available error like below, you need to check with DeNovoLab support to have your switch IP whitelisted:

![](/files/XAviZcAxKUdAxouzHj81)

{% hint style="info" %}
For FREE Community Edition, LRN is not provided by default.  You will ned to subscribe to a LRN service from any LRN provider or subscribe to the LRN service provided by DeNovoLab at <http://denovo.me>.
{% endhint %}

## Specifying the binding IP for LRN query

If you have multiple IP addresses in your server, you may choose one of those IP addresses to be used for querying LRN from remote LRN server. &#x20;

You can lookup the config file dnl*softswitch.conf from \<dnl*softswitch base dir>/conf/dnl\_softswitch.conf&#x20;

Then, in the configuration inside, you can specify the local IP you want to be used by the dnl\_softswitch to query LRN:

```

[lrn]
lrn_local_ip = x.x.x.x
lrn_local_port = 4319
lrn_support_heartbeat = yes
lrn_heartbeat_timeout = 10
lrn_heartbeat_interval = 2
lrn_t1 = 500
lrn_query_retry_count = 3
```

{% hint style="info" %}
This IP address should be provided to your LRN service provider for them to whitelist.
{% endhint %}


# Create Termination Vendor

## Step 1: Create New Vendor

You can go to Termination > Vendor to create a new vendor.

![  Vendor menu](/files/-MXTa9JLUPxbkpfNQ2uE)

Then, you can fill out vendor information:

![Create a new vendor](/files/-MXTalWXYpTm9tZI9ymh)

## Step 2: Create New Vendor Trunk

After you create submit at the end of page, you will be redirected to the Trunk page. There can be multiple trunks for each Vendor.  In this trunk page, you can specify the vendor's IP and tech-prefix if any.

![Vendor Trunk Creation Page](/files/-MXTbFA8pvcMNMGiXo2x)

## Step 3: Create Vendor Rate Table

Each Vendor trunk must have a rate table selected.  If you don't already have the rate table for this vendor, you can create one by clicking on the + button next to the Rate Table dropdown.

The "Add Rate Table" pop up box will be shown and you can create rate table and enter rate records for the rate table.&#x20;

![](/files/-MXTckFMF7v39rn-XoCP)


# Specify IP to send to egress

If you have multiple IP addresses in your switch server, you can add multiple SIP Profile within the VoIP Gateway.  VoIP Gateway is a running instance of dnl\_softswitch.  Each SIP Profile represents a SIP IP and SIP Port.&#x20;

If you have multiple SIP Profile in the switch, you can receive traffic in each one of the SIP IP and SIP Port pair.  By default, dnl\_softswtich will send traffic to egress using the same IP and port where the traffic is sent to. &#x20;

If you want to control what IP and Port the switch should send from in the egress end, you can use the SIP Profile tab in the egress setting. &#x20;

The Ingress Trunk field specifies thish ingress traffic will follow his rule.  If you leave Ingress Trunk empty, then all traffic will follow this rule.&#x20;

![](/files/3RVXTaxgtg23o59dWwBK)


# Create Termination Route

#### Introduction

Class 4 Fusion routing is a hierarchy design.  First, you will need to create "Routing Plan".  Within a routing plan, you can define different criteria for different routing strategy.  A routing criteria is a combination of prefix, min length, and max length.  This criteria can be defined in ANI and/or DNIS. &#x20;

Moreover, you can define different time profile for the routing strategy.  &#x20;

There are two general categories of routing strategy:

* Static Routing&#x20;
* Dynamic Routing

Static Routing means that the routing order is fixed and we support the following routing order:

* Top Down
* Round Robin
* Percentage

Dynamic Routings means that the routing order is dynamic and it is based on real-time condition of the traffic as well as the cost of the vendor for the specific code at that specific time of routing:

* Least Cost Routing
* Highest ASR Routing
* Highest ACD Routing

{% hint style="info" %}
You can look at routing plan as routing condition and static route / dynamic route as the way how you want vendor routes to be selected.&#x20;
{% endhint %}


# Routing Plan

You can go to Routing > Routing Plan to define your routing plan:

![](/files/-MYcfCwKE5Tj2r_DovIj)

Inside the Routing Plan page, you can see all the routing plan you have created:

![](/files/-MYcfQx9yI8LK0rBfHdJ)

You can then create a new routing plan and add routing rule inside.  To add routing rule, you simply click on the "routing name":

![](/files/-MYcfkSqd2gX4htVOmaz)

You can add new routing rule by clicking on the Edit button:

![](/files/-MYcfsXL3T3B8BsL6-Zk)

Each routing rule has a set of condition and actions.  The condition you can defined are:

* ANI Prefix
* ANI Min Length
* ANI Max Length
* DNIS Prefix
* DNIS Min Length
* DNIS Max Length

The action you can defined are :

* Static Routing&#x20;
* Dynamic Routing


# Static Route

#### Introduction

Static Route is how you define actually how vendor trunk is to be selected.  Within Static Route, you can order the vendor trunks by:

* Top Down Routing
* Round Robin Routing
* Percentage Routing

Top Down Routing means Class 4 will always select the route from top to bottom of the vendor trunk list.  Round Robin means Class 4 will balance traffic sent all vendor trunk evenly.  Percentage routing let's you define % of traffic being sent to each vendor trunk.&#x20;

Here is how you create static routing:

#### Step 1: Click on Routing > Static Routing

![](/files/-MYcgfHpqMxJex1PZK_y)

#### Step 2: View all existing static routing

![](/files/-MYcglanaoYhIRCmPxds)

#### Step 3: Add new static routing

You can click on "Create New" and then create a new static routing:

If you are terminating US traffic, you should route by LRN number instead.  For A-Z traffic, pls select DNIS.

![](/files/-MYcj2_rgo6uN7JK6Kh-)

#### Step 4: Add new static routing entry

![](/files/-MYcitwNMN6foiUluQ60)

When you click inside the name of the static route, you get to see the list of routing entry:

You can have different set of vendor trunks defined for different DNIS routing code.  You can have different routing strategy for different DNIS prefix or you can leave it blank.&#x20;


# Dynamic Route

#### Introduction&#x20;

Dynamic Routing is a way for you to define routing based on real-time condition such as Cost, ASR and ACD. Within a dynamic Routing, you can define a group of vendor trunks and you specify whether you want Class 4 to select and order vendor trunk by Least Cost Routing, Highest ASR, or Highest ACD.

This section discuss how you create dynamic routing.&#x20;

#### Step 1: Go to Dynamic Routing page

![](/files/-MYcmf4Oo_QdXtKdWfD9)

#### Step 2: Create a new Dynamic Routing

![](/files/-MYcmjYTt_2TTh7YQwFw)

In the creation page, you can define the ordering method and the vendor trunks you want to select for this routing.&#x20;


# Create Termination Client

#### Step 1: Go to the Client section

![](/files/-MYcn3gudU0TYOsqcwbG)

#### Step 2: Create a Carrier&#x20;

In this page, the minimum set of fields you need to filled in are :

* Name
* Company Name
* Email

![](/files/-MYcn8Sv3WSa2J4DDyTY)

#### Step 3: Create Ingress Trunk

After submit, you will be prompted to create Ingress Trunk as shown here:

![](/files/-MYcn_uM-TLw9jijFi4K)

To get an ingress trunk started, you mainly need to fill out the following fields only:

* Trunk Name
* IP Address(s)
* Tech Prefix ( optional )&#x20;
* Routing Plan
* Rate Table applied to this Client Trunk

##


# Test with Call Simuation

#### Introduction

After you set up your routing then normally you want to validate to check your routing.  Call Simulation is the tool for that.  Within Call Situation, you can enter the Ingress Trunk, ANI, and DNIS. Then, Class 4 will tell you which Egress trunks will terminate the calls to. &#x20;

#### Step 1: Open Call Simulation page

![](/files/-MYcnroeFsmunBtyinb8)

Now, you see the following and this is where you specify the ingress trunk, ANI, and DNIS

#### Step 2: Specify your test information

After you click Submit, you will see the following results:

![](/files/-MYcoacgnsSGWcrDC3KF)


# Test Calls with SIP Client


# Check CDR

#### Step 1 Go to the CDR Page

![](/files/-MYcpPK_3ktx56bdGdPD)

#### Step 2: Select your search filter

![](/files/-MYcp_DsuCF6JvTBU34N)


# Introduction

DeNovoLab Class 4 Fusion has the capability of termination DID origination traffic.  To setup Origination traffic, you just need to use the "DID" main menu:

![](/files/bvZxYdz2r4uM5TBv2c8z)

Here are the process to setup DID routing:

1. Create Billing Rule for your DID Vendor.  This will let you to define the DID's Setup Fee, Monthly Fee, and Per Minute Charge from the Vendor side. &#x20;
2. Create DID Vendor.  This will define where the DIDs are originated from.  You can setup multiple IP address for each DID vendor.&#x20;
3. Create Billing Rules for your DID Clients.   You can have different billing rules for different DID clients.
4. Create DID Clients.


# Create DID Vendors

You can create DID vendors under DID > DID Vendor menu:

![](/files/rikrvt6V6BsyGMQcJlQf)

The Default Vendor Billing Plan is the cost that your DID vendor is charging you.  The switch will calculate the cost of DID as well as cost for each terminated cost for you.&#x20;


# Create DID Billing Plan

Billing Plan defines the cost of DID for the Client and Vendor side.  You can define different Client and Vendor Billing Plan for each client and vendor.&#x20;

Each DID Billing Plan consist of the following pricing components:

* Setup Fee
* Monthly Fee
* Per Minute Rate

When terminating traffic, switch will employ profit protection.  That means, if the DID vendor's per minute rate is higher than DID client's per minute rate, then the switch will not terminate the call.&#x20;


# Create DID Clients

You can define multiple DID Clients that purchase DIDs from you.  You add new DID Client in the DID > DID Client menu:

![](/files/ipNdDawRlAjsjlyBD9qM)

You can either assign DIDs to client manually yourselves, or you can give Portal access to your DID client to buy numbers and to check report and CDRs from DID Client Portal.


# DID Repository

DID Repository is the core of DID routing.  It defines all the routing plan for each DID.  Each record in DID repository defines how each DID is to be routes:&#x20;

* From which DID vendor the DID is to be originated from
* What DID billing rule will be charged by the DID vendor for this DID
* To which DID client the DID is to be terminated to
* What DID billing rule should be charged to the DID client for this DID

The Switch Admin can add each DID routing record one by one via the user interface under DID > DID repository.  Alternatively, Switch Admin can also use Import to upload multiple DIDs at the same time.&#x20;

It is also possible that a DID is brought from DID vendor but it is not yet assigned to any DID client.  Those DIDs that are not assigned to any DID client is considered unassigned DIDs.  An unassigned DID can be searched and purchased by DID client via Client portal or Client API.   If you don't want any DID to be searchable, you can turn on the "reserved" flag, then the DID will not be searchable by user via the client portal.&#x20;

&#x20;


# Assign DID to Client

You can assign DID to client in the DID > DID Repository menu.&#x20;

![](/files/7PMg4ggTmLBBnvyJSZlg)

In this section, you can add DID and associate this DID with DID Client, DID Client's Billing Plan, DID Vendor and DID Vendor's Billing Plan.&#x20;

You can also mark the DID as assigned then there DID client won't be able to search for it in DID Client Portal.&#x20;

If you have a lot of DIDs to add, then you may use the Import tool:

![](/files/xQGV2eXwkgYrmI1JnGFy)

You can add or release numbers with import tool.&#x20;


# Test Calls with Call Simulation

We use this DID repository as an example:

![](/files/cstrFMcs7UxSxxqqyajK)

You can use Call Simulation to check which client will receive the calls for the DID:

![](/files/HdKhCAdZJFBhTTcb927J)


# Setup for your client to buy DIDs from portal

If you want your DID client to be able to search and buy DID via the client portal on a self-service basis, then you can set up portal access as follows:

![](/files/fqiSwbzBROjFdf5KKEdC)


# Postgres Database

You can access to DB via the following command:

```
[root@ns505185 ~]# psql -U postgres
psql (12.5)
Type "help" for help.

postgres=# \l
                                  List of databases
    Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
------------+----------+----------+-------------+-------------+-----------------------
 class4_dnl | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
            |          |          |             |             | postgres=CTc/postgres
 template1  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
            |          |          |             |             | postgres=CTc/postgres
(4 rows)

postgres=# \c class4_dnl ;
You are now connected to database "class4_dnl" as user "postgres".
class4_dnl=# 

```

You can get the list of tables with the following commands:

```
class4_dnl=# \d+;
                                                                                          List of relations
 Schema |                       Name                       |   Type   |    Owner    |    Size    |                                            Description                                            
--------+--------------------------------------------------+----------+-------------+------------+---------------------------------------------------------------------------------------------------
 public | agent                                            | table    | postgres    | 0 bytes    | 
 public | agent_agent_id_seq                               | sequence | postgres    | 8192 bytes | 
 public | agent_client_client                              | table    | postgres    | 0 bytes    | 
 public | agent_client_client_id_seq                       | sequence | postgres    | 8192 bytes | 
 public | agent_client_client_record                       | table    | postgres    | 8192 bytes | 
 public | agent_client_client_record_record_id_seq         | sequence | postgres    | 8192 bytes | 
 public | agent_clients                                    | table    | postgres    | 0 bytes    | 
 public | agent_clients_id_seq                             | sequence | postgres    | 8192 bytes | 
 public | agent_commission_history                         | table    | postgres    | 8192 bytes | 
 public | agent_commission_history_detail                  | table    | postgres    | 8192 bytes | 
 public | agent_commission_history_detail_id_seq           | sequence | postgres    | 8192 bytes | 
 public | agent_commission_history_history_id_seq          | sequence | postgres    | 8192 bytes | 
 public | agent_commission_payment                         | table    | postgres    | 8192 bytes | 
 public | agent_commission_payment_id_seq                  | sequence | postgres    | 8192 bytes | 
 public | alembic_version                                  | table    | postgres    | 8192 bytes | 
 public | alert_rules                                      | table    | postgres    | 8192 bytes | 
 public | alert_rules_id_seq                               | sequence | postgres    | 8192 bytes | 
 public | alert_rules_log                                  | table    | postgres    | 8192 bytes | 
 public | alert_rules_log_detail                           | table    | postgres    | 8192 bytes | 
 public | alert_rules_log_detail_id_seq                    | sequence | postgres    | 8192 bytes | 
 public | alert_rules_log_id_seq                           | sequence | postgres    | 8192 bytes | 
 public | allowed_sendto_ip                                | table    | postgres    | 0 bytes    | 
 public | allowed_sendto_ip_id_seq                         | sequence | postgres    | 8192 bytes | 
 public | allowed_sendto_ip_record                         | table    | postgres    | 8192 bytes | 
 public | allowed_sendto_ip_record_record_id_seq           | sequence | postgres    | 8192 bytes | 
 public | async_ftp_export                                 | table    | postgres    | 8192 bytes | 

```


# Obtain Report Data from DB

Class4 store all pre-aggregated report data in DB.  The data is aggregated on a per minute basis and stored in daily partition table.

Here is how you can get all the termination report:

```

 

public | cdr_report_detail20191029                        | table    | class4_dial | 152 kB     | 
 public | cdr_report_detail20191030                        | table    | class4_dial | 152 kB     | 
 public | cdr_report_detail20191031                        | table    | class4_dial | 160 kB     | 
 public | cdr_report_detail20191101                        | table    | class4_dial | 160 kB     | 
 public | cdr_report_detail20191102                        | table    | class4_dial | 152 kB     | 
 public | cdr_report_detail20191103                        | table    | class4_dial | 144 kB     | 
 public | cdr_report_detail20191104                        | table    | class4_dial | 144 kB     | 
 public | cdr_report_detail20191105                        | table    | class4_dial | 160 kB     | 
 public | cdr_report_detail20191106                        | table    | class4_dial | 184 kB     | 
 public | cdr_report_detail20191107                        | table    | class4_dial | 272 kB     | 
 public | cdr_report_detail20191108                        | table    | class4_dial | 280 kB     | 
 public | cdr_report_detail20191109                        | table    | class4_dial | 272 kB     | 
 
```

Here is how you can get all the origination report:

```
 public | did_report20210402                               | table    | class4_dial | 48 kB      | 
 public | did_report20210403                               | table    | class4_dial | 48 kB      | 
 public | did_report20210404                               | table    | class4_dial | 48 kB      | 
 public | did_report20210405                               | table    | class4_dial | 48 kB      | 
```


# Obtain CDR from DB

Every minute, Class4 pushes CDRs into DB.   &#x20;

You can obtain all CDRs in the following tables:

```
 public | client_cdr20200412                               | table    | class4_dial | 252 MB     | 
 public | client_cdr20200413                               | table    | class4_dial | 293 MB     | 
 public | client_cdr20200414                               | table    | class4_dial | 216 MB     | 
 public | client_cdr20200415                               | table    | class4_dial | 318 MB     | 
 public | client_cdr20200416                               | table    | class4_dial | 353 MB     |  
```


# Raw Switch Data

Class 4 automatically store all PCAPs and CDRs to the local disk.  However, if the local disk is less than 15% free space, Class 4 will stop to terminate calls.  This is done so that Class 4 will not terminate calls if it can't generate CDRs for the billing purpose.&#x20;

You can find the CDRs in the following directory:

```
 [root@Server11 ~]# ls -al /opt/denovo_v6/dnl_softswitch/cdr/2021/04/12/02/2021041202*
-rw-r--r-- 1 root root  3834 Apr 12 02:00 /opt/denovo_v6/dnl_softswitch/cdr/2021/04/12/02/202104120200.cdr
-rw-r--r-- 1 root root  8255 Apr 12 02:01 /opt/denovo_v6/dnl_softswitch/cdr/2021/04/12/02/202104120201.cdr
-rw-r--r-- 1 root root  3977 Apr 12 02:02 /opt/denovo_v6/dnl_softswitch/cdr/2021/04/12/02/202104120202.cdr
-rw-r--r-- 1 root root  6870 Apr 12 02:04 /opt/denovo_v6/dnl_softswitch/cdr/2021/04/12/02/202104120203.cdr
-rw-r--r-- 1 root root  6086 Apr 12 02:04 /opt/denovo_v6/dnl_softswitch/cdr/2021/04/12/02/202104120204.cdr
-rw-r--r-- 1 root root  3760 Apr 12 02:05 /opt/denovo_v6/dnl_softswitch/cdr/2021/04/12/02/202104120205.cdr
-rw-r--r-- 1 root root 10095 Apr 12 02:07 /opt/denovo_v6/dnl_softswitch/cdr/2021/04/12/02/202104120206.cdr
-rw-r--r-- 1 root root  3743 Apr 12 02:07 /opt/denovo_v6/dnl_softswitch/cdr/2021/04/12/02/202104120207.cdr
-rw-r--r-- 1 root root  4480 Apr 12 02:08 /opt/denovo_v6/dnl_softswitch/cdr/2021/04/12/02/202104120208.cdr
-rw-r--r-- 1 root root  4468 Apr 12 02:09 /opt/denovo_v6/dnl_softswitch/cdr/2021/04/12/02/202104120209.cdr
-rw-r--r-- 1 root root 10092 Apr 12 02:11 /opt/denovo_v6/dnl_softswitch/cdr/2021/04/12/02/202104120210.cdr

```

{% hint style="info" %}
&#x20;All CDR files are stored in per-minute interval.
{% endhint %}

You can find the PCAPs in the following directory:

{% code title=" " %}

```bash
[root@Server11 ~]# ls -al /opt/denovo_v6/dnl_softswitch/pcap/20210412/202104120*
-rw-r--r-- 1 root root 547753 Apr 12 00:01 /opt/denovo_v6/dnl_softswitch/pcap/20210412/202104120000.pcap
-rw-r--r-- 1 root root 357445 Apr 12 00:02 /opt/denovo_v6/dnl_softswitch/pcap/20210412/202104120001.pcap
-rw-r--r-- 1 root root 361848 Apr 12 00:03 /opt/denovo_v6/dnl_softswitch/pcap/20210412/202104120002.pcap
-rw-r--r-- 1 root root 614852 Apr 12 00:04 /opt/denovo_v6/dnl_softswitch/pcap/20210412/202104120003.pcap
-rw-r--r-- 1 root root 372762 Apr 12 00:05 /opt/denovo_v6/dnl_softswitch/pcap/20210412/202104120004.pcap
-rw-r--r-- 1 root root 349719 Apr 12 00:06 /opt/denovo_v6/dnl_softswitch/pcap/20210412/202104120005.pcap
-rw-r--r-- 1 root root 343978 Apr 12 00:07 /opt/denovo_v6/dnl_softswitch/pcap/20210412/202104120006.pcap
```

{% endcode %}

{% hint style="info" %}
PCAP is store in a per-minute file.
{% endhint %}


# CDR Data

Here is the Raw CDR field header and corresponding description:

| Field Header                               | Description   |
| ------------------------------------------ | ------------- |
| Answer Time                                |               |
| Response to Ingress                        | Ingress Resp  |
| DNIS LATA                                  | OB LATA       |
| DNIS OCN                                   | OB OCN        |
| DNIS Rate Center                           | OB RC         |
| Dynamic Route Name                         | Dyn Route     |
| Egress Bill Minutes                        | OB Bill Min   |
| Egress Bill Result                         |               |
| Egress Bill Time                           |               |
| Egress Carrier                             | OB Carrier    |
| Egress Cost                                | OB Cost       |
| Egress DNIS Type                           |               |
| Egress Trunk                               | OB Trunk      |
| Egress Rate                                | OB Rate       |
| Egress Rate Effective Date                 |               |
| Egress Rate Table                          | OB Rate Table |
| Egress Rate Type                           | OB JD         |
| Egress Trunk Trace                         |               |
| Final Route                                |               |
| Orig/Term Release                          | Rel. By       |
| Ingress Bill Minutes                       | IB Bill Min   |
| Ingress Bill Result                        |               |
| Ingress Bill Time                          |               |
| Ingress Client Cost                        | IB Cost       |
| Ingress Carrier                            | IB Carrier    |
| Ingress Client Rate                        | IB Rate       |
| Ingress Rate Table                         | IB JD         |
| Ingress DNIS type                          |               |
| Ingress Trunk                              | IB Trunk      |
| Ingress Rate Effective Date                |               |
| Ingress Rate type                          |               |
| Is Final Call                              | Final         |
| LRN Number                                 | LRN           |
| LRN LATA                                   | LRN LATA      |
| LRN OCN                                    | LRN OCN       |
| LRN Rate Center                            | LRN RC        |
| Timezone                                   |               |
| call\_duration                             | OB Dur        |
| Orig Call Duration                         | IB Dur        |
| Orig Code                                  | IB Code       |
| Orig Code Name                             | IB Code Name  |
| Orig Country                               | IB Country    |
| Orig Call id                               | IB Call-ID    |
| Orig Codecs                                | IB Codecs     |
| ORIG Switch IP                             | IB Loc IP     |
| Orig DST Number                            | IB DNIS       |
| Origination Local Payload Ip Address       | IB Loc M IP   |
| Origination Local Payload Port             | IB M Port     |
| termination\_remote\_payload\_ip\_address  | OB M IP       |
| termination\_remote\_payload\_udp\_address | OB M Port     |
| Orig Profile Port                          | IB Loc Port   |
| Orig Media IP                              | IB M. IP      |
| Orig Media Port                            | IB M. Port    |
| Orig IP                                    | IB IP         |
| Orig Src Number                            | IB ANI        |
| Orig Jurisdiction type                     |               |
| PAid user                                  | PAID          |
| PDD                                        | PDD           |
| Q850 Media Q850                            | Q850          |
| Q850 Media CAUSE                           | Q850 Cause    |
| Response from Egress                       | OB Resp       |
| Release Cause                              |               |
| End Time                                   |               |
| Rerate Time                                |               |
| Ring Start time                            |               |
| Ring Time                                  |               |
| Route Plan                                 |               |
| Routing Prefix                             | Prefix        |
| Translational DNIS                         |               |
| Rpid user                                  | RPID          |
| Source Lata                                | IB LATA       |
| Source OCN                                 | IB OCN        |
| Source Rate Center                         | IB RC         |
| Start Time                                 |               |
| Start Route Name                           |               |
| Static Route                               | Static Route  |
| Tax                                        |               |
| Term Code                                  | OB Code       |
| Term Code Name                             | OB Code Name  |
| Term Country                               | OB Country    |
| Term Call id                               | OB Call-ID    |
| Term Codecs                                | OB Codecs     |
| Term IP                                    | OB IP         |
| Term DST Number                            | OB DNIS       |
| Term Media IP                              | OB M IP       |
| Term Media Port                            | OB M Port     |
| Term Profile Port                          | OB Loc Port   |
| Term Media IP                              |               |
| Term Media Port                            |               |
| Class4 IP (Egress)                         | OB Loc IP     |
| Term Src Number                            | OB ANI        |
| Term Jurisdiction Type                     |               |
| Time                                       |               |
| Timeout type                               |               |
| Translational ANI                          |               |

\<!--td {border: 1px solid #ccc;}br {mso-data-placement:same-cell;}-->

## Getting Super Powers

Becoming a super hero is a fairly straight forward process:

```
$ give me super-powers
```

{% hint style="info" %}
&#x20;Super-powers are granted randomly so please submit an issue if you're not happy with yours.
{% endhint %}

Once you're strong enough, save the world:

{% code title="hello.sh" %}

```bash
# Ain't no code for that yet, sorry
echo 'You got to trust me on this, I saved the world'
```

{% endcode %}


# Release Cause Definition

In the CDR, there is a release cause field.  This field gives all the reason cause as to why a spcific call is disconnected in the switch.   Here is a table of all the numeric codes and their corresponding reasons.

| Release Code | Release Cause                     |
| ------------ | --------------------------------- |
| 0            | Invalid Argument                  |
| 1            | System CAP Limit Exceeded         |
| 2            | System CPS Limit Exceeded         |
| 3            | Unauthorized IP Address           |
| 4            | Ingress Prefix Does Not Match     |
| 5            | No Product Found                  |
| 6            | Trunk CAP Limit Exceeded          |
| 7            | Trunk CPS Limit Exceeded          |
| 8            | IP CAP Limit Exceeded             |
| 9            | IP CPS Limit Exceeded             |
| 10           | Invalid Codec Negotiation         |
| 11           | Block due to LRN                  |
| 12           | Ingress Rate Not Found            |
| 13           | Egress Trunk Not Found            |
| 14           | From egress response 404          |
| 15           | From egress response 486          |
| 16           | From egress response 487          |
| 17           | From egress response 200          |
| 18           | No Egress Connection              |
| 19           | Call Connected                    |
| 20           | Ingress Resource disabled         |
| 21           | Balance Use Up                    |
| 22           | No Routing Plan Route             |
| 23           | No Routing Plan Prefix            |
| 24           | Ingress Rate No configure         |
| 25           | Invalid Codec Negotiation         |
| 26           | No Codec Found                    |
| 27           | All egress no confirmed           |
| 28           | LRN Failure                       |
| 29           | Carrier CAP Limit Exceeded        |
| 30           | Carrier CPS Limit Exceeded        |
| 31           | Host Alert Reject                 |
| 32           | Resource Alert Reject             |
| 33           | Resource Reject H323              |
| 34           | 180 Negotiation SDP Failed        |
| 35           | 183 Negotiation SDP Failed        |
| 36           | 200 Negotiation SDP Failed        |
| 37           | LRN Block Higher Rate             |
| 38           | Ingress Block ANI                 |
| 39           | Ingress Block DNIS                |
| 40           | Ingress Block ALL                 |
| 41           | Global Block ANI                  |
| 42           | Global Block DNIS                 |
| 43           | Global Block ALL                  |
| 44           | T38 Reject                        |
| 45           | Partition CAP Limit Exceeded      |
| 46           | Partition CPS Limit Exceeded      |
| 47           | LRN Loop Detected                 |
| 48           | Reject partition                  |
| 49           | Resource Loop Detected            |
| 50           | Code CAP Limit Exceeded           |
| 51           | Code CPS Limit Exceeded           |
| 52           | Switch Profile CAP Limit Exceeded |
| 53           | Switch Profile CPS Limit Exceeded |
| 54           | Allowed Send To IP                |
| 55           | LRN Dipping Failed                |
| 56           | System call limit                 |
| 57           | Egress ANI Block                  |
| 58           | Egress DNIS Block                 |
| 59           | Egress Full Block                 |
| 60           | Resource ANI Block                |
| 61           | Resource DNIS Block               |
| 62           | Resource Full Block               |
| 63           | 404 Number Block                  |
| 64           | No Profitable Egress              |
| 65           | Egress CPS or Call Limit          |
| 66           | Trunk ANI CPS Limit               |
| 67           | Trunk ANI Call Limit              |
| 68           | Trunk DNIS CPS Limit              |
| 69           | Trunk DNIS Call Limit             |
| 70           | Not Jurisdiction Data             |
| 71           | No Identity Header                |
| 72           | Invalid Identity Header           |
| 73           | Shaken Provider Failure           |
| 74           | No Shaken Provider                |
| 75           | Shaken module Error               |
| 76           | Ingress non-US ANI block          |
| 77           | Ingress Wireless block            |
| 78           | Ingress DNC block                 |
| 79           | YouMail Spam DB block             |
| 80           | Ingress wireless DNIS block       |
| 81           | Ingress DNC block                 |
| 82           | YouMail Spam DB block             |
| 83           | Spam SDP block                    |


# PCAP Data

DeNovoLab Class 4 fusion automatically captures all PCAP and keeps it in hard disk for 7 days.  You can configure the pcap capture behavior of switch by modifying the \[capture] section of dnl\_softswitch.conf.  By default it has the following setting:

```
[capture]
#enable_capture = yes
#enable_compress = yes
pcap_save_day = 7
#Query duration, in hour, default is 24Hours
#pcap_query_duration = 24
#pcap_dir =
```

Here are the meaning of each fields and you can modify them based on your needs according:

| Field Name             | Description                                                                                                                                                                                                                                                                                               |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| enable\_capture        | Enable switch to capture PCAP of each call.  Default is "yes"                                                                                                                                                                                                                                             |
| enable\_compress       | Enable switch to auto compress PCAP file.  Default is "yes"                                                                                                                                                                                                                                               |
| pcap\_*save\_*&#x64;ay | Number of days to keep pcap in disk.  Default is "7"                                                                                                                                                                                                                                                      |
| pcap\_query\_duration  | The switch record pcap data in a per-minute file basis.  However, it is likely that a call has long duration and its pcap may span across multiple per-minute file.  This variable specify how far ahead the switch will look up for PCAP when a query to look for pcap for a specific call is requested. |
| pcap\_dir              | This is the directory where you want pcap to be stored.  By default, it is stored in {base dir}/dnl\_softswitch/pcap                                                                                                                                                                                      |

```
```


# Auto Data Cleanup

Class 4 provides utilizes to auto remote CDRs and PCAP from local disk.&#x20;

Here is how you can setup the following:

* number of days to keep local disk CDR
* number of days to keep CDR in DB
* number of days to keep PCAP in local disk&#x20;


# Modules

Class 4 Fusion consists of the following modules:

| Modules           | Purpose                                                                                   |
| ----------------- | ----------------------------------------------------------------------------------------- |
| Postgres          | Store all the setting data needed by Class4                                               |
| Python Controller | Provide API interface                                                                     |
| Softswitch        | SIP switch                                                                                |
| Switch Tool       | Handle regular update tasks for the switch                                                |
| Web Helper        | Handle web async job                                                                      |
| Archive Manager   | Handle interaction related to archiving CDR and PCAP to Google Cloud or FTP or disk mount |

These modules should be installed automatically when you deploy using RPM, Docker, AWS image, or Google Cloud Image.&#x20;


# Start and Stop

Upon instlled from RPM, Docker, AWS Image, Google Cloud Image, you will get a set of systemctl utilities that help you to easily start and stop each module.&#x20;

You can also use the "status" command to check the status of each module.

| Module            | System Control Command                                           |
| ----------------- | ---------------------------------------------------------------- |
| Postgres          | **system**ctl status/start/stop/restart postgresql               |
| Python Controller | **system**ctl status/start/stop/restart dnl\_api\_core           |
| Softswitch        | systemctl status/start/stop/restart dnl\_softswitch              |
| Switch Tool       | systemctl status/start/stop/restart dnl\_tools                   |
| Web Helper        | systemctl status/start/stop/restart dnl\_we&#x62;*\_*&#x68;elper |
| Archive Manager   | systemctl status/start/stop/restart dnl\_cloud\_tool             |


# Logging

Becoming a super hero is a fairly straight forward process:

| Module            | Log Path                                    |
| ----------------- | ------------------------------------------- |
| Postgres          |                                             |
| Python Controller | **/opt/denovo\_v6/dnl\_api/logs**           |
| Softswitch        | /opt/denovo\_*v6/dnl\_*&#x73;oftswitch/logs |
| Switch Tool       | /opt/denovo\_*v6/dnl\_*&#x74;ools/logs      |
| Web Helper        | /opt/denovo\_*v6/dnl\_web\_helper/logs*     |
| Archive Manager   | /opt/denovo*v6/dnl\_cloud\_tools/logs*      |
|                   |                                             |


# Software Updates

##


# Setup additional dnl\_softswitch

The same set of DB and web server can be used to handle multiple dnl*softswitch.  You may want to setup multiple dnl*software  if you have a lot of traffic, or you want to setup geographically redundancy or you want to setup a failover switch. &#x20;

Here is how you can setup additional dnl\_software and connect it to the DB and UI.


# Add Additional IP to Switch

## Introduction&#x20;

Each Class 4 UI can support multiple dnl\_softswitch instanc&#x65;*.*  Each dnl\_softswitch can listen to one or more SIP IP:port. &#x20;

In the&#x20;

#### Step 1: Check the IP address in your server

You need to make sure the IP you want to use is available in the Linux environment where you are installing Class 4 dnl\_softswitch. You can use the following command to check all IP addresses:

```bash
ip addr
```

Once you confirm you have the IP address in your server's networking.  You can add the IP in UI:

#### Step 2: Go to VoIP Gateway setup page

You can click on "VoIP Gateway" on the top right menu.

![](/files/-MZ5FYrua2VtQYqK9PSy)

#### Step 3: Add one ore more SIP Gateway

Each instance of dnl\_softswitch is one SIP gateway.  Each dnl\_softswitch has a private interface for the UI to manipulate with it.

![](/files/-MZ4wTBVNHGwaMSAmE_z)

#### Step 4: Add one or more SIP Profile

You can expand on the SIP Profile within each SIP Gateway and add additional SIP IP to it.&#x20;




---

[Next Page](/llms-full.txt/1)

