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.
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 calleeSideCodec Callee codec for the call.
39 * @param callerSideCodec Caller codec for the call.
40 * @param correlator Constant across all events on this call.
41 * @param midCallRtcp Base64 encoding of the binary RTCP data
42 * (excluding Eth/IP/UDP headers).
43 * @param vendorVnfNameFields Vendor, VNF and VfModule names.
44 * @returns pointer to the newly manufactured ::EVENT_VOICE_QUALITY. If the
45 * event is not used (i.e. posted) it must be released using
46 ::evel_free_voice_quality.
47 * @retval NULL Failed to create the event.
48 *****************************************************************************/
49 EVENT_VOICE_QUALITY * evel_new_voice_quality(const char * const calleeSideCodec,
50 const char * const callerSideCodec, const char * const correlator,
51 const char * const midCallRtcp, const char * const vendorName) {
54 EVENT_VOICE_QUALITY *voiceQuality = NULL;
57 /***************************************************************************/
58 /* Check preconditions. */
59 /***************************************************************************/
60 assert(calleeSideCodec != NULL);
61 assert(callerSideCodec != NULL);
62 assert(correlator != NULL);
63 assert(midCallRtcp != NULL);
64 assert(vendorName != NULL);
66 /***************************************************************************/
67 /* Allocate the Voice Quality. */
68 /***************************************************************************/
69 voiceQuality = malloc(sizeof(EVENT_VOICE_QUALITY));
71 if (voiceQuality == NULL)
73 log_error_state("Out of memory");
77 //Only in case of successful allocation initialize data.
78 if (inError == false) {
79 memset(voiceQuality, 0, sizeof(EVENT_VOICE_QUALITY));
80 EVEL_DEBUG("New Voice Quality is at %lp", voiceQuality);
82 /***************************************************************************/
83 /* Initialize the header & the fault fields. Optional integer values are */
84 /* initialized as 0. */
85 /***************************************************************************/
86 evel_init_header(&voiceQuality->header,"voiceQuality");
87 voiceQuality->header.event_domain = EVEL_DOMAIN_VOICE_QUALITY;
88 voiceQuality->major_version = EVEL_VOICEQ_MAJOR_VERSION;
89 voiceQuality->minor_version = EVEL_VOICEQ_MINOR_VERSION;
91 voiceQuality->calleeSideCodec = strdup(calleeSideCodec);
92 voiceQuality->callerSideCodec = strdup(callerSideCodec);
93 voiceQuality->correlator = strdup(correlator);
94 voiceQuality->midCallRtcp = strdup(midCallRtcp);
95 evel_init_vendor_field(&voiceQuality->vendorVnfNameFields, vendorName);
96 dlist_initialize(&voiceQuality->additionalInformation);
97 dlist_initialize(&voiceQuality->endOfCallVqmSummaries);
98 evel_init_option_string(&voiceQuality->phoneNumber);
106 /**************************************************************************//**
107 * Add an additional value name/value pair to the Voice Quality.
109 * The name and value are null delimited ASCII strings. The library takes
110 * a copy so the caller does not have to preserve values after the function
113 * @param fault Pointer to the fault.
114 * @param name ASCIIZ string with the attribute's name. The caller
115 * does not need to preserve the value once the function
117 * @param value ASCIIZ string with the attribute's value. The caller
118 * does not need to preserve the value once the function
120 *****************************************************************************/
121 void evel_voice_quality_addl_info_add(EVENT_VOICE_QUALITY * voiceQ, char * name, char * value) {
122 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
125 /***************************************************************************/
126 /* Check preconditions. */
127 /***************************************************************************/
128 assert(voiceQ != NULL);
129 assert(voiceQ->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
130 assert(name != NULL);
131 assert(value != NULL);
133 EVEL_DEBUG("Adding name=%s value=%s", name, value);
134 addlInfo = malloc(sizeof(VOICE_QUALITY_ADDL_INFO));
135 assert(addlInfo != NULL);
136 memset(addlInfo, 0, sizeof(VOICE_QUALITY_ADDL_INFO));
137 addlInfo->name = strdup(name);
138 addlInfo->value = strdup(value);
139 assert(addlInfo->name != NULL);
140 assert(addlInfo->value != NULL);
142 dlist_push_last(&voiceQ->additionalInformation, addlInfo);
147 /**************************************************************************//**
148 * Set the Callee side codec for Call for domain Voice Quality
150 * @note The property is treated as immutable: it is only valid to call
151 * the setter once. However, we don't assert if the caller tries to
152 * overwrite, just ignoring the update instead.
154 * @param voiceQuality Pointer to the Voice Quality Event.
155 * @param calleeCodecForCall The Callee Side Codec to be set. ASCIIZ
156 * string. The caller does not need to
157 * preserve the value once the function
159 *****************************************************************************/
160 void evel_voice_quality_callee_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
161 const char * const calleeCodecForCall) {
164 /***************************************************************************/
165 /* Check preconditions. */
166 /***************************************************************************/
167 assert(voiceQuality != NULL);
168 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
169 assert(calleeCodecForCall != NULL);
171 voiceQuality->calleeSideCodec = strdup(calleeCodecForCall);
176 /**************************************************************************//**
177 * Set the Caller side codec for Call for domain Voice Quality
179 * @note The property is treated as immutable: it is only valid to call
180 * the setter once. However, we don't assert if the caller tries to
181 * overwrite, just ignoring the update instead.
183 * @param voiceQuality Pointer to the Voice Quality Event.
184 * @param callerCodecForCall The Caller Side Codec to be set. ASCIIZ
185 * string. The caller does not need to
186 * preserve the value once the function
188 *****************************************************************************/
189 void evel_voice_quality_caller_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
190 const char * const callerCodecForCall) {
193 /***************************************************************************/
194 /* Check preconditions. */
195 /***************************************************************************/
196 assert(voiceQuality != NULL);
197 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
198 assert(callerCodecForCall != NULL);
200 voiceQuality->calleeSideCodec = strdup(callerCodecForCall);
205 /**************************************************************************//**
206 * Set the correlator for domain Voice Quality
208 * @note The property is treated as immutable: it is only valid to call
209 * the setter once. However, we don't assert if the caller tries to
210 * overwrite, just ignoring the update instead.
212 * @param voiceQuality Pointer to the Voice Quality Event.
213 * @param correlator The correlator value to be set. ASCIIZ
214 * string. The caller does not need to
215 * preserve the value once the function
217 *****************************************************************************/
218 void evel_voice_quality_correlator_set(EVENT_VOICE_QUALITY * voiceQuality,
219 const char * const vCorrelator) {
222 /***************************************************************************/
223 /* Check preconditions. */
224 /***************************************************************************/
225 assert(voiceQuality != NULL);
226 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
227 assert(vCorrelator != NULL);
229 voiceQuality->correlator = strdup(vCorrelator);
234 /**************************************************************************//**
235 * Set the RTCP Call Data for domain Voice Quality
237 * @note The property is treated as immutable: it is only valid to call
238 * the setter once. However, we don't assert if the caller tries to
239 * overwrite, just ignoring the update instead.
241 * @param voiceQuality Pointer to the Voice Quality Event.
242 * @param rtcpCallData The RTCP Call Data to be set. ASCIIZ
243 * string. The caller does not need to
244 * preserve the value once the function
246 *****************************************************************************/
247 void evel_voice_quality_rtcp_data_set(EVENT_VOICE_QUALITY * voiceQuality,
248 const char * const rtcpCallData) {
251 /***************************************************************************/
252 /* Check preconditions. */
253 /***************************************************************************/
254 assert(voiceQuality != NULL);
255 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
256 assert(rtcpCallData != NULL);
258 voiceQuality->midCallRtcp = strdup(rtcpCallData);
263 /**************************************************************************//**
264 * Set the Vendor VNF Name fields for domain Voice Quality
266 * @note The property is treated as immutable: it is only valid to call
267 * the setter once. However, we don't assert if the caller tries to
268 * overwrite, just ignoring the update instead.
270 * @param voiceQuality Pointer to the Voice Quality Event.
271 * @param modulename The Vendor, VNF and VfModule names to be set.
272 * ASCIIZ string. The caller does not need to
273 * preserve the value once the function
275 *****************************************************************************/
276 void evel_voice_quality_vnfmodule_name_set(EVENT_VOICE_QUALITY * voiceQuality,
277 const char * const module_name) {
280 /***************************************************************************/
281 /* Check preconditions. */
282 /***************************************************************************/
283 assert(voiceQuality != NULL);
284 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
285 assert(module_name != NULL);
287 evel_vendor_field_module_set(&voiceQuality->vendorVnfNameFields, module_name);
292 /**************************************************************************//**
293 * Set the Vendor VNF Name fields for domain Voice Quality
295 * @note The property is treated as immutable: it is only valid to call
296 * the setter once. However, we don't assert if the caller tries to
297 * overwrite, just ignoring the update instead.
299 * @param voiceQuality Pointer to the Voice Quality Event.
300 * @param modulename The Vendor, VNF and VfModule names to be set.
301 * ASCIIZ string. The caller does not need to
302 * preserve the value once the function
304 *****************************************************************************/
305 void evel_voice_quality_vnfname_set(EVENT_VOICE_QUALITY * voiceQuality,
306 const char * const vnfname) {
309 /***************************************************************************/
310 /* Check preconditions. */
311 /***************************************************************************/
312 assert(voiceQuality != NULL);
313 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
314 assert(vnfname != NULL);
316 evel_vendor_field_vnfname_set(&voiceQuality->vendorVnfNameFields, vnfname);
321 /**************************************************************************//**
322 * Set the Phone Number associated with the Correlator for domain Voice Quality
324 * @note The property is treated as immutable: it is only valid to call
325 * the setter once. However, we don't assert if the caller tries to
326 * overwrite, just ignoring the update instead.
328 * @param voiceQuality Pointer to the Voice Quality Event.
329 * @param calleeCodecForCall The Phone Number to be set. ASCIIZ
330 * string. The caller does not need to
331 * preserve the value once the function
333 *****************************************************************************/
334 void evel_voice_quality_phone_number_set(EVENT_VOICE_QUALITY * voiceQuality,
335 const char * const phoneNumber) {
338 /***************************************************************************/
339 /* Check preconditions. */
340 /***************************************************************************/
341 assert(voiceQuality != NULL);
342 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
343 assert(phoneNumber != NULL);
345 evel_set_option_string(&voiceQuality->phoneNumber, phoneNumber, "Phone_Number");
350 /**************************************************************************//**
351 * Add an End of Call Voice Quality Metrices
353 * The adjacencyName and endpointDescription is null delimited ASCII string.
354 * The library takes a copy so the caller does not have to preserve values
355 * after the function returns.
357 * @param voiceQuality Pointer to the measurement.
358 * @param adjacencyName Adjacency name
359 * @param endpointDescription Enumeration: ‘Caller’, ‘Callee’.
360 * @param endpointJitter Endpoint jitter
361 * @param endpointRtpOctetsDiscarded Endpoint RTP octets discarded.
362 * @param endpointRtpOctetsReceived Endpoint RTP octets received.
363 * @param endpointRtpOctetsSent Endpoint RTP octets sent
364 * @param endpointRtpPacketsDiscarded Endpoint RTP packets discarded.
365 * @param endpointRtpPacketsReceived Endpoint RTP packets received.
366 * @param endpointRtpPacketsSent Endpoint RTP packets sent.
367 * @param localJitter Local jitter.
368 * @param localRtpOctetsDiscarded Local RTP octets discarded.
369 * @param localRtpOctetsReceived Local RTP octets received.
370 * @param localRtpOctetsSent Local RTP octets sent.
371 * @param localRtpPacketsDiscarded Local RTP packets discarded.
372 * @param localRtpPacketsReceived Local RTP packets received.
373 * @param localRtpPacketsSent Local RTP packets sent.
374 * @param mosCqe Decimal range from 1 to 5
376 * @param packetsLost No Packets lost
377 * @param packetLossPercent Calculated percentage packet loss
378 * @param rFactor rFactor from 0 to 100
379 * @param roundTripDelay Round trip delay in milliseconds
380 *****************************************************************************/
381 void evel_voice_quality_end_metrics_add(EVENT_VOICE_QUALITY * voiceQuality,
382 const char * adjacencyName, EVEL_SERVICE_ENDPOINT_DESC endpointDescription,
384 int endpointRtpOctetsDiscarded,
385 int endpointRtpOctetsReceived,
386 int endpointRtpOctetsSent,
387 int endpointRtpPacketsDiscarded,
388 int endpointRtpPacketsReceived,
389 int endpointRtpPacketsSent,
391 int localRtpOctetsDiscarded,
392 int localRtpOctetsReceived,
393 int localRtpOctetsSent,
394 int localRtpPacketsDiscarded,
395 int localRtpPacketsReceived,
396 int localRtpPacketsSent,
399 int packetLossPercent,
401 int roundTripDelay) {
403 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL;
406 /***************************************************************************/
407 /* Check assumptions. */
408 /***************************************************************************/
409 assert(voiceQuality != NULL);
410 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
411 assert(adjacencyName != NULL);
412 assert(endpointDescription >= 0);
413 assert(mosCqe >= 1 && mosCqe <= 5);
414 assert(rFactor >= 0 && rFactor <= 100);
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 dlist_push_last(&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);
525 //endOfCallVqmSummaries
526 evel_json_checkpoint(jbuf);
527 if (evel_json_open_opt_named_list(jbuf, "endOfCallVqmSummaries"))
529 vQMetricsItem = dlist_get_first(&event->endOfCallVqmSummaries);
530 while (vQMetricsItem != NULL)
532 vQMetrics = (END_OF_CALL_VOICE_QUALITY_METRICS *)vQMetricsItem->item;
533 assert(vQMetrics != NULL);
535 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
536 "endOfCallVqmSummaries",
537 vQMetrics->adjacencyName))
539 evel_json_open_object(jbuf);
540 evel_enc_kv_string(jbuf, "adjacencyName", vQMetrics->adjacencyName);
541 evel_enc_kv_string(jbuf, "endpointDescription", vQMetrics->endpointDescription);
542 evel_enc_kv_opt_int(jbuf, "endpointJitter", &vQMetrics->endpointJitter);
543 evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsDiscarded", &vQMetrics->endpointRtpOctetsDiscarded);
544 evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsReceived", &vQMetrics->endpointRtpOctetsReceived);
545 evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsSent", &vQMetrics->endpointRtpOctetsSent);
546 evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsDiscarded", &vQMetrics->endpointRtpPacketsDiscarded);
547 evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsReceived", &vQMetrics->endpointRtpPacketsReceived);
548 evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsSent", &vQMetrics->endpointRtpPacketsSent);
549 evel_enc_kv_opt_int(jbuf, "localJitter", &vQMetrics->localJitter);
550 evel_enc_kv_opt_int(jbuf, "localRtpOctetsDiscarded", &vQMetrics->localRtpOctetsDiscarded);
551 evel_enc_kv_opt_int(jbuf, "localRtpOctetsReceived", &vQMetrics->localRtpOctetsReceived);
552 evel_enc_kv_opt_int(jbuf, "localRtpOctetsSent", &vQMetrics->localRtpOctetsSent);
553 evel_enc_kv_opt_int(jbuf, "localRtpPacketsDiscarded", &vQMetrics->localRtpPacketsDiscarded);
554 evel_enc_kv_opt_int(jbuf, "localRtpPacketsReceived", &vQMetrics->localRtpPacketsReceived);
555 evel_enc_kv_opt_int(jbuf, "localRtpPacketsSent", &vQMetrics->localRtpPacketsSent);
556 evel_enc_kv_opt_int(jbuf, "mosCqe", &vQMetrics->mosCqe);
557 evel_enc_kv_opt_int(jbuf, "packetsLost", &vQMetrics->packetsLost);
558 evel_enc_kv_opt_int(jbuf, "packetLossPercent", &vQMetrics->packetLossPercent);
559 evel_enc_kv_opt_int(jbuf, "rFactor", &vQMetrics->rFactor);
560 evel_enc_kv_opt_int(jbuf, "roundTripDelay", &vQMetrics->roundTripDelay);
562 evel_json_close_object(jbuf);
565 vQMetricsItem = dlist_get_next(vQMetricsItem);
567 evel_json_close_list(jbuf);
570 /*************************************************************************/
571 /* If we've not written anything, rewind to before we opened the list. */
572 /*************************************************************************/
575 evel_json_rewind(jbuf);
578 evel_json_close_object(jbuf);
583 /**************************************************************************//**
584 * Free a Voice Quality.
586 * Free off the Voce Quality supplied. Will free all the contained allocated
589 * @note It does not free the Voice Quality itself, since that may be part of a
591 *****************************************************************************/
592 void evel_free_voice_quality(EVENT_VOICE_QUALITY * voiceQuality) {
593 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL;
594 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
598 /***************************************************************************/
599 /* Check preconditions. As an internal API we don't allow freeing NULL */
600 /* events as we do on the public API. */
601 /***************************************************************************/
602 assert(voiceQuality != NULL);
603 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
605 /***************************************************************************/
606 /* Free all internal strings then the header itself. */
607 /***************************************************************************/
609 //Additional Information
610 addlInfo = dlist_pop_last(&voiceQuality->additionalInformation);
611 while (addlInfo != NULL)
613 EVEL_DEBUG("Freeing Additional Info (%s, %s)",
616 free(addlInfo->name);
617 free(addlInfo->value);
619 addlInfo = dlist_pop_last(&voiceQuality->additionalInformation);
622 //Summary Information
623 vQMetrices = dlist_pop_last(&voiceQuality->endOfCallVqmSummaries);
624 while (vQMetrices != NULL)
626 EVEL_DEBUG("Freeing End of Call Voice Measurements Info (%s, %s)",
627 vQMetrices->adjacencyName,
628 vQMetrices->endpointDescription);
629 free(vQMetrices->adjacencyName);
631 vQMetrices = dlist_pop_last(&voiceQuality->endOfCallVqmSummaries);
635 free(voiceQuality->calleeSideCodec);
636 free(voiceQuality->callerSideCodec);
637 free(voiceQuality->correlator);
638 free(voiceQuality->midCallRtcp);
639 evel_free_option_string(&voiceQuality->phoneNumber);
640 evel_free_event_vendor_field(&voiceQuality->vendorVnfNameFields);
643 evel_free_header(&voiceQuality->header);