diff options
Diffstat (limited to 'VES5.0/evel/evel-library/code/evel_library/evel_voicequality.c')
-rw-r--r-- | VES5.0/evel/evel-library/code/evel_library/evel_voicequality.c | 661 |
1 files changed, 661 insertions, 0 deletions
diff --git a/VES5.0/evel/evel-library/code/evel_library/evel_voicequality.c b/VES5.0/evel/evel-library/code/evel_library/evel_voicequality.c new file mode 100644 index 00000000..b99cfbb6 --- /dev/null +++ b/VES5.0/evel/evel-library/code/evel_library/evel_voicequality.c @@ -0,0 +1,661 @@ +/**************************************************************************//** + * @file + * Implementation of EVEL functions relating to the Voice Quality. + * + * License + * ------- + * + * Copyright(c) <2016>, AT&T Intellectual Property. All other rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: This product includes + * software developed by the AT&T. + * 4. Neither the name of AT&T nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include <string.h> +#include <assert.h> +#include <stdlib.h> + +#include "evel.h" +#include "evel_internal.h" +#include "evel_throttle.h" + +/**************************************************************************//** + * Create a new voice quality event. + * + * @note The mandatory fields on the Voice Quality must be supplied to this + * factory function and are immutable once set. Optional fields have + * explicit setter functions, but again values may only be set once + * so that the Voice Quality has immutable properties. + * @param calleeSideCodec Callee codec for the call. + * @param callerSideCodec Caller codec for the call. + * @param correlator Constant across all events on this call. + * @param midCallRtcp Base64 encoding of the binary RTCP data + * (excluding Eth/IP/UDP headers). + * @param vendorVnfNameFields Vendor, VNF and VfModule names. + * @returns pointer to the newly manufactured ::EVENT_VOICE_QUALITY. If the + * event is not used (i.e. posted) it must be released using + ::evel_free_voice_quality. + * @retval NULL Failed to create the event. + *****************************************************************************/ +EVENT_VOICE_QUALITY * evel_new_voice_quality(const char * const calleeSideCodec, + const char * const callerSideCodec, const char * const correlator, + const char * const midCallRtcp, const char * const vendorName) { + + bool inError = false; + EVENT_VOICE_QUALITY *voiceQuality = NULL; + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + assert(calleeSideCodec != NULL); + assert(callerSideCodec != NULL); + assert(correlator != NULL); + assert(midCallRtcp != NULL); + assert(vendorName != NULL); + + /***************************************************************************/ + /* Allocate the Voice Quality. */ + /***************************************************************************/ + voiceQuality = malloc(sizeof(EVENT_VOICE_QUALITY)); + + if (voiceQuality == NULL) + { + log_error_state("Out of memory"); + inError = true; + } + + //Only in case of successful allocation initialize data. + if (inError == false) { + memset(voiceQuality, 0, sizeof(EVENT_VOICE_QUALITY)); + EVEL_DEBUG("New Voice Quality is at %lp", voiceQuality); + + /***************************************************************************/ + /* Initialize the header & the fault fields. Optional integer values are */ + /* initialized as 0. */ + /***************************************************************************/ + evel_init_header(&voiceQuality->header,"voiceQuality"); + voiceQuality->header.event_domain = EVEL_DOMAIN_VOICE_QUALITY; + voiceQuality->major_version = EVEL_VOICEQ_MAJOR_VERSION; + voiceQuality->minor_version = EVEL_VOICEQ_MINOR_VERSION; + + voiceQuality->calleeSideCodec = strdup(calleeSideCodec); + voiceQuality->callerSideCodec = strdup(callerSideCodec); + voiceQuality->correlator = strdup(correlator); + voiceQuality->midCallRtcp = strdup(midCallRtcp); + evel_init_vendor_field(&voiceQuality->vendorVnfNameFields, vendorName); + dlist_initialize(&voiceQuality->additionalInformation); + dlist_initialize(&voiceQuality->endOfCallVqmSummaries); + evel_init_option_string(&voiceQuality->phoneNumber); + } + + EVEL_EXIT(); + return voiceQuality; + +} + +/**************************************************************************//** + * Add an additional value name/value pair to the Voice Quality. + * + * The name and value are null delimited ASCII strings. The library takes + * a copy so the caller does not have to preserve values after the function + * returns. + * + * @param fault Pointer to the fault. + * @param name ASCIIZ string with the attribute's name. The caller + * does not need to preserve the value once the function + * returns. + * @param value ASCIIZ string with the attribute's value. The caller + * does not need to preserve the value once the function + * returns. + *****************************************************************************/ +void evel_voice_quality_addl_info_add(EVENT_VOICE_QUALITY * voiceQ, char * name, char * value) { + VOICE_QUALITY_ADDL_INFO * addlInfo = NULL; + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + assert(voiceQ != NULL); + assert(voiceQ->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY); + assert(name != NULL); + assert(value != NULL); + + EVEL_DEBUG("Adding name=%s value=%s", name, value); + addlInfo = malloc(sizeof(VOICE_QUALITY_ADDL_INFO)); + assert(addlInfo != NULL); + memset(addlInfo, 0, sizeof(VOICE_QUALITY_ADDL_INFO)); + addlInfo->name = strdup(name); + addlInfo->value = strdup(value); + assert(addlInfo->name != NULL); + assert(addlInfo->value != NULL); + + dlist_push_last(&voiceQ->additionalInformation, addlInfo); + + EVEL_EXIT(); +} + +/**************************************************************************//** + * Set the Callee side codec for Call for domain Voice Quality + * + * @note The property is treated as immutable: it is only valid to call + * the setter once. However, we don't assert if the caller tries to + * overwrite, just ignoring the update instead. + * + * @param voiceQuality Pointer to the Voice Quality Event. + * @param calleeCodecForCall The Callee Side Codec to be set. ASCIIZ + * string. The caller does not need to + * preserve the value once the function + * returns. + *****************************************************************************/ +void evel_voice_quality_callee_codec_set(EVENT_VOICE_QUALITY * voiceQuality, + const char * const calleeCodecForCall) { + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + assert(voiceQuality != NULL); + assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY); + assert(calleeCodecForCall != NULL); + + voiceQuality->calleeSideCodec = strdup(calleeCodecForCall); + + EVEL_EXIT(); +} + +/**************************************************************************//** + * Set the Caller side codec for Call for domain Voice Quality + * + * @note The property is treated as immutable: it is only valid to call + * the setter once. However, we don't assert if the caller tries to + * overwrite, just ignoring the update instead. + * + * @param voiceQuality Pointer to the Voice Quality Event. + * @param callerCodecForCall The Caller Side Codec to be set. ASCIIZ + * string. The caller does not need to + * preserve the value once the function + * returns. + *****************************************************************************/ +void evel_voice_quality_caller_codec_set(EVENT_VOICE_QUALITY * voiceQuality, + const char * const callerCodecForCall) { + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + assert(voiceQuality != NULL); + assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY); + assert(callerCodecForCall != NULL); + + voiceQuality->calleeSideCodec = strdup(callerCodecForCall); + + EVEL_EXIT(); +} + +/**************************************************************************//** + * Set the correlator for domain Voice Quality + * + * @note The property is treated as immutable: it is only valid to call + * the setter once. However, we don't assert if the caller tries to + * overwrite, just ignoring the update instead. + * + * @param voiceQuality Pointer to the Voice Quality Event. + * @param correlator The correlator value to be set. ASCIIZ + * string. The caller does not need to + * preserve the value once the function + * returns. + *****************************************************************************/ +void evel_voice_quality_correlator_set(EVENT_VOICE_QUALITY * voiceQuality, + const char * const vCorrelator) { + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + assert(voiceQuality != NULL); + assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY); + assert(vCorrelator != NULL); + + voiceQuality->correlator = strdup(vCorrelator); + + EVEL_EXIT(); +} + +/**************************************************************************//** + * Set the RTCP Call Data for domain Voice Quality + * + * @note The property is treated as immutable: it is only valid to call + * the setter once. However, we don't assert if the caller tries to + * overwrite, just ignoring the update instead. + * + * @param voiceQuality Pointer to the Voice Quality Event. + * @param rtcpCallData The RTCP Call Data to be set. ASCIIZ + * string. The caller does not need to + * preserve the value once the function + * returns. + *****************************************************************************/ +void evel_voice_quality_rtcp_data_set(EVENT_VOICE_QUALITY * voiceQuality, + const char * const rtcpCallData) { + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + assert(voiceQuality != NULL); + assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY); + assert(rtcpCallData != NULL); + + voiceQuality->midCallRtcp = strdup(rtcpCallData); + + EVEL_EXIT(); +} + +/**************************************************************************//** + * Set the Vendor VNF Name fields for domain Voice Quality + * + * @note The property is treated as immutable: it is only valid to call + * the setter once. However, we don't assert if the caller tries to + * overwrite, just ignoring the update instead. + * + * @param voiceQuality Pointer to the Voice Quality Event. + * @param modulename The Vendor, VNF and VfModule names to be set. + * ASCIIZ string. The caller does not need to + * preserve the value once the function + * returns. + *****************************************************************************/ +void evel_voice_quality_vnfmodule_name_set(EVENT_VOICE_QUALITY * voiceQuality, + const char * const module_name) { + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + assert(voiceQuality != NULL); + assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY); + assert(module_name != NULL); + + evel_vendor_field_module_set(&voiceQuality->vendorVnfNameFields, module_name); + + EVEL_EXIT(); +} + +/**************************************************************************//** + * Set the Vendor VNF Name fields for domain Voice Quality + * + * @note The property is treated as immutable: it is only valid to call + * the setter once. However, we don't assert if the caller tries to + * overwrite, just ignoring the update instead. + * + * @param voiceQuality Pointer to the Voice Quality Event. + * @param modulename The Vendor, VNF and VfModule names to be set. + * ASCIIZ string. The caller does not need to + * preserve the value once the function + * returns. + *****************************************************************************/ +void evel_voice_quality_vnfname_set(EVENT_VOICE_QUALITY * voiceQuality, + const char * const vnfname) { + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + assert(voiceQuality != NULL); + assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY); + assert(vnfname != NULL); + + evel_vendor_field_vnfname_set(&voiceQuality->vendorVnfNameFields, vnfname); + + EVEL_EXIT(); +} + +/**************************************************************************//** + * Set the Phone Number associated with the Correlator for domain Voice Quality + * + * @note The property is treated as immutable: it is only valid to call + * the setter once. However, we don't assert if the caller tries to + * overwrite, just ignoring the update instead. + * + * @param voiceQuality Pointer to the Voice Quality Event. + * @param calleeCodecForCall The Phone Number to be set. ASCIIZ + * string. The caller does not need to + * preserve the value once the function + * returns. + *****************************************************************************/ +void evel_voice_quality_phone_number_set(EVENT_VOICE_QUALITY * voiceQuality, + const char * const phoneNumber) { + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + assert(voiceQuality != NULL); + assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY); + assert(phoneNumber != NULL); + + evel_set_option_string(&voiceQuality->phoneNumber, phoneNumber, "Phone_Number"); + + EVEL_EXIT(); +} + +/**************************************************************************//** + * Add an End of Call Voice Quality Metrices + + * The adjacencyName and endpointDescription is null delimited ASCII string. + * The library takes a copy so the caller does not have to preserve values + * after the function returns. + * + * @param voiceQuality Pointer to the measurement. + * @param adjacencyName Adjacency name + * @param endpointDescription Enumeration: ‘Caller’, ‘Callee’. + * @param endpointJitter Endpoint jitter + * @param endpointRtpOctetsDiscarded Endpoint RTP octets discarded. + * @param endpointRtpOctetsReceived Endpoint RTP octets received. + * @param endpointRtpOctetsSent Endpoint RTP octets sent + * @param endpointRtpPacketsDiscarded Endpoint RTP packets discarded. + * @param endpointRtpPacketsReceived Endpoint RTP packets received. + * @param endpointRtpPacketsSent Endpoint RTP packets sent. + * @param localJitter Local jitter. + * @param localRtpOctetsDiscarded Local RTP octets discarded. + * @param localRtpOctetsReceived Local RTP octets received. + * @param localRtpOctetsSent Local RTP octets sent. + * @param localRtpPacketsDiscarded Local RTP packets discarded. + * @param localRtpPacketsReceived Local RTP packets received. + * @param localRtpPacketsSent Local RTP packets sent. + * @param mosCqe Decimal range from 1 to 5 + * (1 decimal place) + * @param packetsLost No Packets lost + * @param packetLossPercent Calculated percentage packet loss + * @param rFactor rFactor from 0 to 100 + * @param roundTripDelay Round trip delay in milliseconds + *****************************************************************************/ +void evel_voice_quality_end_metrics_add(EVENT_VOICE_QUALITY * voiceQuality, + const char * adjacencyName, EVEL_SERVICE_ENDPOINT_DESC endpointDescription, + int endpointJitter, + int endpointRtpOctetsDiscarded, + int endpointRtpOctetsReceived, + int endpointRtpOctetsSent, + int endpointRtpPacketsDiscarded, + int endpointRtpPacketsReceived, + int endpointRtpPacketsSent, + int localJitter, + int localRtpOctetsDiscarded, + int localRtpOctetsReceived, + int localRtpOctetsSent, + int localRtpPacketsDiscarded, + int localRtpPacketsReceived, + int localRtpPacketsSent, + int mosCqe, + int packetsLost, + int packetLossPercent, + int rFactor, + int roundTripDelay) { + + END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL; + EVEL_ENTER(); + + /***************************************************************************/ + /* Check assumptions. */ + /***************************************************************************/ + assert(voiceQuality != NULL); + assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY); + assert(adjacencyName != NULL); + assert(endpointDescription >= 0); + assert(mosCqe >= 1 && mosCqe <= 5); + assert(rFactor >= 0 && rFactor <= 100); + + /***************************************************************************/ + /* Allocate a container for the value and push onto the list. */ + /***************************************************************************/ + EVEL_DEBUG("Adding adjacencyName=%s endpointDescription=%d", adjacencyName, endpointDescription); + vQMetrices = malloc(sizeof(END_OF_CALL_VOICE_QUALITY_METRICS)); + assert(vQMetrices != NULL); + memset(vQMetrices, 0, sizeof(END_OF_CALL_VOICE_QUALITY_METRICS)); + + vQMetrices->adjacencyName = strdup(adjacencyName); + vQMetrices->endpointDescription = evel_service_endpoint_desc(endpointDescription); + + evel_set_option_int(&vQMetrices->endpointJitter, endpointJitter, "Endpoint jitter"); + evel_set_option_int(&vQMetrices->endpointRtpOctetsDiscarded, endpointRtpOctetsDiscarded, "Endpoint RTP octets discarded"); + evel_set_option_int(&vQMetrices->endpointRtpOctetsReceived, endpointRtpOctetsReceived, "Endpoint RTP octets received"); + evel_set_option_int(&vQMetrices->endpointRtpOctetsSent, endpointRtpOctetsSent, "Endpoint RTP octets sent"); + evel_set_option_int(&vQMetrices->endpointRtpPacketsDiscarded, endpointRtpPacketsDiscarded, "Endpoint RTP packets discarded"); + evel_set_option_int(&vQMetrices->endpointRtpPacketsReceived, endpointRtpPacketsReceived, "Endpoint RTP packets received"); + evel_set_option_int(&vQMetrices->endpointRtpPacketsSent, endpointRtpPacketsSent, "Endpoint RTP packets sent"); + evel_set_option_int(&vQMetrices->localJitter, localJitter, "Local jitter"); + evel_set_option_int(&vQMetrices->localRtpOctetsDiscarded, localRtpOctetsDiscarded, "Local RTP octets discarded"); + evel_set_option_int(&vQMetrices->localRtpOctetsReceived, localRtpOctetsReceived, "Local RTP octets received"); + evel_set_option_int(&vQMetrices->localRtpOctetsSent, localRtpOctetsSent, "Local RTP octets sent"); + evel_set_option_int(&vQMetrices->localRtpPacketsDiscarded, localRtpPacketsDiscarded, "Local RTP packets discarded"); + evel_set_option_int(&vQMetrices->localRtpPacketsReceived, localRtpPacketsReceived, "Local RTP packets received"); + evel_set_option_int(&vQMetrices->localRtpPacketsSent, localRtpPacketsSent, "Local RTP packets sent"); + evel_set_option_int(&vQMetrices->mosCqe, mosCqe, "Decimal range from 1 to 5 (1 decimal place)"); + evel_set_option_int(&vQMetrices->packetsLost, packetsLost, "Packets lost"); + evel_set_option_int(&vQMetrices->packetLossPercent, packetLossPercent, "Calculated percentage packet loss"); + evel_set_option_int(&vQMetrices->rFactor, rFactor, "rFactor "); + evel_set_option_int(&vQMetrices->roundTripDelay, roundTripDelay, "Round trip delay in milliseconds "); + + dlist_push_last(&voiceQuality->endOfCallVqmSummaries, vQMetrices); + + EVEL_EXIT(); +} + +/**************************************************************************//** + * Encode the Voce Quality in JSON according to AT&T's schema for the voice + * quality type. + * + * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into. + * @param event Pointer to the ::EVENT_HEADER to encode. + *****************************************************************************/ +void evel_json_encode_voice_quality(EVEL_JSON_BUFFER * jbuf, + EVENT_VOICE_QUALITY * event) +{ + VOICE_QUALITY_ADDL_INFO * addlInfo = NULL; + DLIST_ITEM * addlInfoItem = NULL; + + END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrics = NULL; + DLIST_ITEM * vQMetricsItem = NULL; + + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + assert(event != NULL); + assert(event->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY); + + evel_json_encode_header(jbuf, &event->header); + evel_json_open_named_object(jbuf, "voiceQualityFields"); + + /***************************************************************************/ + /* Mandatory fields. */ + /***************************************************************************/ + evel_enc_kv_string(jbuf, "calleeSideCodec", event->calleeSideCodec); + evel_enc_kv_string(jbuf, "callerSideCodec", event->callerSideCodec); + evel_enc_kv_string(jbuf, "correlator", event->correlator); + evel_enc_kv_string(jbuf, "midCallRtcp", event->midCallRtcp); + evel_json_encode_vendor_field(jbuf, &event->vendorVnfNameFields); + evel_enc_version( + jbuf, "voiceQualityFieldsVersion", event->major_version, event->minor_version); + + /***************************************************************************/ + /* Optional fields. */ + /***************************************************************************/ + evel_enc_kv_opt_string(jbuf, "phoneNumber", &event->phoneNumber); + /***************************************************************************/ + /* Checkpoint, so that we can wind back if all fields are suppressed. */ + /***************************************************************************/ + //additionalInformation for Voice Quality + bool item_added = false; + + evel_json_checkpoint(jbuf); + if (evel_json_open_opt_named_list(jbuf, "additionalInformation")) + { + + addlInfoItem = dlist_get_first(&event->additionalInformation); + while (addlInfoItem != NULL) + { + addlInfo = (VOICE_QUALITY_ADDL_INFO*)addlInfoItem->item; + assert(addlInfo != NULL); + + if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec, + "additionalInformation", + addlInfo->name)) + { + evel_json_open_object(jbuf); + evel_enc_kv_string(jbuf, "name", addlInfo->name); + evel_enc_kv_string(jbuf, "value", addlInfo->value); + evel_json_close_object(jbuf); + item_added = true; + } + addlInfoItem = dlist_get_next(addlInfoItem); + } + evel_json_close_list(jbuf); + } + + //endOfCallVqmSummaries + evel_json_checkpoint(jbuf); + if (evel_json_open_opt_named_list(jbuf, "endOfCallVqmSummaries")) + { + vQMetricsItem = dlist_get_first(&event->endOfCallVqmSummaries); + while (vQMetricsItem != NULL) + { + vQMetrics = (END_OF_CALL_VOICE_QUALITY_METRICS *)vQMetricsItem->item; + assert(vQMetrics != NULL); + + if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec, + "endOfCallVqmSummaries", + vQMetrics->adjacencyName)) + { + evel_json_open_object(jbuf); + evel_enc_kv_string(jbuf, "adjacencyName", vQMetrics->adjacencyName); + evel_enc_kv_string(jbuf, "endpointDescription", vQMetrics->endpointDescription); + evel_enc_kv_opt_int(jbuf, "endpointJitter", &vQMetrics->endpointJitter); + evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsDiscarded", &vQMetrics->endpointRtpOctetsDiscarded); + evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsReceived", &vQMetrics->endpointRtpOctetsReceived); + evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsSent", &vQMetrics->endpointRtpOctetsSent); + evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsDiscarded", &vQMetrics->endpointRtpPacketsDiscarded); + evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsReceived", &vQMetrics->endpointRtpPacketsReceived); + evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsSent", &vQMetrics->endpointRtpPacketsSent); + evel_enc_kv_opt_int(jbuf, "localJitter", &vQMetrics->localJitter); + evel_enc_kv_opt_int(jbuf, "localRtpOctetsDiscarded", &vQMetrics->localRtpOctetsDiscarded); + evel_enc_kv_opt_int(jbuf, "localRtpOctetsReceived", &vQMetrics->localRtpOctetsReceived); + evel_enc_kv_opt_int(jbuf, "localRtpOctetsSent", &vQMetrics->localRtpOctetsSent); + evel_enc_kv_opt_int(jbuf, "localRtpPacketsDiscarded", &vQMetrics->localRtpPacketsDiscarded); + evel_enc_kv_opt_int(jbuf, "localRtpPacketsReceived", &vQMetrics->localRtpPacketsReceived); + evel_enc_kv_opt_int(jbuf, "localRtpPacketsSent", &vQMetrics->localRtpPacketsSent); + evel_enc_kv_opt_int(jbuf, "mosCqe", &vQMetrics->mosCqe); + evel_enc_kv_opt_int(jbuf, "packetsLost", &vQMetrics->packetsLost); + evel_enc_kv_opt_int(jbuf, "packetLossPercent", &vQMetrics->packetLossPercent); + evel_enc_kv_opt_int(jbuf, "rFactor", &vQMetrics->rFactor); + evel_enc_kv_opt_int(jbuf, "roundTripDelay", &vQMetrics->roundTripDelay); + + evel_json_close_object(jbuf); + item_added = true; + } + vQMetricsItem = dlist_get_next(vQMetricsItem); + } + evel_json_close_list(jbuf); + } + + /*************************************************************************/ + /* If we've not written anything, rewind to before we opened the list. */ + /*************************************************************************/ + if (!item_added) + { + evel_json_rewind(jbuf); + } + + evel_json_close_object(jbuf); + + EVEL_EXIT(); +} + +/**************************************************************************//** + * Free a Voice Quality. + * + * Free off the Voce Quality supplied. Will free all the contained allocated + * memory. + * + * @note It does not free the Voice Quality itself, since that may be part of a + * larger structure. + *****************************************************************************/ +void evel_free_voice_quality(EVENT_VOICE_QUALITY * voiceQuality) { + END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL; + VOICE_QUALITY_ADDL_INFO * addlInfo = NULL; + + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. As an internal API we don't allow freeing NULL */ + /* events as we do on the public API. */ + /***************************************************************************/ + assert(voiceQuality != NULL); + assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY); + + /***************************************************************************/ + /* Free all internal strings then the header itself. */ + /***************************************************************************/ + + //Additional Information + addlInfo = dlist_pop_last(&voiceQuality->additionalInformation); + while (addlInfo != NULL) + { + EVEL_DEBUG("Freeing Additional Info (%s, %s)", + addlInfo->name, + addlInfo->value); + free(addlInfo->name); + free(addlInfo->value); + free(addlInfo); + addlInfo = dlist_pop_last(&voiceQuality->additionalInformation); + } + + //Summary Information + vQMetrices = dlist_pop_last(&voiceQuality->endOfCallVqmSummaries); + while (vQMetrices != NULL) + { + EVEL_DEBUG("Freeing End of Call Voice Measurements Info (%s, %s)", + vQMetrices->adjacencyName, + vQMetrices->endpointDescription); + free(vQMetrices->adjacencyName); + free(vQMetrices); + vQMetrices = dlist_pop_last(&voiceQuality->endOfCallVqmSummaries); + } + + //Members + free(voiceQuality->calleeSideCodec); + free(voiceQuality->callerSideCodec); + free(voiceQuality->correlator); + free(voiceQuality->midCallRtcp); + evel_free_option_string(&voiceQuality->phoneNumber); + evel_free_event_vendor_field(&voiceQuality->vendorVnfNameFields); + + //header + evel_free_header(&voiceQuality->header); + + EVEL_EXIT(); +} + |