1 /*************************************************************************//**
3 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 ****************************************************************************/
17 /**************************************************************************//**
19 * Implementation of EVEL functions relating to the Voice Quality.
20 *****************************************************************************/
27 #include "evel_internal.h"
28 #include "evel_throttle.h"
30 /**************************************************************************//**
31 * Create a new voice quality event.
33 * @note The mandatory fields on the Voice Quality must be supplied to this
34 * factory function and are immutable once set. Optional fields have
35 * explicit setter functions, but again values may only be set once
36 * so that the Voice Quality has immutable properties.
37 * @param calleeSideCodec Callee codec for the call.
38 * @param callerSideCodec Caller codec for the call.
39 * @param correlator Constant across all events on this call.
40 * @param midCallRtcp Base64 encoding of the binary RTCP data
41 * (excluding Eth/IP/UDP headers).
42 * @param vendorVnfNameFields Vendor, VNF and VfModule names.
43 * @returns pointer to the newly manufactured ::EVENT_VOICE_QUALITY. If the
44 * event is not used (i.e. posted) it must be released using
45 ::evel_free_voice_quality.
46 * @retval NULL Failed to create the event.
47 *****************************************************************************/
48 EVENT_VOICE_QUALITY * evel_new_voice_quality(const char * const calleeSideCodec,
49 const char * const callerSideCodec, const char * const correlator,
50 const char * const midCallRtcp, const char * const vendorName) {
53 EVENT_VOICE_QUALITY *voiceQuality = NULL;
56 /***************************************************************************/
57 /* Check preconditions. */
58 /***************************************************************************/
59 assert(calleeSideCodec != NULL);
60 assert(callerSideCodec != NULL);
61 assert(correlator != NULL);
62 assert(midCallRtcp != NULL);
63 assert(vendorName != NULL);
65 /***************************************************************************/
66 /* Allocate the Voice Quality. */
67 /***************************************************************************/
68 voiceQuality = malloc(sizeof(EVENT_VOICE_QUALITY));
70 if (voiceQuality == NULL)
72 log_error_state("Out of memory");
76 //Only in case of successful allocation initialize data.
77 if (inError == false) {
78 memset(voiceQuality, 0, sizeof(EVENT_VOICE_QUALITY));
79 EVEL_DEBUG("New Voice Quality is at %lp", voiceQuality);
81 /***************************************************************************/
82 /* Initialize the header & the fault fields. Optional integer values are */
83 /* initialized as 0. */
84 /***************************************************************************/
85 evel_init_header(&voiceQuality->header,"voiceQuality");
86 voiceQuality->header.event_domain = EVEL_DOMAIN_VOICE_QUALITY;
87 voiceQuality->major_version = EVEL_VOICEQ_MAJOR_VERSION;
88 voiceQuality->minor_version = EVEL_VOICEQ_MINOR_VERSION;
90 voiceQuality->calleeSideCodec = strdup(calleeSideCodec);
91 voiceQuality->callerSideCodec = strdup(callerSideCodec);
92 voiceQuality->correlator = strdup(correlator);
93 voiceQuality->midCallRtcp = strdup(midCallRtcp);
94 evel_init_vendor_field(&voiceQuality->vendorVnfNameFields, vendorName);
95 dlist_initialize(&voiceQuality->additionalInformation);
96 voiceQuality->endOfCallVqmSummaries = NULL;
97 evel_init_option_string(&voiceQuality->phoneNumber);
105 /**************************************************************************//**
106 * Add an additional value name/value pair to the Voice Quality.
108 * The name and value are null delimited ASCII strings. The library takes
109 * a copy so the caller does not have to preserve values after the function
112 * @param fault Pointer to the fault.
113 * @param name ASCIIZ string with the attribute's name. The caller
114 * does not need to preserve the value once the function
116 * @param value ASCIIZ string with the attribute's value. The caller
117 * does not need to preserve the value once the function
119 *****************************************************************************/
120 void evel_voice_quality_addl_info_add(EVENT_VOICE_QUALITY * voiceQ, char * name, char * value) {
121 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
124 /***************************************************************************/
125 /* Check preconditions. */
126 /***************************************************************************/
127 assert(voiceQ != NULL);
128 assert(voiceQ->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
129 assert(name != NULL);
130 assert(value != NULL);
132 EVEL_DEBUG("Adding name=%s value=%s", name, value);
133 addlInfo = malloc(sizeof(VOICE_QUALITY_ADDL_INFO));
134 assert(addlInfo != NULL);
135 memset(addlInfo, 0, sizeof(VOICE_QUALITY_ADDL_INFO));
136 addlInfo->name = strdup(name);
137 addlInfo->value = strdup(value);
138 assert(addlInfo->name != NULL);
139 assert(addlInfo->value != NULL);
141 dlist_push_last(&voiceQ->additionalInformation, addlInfo);
146 /**************************************************************************//**
147 * Set the Callee side codec for Call for domain Voice Quality
149 * @note The property is treated as immutable: it is only valid to call
150 * the setter once. However, we don't assert if the caller tries to
151 * overwrite, just ignoring the update instead.
153 * @param voiceQuality Pointer to the Voice Quality Event.
154 * @param calleeCodecForCall The Callee Side Codec to be set. ASCIIZ
155 * string. The caller does not need to
156 * preserve the value once the function
158 *****************************************************************************/
159 void evel_voice_quality_callee_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
160 const char * const calleeCodecForCall) {
163 /***************************************************************************/
164 /* Check preconditions. */
165 /***************************************************************************/
166 assert(voiceQuality != NULL);
167 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
168 assert(calleeCodecForCall != NULL);
170 voiceQuality->calleeSideCodec = strdup(calleeCodecForCall);
175 /**************************************************************************//**
176 * Set the Caller side codec for Call for domain Voice Quality
178 * @note The property is treated as immutable: it is only valid to call
179 * the setter once. However, we don't assert if the caller tries to
180 * overwrite, just ignoring the update instead.
182 * @param voiceQuality Pointer to the Voice Quality Event.
183 * @param callerCodecForCall The Caller Side Codec to be set. ASCIIZ
184 * string. The caller does not need to
185 * preserve the value once the function
187 *****************************************************************************/
188 void evel_voice_quality_caller_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
189 const char * const callerCodecForCall) {
192 /***************************************************************************/
193 /* Check preconditions. */
194 /***************************************************************************/
195 assert(voiceQuality != NULL);
196 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
197 assert(callerCodecForCall != NULL);
199 voiceQuality->calleeSideCodec = strdup(callerCodecForCall);
204 /**************************************************************************//**
205 * Set the correlator for domain Voice Quality
207 * @note The property is treated as immutable: it is only valid to call
208 * the setter once. However, we don't assert if the caller tries to
209 * overwrite, just ignoring the update instead.
211 * @param voiceQuality Pointer to the Voice Quality Event.
212 * @param correlator The correlator value to be set. ASCIIZ
213 * string. The caller does not need to
214 * preserve the value once the function
216 *****************************************************************************/
217 void evel_voice_quality_correlator_set(EVENT_VOICE_QUALITY * voiceQuality,
218 const char * const vCorrelator) {
221 /***************************************************************************/
222 /* Check preconditions. */
223 /***************************************************************************/
224 assert(voiceQuality != NULL);
225 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
226 assert(vCorrelator != NULL);
228 voiceQuality->correlator = strdup(vCorrelator);
233 /**************************************************************************//**
234 * Set the RTCP Call Data for domain Voice Quality
236 * @note The property is treated as immutable: it is only valid to call
237 * the setter once. However, we don't assert if the caller tries to
238 * overwrite, just ignoring the update instead.
240 * @param voiceQuality Pointer to the Voice Quality Event.
241 * @param rtcpCallData The RTCP Call Data to be set. ASCIIZ
242 * string. The caller does not need to
243 * preserve the value once the function
245 *****************************************************************************/
246 void evel_voice_quality_rtcp_data_set(EVENT_VOICE_QUALITY * voiceQuality,
247 const char * const rtcpCallData) {
250 /***************************************************************************/
251 /* Check preconditions. */
252 /***************************************************************************/
253 assert(voiceQuality != NULL);
254 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
255 assert(rtcpCallData != NULL);
257 voiceQuality->midCallRtcp = strdup(rtcpCallData);
262 /**************************************************************************//**
263 * Set the Vendor VNF Name fields for domain Voice Quality
265 * @note The property is treated as immutable: it is only valid to call
266 * the setter once. However, we don't assert if the caller tries to
267 * overwrite, just ignoring the update instead.
269 * @param voiceQuality Pointer to the Voice Quality Event.
270 * @param modulename The Vendor, VNF and VfModule names to be set.
271 * ASCIIZ string. The caller does not need to
272 * preserve the value once the function
274 *****************************************************************************/
275 void evel_voice_quality_vnfmodule_name_set(EVENT_VOICE_QUALITY * voiceQuality,
276 const char * const module_name) {
279 /***************************************************************************/
280 /* Check preconditions. */
281 /***************************************************************************/
282 assert(voiceQuality != NULL);
283 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
284 assert(module_name != NULL);
286 evel_vendor_field_module_set(&voiceQuality->vendorVnfNameFields, module_name);
291 /**************************************************************************//**
292 * Set the Vendor VNF Name fields for domain Voice Quality
294 * @note The property is treated as immutable: it is only valid to call
295 * the setter once. However, we don't assert if the caller tries to
296 * overwrite, just ignoring the update instead.
298 * @param voiceQuality Pointer to the Voice Quality Event.
299 * @param modulename The Vendor, VNF and VfModule names to be set.
300 * ASCIIZ string. The caller does not need to
301 * preserve the value once the function
303 *****************************************************************************/
304 void evel_voice_quality_vnfname_set(EVENT_VOICE_QUALITY * voiceQuality,
305 const char * const vnfname) {
308 /***************************************************************************/
309 /* Check preconditions. */
310 /***************************************************************************/
311 assert(voiceQuality != NULL);
312 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
313 assert(vnfname != NULL);
315 evel_vendor_field_vnfname_set(&voiceQuality->vendorVnfNameFields, vnfname);
320 /**************************************************************************//**
321 * Set the Phone Number associated with the Correlator for domain Voice Quality
323 * @note The property is treated as immutable: it is only valid to call
324 * the setter once. However, we don't assert if the caller tries to
325 * overwrite, just ignoring the update instead.
327 * @param voiceQuality Pointer to the Voice Quality Event.
328 * @param calleeCodecForCall The Phone Number to be set. ASCIIZ
329 * string. The caller does not need to
330 * preserve the value once the function
332 *****************************************************************************/
333 void evel_voice_quality_phone_number_set(EVENT_VOICE_QUALITY * voiceQuality,
334 const char * const phoneNumber) {
337 /***************************************************************************/
338 /* Check preconditions. */
339 /***************************************************************************/
340 assert(voiceQuality != NULL);
341 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
342 assert(phoneNumber != NULL);
344 evel_set_option_string(&voiceQuality->phoneNumber, phoneNumber, "Phone_Number");
349 /**************************************************************************//**
350 * Add an End of Call Voice Quality Metrices
352 * The adjacencyName and endpointDescription is null delimited ASCII string.
353 * The library takes a copy so the caller does not have to preserve values
354 * after the function returns.
356 * @param voiceQuality Pointer to the measurement.
357 * @param adjacencyName Adjacency name
358 * @param endpointDescription Enumeration: ‘Caller’, ‘Callee’.
359 * @param endpointJitter Endpoint jitter
360 * @param endpointRtpOctetsDiscarded Endpoint RTP octets discarded.
361 * @param endpointRtpOctetsReceived Endpoint RTP octets received.
362 * @param endpointRtpOctetsSent Endpoint RTP octets sent
363 * @param endpointRtpPacketsDiscarded Endpoint RTP packets discarded.
364 * @param endpointRtpPacketsReceived Endpoint RTP packets received.
365 * @param endpointRtpPacketsSent Endpoint RTP packets sent.
366 * @param localJitter Local jitter.
367 * @param localRtpOctetsDiscarded Local RTP octets discarded.
368 * @param localRtpOctetsReceived Local RTP octets received.
369 * @param localRtpOctetsSent Local RTP octets sent.
370 * @param localRtpPacketsDiscarded Local RTP packets discarded.
371 * @param localRtpPacketsReceived Local RTP packets received.
372 * @param localRtpPacketsSent Local RTP packets sent.
373 * @param mosCqe Decimal range from 1 to 5
375 * @param packetsLost No Packets lost
376 * @param packetLossPercent Calculated percentage packet loss
377 * @param rFactor rFactor from 0 to 100
378 * @param roundTripDelay Round trip delay in milliseconds
379 *****************************************************************************/
380 void evel_voice_quality_end_metrics_add(EVENT_VOICE_QUALITY * voiceQuality,
381 const char * adjacencyName, EVEL_SERVICE_ENDPOINT_DESC endpointDescription,
383 int endpointRtpOctetsDiscarded,
384 int endpointRtpOctetsReceived,
385 int endpointRtpOctetsSent,
386 int endpointRtpPacketsDiscarded,
387 int endpointRtpPacketsReceived,
388 int endpointRtpPacketsSent,
390 int localRtpOctetsDiscarded,
391 int localRtpOctetsReceived,
392 int localRtpOctetsSent,
393 int localRtpPacketsDiscarded,
394 int localRtpPacketsReceived,
395 int localRtpPacketsSent,
398 int packetLossPercent,
400 int roundTripDelay) {
402 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL;
405 /***************************************************************************/
406 /* Check assumptions. */
407 /***************************************************************************/
408 assert(voiceQuality != NULL);
409 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
410 assert(adjacencyName != NULL);
411 assert(endpointDescription >= 0);
412 assert(mosCqe >= 1 && mosCqe <= 5);
413 assert(rFactor >= 0 && rFactor <= 100);
414 assert(voiceQuality->endOfCallVqmSummaries == NULL);
416 /***************************************************************************/
417 /* Allocate a container for the value and push onto the list. */
418 /***************************************************************************/
419 EVEL_DEBUG("Adding adjacencyName=%s endpointDescription=%d", adjacencyName, endpointDescription);
420 vQMetrices = malloc(sizeof(END_OF_CALL_VOICE_QUALITY_METRICS));
421 assert(vQMetrices != NULL);
422 memset(vQMetrices, 0, sizeof(END_OF_CALL_VOICE_QUALITY_METRICS));
424 vQMetrices->adjacencyName = strdup(adjacencyName);
425 vQMetrices->endpointDescription = evel_service_endpoint_desc(endpointDescription);
427 evel_set_option_int(&vQMetrices->endpointJitter, endpointJitter, "Endpoint jitter");
428 evel_set_option_int(&vQMetrices->endpointRtpOctetsDiscarded, endpointRtpOctetsDiscarded, "Endpoint RTP octets discarded");
429 evel_set_option_int(&vQMetrices->endpointRtpOctetsReceived, endpointRtpOctetsReceived, "Endpoint RTP octets received");
430 evel_set_option_int(&vQMetrices->endpointRtpOctetsSent, endpointRtpOctetsSent, "Endpoint RTP octets sent");
431 evel_set_option_int(&vQMetrices->endpointRtpPacketsDiscarded, endpointRtpPacketsDiscarded, "Endpoint RTP packets discarded");
432 evel_set_option_int(&vQMetrices->endpointRtpPacketsReceived, endpointRtpPacketsReceived, "Endpoint RTP packets received");
433 evel_set_option_int(&vQMetrices->endpointRtpPacketsSent, endpointRtpPacketsSent, "Endpoint RTP packets sent");
434 evel_set_option_int(&vQMetrices->localJitter, localJitter, "Local jitter");
435 evel_set_option_int(&vQMetrices->localRtpOctetsDiscarded, localRtpOctetsDiscarded, "Local RTP octets discarded");
436 evel_set_option_int(&vQMetrices->localRtpOctetsReceived, localRtpOctetsReceived, "Local RTP octets received");
437 evel_set_option_int(&vQMetrices->localRtpOctetsSent, localRtpOctetsSent, "Local RTP octets sent");
438 evel_set_option_int(&vQMetrices->localRtpPacketsDiscarded, localRtpPacketsDiscarded, "Local RTP packets discarded");
439 evel_set_option_int(&vQMetrices->localRtpPacketsReceived, localRtpPacketsReceived, "Local RTP packets received");
440 evel_set_option_int(&vQMetrices->localRtpPacketsSent, localRtpPacketsSent, "Local RTP packets sent");
441 evel_set_option_int(&vQMetrices->mosCqe, mosCqe, "Decimal range from 1 to 5 (1 decimal place)");
442 evel_set_option_int(&vQMetrices->packetsLost, packetsLost, "Packets lost");
443 evel_set_option_int(&vQMetrices->packetLossPercent, packetLossPercent, "Calculated percentage packet loss");
444 evel_set_option_int(&vQMetrices->rFactor, rFactor, "rFactor ");
445 evel_set_option_int(&vQMetrices->roundTripDelay, roundTripDelay, "Round trip delay in milliseconds ");
447 voiceQuality->endOfCallVqmSummaries = vQMetrices;
452 /**************************************************************************//**
453 * Encode the Voce Quality in JSON according to AT&T's schema for the voice
456 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
457 * @param event Pointer to the ::EVENT_HEADER to encode.
458 *****************************************************************************/
459 void evel_json_encode_voice_quality(EVEL_JSON_BUFFER * jbuf,
460 EVENT_VOICE_QUALITY * event)
462 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
463 DLIST_ITEM * addlInfoItem = NULL;
465 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrics = NULL;
466 DLIST_ITEM * vQMetricsItem = NULL;
470 /***************************************************************************/
471 /* Check preconditions. */
472 /***************************************************************************/
473 assert(event != NULL);
474 assert(event->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
476 evel_json_encode_header(jbuf, &event->header);
477 evel_json_open_named_object(jbuf, "voiceQualityFields");
479 /***************************************************************************/
480 /* Mandatory fields. */
481 /***************************************************************************/
482 evel_enc_kv_string(jbuf, "calleeSideCodec", event->calleeSideCodec);
483 evel_enc_kv_string(jbuf, "callerSideCodec", event->callerSideCodec);
484 evel_enc_kv_string(jbuf, "correlator", event->correlator);
485 evel_enc_kv_string(jbuf, "midCallRtcp", event->midCallRtcp);
486 evel_json_encode_vendor_field(jbuf, &event->vendorVnfNameFields);
488 jbuf, "voiceQualityFieldsVersion", event->major_version, event->minor_version);
490 /***************************************************************************/
491 /* Optional fields. */
492 /***************************************************************************/
493 evel_enc_kv_opt_string(jbuf, "phoneNumber", &event->phoneNumber);
494 /***************************************************************************/
495 /* Checkpoint, so that we can wind back if all fields are suppressed. */
496 /***************************************************************************/
497 //additionalInformation for Voice Quality
498 bool item_added = false;
500 evel_json_checkpoint(jbuf);
501 if (evel_json_open_opt_named_list(jbuf, "additionalInformation"))
504 addlInfoItem = dlist_get_first(&event->additionalInformation);
505 while (addlInfoItem != NULL)
507 addlInfo = (VOICE_QUALITY_ADDL_INFO*)addlInfoItem->item;
508 assert(addlInfo != NULL);
510 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
511 "additionalInformation",
514 evel_json_open_object(jbuf);
515 evel_enc_kv_string(jbuf, "name", addlInfo->name);
516 evel_enc_kv_string(jbuf, "value", addlInfo->value);
517 evel_json_close_object(jbuf);
520 addlInfoItem = dlist_get_next(addlInfoItem);
522 evel_json_close_list(jbuf);
523 /*************************************************************************/
524 /* If we've not written anything, rewind to before we opened the list. */
525 /*************************************************************************/
528 evel_json_rewind(jbuf);
532 //endOfCallVqmSummaries
533 if( event->endOfCallVqmSummaries != NULL )
535 evel_json_open_named_object(jbuf, "endOfCallVqmSummaries");
536 vQMetrics = event->endOfCallVqmSummaries;
537 assert(vQMetrics != NULL);
539 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
540 "endOfCallVqmSummaries", vQMetrics->adjacencyName))
542 evel_enc_kv_string(jbuf, "adjacencyName", vQMetrics->adjacencyName);
543 evel_enc_kv_string(jbuf, "endpointDescription", vQMetrics->endpointDescription);
544 evel_enc_kv_opt_int(jbuf, "endpointJitter", &vQMetrics->endpointJitter);
545 evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsDiscarded", &vQMetrics->endpointRtpOctetsDiscarded);
546 evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsReceived", &vQMetrics->endpointRtpOctetsReceived);
547 evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsSent", &vQMetrics->endpointRtpOctetsSent);
548 evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsDiscarded", &vQMetrics->endpointRtpPacketsDiscarded);
549 evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsReceived", &vQMetrics->endpointRtpPacketsReceived);
550 evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsSent", &vQMetrics->endpointRtpPacketsSent);
551 evel_enc_kv_opt_int(jbuf, "localJitter", &vQMetrics->localJitter);
552 evel_enc_kv_opt_int(jbuf, "localRtpOctetsDiscarded", &vQMetrics->localRtpOctetsDiscarded);
553 evel_enc_kv_opt_int(jbuf, "localRtpOctetsReceived", &vQMetrics->localRtpOctetsReceived);
554 evel_enc_kv_opt_int(jbuf, "localRtpOctetsSent", &vQMetrics->localRtpOctetsSent);
555 evel_enc_kv_opt_int(jbuf, "localRtpPacketsDiscarded", &vQMetrics->localRtpPacketsDiscarded);
556 evel_enc_kv_opt_int(jbuf, "localRtpPacketsReceived", &vQMetrics->localRtpPacketsReceived);
557 evel_enc_kv_opt_int(jbuf, "localRtpPacketsSent", &vQMetrics->localRtpPacketsSent);
558 evel_enc_kv_opt_int(jbuf, "mosCqe", &vQMetrics->mosCqe);
559 evel_enc_kv_opt_int(jbuf, "packetsLost", &vQMetrics->packetsLost);
560 evel_enc_kv_opt_int(jbuf, "packetLossPercent", &vQMetrics->packetLossPercent);
561 evel_enc_kv_opt_int(jbuf, "rFactor", &vQMetrics->rFactor);
562 evel_enc_kv_opt_int(jbuf, "roundTripDelay", &vQMetrics->roundTripDelay);
566 evel_json_close_object(jbuf);
569 evel_json_close_object(jbuf);
574 /**************************************************************************//**
575 * Free a Voice Quality.
577 * Free off the Voce Quality supplied. Will free all the contained allocated
580 * @note It does not free the Voice Quality itself, since that may be part of a
582 *****************************************************************************/
583 void evel_free_voice_quality(EVENT_VOICE_QUALITY * voiceQuality) {
584 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL;
585 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
589 /***************************************************************************/
590 /* Check preconditions. As an internal API we don't allow freeing NULL */
591 /* events as we do on the public API. */
592 /***************************************************************************/
593 assert(voiceQuality != NULL);
594 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
596 /***************************************************************************/
597 /* Free all internal strings then the header itself. */
598 /***************************************************************************/
600 //Additional Information
601 addlInfo = dlist_pop_last(&voiceQuality->additionalInformation);
602 while (addlInfo != NULL)
604 EVEL_DEBUG("Freeing Additional Info (%s, %s)",
607 free(addlInfo->name);
608 free(addlInfo->value);
610 addlInfo = dlist_pop_last(&voiceQuality->additionalInformation);
613 //Summary Information
614 if(voiceQuality->endOfCallVqmSummaries != NULL)
616 vQMetrices = voiceQuality->endOfCallVqmSummaries;
617 EVEL_DEBUG("Freeing End of Call Voice Measurements Info (%s, %s)",
618 vQMetrices->adjacencyName,
619 vQMetrices->endpointDescription);
620 free(vQMetrices->adjacencyName);
625 free(voiceQuality->calleeSideCodec);
626 free(voiceQuality->callerSideCodec);
627 free(voiceQuality->correlator);
628 free(voiceQuality->midCallRtcp);
629 evel_free_option_string(&voiceQuality->phoneNumber);
630 evel_free_event_vendor_field(&voiceQuality->vendorVnfNameFields);
633 evel_free_header(&voiceQuality->header);