1 /*************************************************************************//**
3 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
5 * Unless otherwise specified, all software contained herein is
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
17 ****************************************************************************/
18 /**************************************************************************//**
20 * Implementation of EVEL functions relating to the Voice Quality.
21 *****************************************************************************/
28 #include "evel_internal.h"
29 #include "evel_throttle.h"
31 /**************************************************************************//**
32 * Create a new voice quality event.
34 * @note The mandatory fields on the Voice Quality must be supplied to this
35 * factory function and are immutable once set. Optional fields have
36 * explicit setter functions, but again values may only be set once
37 * so that the Voice Quality has immutable properties.
38 * @param event_name Unique Event Name
39 * @param event_id A universal identifier of the event for analysis etc.
40 * @param calleeSideCodec Callee codec for the call.
41 * @param callerSideCodec Caller codec for the call.
42 * @param correlator Constant across all events on this call.
43 * @param midCallRtcp Base64 encoding of the binary RTCP data
44 * (excluding Eth/IP/UDP headers).
45 * @param vendorVnfNameFields Vendor, VNF and VfModule names.
46 * @returns pointer to the newly manufactured ::EVENT_VOICE_QUALITY. If the
47 * event is not used (i.e. posted) it must be released using
48 ::evel_free_voice_quality.
49 * @retval NULL Failed to create the event.
50 *****************************************************************************/
51 EVENT_VOICE_QUALITY * evel_new_voice_quality(const char* ev_name, const char *ev_id,
52 const char * const calleeSideCodec,
53 const char * const callerSideCodec, const char * const correlator,
54 const char * const midCallRtcp, const char * const vendorName) {
57 EVENT_VOICE_QUALITY *voiceQuality = NULL;
60 /***************************************************************************/
61 /* Check preconditions. */
62 /***************************************************************************/
63 assert(calleeSideCodec != NULL);
64 assert(callerSideCodec != NULL);
65 assert(correlator != NULL);
66 assert(midCallRtcp != NULL);
67 assert(vendorName != NULL);
69 /***************************************************************************/
70 /* Allocate the Voice Quality. */
71 /***************************************************************************/
72 voiceQuality = malloc(sizeof(EVENT_VOICE_QUALITY));
74 if (voiceQuality == NULL)
76 log_error_state("Out of memory");
80 //Only in case of successful allocation initialize data.
81 if (inError == false) {
82 memset(voiceQuality, 0, sizeof(EVENT_VOICE_QUALITY));
83 EVEL_DEBUG("New Voice Quality is at %lp", voiceQuality);
85 /***************************************************************************/
86 /* Initialize the header & the fault fields. Optional integer values are */
87 /* initialized as 0. */
88 /***************************************************************************/
89 evel_init_header_nameid(&voiceQuality->header,ev_name,ev_id);
90 voiceQuality->header.event_domain = EVEL_DOMAIN_VOICE_QUALITY;
91 voiceQuality->major_version = EVEL_VOICEQ_MAJOR_VERSION;
92 voiceQuality->minor_version = EVEL_VOICEQ_MINOR_VERSION;
94 voiceQuality->calleeSideCodec = strdup(calleeSideCodec);
95 voiceQuality->callerSideCodec = strdup(callerSideCodec);
96 voiceQuality->correlator = strdup(correlator);
97 voiceQuality->midCallRtcp = strdup(midCallRtcp);
98 evel_init_vendor_field(&voiceQuality->vendorVnfNameFields, vendorName);
99 dlist_initialize(&voiceQuality->additionalInformation);
100 voiceQuality->endOfCallVqmSummaries = NULL;
101 evel_init_option_string(&voiceQuality->phoneNumber);
109 /**************************************************************************//**
110 * Add an additional value name/value pair to the Voice Quality.
112 * The name and value are null delimited ASCII strings. The library takes
113 * a copy so the caller does not have to preserve values after the function
116 * @param fault Pointer to the fault.
117 * @param name ASCIIZ string with the attribute's name. The caller
118 * does not need to preserve the value once the function
120 * @param value ASCIIZ string with the attribute's value. The caller
121 * does not need to preserve the value once the function
123 *****************************************************************************/
124 void evel_voice_quality_addl_info_add(EVENT_VOICE_QUALITY * voiceQ, char * name, char * value) {
125 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
128 /***************************************************************************/
129 /* Check preconditions. */
130 /***************************************************************************/
131 assert(voiceQ != NULL);
132 assert(voiceQ->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
133 assert(name != NULL);
134 assert(value != NULL);
136 EVEL_DEBUG("Adding name=%s value=%s", name, value);
137 addlInfo = malloc(sizeof(VOICE_QUALITY_ADDL_INFO));
138 assert(addlInfo != NULL);
139 memset(addlInfo, 0, sizeof(VOICE_QUALITY_ADDL_INFO));
140 addlInfo->name = strdup(name);
141 addlInfo->value = strdup(value);
142 assert(addlInfo->name != NULL);
143 assert(addlInfo->value != NULL);
145 dlist_push_last(&voiceQ->additionalInformation, addlInfo);
150 /**************************************************************************//**
151 * Set the Callee side codec for Call for domain Voice Quality
153 * @note The property is treated as immutable: it is only valid to call
154 * the setter once. However, we don't assert if the caller tries to
155 * overwrite, just ignoring the update instead.
157 * @param voiceQuality Pointer to the Voice Quality Event.
158 * @param calleeCodecForCall The Callee Side Codec to be set. ASCIIZ
159 * string. The caller does not need to
160 * preserve the value once the function
162 *****************************************************************************/
163 void evel_voice_quality_callee_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
164 const char * const calleeCodecForCall) {
167 /***************************************************************************/
168 /* Check preconditions. */
169 /***************************************************************************/
170 assert(voiceQuality != NULL);
171 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
172 assert(calleeCodecForCall != NULL);
174 voiceQuality->calleeSideCodec = strdup(calleeCodecForCall);
179 /**************************************************************************//**
180 * Set the Caller side codec for Call for domain Voice Quality
182 * @note The property is treated as immutable: it is only valid to call
183 * the setter once. However, we don't assert if the caller tries to
184 * overwrite, just ignoring the update instead.
186 * @param voiceQuality Pointer to the Voice Quality Event.
187 * @param callerCodecForCall The Caller Side Codec to be set. ASCIIZ
188 * string. The caller does not need to
189 * preserve the value once the function
191 *****************************************************************************/
192 void evel_voice_quality_caller_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
193 const char * const callerCodecForCall) {
196 /***************************************************************************/
197 /* Check preconditions. */
198 /***************************************************************************/
199 assert(voiceQuality != NULL);
200 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
201 assert(callerCodecForCall != NULL);
203 voiceQuality->calleeSideCodec = strdup(callerCodecForCall);
208 /**************************************************************************//**
209 * Set the correlator for domain Voice Quality
211 * @note The property is treated as immutable: it is only valid to call
212 * the setter once. However, we don't assert if the caller tries to
213 * overwrite, just ignoring the update instead.
215 * @param voiceQuality Pointer to the Voice Quality Event.
216 * @param correlator The correlator value to be set. ASCIIZ
217 * string. The caller does not need to
218 * preserve the value once the function
220 *****************************************************************************/
221 void evel_voice_quality_correlator_set(EVENT_VOICE_QUALITY * voiceQuality,
222 const char * const vCorrelator) {
225 /***************************************************************************/
226 /* Check preconditions. */
227 /***************************************************************************/
228 assert(voiceQuality != NULL);
229 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
230 assert(vCorrelator != NULL);
232 voiceQuality->correlator = strdup(vCorrelator);
237 /**************************************************************************//**
238 * Set the RTCP Call Data for domain Voice Quality
240 * @note The property is treated as immutable: it is only valid to call
241 * the setter once. However, we don't assert if the caller tries to
242 * overwrite, just ignoring the update instead.
244 * @param voiceQuality Pointer to the Voice Quality Event.
245 * @param rtcpCallData The RTCP Call Data to be set. ASCIIZ
246 * string. The caller does not need to
247 * preserve the value once the function
249 *****************************************************************************/
250 void evel_voice_quality_rtcp_data_set(EVENT_VOICE_QUALITY * voiceQuality,
251 const char * const rtcpCallData) {
254 /***************************************************************************/
255 /* Check preconditions. */
256 /***************************************************************************/
257 assert(voiceQuality != NULL);
258 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
259 assert(rtcpCallData != NULL);
261 voiceQuality->midCallRtcp = strdup(rtcpCallData);
266 /**************************************************************************//**
267 * Set the Vendor VNF Name fields for domain Voice Quality
269 * @note The property is treated as immutable: it is only valid to call
270 * the setter once. However, we don't assert if the caller tries to
271 * overwrite, just ignoring the update instead.
273 * @param voiceQuality Pointer to the Voice Quality Event.
274 * @param modulename The Vendor, VNF and VfModule names to be set.
275 * ASCIIZ string. The caller does not need to
276 * preserve the value once the function
278 *****************************************************************************/
279 void evel_voice_quality_vnfmodule_name_set(EVENT_VOICE_QUALITY * voiceQuality,
280 const char * const module_name) {
283 /***************************************************************************/
284 /* Check preconditions. */
285 /***************************************************************************/
286 assert(voiceQuality != NULL);
287 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
288 assert(module_name != NULL);
290 evel_vendor_field_module_set(&voiceQuality->vendorVnfNameFields, module_name);
295 /**************************************************************************//**
296 * Set the Vendor VNF Name fields for domain Voice Quality
298 * @note The property is treated as immutable: it is only valid to call
299 * the setter once. However, we don't assert if the caller tries to
300 * overwrite, just ignoring the update instead.
302 * @param voiceQuality Pointer to the Voice Quality Event.
303 * @param modulename The Vendor, VNF and VfModule names to be set.
304 * ASCIIZ string. The caller does not need to
305 * preserve the value once the function
307 *****************************************************************************/
308 void evel_voice_quality_vnfname_set(EVENT_VOICE_QUALITY * voiceQuality,
309 const char * const vnfname) {
312 /***************************************************************************/
313 /* Check preconditions. */
314 /***************************************************************************/
315 assert(voiceQuality != NULL);
316 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
317 assert(vnfname != NULL);
319 evel_vendor_field_vnfname_set(&voiceQuality->vendorVnfNameFields, vnfname);
324 /**************************************************************************//**
325 * Set the Phone Number associated with the Correlator for domain Voice Quality
327 * @note The property is treated as immutable: it is only valid to call
328 * the setter once. However, we don't assert if the caller tries to
329 * overwrite, just ignoring the update instead.
331 * @param voiceQuality Pointer to the Voice Quality Event.
332 * @param calleeCodecForCall The Phone Number to be set. ASCIIZ
333 * string. The caller does not need to
334 * preserve the value once the function
336 *****************************************************************************/
337 void evel_voice_quality_phone_number_set(EVENT_VOICE_QUALITY * voiceQuality,
338 const char * const phoneNumber) {
341 /***************************************************************************/
342 /* Check preconditions. */
343 /***************************************************************************/
344 assert(voiceQuality != NULL);
345 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
346 assert(phoneNumber != NULL);
348 evel_set_option_string(&voiceQuality->phoneNumber, phoneNumber, "Phone_Number");
353 /**************************************************************************//**
354 * Add an End of Call Voice Quality Metrices
356 * The adjacencyName and endpointDescription is null delimited ASCII string.
357 * The library takes a copy so the caller does not have to preserve values
358 * after the function returns.
360 * @param voiceQuality Pointer to the measurement.
361 * @param adjacencyName Adjacency name
362 * @param endpointDescription Enumeration: ‘Caller’, ‘Callee’.
363 * @param endpointJitter Endpoint jitter
364 * @param endpointRtpOctetsDiscarded Endpoint RTP octets discarded.
365 * @param endpointRtpOctetsReceived Endpoint RTP octets received.
366 * @param endpointRtpOctetsSent Endpoint RTP octets sent
367 * @param endpointRtpPacketsDiscarded Endpoint RTP packets discarded.
368 * @param endpointRtpPacketsReceived Endpoint RTP packets received.
369 * @param endpointRtpPacketsSent Endpoint RTP packets sent.
370 * @param localJitter Local jitter.
371 * @param localRtpOctetsDiscarded Local RTP octets discarded.
372 * @param localRtpOctetsReceived Local RTP octets received.
373 * @param localRtpOctetsSent Local RTP octets sent.
374 * @param localRtpPacketsDiscarded Local RTP packets discarded.
375 * @param localRtpPacketsReceived Local RTP packets received.
376 * @param localRtpPacketsSent Local RTP packets sent.
377 * @param mosCqe Decimal range from 1 to 5
379 * @param packetsLost No Packets lost
380 * @param packetLossPercent Calculated percentage packet loss
381 * @param rFactor rFactor from 0 to 100
382 * @param roundTripDelay Round trip delay in milliseconds
383 *****************************************************************************/
384 void evel_voice_quality_end_metrics_add(EVENT_VOICE_QUALITY * voiceQuality,
385 const char * adjacencyName, EVEL_SERVICE_ENDPOINT_DESC endpointDescription,
387 int endpointRtpOctetsDiscarded,
388 int endpointRtpOctetsReceived,
389 int endpointRtpOctetsSent,
390 int endpointRtpPacketsDiscarded,
391 int endpointRtpPacketsReceived,
392 int endpointRtpPacketsSent,
394 int localRtpOctetsDiscarded,
395 int localRtpOctetsReceived,
396 int localRtpOctetsSent,
397 int localRtpPacketsDiscarded,
398 int localRtpPacketsReceived,
399 int localRtpPacketsSent,
402 int packetLossPercent,
404 int roundTripDelay) {
406 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL;
409 /***************************************************************************/
410 /* Check assumptions. */
411 /***************************************************************************/
412 assert(voiceQuality != NULL);
413 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
414 assert(adjacencyName != NULL);
415 assert(endpointDescription >= 0);
416 assert(mosCqe >= 1 && mosCqe <= 5);
417 assert(rFactor >= 0 && rFactor <= 100);
418 assert(voiceQuality->endOfCallVqmSummaries == NULL);
420 /***************************************************************************/
421 /* Allocate a container for the value and push onto the list. */
422 /***************************************************************************/
423 EVEL_DEBUG("Adding adjacencyName=%s endpointDescription=%d", adjacencyName, endpointDescription);
424 vQMetrices = malloc(sizeof(END_OF_CALL_VOICE_QUALITY_METRICS));
425 assert(vQMetrices != NULL);
426 memset(vQMetrices, 0, sizeof(END_OF_CALL_VOICE_QUALITY_METRICS));
428 vQMetrices->adjacencyName = strdup(adjacencyName);
429 vQMetrices->endpointDescription = evel_service_endpoint_desc(endpointDescription);
431 evel_set_option_int(&vQMetrices->endpointJitter, endpointJitter, "Endpoint jitter");
432 evel_set_option_int(&vQMetrices->endpointRtpOctetsDiscarded, endpointRtpOctetsDiscarded, "Endpoint RTP octets discarded");
433 evel_set_option_int(&vQMetrices->endpointRtpOctetsReceived, endpointRtpOctetsReceived, "Endpoint RTP octets received");
434 evel_set_option_int(&vQMetrices->endpointRtpOctetsSent, endpointRtpOctetsSent, "Endpoint RTP octets sent");
435 evel_set_option_int(&vQMetrices->endpointRtpPacketsDiscarded, endpointRtpPacketsDiscarded, "Endpoint RTP packets discarded");
436 evel_set_option_int(&vQMetrices->endpointRtpPacketsReceived, endpointRtpPacketsReceived, "Endpoint RTP packets received");
437 evel_set_option_int(&vQMetrices->endpointRtpPacketsSent, endpointRtpPacketsSent, "Endpoint RTP packets sent");
438 evel_set_option_int(&vQMetrices->localJitter, localJitter, "Local jitter");
439 evel_set_option_int(&vQMetrices->localRtpOctetsDiscarded, localRtpOctetsDiscarded, "Local RTP octets discarded");
440 evel_set_option_int(&vQMetrices->localRtpOctetsReceived, localRtpOctetsReceived, "Local RTP octets received");
441 evel_set_option_int(&vQMetrices->localRtpOctetsSent, localRtpOctetsSent, "Local RTP octets sent");
442 evel_set_option_int(&vQMetrices->localRtpPacketsDiscarded, localRtpPacketsDiscarded, "Local RTP packets discarded");
443 evel_set_option_int(&vQMetrices->localRtpPacketsReceived, localRtpPacketsReceived, "Local RTP packets received");
444 evel_set_option_int(&vQMetrices->localRtpPacketsSent, localRtpPacketsSent, "Local RTP packets sent");
445 evel_set_option_int(&vQMetrices->mosCqe, mosCqe, "Decimal range from 1 to 5 (1 decimal place)");
446 evel_set_option_int(&vQMetrices->packetsLost, packetsLost, "Packets lost");
447 evel_set_option_int(&vQMetrices->packetLossPercent, packetLossPercent, "Calculated percentage packet loss");
448 evel_set_option_int(&vQMetrices->rFactor, rFactor, "rFactor ");
449 evel_set_option_int(&vQMetrices->roundTripDelay, roundTripDelay, "Round trip delay in milliseconds ");
451 voiceQuality->endOfCallVqmSummaries = vQMetrices;
456 /**************************************************************************//**
457 * Encode the Voce Quality in JSON according to AT&T's schema for the voice
460 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
461 * @param event Pointer to the ::EVENT_HEADER to encode.
462 *****************************************************************************/
463 void evel_json_encode_voice_quality(EVEL_JSON_BUFFER * jbuf,
464 EVENT_VOICE_QUALITY * event)
466 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
467 DLIST_ITEM * addlInfoItem = NULL;
469 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrics = NULL;
473 /***************************************************************************/
474 /* Check preconditions. */
475 /***************************************************************************/
476 assert(event != NULL);
477 assert(event->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
479 evel_json_encode_header(jbuf, &event->header);
480 evel_json_open_named_object(jbuf, "voiceQualityFields");
482 /***************************************************************************/
483 /* Mandatory fields. */
484 /***************************************************************************/
485 evel_enc_kv_string(jbuf, "calleeSideCodec", event->calleeSideCodec);
486 evel_enc_kv_string(jbuf, "callerSideCodec", event->callerSideCodec);
487 evel_enc_kv_string(jbuf, "correlator", event->correlator);
488 evel_enc_kv_string(jbuf, "midCallRtcp", event->midCallRtcp);
489 evel_json_encode_vendor_field(jbuf, &event->vendorVnfNameFields);
491 jbuf, "voiceQualityFieldsVersion", event->major_version, event->minor_version);
493 /***************************************************************************/
494 /* Optional fields. */
495 /***************************************************************************/
496 evel_enc_kv_opt_string(jbuf, "phoneNumber", &event->phoneNumber);
497 /***************************************************************************/
498 /* Checkpoint, so that we can wind back if all fields are suppressed. */
499 /***************************************************************************/
500 //additionalInformation for Voice Quality
501 bool item_added = false;
503 evel_json_checkpoint(jbuf);
504 if (evel_json_open_opt_named_list(jbuf, "additionalInformation"))
507 addlInfoItem = dlist_get_first(&event->additionalInformation);
508 while (addlInfoItem != NULL)
510 addlInfo = (VOICE_QUALITY_ADDL_INFO*)addlInfoItem->item;
511 assert(addlInfo != NULL);
513 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
514 "additionalInformation",
517 evel_json_open_object(jbuf);
518 evel_enc_kv_string(jbuf, "name", addlInfo->name);
519 evel_enc_kv_string(jbuf, "value", addlInfo->value);
520 evel_json_close_object(jbuf);
523 addlInfoItem = dlist_get_next(addlInfoItem);
525 evel_json_close_list(jbuf);
526 /*************************************************************************/
527 /* If we've not written anything, rewind to before we opened the list. */
528 /*************************************************************************/
531 evel_json_rewind(jbuf);
535 //endOfCallVqmSummaries
536 if( event->endOfCallVqmSummaries != NULL )
538 evel_json_open_named_object(jbuf, "endOfCallVqmSummaries");
539 vQMetrics = event->endOfCallVqmSummaries;
540 assert(vQMetrics != NULL);
542 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
543 "endOfCallVqmSummaries", vQMetrics->adjacencyName))
545 evel_enc_kv_string(jbuf, "adjacencyName", vQMetrics->adjacencyName);
546 evel_enc_kv_string(jbuf, "endpointDescription", vQMetrics->endpointDescription);
547 evel_enc_kv_opt_int(jbuf, "endpointJitter", &vQMetrics->endpointJitter);
548 evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsDiscarded", &vQMetrics->endpointRtpOctetsDiscarded);
549 evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsReceived", &vQMetrics->endpointRtpOctetsReceived);
550 evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsSent", &vQMetrics->endpointRtpOctetsSent);
551 evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsDiscarded", &vQMetrics->endpointRtpPacketsDiscarded);
552 evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsReceived", &vQMetrics->endpointRtpPacketsReceived);
553 evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsSent", &vQMetrics->endpointRtpPacketsSent);
554 evel_enc_kv_opt_int(jbuf, "localJitter", &vQMetrics->localJitter);
555 evel_enc_kv_opt_int(jbuf, "localRtpOctetsDiscarded", &vQMetrics->localRtpOctetsDiscarded);
556 evel_enc_kv_opt_int(jbuf, "localRtpOctetsReceived", &vQMetrics->localRtpOctetsReceived);
557 evel_enc_kv_opt_int(jbuf, "localRtpOctetsSent", &vQMetrics->localRtpOctetsSent);
558 evel_enc_kv_opt_int(jbuf, "localRtpPacketsDiscarded", &vQMetrics->localRtpPacketsDiscarded);
559 evel_enc_kv_opt_int(jbuf, "localRtpPacketsReceived", &vQMetrics->localRtpPacketsReceived);
560 evel_enc_kv_opt_int(jbuf, "localRtpPacketsSent", &vQMetrics->localRtpPacketsSent);
561 evel_enc_kv_opt_int(jbuf, "mosCqe", &vQMetrics->mosCqe);
562 evel_enc_kv_opt_int(jbuf, "packetsLost", &vQMetrics->packetsLost);
563 evel_enc_kv_opt_int(jbuf, "packetLossPercent", &vQMetrics->packetLossPercent);
564 evel_enc_kv_opt_int(jbuf, "rFactor", &vQMetrics->rFactor);
565 evel_enc_kv_opt_int(jbuf, "roundTripDelay", &vQMetrics->roundTripDelay);
569 evel_json_close_object(jbuf);
572 evel_json_close_object(jbuf);
577 /**************************************************************************//**
578 * Free a Voice Quality.
580 * Free off the Voce Quality supplied. Will free all the contained allocated
583 * @note It does not free the Voice Quality itself, since that may be part of a
585 *****************************************************************************/
586 void evel_free_voice_quality(EVENT_VOICE_QUALITY * voiceQuality) {
587 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL;
588 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
592 /***************************************************************************/
593 /* Check preconditions. As an internal API we don't allow freeing NULL */
594 /* events as we do on the public API. */
595 /***************************************************************************/
596 assert(voiceQuality != NULL);
597 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
599 /***************************************************************************/
600 /* Free all internal strings then the header itself. */
601 /***************************************************************************/
603 //Additional Information
604 addlInfo = dlist_pop_last(&voiceQuality->additionalInformation);
605 while (addlInfo != NULL)
607 EVEL_DEBUG("Freeing Additional Info (%s, %s)",
610 free(addlInfo->name);
611 free(addlInfo->value);
613 addlInfo = dlist_pop_last(&voiceQuality->additionalInformation);
616 //Summary Information
617 if(voiceQuality->endOfCallVqmSummaries != NULL)
619 vQMetrices = voiceQuality->endOfCallVqmSummaries;
620 EVEL_DEBUG("Freeing End of Call Voice Measurements Info (%s, %s)",
621 vQMetrices->adjacencyName,
622 vQMetrices->endpointDescription);
623 free(vQMetrices->adjacencyName);
628 free(voiceQuality->calleeSideCodec);
629 free(voiceQuality->callerSideCodec);
630 free(voiceQuality->correlator);
631 free(voiceQuality->midCallRtcp);
632 evel_free_option_string(&voiceQuality->phoneNumber);
633 evel_free_event_vendor_field(&voiceQuality->vendorVnfNameFields);
636 evel_free_header(&voiceQuality->header);