This documentation applies to NMS version 5.4. An online version of the software can be found here.
the Telephony Plugin polls data for Telephony Reports that display call statistics, assist with billing, track down call quality problems, detect telephone system abuse, and plan future telecommunications needs. Telephony transmits voice communications over the network using open, standards-based Internet Protocol. SevOne NMS uses the International Telecommunication Union G.107: E-model computational model to calculate telephony statistics. See the following website for details https://www.itu.int/rec/T-REC-G.107/en.
The Telephony plugin polls metrics from several telephony device sources and each telephony vendor has a specific set of functions that the Telephony plugin compiles together via the SevOne-calld executable.
Avaya RTCP- socket_listen_rtcp
Cisco CallManager CDR - poll_listen_cmcdr
SIP - socket_listen_sip_vqrtcpxr
Values are loaded into net.telephonylisteners and are launched from Listener.cpp. The Telephony plugin looks at the library, entrance point function, and number of threads then stores data in normalized tables that are joined together to present a view of calls.
Table |
Key Linkage |
Description |
telephony.calls |
id |
Initial record of the call for reports. The table contains a monotonically increasing set of IDs that correspond to a conversation. |
telephony.legs |
call_id = calls.id |
Table that contains the information for each leg of a call. This represents a single endpoint of a call for Avaya (RTCP) and SIP sources. |
telephony.cmcdrlegs |
leg_id = legs.id |
Contains Cisco CM specific information that comes from the combination of CDR and CMR files |
telephony.rtcplegs |
leg_id = legs.id |
Contains Avaya (RTCP) specific information |
telephony.vqrtcpxrlegs |
leg_id = legs.id |
Contains SIP specific information |
net.telephonyregistereddevices |
<none> |
Contains information about all known VoIP endpoints that are linked to the telephony.legs records outside of the database. |
The Telephony plugin for Avaya uses RTCP (Real Time Control Protocol) and works with RTP (Real time Transport Protocol) to deliver both the call payload and management information. RTP is a framing protocol for real time applications that provides content labels and time functions for inter-media and intra-media synchronization. RTCP is a periodic control packet that provides a feedback mechanism for the media flow. Both are carried over UDP. This is useful as a management interface because the devices involved in a call can send the control packets to multiple destinations. Management applications can observe the results of a call without the need to actively participate in the control of the device.
RTCP has five basic packet types:
SR - Sender Reports (basic tx and rx statistics from senders) In telephony, all ends of the call are senders
RR - Receiver Reports (rx statistics from other participants or from active senders if > 31 sources)
SDES - Source description, including CNAME
BYE - explicit leave
APP - application specific extensions
Avaya call process code is an RTCP listener that lives in following files:
listener.rtcp.cpp
listener.rtcp.hpp
These use functions from:
ListenerUtil.cpp
ListenerUtil.hpp
The call process code parses the four basic types and does not support APP (application specific extensions). It is a generic RTCP listener that is tied to Avaya devices. The primary data source is the Sender Report which provides the following information:
SSRC (identification of the source)
NTP data (time stamp when the report was sent)
RTP data (corresponding RTP time)
packet count
octet count
Jitter
time stamp of last SR
delay since last SR
cumulative number of packets lost
fraction of packets lost since last report
Because RTCP packets are periodically sent, the data from all of the packets for a given conversation are summed together to provide data representative of a call via the following processing logic:
Obtain port, threads, device_id, and domain from the list of passed arguments
Obtain the value of "synced" from the row
Initialize the listener
Create a thread pool of the size specified that call parse_packet() method
Create a epoll fd with the following three fds:
The socket listening to the port specified
A timerfd to send periodic updates
Listener.pipe_read for communication with the calling process
Use epoll_wait to absorb multiple events
If the event came from pipe_read, assume it was a thread aborting and remove it from the pool
If the event came from the socket
call recv_packet()
calloc for the size of the buffer
calloc for a SevonePacketData pointer
add length, timestamp, and point SevonePacketData->buffer to buf
dispatch a thread to process the data
If the event came from the timerfd
complete_timedout_calls() for anything that last had an update > 300 seconds ago
reset the timerfd
parse_packet()
Make and verify a local DB connection to use within the specific parsing functions
Specific Parsing for the various types to return MetricData
SR - pull pertinent metrics, normalize time values, and call mergeCallDataPacket()
RR - functionally empty
SDES - pull CNAME, NAME, EMAIL, PHONE, LOC, TOOL, NOTE, and call mergeCallDataPacket()
BYE - call report_completed_call()
Immediately free MetricData without examination
MetricData is handled within each packet type parser
mergeCallDataPacket()
Data primarily keyed on "cname" which is the SSRC
Cisco CallManager has a different interface even though the handsets may support SIP and/or RTCP. Cisco expects the poller to use the CDROnDemand service to reverse SFTP files that describe each discrete call from the CallManager. Each call is described by a CDR (Call Detail Record) and may be accompanied by zero or multiple CMRs (Call Management Records). CMRs are generated for each endpoint that participates in a call, but in certain situations (encoding changes, conference calls, etc.) there may be multiple records issued. In order to fit those records within the database structure, the Telephony plugin makes one entry in telephony.legs and one entry in telephony.cmcdrlegs for each CDR.
The Telephony plugin uses the following for CDR call collection:
Periodically wake and ask the CM for the list of files that have been generated since the last successful import. This builds the list of call records to be fetched.
For each file, bring it over to the current system (done via CM SFTPing the file to SevOne NMS)
drop the files into /cmcdr
Call Processing (see below)
If a file was not received or had general parsing errors, attempt to retransmit the file from the source
If the file was processed successfully, move it to the processed files section
Identify that the call processing for this time block has been successful and move the import time forward in the database
Periodically remove older files from the system.
The Telephony plugin uses the following for CDR call processing when the file comes in:
Check the field cdrRecordType to determine it is a CDR or CMR, 1 is CDR, 2 is CMR
If CDR, for each line of records:
Insert into telephony.calls with the domain name and get the insert ID to use as the call_id for telephony.legs.
Parse and add CDR record to the database
Check telephony.cmcdrlegs, which contains CMR records, to see if any CMR records for this CDR arrived earlier than this record. If so, update the cmcdrlegs.leg_id with leg.id
If CMR, for each line of records:
Check if a CDR record arrived earlier, if so, grab the leg.id and use it for cmcdrlegs.leg_id.
Update telephony.cmcdrlegs with this CMR record
Matching CDR and CMR records
Use source_callId which is the combination of globalCallID_callManagerId and globalCallId_callId
This ID loops back every 7 days (extremely worst case) to match the CDR and CMR records and checks for the file arrival time. If the time difference is within 1 day, the records are paired.
The Telephony plugin uses the following for CDR statistical analysis
Jitter and Latency are the MAX value across all CMR files for a particular leg_id
Loss is calculated (in percentage) by the sum(packet_lost)/sum(packets_sent+packets_recv)
MOS for each leg is the average value of MLQK, which is MLQKav
R is calculated by using MIN(mos)
Session Initiation Protocol (SIP) is a communications protocol that signals and controls multimedia communication sessions. The most common applications of SIP are in Internet telephony for voice and video calls, as well as instant messaging all over Internet Protocol (IP) networks. The protocol defines the messages that are sent between endpoints, which govern establishment, termination and other essential elements of a call. SIP is an application layer protocol designed to be independent of the underlying transport layer.
The SIP processing logic is similar to the RTCP handling code except that:
There is only a single message type
Calls are terminated when the Telephony plugin stops getting messages
Telephony reports take data from two principle tables and one vendor specific table that describe each call. All data for Telephony Report comes from telephony.legs table unless otherwise noted.
telephony.calls
telephony.legs
telephony.cmcdrlegs
Basic Report Fields
Field |
Source |
id |
legs.call_id |
domain |
calls.domain |
src |
src |
srcip |
srcip |
srcphone |
src_phone |
dst |
dst |
dst |
dstip |
dstphone |
IF(legs.dst_phone, legs.dst_phone,'0000') |
origcodec |
cmcdrlegs.orig_codec |
dstcodec |
cmcdrlegs.dest_codec |
origdevicepool |
cmcdrlegs.orig_device_pool |
dstdevicepool |
cmcdrlegs.dest_device_pool |
start |
IF(legs.start,legs.start,'N/A') |
end |
IF(legs.end,legs.end,'N/A') |
duration |
IF(legs.end>0 AND legs.start >0, TIMEDIFF(FROM_UNIXTIMend),FROM_UNIXTIME(start)),'N/A') |
jitter |
jitter |
latency |
latency |
r |
r |
mos |
(1+0.035*r+r*(r-60)*(100-r)*0.000007) |
loss |
loss |
Each row in the database represents a discrete call (or endpoint of a call). The Telephony plugin uses Group By and Sort By to organize the resulting data.
Field |
Call ID |
Source |
Destination |
Domain |
Origin Codec |
Destination Codec |
Origin Device Pool |
Destination Device Pool |
id |
X |
X |
X |
X |
X |
X |
X |
X |
domain |
|
|
|
|
|
|
|
|
src |
X |
|
X |
X |
X |
X |
X |
X |
srcip |
X |
|
X |
X |
X |
X |
X |
X |
srcphone |
X |
|
X |
X |
X |
X |
X |
X |
dst |
X |
X |
|
X |
X |
X |
X |
X |
dstip |
X |
X |
|
X |
X |
X |
X |
X |
dstphone |
X |
X |
|
X |
X |
X |
X |
X |
origcodec |
X |
X |
X |
X |
|
X |
X |
X |
dstcodec |
X |
X |
X |
X |
X |
|
X |
X |
origdevicepool |
X |
X |
X |
X |
X |
X |
|
X |
dstdevicepool |
X |
X |
X |
X |
X |
X |
X |
|
start |
X |
X |
X |
X |
X |
X |
X |
X |
end |
X |
X |
X |
X |
X |
X |
X |
X |
Special Handing
Field |
Handling |
duration |
average difference (in seconds) between start and end for each call, else 0 |
jitter |
average else 0 |
latency |
average else 0 |
r |
average else 0 |
mos |
average (based on computation above) else 6 |
loss |
average else 0 |
count |
the total number of calls aggregated into a row in the display |
The Telephony plugin polls CallManager and SIP devices for telephony data and no changes need to be made for SIP and CDR telephony devices. This section describes how to enable Avaya devices to send RTCP data to SevOne NMS. This workflow is outside of the SevOne NMS application and may not present all of the steps your network requires to enable devices to send RTCP data. You may need to reference the device manufacturer's documentation. For Avaya devices, make the following entries in the Avaya Communications Manager to configure the device to send telephony data to SevOne NMS.
Related SevOne NMS workflows include the Device Manager that provides access to the New Device page and the Edit Device page where you enable the Telephony plugin for a device.
Please use the following settings on your Avaya device.