# Introduction

## About Class4 Version 5

DNL Class 4 Fusion Version 5 is a popular Class 4 switch especially in the United States.  This cook book is a mean to help new user to start using our switch.

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/CLASv5d2/Welcome+to+Denovo+Class+4) at <https://doc.denovolab.com/display/CLASv5d2/Welcome+to+Denovo+Class+4>.


# Support

Denovolab provides support to both our Community version user and Licensed user.   We have support staff working 24 by 7 to assist you in answering you all questions you need to know.   The only difference is that for Licensed user, we will provide installation support, server monitoring and live hands-on assistance in managing your switch.  For Community version user, Denovolab provides details on how to configure our switch via Live Chat, Ticket System, and Google Group.

| Support Channel                                             | Community Version | Licensed User |
| ----------------------------------------------------------- | ----------------- | ------------- |
| [Google Group](https://groups.google.com/g/dnl-class4-user) | Yes               | Yes           |
| [Ticket System  ](http://support.denovolab.com)             | Yes               | Yes           |
| [Live Chat](http://support.denovolab.com)                   | Yes               | Yes           |
| Skype                                                       | No                | Yes           |
|                                                             |                   |               |


# Create Vendor

## Step 1: Go to Client Page

Click on Management > Carrier:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYTjrV0Qc2Wsk0mbOs7%2F-MYTogRepSVF6ingQmS5%2Fimage.png?alt=media\&token=49545d10-29e3-4893-ad7b-c86aebdf1e12)

{% hint style="info" %}
&#x20;Each Carrier can be both client and vendor.  To use a Carrier as a client, you just need to create ingress trunk.  To use a Carrier as a vendor, you just need to create egress trunk.
{% endhint %}

Once you see the Carrier listing, you can click Create:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYTjrV0Qc2Wsk0mbOs7%2F-MYTqMIu3_bD3zvZVyQv%2Fimage.png?alt=media\&token=dc9d83e9-90c0-440c-adcc-ce7df0833902)

In the "Create New" page, you can fill out the Carrier detail.  The basic fields you need are : Company Name and Contact Email.

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYTjrV0Qc2Wsk0mbOs7%2F-MYTqiP1tVASMooMRjfe%2Fimage.png?alt=media\&token=48af2712-c031-4509-a939-437d0a28af9f)

## Step 2: Create Vendor Trunk

After submit, you will be asked to creat ingress or egress trunk.&#x20;

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYTjrV0Qc2Wsk0mbOs7%2F-MYTqrOYrXGPc4rqXHpc%2Fimage.png?alt=media\&token=df83d82f-2740-4e8c-8d60-30b331c7d94a)

For vendor, you will click "Egress Trunk".

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYTjrV0Qc2Wsk0mbOs7%2F-MYTr4dA3VER7syHghvf%2Fimage.png?alt=media\&token=b73fb722-0ffc-49c5-8b54-0bf6c09552d5)

You just fill out the vendor trunk detail.  Then, your vendor is successfully created.&#x20;

## Step 3: Create Tech Prefix for Vendor Trunk

Within the Egress trunk you created on Step 2, you can see the list of tags on top.  The tag that let you to create tech-prefix is the "Action" tag:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWHHcJSVJ-9F7LXCtk%2F-MYWHRc2I52tl5sxBfmI%2Fimage.png?alt=media\&token=81c875c5-963f-47ee-adb7-0713f223cead)

You can see the following after you click into the Action tag:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWHHcJSVJ-9F7LXCtk%2F-MYWNoWCBUx__VBvx4t4%2Fimage.png?alt=media\&token=cfc82c9b-b8da-4c2b-a6cb-2f0416e048b7)


# Create Routing

## 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:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWQpVGfczdrZuJBDAG%2F-MYWc7WVXd2eMGexNbS1%2Fimage.png?alt=media\&token=48c82c61-b784-4aa7-b13e-c7f9ef808f27)

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWQpVGfczdrZuJBDAG%2F-MYWcgYSJgPKFF2I4a7w%2Fimage.png?alt=media\&token=7fa9effe-1aba-4178-96a5-6cb3a9fac99c)

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWQpVGfczdrZuJBDAG%2F-MYWcuzS-yEmAQJzXTQD%2Fimage.png?alt=media\&token=ee24c43b-5e93-47cf-a613-65f080d36605)

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWQpVGfczdrZuJBDAG%2F-MYWd0QSFyawUULbbuJB%2Fimage.png?alt=media\&token=08794674-b72f-43eb-b842-8ef2ca99e0f6)

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWQpVGfczdrZuJBDAG%2F-MYWecLM1C6pQkGHZsL_%2Fimage.png?alt=media\&token=1df791b7-f936-4c58-8335-d44afc47373c)

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWQpVGfczdrZuJBDAG%2F-MYWel0cKzU_1ZnTftY-%2Fimage.png?alt=media\&token=21f8254e-2ad9-462f-a992-d4171288fcef)

#### Step 3: Add new static routing

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWQpVGfczdrZuJBDAG%2F-MYWex0SHpkVdAPTDljQ%2Fimage.png?alt=media\&token=8afa574e-6dc8-4a8d-a4e3-fd23bbc45811)

If you are terminating US traffic, you should route by LRN number instead.

Step 4: Add new static routing entry

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWQpVGfczdrZuJBDAG%2F-MYWfJVnAspbfzEYkfxy%2Fimage.png?alt=media\&token=8389668b-c8bf-4dfe-830b-c7169130fec2)

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWfYmdfQwv2O0-Xsqm%2F-MYWtiZFY2cLD86SWsix%2Fimage.png?alt=media\&token=4eca88ec-752f-43b7-b1a1-8d0ac997e713)

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWfYmdfQwv2O0-Xsqm%2F-MYWtrHj5PkigytvZTqi%2Fimage.png?alt=media\&token=40ed3fcd-1e79-4429-b5ab-3bf5a4e5dea0)

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


# Create Client

## Introduction

To create a client, you need to have a Carrier created.  In Class 4 Version 5, a carrier can be both client and vendor.  When you give it an ingress trunk, it becomes a Client.  When you give it an egress trunk, it becomes a Vendor.  A carrier can be both Client and Vendor.

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWu-OvRvPes5YxE8NZ%2F-MYWuO1PgzIDaQhitQZT%2Fimage.png?alt=media\&token=3c566fc3-9df5-4f62-98cb-7e755a85579d)

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

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

* Name
* Company Name
* Email

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWu-OvRvPes5YxE8NZ%2F-MYWuc9gPxhCygKyqX5L%2Fimage.png?alt=media\&token=afafca18-691e-4977-a832-ffb61d5a40b6)

#### Step 3: Create Ingress Trunk

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWu-OvRvPes5YxE8NZ%2F-MYWuv6g8coHhwfCXGA1%2Fimage.png?alt=media\&token=26aa9d30-e979-43ca-878c-a33cad5c3181)

When you click "Create Ingress Trunk", you comes to this page:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWu-OvRvPes5YxE8NZ%2F-MYWvQfD0IED-feictP7%2Fimage.png?alt=media\&token=c5a2f187-6c4c-4c54-a8fd-d8d39257dfeb)

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


# Call Simulation

#### 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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWvb-8lEECs04l5XoP%2F-MYWwMZO6QG-1LUP6Njj%2Fimage.png?alt=media\&token=02f1776b-6d66-40e2-9822-6b58821154cf)

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWvb-8lEECs04l5XoP%2F-MYWwS3vAqoddBTglGuz%2Fimage.png?alt=media\&token=ae4bb17f-6b86-40c1-a3a7-e981fbab86e6)

#### Step 2: Specify your test information

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

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWvb-8lEECs04l5XoP%2F-MYWwzC_OVVzRAr3YHqe%2Fimage.png?alt=media\&token=81bc75c2-b7b4-4d40-89f1-c716dafb085c)


# Check CDR

Class 4 provides a very comprehensive filter for you to look up CDRs that you are looking for.  To search for CDRs, you go to Statistics > CDR Lists:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWx3KPXZloTgCD0PbC%2F-MYWxX54NzoOFuXikIz2%2Fimage.png?alt=media\&token=21502b1b-5235-4657-8f5f-5ae8bdc63723)

Then, you can see all the search criteria:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWx3KPXZloTgCD0PbC%2F-MYWxdRXQVJlYt0UdEKl%2Fimage.png?alt=media\&token=d59808df-ec19-4140-b918-4870d9f28fa3)

Class 4 gives you complete set of fields to view your CDRs:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWx3KPXZloTgCD0PbC%2F-MYWxlBERXjsVsMqMp8K%2Fimage.png?alt=media\&token=a1c587b3-64b9-449d-b125-11cd09b4a26a)

If you are search for CDRs within a long period of time, it may take a while.  Class 4 let you run your CDR search job in the background by selecting "Excel CSV" option.

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWxm-ohG6eDJrAelhH%2F-MYWy4jfiatgeYRoEWQf%2Fimage.png?alt=media\&token=b2228b50-1dcc-41ab-80b7-6dfabe05b2e6)

When this option is selected, your CDR download will be available in the Export tag when ready:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWxm-ohG6eDJrAelhH%2F-MYWyHuuwHPLji4e6qom%2Fimage.png?alt=media\&token=5c6fc970-3c95-49f2-9fae-fcc26d526cb8)


# Check Report

Class 4 Fusion provides you many reports to render your traffic with different angle:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWyJ8F8N69vG_t_Gok%2F-MYWykI8xX1VrmYhdTXf%2Fimage.png?alt=media\&token=5307f4ee-9bfd-4a38-87d4-1f12bdec79c8)

The most common report is Summary Report where you can check traffic grouping by different fields:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWyJ8F8N69vG_t_Gok%2F-MYWzlaK-6dqhQrsa3rC%2Fimage.png?alt=media\&token=7f81f17a-83b2-4b68-b89c-1264435c4011)

You also can view different fields:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWyJ8F8N69vG_t_Gok%2F-MYWzqMlqG2uKULqWGU7%2Fimage.png?alt=media\&token=c4e82993-8624-44ae-89ad-db39bdbc5671)


# Check PCAP

Class 4 let's you search for PCAP simply.  To do so, you first go to Tools > SIP Packet Search:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWzrMWbRs0-fNlpIrX%2F-MYX-GfWRHfivqkbEphz%2Fimage.png?alt=media\&token=846e9908-6328-479b-9e31-1728dd9d3954)

Then, you can see the search page with all the filter fields:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWzrMWbRs0-fNlpIrX%2F-MYX-RO6435Lc_r8DsJk%2Fimage.png?alt=media\&token=737ef8cc-7b9e-42f3-8f17-0fb2bd7f09f8)

After you submit, you can see all the CDRs that match your search criteria:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWzrMWbRs0-fNlpIrX%2F-MYX-jSpFwUhWGG4T0Or%2Fimage.png?alt=media\&token=661401a0-4aa9-4297-aa8c-4bc1add2dc45)

You can click "SIP" next to Origination Call ID to see the ingress side of PCAP and you can click on Termination Call ID to see the ingress side of the PCAP.&#x20;

You can click "Full" to see the full ingress + egress PCAPs for a specific incoming call. &#x20;

It will take a short time to retrieve the PCAP file and it will be available in the "SIP Requests" tag:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYX-yOZrQc1lgopIxez%2F-MYX08Z-gH4Ppsgq8tgz%2Fimage.png?alt=media\&token=3ad6071c-0720-4ff0-9c96-1d8385a01c1f)


# Setup ANI Rotation

#### Introduction

Class 4 let's you upload a list of ANIs that you want to replace with.  You can setup multiple ANI groups and specify the ANI group in egress trunk.  Then, when terminating traffic via egress, Class 4 will replace the ANI for each calls that terminating via that vendor trunk.

#### Step 1: Go into Switch > Random ANI Group&#x20;

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYX0Bxln_31ltS2_SBV%2F-MYX1aztoJmgtl9TtTOh%2Fimage.png?alt=media\&token=c0ca0e68-6c00-4b1e-b224-80627c47c930)

#### Step 2: Define list of ANI Group

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYX0Bxln_31ltS2_SBV%2F-MYX1f5PENjwa9AJkWt3%2Fimage.png?alt=media\&token=d6e2e9c1-ab75-4576-a86f-cbca440935ce)

#### Step 3: Upload Numbers to your ANI Groups

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYX0Bxln_31ltS2_SBV%2F-MYX1jINJU5-etfPyNqe%2Fimage.png?alt=media\&token=723cfe0f-25a3-4960-bf01-7c3731107e7f)

#### Step 4: Associate the ANI Group to the vendor trunk

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYX0Bxln_31ltS2_SBV%2F-MYX2T5Bpj0UNqXsoc2F%2Fimage.png?alt=media\&token=6850b323-1f26-4cd3-9479-456be8bc4b0f)


# Set Min Call Duration

Introduction

It is a common requirement to set a minimum duration in the outbound vendor trunk.  In Class 4, you can manipulate the Min Call Duration within each Vendor Trunk setting:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYX34VHC8TjCR0VfdnL%2F-MYX3vQCoP6kkHLS94if%2Fimage.png?alt=media\&token=c0d333b1-3991-4bd7-b71d-79de00dbcfc6)

At the bottom of the Egress Trunk page, you can expand on the "Timeout Setting" section and configure these values.&#x20;


# Block Calls by DNC

## Introduction

Click here to download a curtesy [copy](https://drive.google.com/file/d/1MCQefBezKUxTriNZL2ZojhMqZq-Khhnj/view?usp=sharing) of non-updated DNC.&#x20;


# Update US LERG in Switch

You can go to "US Jurisdiction" page and click on Import tag, as shown here:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYXBHS-zcRMZ_EIVNSU%2F-MYXBP2iKB7RAt-HliWR%2FOX1YjJ.png?alt=media\&token=acd502c3-ca56-4a9c-b0a2-1c43785ca03c)

\
\
\
Ongoing, you can also download updated lerg file from the following URLs:\
\
US only:\
\
<http://lerg.denovolab.com/lerg/download?countries=US>\
\
US and Canada:\
\
<http://lerg.denovolab.com/lerg/download?countries=US,CA>\
\
If you need help, you may reach out to  dnl\_support on skype, support ticket site, or email, and we will upload for you as well.\
\
\
&#x20;


# How to manage PCAP cleaning

## How it works

Class 4 store all SIP capture in a file every minute.  You can find all the PCAP log under the following directory path:

&#x20;{installdir}/dnl\_softswitch/pcap.

{% hint style="info" %}
If you are installed using the standard RPM, AWS cloud image or Google cloud image, the default install path should be /opt/denovo
{% endhint %}

PCAP files get accumulated very fast.  If you don't have sufficient space, you may want to setup Class 4 to automatically clean the pcap files.

Here is the config file you need to use to control the pcap setting:

```
/opt/denovo/dnl_softswitch/conf/dnl_softswitch.conf
```

The section you need to update is:

```
[capture]
enable_capture = yes
enable_compress = yes
pcap_save_day = 3
#this setting tells the switch from when you want the old pcap be compressed
#delay_compress_days = 2
#this section tells the switch at which hour of the day ( GMT ) that you want the compress to take place.
#delay_compress_exe_hour = 5
    
```

After you make changes to this config file, you must restart the switch to make it effective.  Here is the command to restart Class 4 softswitch:

```
systemctl restart dnl_softswitch
```


# How to manage CDR cleaning

## How it works

Class 4 store CDRs to the local direct every minute and it is saved in a per minute file.  You can find the local CDRs from {installdir}/dnl\_softswitch/cdr.

{% hint style="info" %}
If you are installed using the standard RPM, AWS cloud image or Google cloud image, the default install path should be /opt/denovo
{% endhint %}

Class 4 automatically compresses the daily CDR into .tar.gz format.  The local CDR can be setup to be automatically cleaned.  You may also configure Class 4 to push the CDRs to remote storage such as FTP and Google Cloud bucket.  Class 4 also provides facility to automatically remove old CDRs from FTP and Google Cloud bucket after it has been stored for a period of time.&#x20;

If you are using old install, then you are likely be using dnl-backup-tool.  All new install started from March of 2021 should be using dnl-cloud-tool.  They both serves the same purpose but dnl-cloud-tool provides additional tools to monitor remote archive, manage remote archive, and search for CDR from remote archive.&#x20;


# Using dnl\_backup\_tool

## CDR Management

Assuming you are using the default installation path, then you can find the configuration in the following file:

```

/opt/denovo/dnl_backup_tool/conf/dnl_backup_tool.conf
```

The following fields let you configure how many days you want to keep CDRs in local disk.

{% code title=" " %}

```bash
basepath	/opt/denovo/dnl_softswitch/cdr/

# Compress CDR all data older than this value (in days)
# Default: 0 - do not compress .cdr files
keep_cdr	3

# Remove all archives older than this value (in days)
# Default: 0 - do not remove old archives
keep_archives	10


```

{% endcode %}

Within the same config file, you can setup Google cloud storage as follows:

```bash
### Gcloud configuration


# Authentication type (service, oauth2)
# Default: service
gcloud_type		service

# (M) Bucket to use
gcloud_backup_bucket	your_bucket_name

# (M) Authorization methods
#
# Service account:
#   - set gcs_auth_type to SERVICE
#   - provide path to JSON keyfile in *gcs_keyfile_path
#
# OAuth2:
#   - set gcs_auth_type to OAUTH2
#   - specify client email, secret and refresh token 
#
gcloud_key_file		/opt/denovo/dnl_backup_tool/conf/tokyo-bird-344444-7c1c6325c412.json
#gcloud_key_file		/opt/denovo/dnl_backup_tool/conf/ytel-powersips.json
gcloud_email		your_google_cloud_account
gcloud_secret		RkLYIe3k5tfffhJbi96Kut
gcloud_token		1/7jrRTfff7ZFkTp9u4sA1f0595t7__SmLS7oXP
```

If you prefer to use FTP for your cold storage, then you can setup the following parameters:

```bash
### (S)FTP configuration


# (M) Server URL
ftp_url		your_ftp_ip_or_host

# Server port
# Default: 21 - FTP, 22 - SFTP
ftp_port	21

# (M) Path to the CDR directory on the server
ftp_backup_dir	/fto_path/switch1

# Use relative paths in QUOT commands instead of absolute
# Default: false
ftp_use_relative_paths	false

# (M) Authorization methods
#
# FTP:
#   - By login/password pair:
#     set *ftp_user, and *ftp_password if required
#     leave *netrc_path empty
#
#   - Using system settings:
#     provide path to .netrc file in *netrc_path
#
#   - Anonymous:
#     set *ftp_user to "anonymous" and leave *ftp_pass empty
#
# SFTP:
#   - By login/password pair:
#     set *ftp_user and *ftp_pass values
#
#   - Using SSH keys:
#     set *pubkey_path, *privkey_path, and *passphrase if required
#     leave *ftp_user and *ftp_pass empty
#
ftp_user	your_ftp_username
ftp_password	your_ftp_password 


```

After you make changes to this config file, you must restart the switch to make it effective.  Here is the command to restart Class 4 backup tool:

```
systemctl restart dnl_backup_tool
```

When setup correctly, you should see CDRs being pushed to your Google Cloud bucket like below:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYTQUaa3dtXlWIQjSt8%2F-MYTRFwJSAEQVDABBlfy%2Fimage.png?alt=media\&token=95367c20-22b7-45ed-9bed-0101cc8a7de0)


# Using dnl\_cloud\_tool

### Introduction

Package provides a set of applications:

1. Database manager (`dnl_cloud_dbman`) - program, which performs data manipulations (backup, outdated files compression, storage cleanup), maintains the internal database and coordinates other applications. It is necessary to run database manager at least once before starting other programs.
2. Files downloader (`dnl_cloud_downloader`) - program which provides access to the actual data (CDR and PCAP files).
3. Database search (`dnl_cloud_search`) - program to filter CDR and PCAP by a set of parameters.

### Configuration

Every program is fully configurable from PostgreSQL database, yet the global server parameters must be put in configuration file.

For complete list of parameters with their description and constrains see `doc/class_cfg_tables.sql`.

#### Server configuration

Server global configuration is placed in configuration file. Location of this file must be passed to each daemon in command-line arguments.

**General**

* `server_name` - unique human-readable name of the server. It is used to identify server across the network.
* `sqlite_db` - path to SQLite DB. On first run Database Manager will create database at this location.

**SSL configuration**

In order to run HTTP server with SSL support, you need to provide server certificate and key file.

* `key_pem_path` - path to server key file
* `cert_pem_path` - Path to server certificate

**PostgreSQL configuration**

* `pgsql_hostaddr` - binding address. Default: connect to Unix-domain socket
* `pgsql_port` - binding port. Default: 5432
* `pgsql_user` - username. Default: postgres
* `pgsql_pass` - account password. Default: none
* `pgsql_dbname` - name of the database (mandatory)

See `conf/dnl_cloud_solution.conf`

#### Connecting remote storage

The following tables contain remote storage configuration:

* `dnl_cloud_storages` - list of all storage connections
* `dnl_cloud_ftp_cfg` - FTP connection settings
* `dnl_cloud_sftp_cfg` - SFTP connection settings
* `dnl_cloud_gcloud_cfg` - Google Cloud connection settings

**In order to add new remote storage:**

1. Generate UUID and put UUID-type pair into the `dnl_cloud_storages` table.
2. With generated UUID create new configuration in one of the tables `dnl_cloud_ftp_cfg`, `dnl_cloud_sftp_cfg`, and `dnl_cloud_gcloud_cfg` for FTP, SFTP or Google Cloud connections respectively.
3. Put UUID into `cdr_storage_cfg_uuid` or `pcap_storage_cfg_uuid` field of `dnl_cloud_dbman_cfg` table for CDR and PCAP storage respectively.

The same configuration may be used for CDR and PCAP storage at the same time. However, it is recommended to use configurations with different `workdir` to prevent possible data overlap and confusion.

Remote files will be stored at:

* CDR: `/workdir/switch_name/YYYY/MM/DD.tar.gz`
* PCAP: `/workdir/switch_name/YYYY/MM/YYYYMMDD.tar.gz`

**NOTE:** Instead of UUID any unique name can be used.

#### HTTP server

Every program runs separate HTTP server. Configuration parameters have the same names and meaning between programs.

* `server_ip` - sever bind address. Default: 127.0.0.1
* `server_port` - server port. Default: 33500 - DB manager; 33501 - Downloader; 33502 - Search
* `server_use_ssl` - enable SSL

Firewall

The following parameters accept comma-separated list of wildcards to allow or to block. Example: `127.0.0.1,192.168.*.*`. By default all connections are allowed.

* `server_ip_whitelist`
* `server_ip_blacklist`

**NOTE**: Naturally you cannot have both lists enabled.

#### DB manager

* `keep_cdr`, `keep_pcap` - compress local files older than specified amount of days for CDR and PCAP respectively. Default: 0 - do not compress local files.
* `keep_cdr_archives`, `keep_pcap_archives` - remove local archives older than specified amount of days for CDR and PCAP files respectively. Default: 0 - do not remove local archives.
* `keep_cdr_remote`, `keep_pcap_remote` - remove remote archives older than specified amount of days for CDR and PCAP files respectively. Default: 0 - do not remove remote archives.
* `hourly_cdr_backup`- upload temporary CDR backup every hour
* `startup_delay` - amount of seconds to wait after midnight before starting the backup. Default: 10800 - 03:00 AM. **NOTE:** 0 represents 00:00:59 (this minimum delay is required to let switch finish updating latest data).
* `run_on_start` - run backup thread immediately on start. Otherwise run as scheduled in startup\_delay.

#### Search

* `pcap_time_margin` - time-window margin in seconds. This value is used to expand PCAP search time-window, which is necessary to ensure, that call has ended. Default: 60 seconds (recommended value).
* `req_exp_time` - request expiration time *after completion* in seconds. Expired requests will be removed from the database automatically with all data. If set to 0, daemon will not cleanup requests. Default: 604800 (7 days).
* `threads_max` - maximum amount of simultaneous processing threads. Default: 0 - unlimited

### Switch detection

On start DB manager will try to automatically find all the running switches in system, which meet the following criteria:

* Switch must be running.
* Switch binary must be called `dnl_softswitch`.
* Switch configuration file must be located near the binary (sub-directories are allowed).

You can add switches manually, using REST API (see bellow).

### REST API

#### Content type

All POST methods allow both url-encoded and JSON parameters. However, when using JSON one must specify Content-Type header.

Example:

```
% curl -L -k "https://127.0.0.1:33502/cdr" -X POST -H "Content-Type: application/json" --data '{ "switch_name" : "class", "start_time" : 1582329600 , "end_time" : 1582329600 }'

% curl -L -k "https://127.0.0.1/cdr" -X POST --data 'switch_name=class&start_time=1582329600&end_time=1582329600'
```

#### App control functions

Every program supports the same list of control functions.

**Get list of running applications with their status**

Request: `GET /status`

Arguments: none

Return: JSON array with full list of servers

* `server_name` - identification string of the server
* `ip` - HTTP server binding IP address
* `port` - HTTP server binding port
* `use_ssl` - whether HTTP server uses SSL or not
* `is_online` - whether HTTP server is online
* `operation` - current server operation

Example:

```
% curl -L -k "https://127.0.0.1:33500/status"
{
  "code" : 200,
  "error" : null,
  "servers" :
  [
    {
      "server_name" : "class4-main",
      "ip" : "127.0.0.1",
      "port" : 33500,
      "use_ssl" : true,
      "is_online" : true,
      "operation" : "Database re-indexing"
    },
    {
      "server_name" : "class4-secondary",
      "ip" : "192.168.0.1",
      "port" : 11500,
      "use_ssl" : true,
      "is_online" : true,
      "operation" : null
    }
  ]
}
```

**Common control functions**

* POST `/server_name/reload` - reload configuration. This must be called to notify daemon when configuration has changed.
* POST `/server_name/restart` - restart the application.
* POST `/server_name/shutdown` - terminate the application.

#### DB Manager

**DB control operations**

* POST `/server_name/reindex` - manually trigger DB re-indexing
* POST `/server_name/run-backup` - manually trigger backup operation

**Get list of connected switches**

Request: `GET /server_name/switch/list`

Arguments: none

Return: JSON array with list of switches

* `name` - switch name
* `cdr_dir` - path to CDR directory
* `pcap_dir` - path to PCAP directory
* `autodetected` - whether switch was automatically detected, or added manually

Example:

```
% curl -L -k "https://127.0.0.1:33500/class4-main/switch/list"
{
  "code" : 200,
  "error" : null,
  "data" : [
  {
    "name" : "class4",
    "cdr_dir" : "/opt/class4/dnl_softswitch/cdr",
    "pcap_dir" : "/opt/class4/dnl_softswitch/pcap",
    "autodetected" : true
  },
  {
    "name" : "class4-1",
    "cdr_dir" : "/opt/class4_1/dnl_softswitch/cdr",
    "pcap_dir" : "/opt/class4_1/dnl_softswitch/pcap",
    "autodetected" : false
  }
  ]
}
```

**Add new switch to the database**

Request: `POST /switch/add`

Arguments:

* `name` - unique name (mandatory)
* `cdr_dir` - path to CDR directory (mandatory)
* `pcap_dir` - path to PCAP directory (mandatory)

Return: status of the operation

NOTE: provided CDR and PCAP directories must exist.

**Remove switch from the database**

Request: `POST /switch/delete`

Arguments:

* `name` - name of the switch to remove (mandatory)

Return: status of the operation

#### Downloader

**List all files on server**

Request: `GET /server_name/list/cdr` - list CDR files; `GET /server_name/list/pcap` - list PCAP files

Arguments:

* `switch_name` - name of the switch to filter
* `start_time`, `end_time` - time filter (Unix timestamp)

Return: list of files available for downloading

* `switch_name` - name of the switch
* `timestamp` - Unix timestamp
* `has_backup` - whether file has backup in remote storage or not

Example:

```
% curl -L -k "https://127.0.0.1:33501/class4-main/list/cdr?start_time=1582329600&end_time=1582416000"
{
  "code" : 200,
  "error" : null,
  "data" : [
  {
    "switch_name" : "class4",
    "timestamp" : 1582416000,
    "has_backup" : false
  },
  {
    "switch_name" : "class4",
    "timestamp" : 1582329600,
    "has_backup" : true
  },
  {
    "switch_name" : "class4-1",
    "timestamp" : 1582416000,
    "has_backup" : true
  },
  {
    "switch_name" : "class4-1",
    "timestamp" : 1582329600,
    "has_backup" : true
  }
  ]
}
```

**List all switch files**

Request: `GET /list/cdr` - list CDR files; `GET /list/pcap` - list PCAP files

Arguments:

* `switch_name` - name of the switch to filter (mandatory)
* `start_time`, `end_time` - time filter (Unix timestamp)

Return: list of files available for downloading

**Download data**

Request: `GET /get/cdr` - download CDR file; `GET /get/pcap` - download PCAP file

Arguments:

* `switch_name` - name of the switch (mandatory)
* `timestamp` - timestamp of data file (mandatory)

Return: compressed binary data (tar.gz archive for CDR; tar archive for PCAP)

Example:

```
% curl -L -k "https://127.0.0.1:33501/get/cdr?switch_name=class4&timestamp=1582329600" -O -J
curl: Saved to filename 'class4_20200222.tar.gz'
```

#### Search

**Create CDR search request**

Request: `POST /cdr`

Arguments:

* `switch_name` - switch to filter (mandatory)
* `start_time` - call start time since Unix Epoch (mandatory)
* `end_time` - call end time since Unix Epoch (mandatory)
* `fields` - CDR fields to printout (comma-separated list of digits \[0;107])
* `ani`, `dnis` - comma-separated list of phone numbers
* `ingress_trunk_id`, `egress_trunk_id` - comma-separated list of trunk IDs
* `ingress_call_id`, `egress_call_id` - comma-separated list of call IDs

Return: unique request ID

Example:

```
% curl -L -k "https://127.0.0.1:33502/cdr" --data "switch_name=class4&start_time=1582416000&end_time=1582417200"
{
  "code" : 200,
  "error" : null,
  "uuid" : "cb875266-bfa9-4e5e-aba9-0875508c8dae"
}
```

**Create PCAP search request**

Request: `POST /pcap`

Arguments:

* `switch_name` - switch to filter (mandatory)
* `start_time` - call start time since Unix Epoch (mandatory)
* `end_time` - call end time since Unix Epoch (mandatory)
* `call_id` - comma-separated list of Call IDs (mandatory)
* `ani`, `dnis` - comma-separated list of phone numbers

Return: unique request ID

**Get status of search request**

Request: `GET /<uuid>`

Arguments: none

Return: request status

* `uuid` - request UUID
* `type` - type of request ("cdr" or "pcap")
* `created` - request creation time
* `started` - request start time
* `finished` - request completion time
* `exp_time` - request expiration time
* `status` - request status ("invalid", "created", "processing", "complete", "failed")
* `error` - error description
* `empty` - whether output file is empty
* `downloaded` - whether file was downloaded
* list of requested arguments

Example:

```
% curl -L -k "https://127.0.0.1:33502/cb875266-bfa9-4e5e-aba9-0875508c8dae"
{
  "code" : 200,
  "error" : null,
  "data" : {
    "uuid" : "cb875266-bfa9-4e5e-aba9-0875508c8dae",
    "type" : "cdr",
    "created" : 1582481551,
    "started" : 1582481551,
    "finished" : 1582481597,
    "exp_time" : 1583086397,
    "status" : "complete",
    "error" : null,
    "empty" : false,
    "downloaded" : false,
    "switch_name" : "class4",
    "start_time" : 1582416000,
    "end_time" : 1582417200,
    "ani" : null,
    "dnis" : null,
    "fields" : null,
    "ingress_trunk_id" : null,
    "egress_trunk_id" : null,
    "ingress_call_id" : null,
    "egress_call_id" : null,
  }
}
```

**List all search requests**

Request: `GET /list` - list all search requests; `GET /list/cdr` - only CDR; `GET /list/pcap` - only PCAP.

Arguments:

* `start_time`, `end_time` - time filter (Unix timestamp)

Return: list of non-expired search requests with full status (see "Get status of search request" section)

**Download file**

Request: `GET /<uuid>/download`

Arguments: none

Return: binary file (csv file for CDR; zip archive for PCAP)

Example:

```
% curl -L -k "https://127.0.0.1:33502/cb875266-bfa9-4e5e-aba9-0875508c8dae/download" -O -J
curl: Saved to filename '2020-02-23_1582416000-1582417200.csv'
```

**Delete request**

Request: `DELETE /<uuid>`

Arguments: none

Return: status of the operation

Example:

```
% curl -L -k "https://127.0.0.1:33502/cb875266-bfa9-4e5e-aba9-0875508c8dae" -X DELETE
{
  "code" : 200,
  "error" : null
}
```

### Multi server setup

It is possible to synchronize many running daemons with each other, allowing unified access to all servers from a single IP address.

In such setup one of the servers will act as a main host, redirecting requests from UI to server with requested data.

**Security**

Neither of these programs support authorization, so be sure to enable SSL and setup firewall for every application. The firewall must allow connections only from server where UI is running, plus server which will act as the main access point for UI.

**Deployment steps**

1. Install package on every server with running switch(-es).
2. On each server set unique server\_name in configuration file.
3. Set paths to SSL key/cert files and PostgreSQL connection in configuration file on each server.
4. Run `dnl_cloud_dbman` service on every server.
5. Run `dnl_cloud_downloader` and `dnl_cloud_search` on every server.

Daemons will automatically create default configurations in PostgreSQL database.

**Configuration steps**

1. For each entry in `dnl_cloud_dbman_cfg`, `dnl_cloud_downloader_cfg` and `dnl_cloud_search_cfg` tables set `server_ip`, `server_port` and `server_use_ssl` accordingly. Make sure that IP addresses are visible to the main access server, and that configured ports are not blocked by firewall. The default ports are: 33500 for DB manager; 33501 - downloader; 33502 - search.
2. For each entry in these tables set `server_ip_whitelist` value to `ip_addr_of_main_host,ip_address_of_UI`.
3. Reload or restart every application.

**Test**

Login to the server, which serves as an access point, and check status of each application:

```
% curl -L -k "https://<bind-address>:<port>/status
```

This command must return a list of recognized servers with their IP addresses.


# Getting "Missing table" error during invoice generation

## Problem Description

When generating manual invoice, the UI is showing "Missing table: cdr\_reportdetailyyyymmdd"

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYlJ6sC2Otr7lUVb9W-%2F-MYlJAg7Dt9xdm6XGfUS%2Fimage.png?alt=media\&token=1cd10c1a-f07c-4442-8030-1ba99a5dba84)

Class 4 Fusion generates invoices based off on the pre-generated reports.  If you attempt to generate invoices for dates that have no report data, it will give you that error.&#x20;

You can check when you have report data in DB:

```bash
psql -U postgres
softswitch4v5=# \d+;

```

```
 public | cdr_report_detail                                    | table    | postgres    | 8192 bytes | é¢„ç»Ÿè®¡
 public | cdr_report_detail20200608                            | table    | class4_user | 8192 bytes | 
 public | cdr_report_detail20200609                            | table    | class4_user | 8192 bytes | 
 public | cdr_report_detail20200610                            | table    | class4_user | 8192 bytes | 
 public | cdr_report_detail20200611                            | table    | class4_user | 8192 bytes | 
 public | cdr_report_detail20200612                            | table    | class4_user | 8192 bytes | 
```

{% hint style="info" %}
&#x20;Normally, this report data is not archived because it does not utilize much space.   Your system admin can drop those old cdr *report* detailyyyymmdd tables or you can use auto archiving facility in Class 4 switch to auto archive it after some times.
{% endhint %}

This cdr\_report table is also used for populating the statistics reports in the Class 4 Fusion UI.


# Switch can't process more than 30K ports

## Introduction

By default, Class 4 softswitch cap the max inbound session to 30K to avoid servers without sufficient memory to run out of memory.  This is useful when someone runs the Class 4 softswitch using less memory.&#x20;

If you are seeing the following error in the {dnlsoftswitch\_dir}/log/dnl\_softswitch.log, that means the switch's internal max\_inbound\_session is exceeded:

```
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
2021-04-19 17:30:19  [WARNING] sip_sessions.c:787 Maximum inbound call in progress, can't accept a new incoming call
```

If you have sufficient memory, you can increase this value in dnl\_softswitch.conf.

```
[general]
Default Global Log Level - value is one of debug(7),info(6),notice(5),warning(4),err(3),crit(2),alert(1),emergency(0)
log_level = 5
#System sip channel limit
max_inbound_session = 30000 
max_outbound_session = 60000
#Default switch server process thread count
task_counts = 20  
```

After you change this config file, you must remember to restart dnl\_softswitch using systemctl:

```
systemctl restart dnl_softswitch    
```

The path for this config file is :

```
 {installpath}/denovo/dnl_softswitch/conf/cnl_softswitch.conf

```


# How many calls are client sending

In the Dashboard, you can see the total channels that each of your clients are sending.  Here is the step on how to do it:

Step 1: Go to Dashboard

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYeK9uBsgtSpxEHnR66%2F-MYeLB5BxoY9WfplgKgl%2Fimage.png?alt=media\&token=2723937b-2f58-4334-8db0-110df510ee21)

#### Step 2: Check Ingress Channel Graph

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYeK9uBsgtSpxEHnR66%2F-MYeLL4b2pZslE7UFVPJ%2Fimage.png?alt=media\&token=1132b87e-5aed-40dd-bdbd-53ae92a7bb64)

It is shown here that the client sent 122 channel of traffic.

#### Step 3: Check Connected Calls Graph

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYeK9uBsgtSpxEHnR66%2F-MYeLWryDVLNQNS5O5NZ%2Fimage.png?alt=media\&token=8473018e-8dc0-4ba4-bf22-1c93b0dbfec8)

At that point in time, only 55 of those 122 channels are connected calls.  The rest of calls can be calls in progress or calls that get rejected.&#x20;


# Call Failure

There are many reasons why calls are failed.  Sometimes, it can be calls that are dropped by the switch.  Sometimes, it can be calls that are blocked by the vendor.&#x20;

Here are some steps to go about solving them.&#x20;

#### Step 1: Go to Disconnect Reports

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYeJqrwJ4BF9oR1JT_T%2F-MYeJypFTJ9oq_ie_G0c%2Fimage.png?alt=media\&token=86500c37-0007-4065-9d06-62d06ca2ec50)

#### Step 2: Check the Client Side  Disconnect Cause

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYeJqrwJ4BF9oR1JT_T%2F-MYeK0l-s9IyTvgB8MuP%2Fimage.png?alt=media\&token=57d2fc9d-3ee2-43f4-9df7-169ffda133f7)

You can click on the "Counts" to look into CDRs:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYeJqrwJ4BF9oR1JT_T%2F-MYeK4EnGYtWEy8Xgems%2Fimage.png?alt=media\&token=d90785b9-b4b5-45af-a7ec-66cb46cf38de)

#### Step 3: Check the Vendor Side Disconnect Cause

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYeJqrwJ4BF9oR1JT_T%2F-MYeK6wm6iyuCBKCZ6JS%2Fimage.png?alt=media\&token=fcaf0af2-dafe-4088-ad4f-b59665d47560)

These are the various errors that your vendors are returning for all your calls sent to them.  Note that Class 4 may attempt multiple vendors for each inbound calls.  Therefore, you will see larger count value in Vendor side than the Client side normally.


# Enforce Valid DNIS Length

&#x20;In this article, I am going to show you how to block calls that have valid length for the DNIS and ANI.&#x20;

Here is how a normal basic routing plan looks.  It basically just route all calls according to the vendor trunks defined in the dynamic route specified.&#x20;

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWPCrfhziESThfOiBU%2F-MYWQGuAq1LlTXsDwWyR%2Fimage.png?alt=media\&token=730a348e-7837-4ae4-829d-cb4a52b34f70)

However, you can set it so that this rule is applied with the length of ANI and DNIS meets the valid size.&#x20;

You can do this by clicking "Edit" on this rule:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWPCrfhziESThfOiBU%2F-MYWQXnHgn7ucZ0bbu_G%2Fimage.png?alt=media\&token=a6b03be3-f196-4aa4-ba59-38b52061ea6a)

You can use ANI/DNIS Prefix, Min Length, and Max Length to specify traffic you don't like.  For those traffic, you can send them to a different Dynamic or Static Route that either always return 503 or route to a miss call vendors like some of our clients are doing.&#x20;


# Enforce E164 Format for Vendor Trunk

In this article, I will talk about how you can enforce E164 formatted DNIS be sent to your Egress Vendor. Assuming this Vendor is for US traffic and US DNIS have the following format:

* 11 digits with +
* 10 digits without +

You can setup Action rules as follows:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYWHHcJSVJ-9F7LXCtk%2F-MYWOelBPorV7m5e74N1%2Fimage.png?alt=media\&token=e465530c-2fa6-482f-ab7b-57c2091d4cdd)


# Configure VoIP Switch in UI

## How it works

Each Class 4 platform can run multiple softswitch instance&#x73;*.*  Each of softswitch can connect to the UI via the following section:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYTUHO1MbpLiKn4fCy9%2F-MYT_-eQKxMMwqdwFhPs%2Fimage.png?alt=media\&token=8bedf149-764f-4900-abfc-e9fac912a811)

Within the VoIP Gateway, you can add your softswitch instance:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYTUHO1MbpLiKn4fCy9%2F-MYT_PThiI3QER9F-96L%2Fimage.png?alt=media\&token=445289fb-a801-4053-9a50-aca98ed53318)

Each softswitch has a "name" and this name is configured in the following config:

```
/opt/denovo/dnl_softswitch/conf/dnl_softswitch.conf 

```

Inside the file, you can see the name :

```
################################################
#
# Denovolab softswitch configuration
#
################################################

[general]
 #....
switch_name = class4

[CLI]
cli_listen_ip = 127.0.0.1
cli_listen_port = 4320
cli_connection_expires = 600
cli_connection_limit = 200


```

The CLI interface allow the UI to telnet into the switch and query for switch information.

If started correctly, you should see the following CLI port is up:

```
tcp        0      0 127.0.0.1:4320          0.0.0.0:*               LISTEN      9559/dnl_softswitch 
tcp        0      0 127.0.0.1:49292         127.0.0.1:6240          ESTABLISHED 9559/dnl_softswitch 
tcp        0      0 127.0.0.1:44122         127.0.0.1:6230          ESTABLISHED 9559/dnl_softswitch 
udp        0      0 176.31.100.14:4319      0.0.0.0:*                           9559/dnl_softswitch 
unix  3      [ ]         STREAM     CONNECTED     1175410976 9559/dnl_softswitch  
unix  2      [ ]         DGRAM                    1175410045 9559/dnl_softswitch  

```

Once CLI port is up, you can configure the VoIP Gateway as follows:

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYTUHO1MbpLiKn4fCy9%2F-MYTaiBQN3dAycCyNYRv%2Fimage.png?alt=media\&token=8d215ea2-cf56-465f-8729-e72f656894ee)

Now, notice that SIP is not up.

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYTUHO1MbpLiKn4fCy9%2F-MYTasS_gK6uPBVOndTN%2Fimage.png?alt=media\&token=805d2bd3-6df8-4590-9cf7-02b7268aa065)

Our next step is to add SIP interface to the VoIP gateway.

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYTUHO1MbpLiKn4fCy9%2F-MYTbHQ4Uqdo4ZFLdI0W%2Fimage.png?alt=media\&token=79809d9f-a7e3-4d9b-95b6-c8babf8f5611)

After you add a new SIP interface, you can restart softswitch using the following command:

```
systemctl restart dnl_softswitch
```

After you restart Class4 softswtich, you can see the SIP interface with 6060 port is started.&#x20;

```
[root@ns389055 denovo]# netstat -anp |grep dnl_softswitch
tcp        0      0 127.0.0.1:4320          0.0.0.0:*               LISTEN      13446/dnl_softswitc 
tcp        0      0 127.0.0.1:56574         127.0.0.1:6240          ESTABLISHED 13446/dnl_softswitc 
tcp        0      0 127.0.0.1:51428         127.0.0.1:6230          ESTABLISHED 13446/dnl_softswitc 
udp        0      0 176.31.100.14:4319      0.0.0.0:*                           13446/dnl_softswitc 
udp        0      0 176.31.100.14:6060      0.0.0.0:*                           13446/dnl_softswitc 
```


# SIP Switch is Down

How do you tell if Class 4 is down?

![](https://2160858555-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MYRPW5mw1EmjxhpuA4p%2F-MYTcu0T0t5IPKZjJmcI%2F-MYTdGjk8BQ5pUpgqqS4%2Fimage.png?alt=media\&token=ba0812e4-662f-4892-83f7-f93572ba2fc2)

If you see the class4 switch is disconnected, then you can restart it.

Here is the command to restart Class 4 softswitch if it is down:

```
systemctl start dnl_softswitch
```

&#x20; you're strong enough, save the world:


# Validate Auto-Invoice Rule

## What it does

Becoming a super hero is a fairly straight forward process:

```
 Usage
 
curl -X GET "http://localhost:18881/inv5/v1/client/288/auto_invoice_test?date=2021-03-28" -H  "accept: application/json"
 
```

Once you're strong enough, save the world:

{% code title=" " %}

```bash
{
  "invoice_next_date": "2021-03-24",
  "invoice_cycle_days": [],
  "messages": "Client sip_ingress id 288  period 2021-03-23 2021-03-27 success",
  "invoice_next_date_of_test": "2021-03-28",
  "generated_period": [
    {
      "start_time": "2021-03-23T00:00:00",
      "end_time": "2021-03-27T23:59:59"
    }
  ],
  "invoice_cycle": "Every 1st day(s)",
  "last_invoice_date": "2021-03-23",
  "will_generate": true
}
```

{% endcode %}


# Installation 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 license from <http://www.denovo.me>.

```
yum -y install epel-release
yum -y install https://repo.ius.io/ius-release-el7.rpm
yum -y install centos-release-scl
yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
yum install -y https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
yum -y install http://repo.denovolab.com/centos/7/noarch/denovolab-1-1.noarch.rpm
yum -y install dnl_database
yum -y install denovolab-software you're strong enough, save the world:
```


