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 event_name Unique Event Name
38 * @param event_id A universal identifier of the event for analysis etc.
39 * @param calleeSideCodec Callee codec for the call.
40 * @param callerSideCodec Caller codec for the call.
41 * @param correlator Constant across all events on this call.
42 * @param midCallRtcp Base64 encoding of the binary RTCP data
43 * (excluding Eth/IP/UDP headers).
44 * @param vendorVnfNameFields Vendor, VNF and VfModule names.
45 * @returns pointer to the newly manufactured ::EVENT_VOICE_QUALITY. If the
46 * event is not used (i.e. posted) it must be released using
47 ::evel_free_voice_quality.
48 * @retval NULL Failed to create the event.
49 *****************************************************************************/
50 EVENT_VOICE_QUALITY * evel_new_voice_quality(const char* ev_name, const char *ev_id,
51 const char * const calleeSideCodec,
52 const char * const callerSideCodec, const char * const correlator,
53 const char * const midCallRtcp, const char * const vendorName) {
56 EVENT_VOICE_QUALITY *voiceQuality = NULL;
59 /***************************************************************************/
60 /* Check preconditions. */
61 /***************************************************************************/
62 assert(calleeSideCodec != NULL);
63 assert(callerSideCodec != NULL);
64 assert(correlator != NULL);
65 assert(midCallRtcp != NULL);
66 assert(vendorName != NULL);
68 /***************************************************************************/
69 /* Allocate the Voice Quality. */
70 /***************************************************************************/
71 voiceQuality = malloc(sizeof(EVENT_VOICE_QUALITY));
73 if (voiceQuality == NULL)
75 log_error_state("Out of memory");
79 //Only in case of successful allocation initialize data.
80 if (inError == false) {
81 memset(voiceQuality, 0, sizeof(EVENT_VOICE_QUALITY));
82 EVEL_DEBUG("New Voice Quality is at %lp", voiceQuality);
84 /***************************************************************************/
85 /* Initialize the header & the fault fields. Optional integer values are */
86 /* initialized as 0. */
87 /***************************************************************************/
88 evel_init_header_nameid(&voiceQuality->header,ev_name,ev_id);
89 voiceQuality->header.event_domain = EVEL_DOMAIN_VOICE_QUALITY;
90 voiceQuality->major_version = EVEL_VOICEQ_MAJOR_VERSION;
91 voiceQuality->minor_version = EVEL_VOICEQ_MINOR_VERSION;
93 voiceQuality->calleeSideCodec = strdup(calleeSideCodec);
94 voiceQuality->callerSideCodec = strdup(callerSideCodec);
95 voiceQuality->correlator = strdup(correlator);
96 voiceQuality->midCallRtcp = strdup(midCallRtcp);
97 evel_init_vendor_field(&voiceQuality->vendorVnfNameFields, vendorName);
98 dlist_initialize(&voiceQuality->additionalInformation);
99 voiceQuality->endOfCallVqmSummaries = NULL;
100 evel_init_option_string(&voiceQuality->phoneNumber);
108 /**************************************************************************//**
109 * Add an additional value name/value pair to the Voice Quality.
111 * The name and value are null delimited ASCII strings. The library takes
112 * a copy so the caller does not have to preserve values after the function
115 * @param fault Pointer to the fault.
116 * @param name ASCIIZ string with the attribute's name. The caller
117 * does not need to preserve the value once the function
119 * @param value ASCIIZ string with the attribute's value. The caller
120 * does not need to preserve the value once the function
122 *****************************************************************************/
123 void evel_voice_quality_addl_info_add(EVENT_VOICE_QUALITY * voiceQ, char * name, char * value) {
124 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
127 /***************************************************************************/
128 /* Check preconditions. */
129 /***************************************************************************/
130 assert(voiceQ != NULL);
131 assert(voiceQ->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
132 assert(name != NULL);
133 assert(value != NULL);
135 EVEL_DEBUG("Adding name=%s value=%s", name, value);
136 addlInfo = malloc(sizeof(VOICE_QUALITY_ADDL_INFO));
137 assert(addlInfo != NULL);
138 memset(addlInfo, 0, sizeof(VOICE_QUALITY_ADDL_INFO));
139 addlInfo->name = strdup(name);
140 addlInfo->value = strdup(value);
141 assert(addlInfo->name != NULL);
142 assert(addlInfo->value != NULL);
144 dlist_push_last(&voiceQ->additionalInformation, addlInfo);
149 /**************************************************************************//**
150 * Set the Callee side codec for Call for domain Voice Quality
152 * @note The property is treated as immutable: it is only valid to call
153 * the setter once. However, we don't assert if the caller tries to
154 * overwrite, just ignoring the update instead.
156 * @param voiceQuality Pointer to the Voice Quality Event.
157 * @param calleeCodecForCall The Callee Side Codec to be set. ASCIIZ
158 * string. The caller does not need to
159 * preserve the value once the function
161 *****************************************************************************/
162 void evel_voice_quality_callee_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
163 const char * const calleeCodecForCall) {
166 /***************************************************************************/
167 /* Check preconditions. */
168 /***************************************************************************/
169 assert(voiceQuality != NULL);
170 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
171 assert(calleeCodecForCall != NULL);
173 voiceQuality->calleeSideCodec = strdup(calleeCodecForCall);
178 /**************************************************************************//**
179 * Set the Caller side codec for Call for domain Voice Quality
181 * @note The property is treated as immutable: it is only valid to call
182 * the setter once. However, we don't assert if the caller tries to
183 * overwrite, just ignoring the update instead.
185 * @param voiceQuality Pointer to the Voice Quality Event.
186 * @param callerCodecForCall The Caller Side Codec to be set. ASCIIZ
187 * string. The caller does not need to
188 * preserve the value once the function
190 *****************************************************************************/
191 void evel_voice_quality_caller_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
192 const char * const callerCodecForCall) {
195 /***************************************************************************/
196 /* Check preconditions. */
197 /***************************************************************************/
198 assert(voiceQuality != NULL);
199 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
200 assert(callerCodecForCall != NULL);
202 voiceQuality->calleeSideCodec = strdup(callerCodecForCall);
207 /**************************************************************************//**
208 * Set the correlator for domain Voice Quality
210 * @note The property is treated as immutable: it is only valid to call
211 * the setter once. However, we don't assert if the caller tries to
212 * overwrite, just ignoring the update instead.
214 * @param voiceQuality Pointer to the Voice Quality Event.
215 * @param correlator The correlator value to be set. ASCIIZ
216 * string. The caller does not need to
217 * preserve the value once the function
219 *****************************************************************************/
220 void evel_voice_quality_correlator_set(EVENT_VOICE_QUALITY * voiceQuality,
221 const char * const vCorrelator) {
224 /***************************************************************************/
225 /* Check preconditions. */
226 /***************************************************************************/
227 assert(voiceQuality != NULL);
228 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
229 assert(vCorrelator != NULL);
231 voiceQuality->correlator = strdup(vCorrelator);
236 /**************************************************************************//**
237 * Set the RTCP Call Data for domain Voice Quality
239 * @note The property is treated as immutable: it is only valid to call
240 * the setter once. However, we don't assert if the caller tries to
241 * overwrite, just ignoring the update instead.
243 * @param voiceQuality Pointer to the Voice Quality Event.
244 * @param rtcpCallData The RTCP Call Data to be set. ASCIIZ
245 * string. The caller does not need to
246 * preserve the value once the function
248 *****************************************************************************/
249 void evel_voice_quality_rtcp_data_set(EVENT_VOICE_QUALITY * voiceQuality,
250 const char * const rtcpCallData) {
253 /***************************************************************************/
254 /* Check preconditions. */
255 /***************************************************************************/
256 assert(voiceQuality != NULL);
257 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
258 assert(rtcpCallData != NULL);
260 voiceQuality->midCallRtcp = strdup(rtcpCallData);
265 /**************************************************************************//**
266 * Set the Vendor VNF Name fields for domain Voice Quality
268 * @note The property is treated as immutable: it is only valid to call
269 * the setter once. However, we don't assert if the caller tries to
270 * overwrite, just ignoring the update instead.
272 * @param voiceQuality Pointer to the Voice Quality Event.
273 * @param modulename The Vendor, VNF and VfModule names to be set.
274 * ASCIIZ string. The caller does not need to
275 * preserve the value once the function
277 *****************************************************************************/
278 void evel_voice_quality_vnfmodule_name_set(EVENT_VOICE_QUALITY * voiceQuality,
279 const char * const module_name) {
282 /***************************************************************************/
283 /* Check preconditions. */
284 /***************************************************************************/
285 assert(voiceQuality != NULL);
286 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
287 assert(module_name != NULL);
289 evel_vendor_field_module_set(&voiceQuality->vendorVnfNameFields, module_name);
294 /**************************************************************************//**
295 * Set the Vendor VNF Name fields for domain Voice Quality
297 * @note The property is treated as immutable: it is only valid to call
298 * the setter once. However, we don't assert if the caller tries to
299 * overwrite, just ignoring the update instead.
301 * @param voiceQuality Pointer to the Voice Quality Event.
302 * @param modulename The Vendor, VNF and VfModule names to be set.
303 * ASCIIZ string. The caller does not need to
304 * preserve the value once the function
306 *****************************************************************************/
307 void evel_voice_quality_vnfname_set(EVENT_VOICE_QUALITY * voiceQuality,
308 const char * const vnfname) {
311 /***************************************************************************/
312 /* Check preconditions. */
313 /***************************************************************************/
314 assert(voiceQuality != NULL);
315 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
316 assert(vnfname != NULL);
318 evel_vendor_field_vnfname_set(&voiceQuality->vendorVnfNameFields, vnfname);
323 /**************************************************************************//**
324 * Set the Phone Number associated with the Correlator for domain Voice Quality
326 * @note The property is treated as immutable: it is only valid to call
327 * the setter once. However, we don't assert if the caller tries to
328 * overwrite, just ignoring the update instead.
330 * @param voiceQuality Pointer to the Voice Quality Event.
331 * @param calleeCodecForCall The Phone Number to be set. ASCIIZ
332 * string. The caller does not need to
333 * preserve the value once the function
335 *****************************************************************************/
336 void evel_voice_quality_phone_number_set(EVENT_VOICE_QUALITY * voiceQuality,
337 const char * const phoneNumber) {
340 /***************************************************************************/
341 /* Check preconditions. */
342 /***************************************************************************/
343 assert(voiceQuality != NULL);
344 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
345 assert(phoneNumber != NULL);
347 evel_set_option_string(&voiceQuality->phoneNumber, phoneNumber, "Phone_Number");
352 /**************************************************************************//**
353 * Add an End of Call Voice Quality Metrices
355 * The adjacencyName and endpointDescription is null delimited ASCII string.
356 * The library takes a copy so the caller does not have to preserve values
357 * after the function returns.
359 * @param voiceQuality Pointer to the measurement.
360 * @param adjacencyName Adjacency name
361 * @param endpointDescription Enumeration: ‘Caller’, ‘Callee’.
362 * @param endpointJitter Endpoint jitter
363 * @param endpointRtpOctetsDiscarded Endpoint RTP octets discarded.
364 * @param endpointRtpOctetsReceived Endpoint RTP octets received.
365 * @param endpointRtpOctetsSent Endpoint RTP octets sent
366 * @param endpointRtpPacketsDiscarded Endpoint RTP packets discarded.
367 * @param endpointRtpPacketsReceived Endpoint RTP packets received.
368 * @param endpointRtpPacketsSent Endpoint RTP packets sent.
369 * @param localJitter Local jitter.
370 * @param localRtpOctetsDiscarded Local RTP octets discarded.
371 * @param localRtpOctetsReceived Local RTP octets received.
372 * @param localRtpOctetsSent Local RTP octets sent.
373 * @param localRtpPacketsDiscarded Local RTP packets discarded.
374 * @param localRtpPacketsReceived Local RTP packets received.
375 * @param localRtpPacketsSent Local RTP packets sent.
376 * @param mosCqe Decimal range from 1 to 5
378 * @param packetsLost No Packets lost
379 * @param packetLossPercent Calculated percentage packet loss
380 * @param rFactor rFactor from 0 to 100
381 * @param roundTripDelay Round trip delay in milliseconds
382 *****************************************************************************/
383 void evel_voice_quality_end_metrics_add(EVENT_VOICE_QUALITY * voiceQuality,
384 const char * adjacencyName, EVEL_SERVICE_ENDPOINT_DESC endpointDescription,
386 int endpointRtpOctetsDiscarded,
387 int endpointRtpOctetsReceived,
388 int endpointRtpOctetsSent,
389 int endpointRtpPacketsDiscarded,
390 int endpointRtpPacketsReceived,
391 int endpointRtpPacketsSent,
393 int localRtpOctetsDiscarded,
394 int localRtpOctetsReceived,
395 int localRtpOctetsSent,
396 int localRtpPacketsDiscarded,
397 int localRtpPacketsReceived,
398 int localRtpPacketsSent,
401 int packetLossPercent,
403 int roundTripDelay) {
405 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL;
408 /***************************************************************************/
409 /* Check assumptions. */
410 /***************************************************************************/
411 assert(voiceQuality != NULL);
412 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
413 assert(adjacencyName != NULL);
414 assert(endpointDescription >= 0);
415 assert(mosCqe >= 1 && mosCqe <= 5);
416 assert(rFactor >= 0 && rFactor <= 100);
417 assert(voiceQuality->endOfCallVqmSummaries == NULL);
419 /***************************************************************************/
420 /* Allocate a container for the value and push onto the list. */
421 /***************************************************************************/
422 EVEL_DEBUG("Adding adjacencyName=%s endpointDescription=%d", adjacencyName, endpointDescription);
423 vQMetrices = malloc(sizeof(END_OF_CALL_VOICE_QUALITY_METRICS));
424 assert(vQMetrices != NULL);
425 memset(vQMetrices, 0, sizeof(END_OF_CALL_VOICE_QUALITY_METRICS));
427 vQMetrices->adjacencyName = strdup(adjacencyName);
428 vQMetrices->endpointDescription = evel_service_endpoint_desc(endpointDescription);
430 evel_set_option_int(&vQMetrices->endpointJitter, endpointJitter, "Endpoint jitter");
431 evel_set_option_int(&vQMetrices->endpointRtpOctetsDiscarded, endpointRtpOctetsDiscarded, "Endpoint RTP octets discarded");
432 evel_set_option_int(&vQMetrices->endpointRtpOctetsReceived, endpointRtpOctetsReceived, "Endpoint RTP octets received");
433 evel_set_option_int(&vQMetrices->endpointRtpOctetsSent, endpointRtpOctetsSent, "Endpoint RTP octets sent");
434 evel_set_option_int(&vQMetrices->endpointRtpPacketsDiscarded, endpointRtpPacketsDiscarded, "Endpoint RTP packets discarded");
435 evel_set_option_int(&vQMetrices->endpointRtpPacketsReceived, endpointRtpPacketsReceived, "Endpoint RTP packets received");
436 evel_set_option_int(&vQMetrices->endpointRtpPacketsSent, endpointRtpPacketsSent, "Endpoint RTP packets sent");
437 evel_set_option_int(&vQMetrices->localJitter, localJitter, "Local jitter");
438 evel_set_option_int(&vQMetrices->localRtpOctetsDiscarded, localRtpOctetsDiscarded, "Local RTP octets discarded");
439 evel_set_option_int(&vQMetrices->localRtpOctetsReceived, localRtpOctetsReceived, "Local RTP octets received");
440 evel_set_option_int(&vQMetrices->localRtpOctetsSent, localRtpOctetsSent, "Local RTP octets sent");
441 evel_set_option_int(&vQMetrices->localRtpPacketsDiscarded, localRtpPacketsDiscarded, "Local RTP packets discarded");
442 evel_set_option_int(&vQMetrices->localRtpPacketsReceived, localRtpPacketsReceived, "Local RTP packets received");
443 evel_set_option_int(&vQMetrices->localRtpPacketsSent, localRtpPacketsSent, "Local RTP packets sent");
444 evel_set_option_int(&vQMetrices->mosCqe, mosCqe, "Decimal range from 1 to 5 (1 decimal place)");
445 evel_set_option_int(&vQMetrices->packetsLost, packetsLost, "Packets lost");
446 evel_set_option_int(&vQMetrices->packetLossPercent, packetLossPercent, "Calculated percentage packet loss");
447 evel_set_option_int(&vQMetrices->rFactor, rFactor, "rFactor ");
448 evel_set_option_int(&vQMetrices->roundTripDelay, roundTripDelay, "Round trip delay in milliseconds ");
450 voiceQuality->endOfCallVqmSummaries = vQMetrices;
455 /**************************************************************************//**
456 * Encode the Voce Quality in JSON according to AT&T's schema for the voice
459 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
460 * @param event Pointer to the ::EVENT_HEADER to encode.
461 *****************************************************************************/
462 void evel_json_encode_voice_quality(EVEL_JSON_BUFFER * jbuf,
463 EVENT_VOICE_QUALITY * event)
465 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
466 DLIST_ITEM * addlInfoItem = NULL;
468 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrics = NULL;
469 DLIST_ITEM * vQMetricsItem = 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);