1 /**************************************************************************//**
3 * Implementation of EVEL functions relating to the Voice Quality.
8 * Copyright(c) <2016>, AT&T Intellectual Property. All other rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
13 * 1. Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement: This product includes
20 * software developed by the AT&T.
21 * 4. Neither the name of AT&T nor the names of its contributors may be used to
22 * endorse or promote products derived from this software without specific
23 * prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY ''AS IS'' AND ANY
26 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 * DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY
29 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *****************************************************************************/
42 #include "evel_internal.h"
43 #include "evel_throttle.h"
45 /**************************************************************************//**
46 * Create a new voice quality event.
48 * @note The mandatory fields on the Voice Quality must be supplied to this
49 * factory function and are immutable once set. Optional fields have
50 * explicit setter functions, but again values may only be set once
51 * so that the Voice Quality has immutable properties.
52 * @param calleeSideCodec Callee codec for the call.
53 * @param callerSideCodec Caller codec for the call.
54 * @param correlator Constant across all events on this call.
55 * @param midCallRtcp Base64 encoding of the binary RTCP data
56 * (excluding Eth/IP/UDP headers).
57 * @param vendorVnfNameFields Vendor, VNF and VfModule names.
58 * @returns pointer to the newly manufactured ::EVENT_VOICE_QUALITY. If the
59 * event is not used (i.e. posted) it must be released using
60 ::evel_free_voice_quality.
61 * @retval NULL Failed to create the event.
62 *****************************************************************************/
63 EVENT_VOICE_QUALITY * evel_new_voice_quality(const char * const calleeSideCodec,
64 const char * const callerSideCodec, const char * const correlator,
65 const char * const midCallRtcp, const char * const vendorName) {
68 EVENT_VOICE_QUALITY *voiceQuality = NULL;
71 /***************************************************************************/
72 /* Check preconditions. */
73 /***************************************************************************/
74 assert(calleeSideCodec != NULL);
75 assert(callerSideCodec != NULL);
76 assert(correlator != NULL);
77 assert(midCallRtcp != NULL);
78 assert(vendorName != NULL);
80 /***************************************************************************/
81 /* Allocate the Voice Quality. */
82 /***************************************************************************/
83 voiceQuality = malloc(sizeof(EVENT_VOICE_QUALITY));
85 if (voiceQuality == NULL)
87 log_error_state("Out of memory");
91 //Only in case of successful allocation initialize data.
92 if (inError == false) {
93 memset(voiceQuality, 0, sizeof(EVENT_VOICE_QUALITY));
94 EVEL_DEBUG("New Voice Quality is at %lp", voiceQuality);
96 /***************************************************************************/
97 /* Initialize the header & the fault fields. Optional integer values are */
98 /* initialized as 0. */
99 /***************************************************************************/
100 evel_init_header(&voiceQuality->header,"voiceQuality");
101 voiceQuality->header.event_domain = EVEL_DOMAIN_VOICE_QUALITY;
102 voiceQuality->major_version = EVEL_VOICEQ_MAJOR_VERSION;
103 voiceQuality->minor_version = EVEL_VOICEQ_MINOR_VERSION;
105 voiceQuality->calleeSideCodec = strdup(calleeSideCodec);
106 voiceQuality->callerSideCodec = strdup(callerSideCodec);
107 voiceQuality->correlator = strdup(correlator);
108 voiceQuality->midCallRtcp = strdup(midCallRtcp);
109 evel_init_vendor_field(&voiceQuality->vendorVnfNameFields, vendorName);
110 dlist_initialize(&voiceQuality->additionalInformation);
111 dlist_initialize(&voiceQuality->endOfCallVqmSummaries);
112 evel_init_option_string(&voiceQuality->phoneNumber);
120 /**************************************************************************//**
121 * Add an additional value name/value pair to the Voice Quality.
123 * The name and value are null delimited ASCII strings. The library takes
124 * a copy so the caller does not have to preserve values after the function
127 * @param fault Pointer to the fault.
128 * @param name ASCIIZ string with the attribute's name. The caller
129 * does not need to preserve the value once the function
131 * @param value ASCIIZ string with the attribute's value. The caller
132 * does not need to preserve the value once the function
134 *****************************************************************************/
135 void evel_voice_quality_addl_info_add(EVENT_VOICE_QUALITY * voiceQ, char * name, char * value) {
136 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
139 /***************************************************************************/
140 /* Check preconditions. */
141 /***************************************************************************/
142 assert(voiceQ != NULL);
143 assert(voiceQ->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
144 assert(name != NULL);
145 assert(value != NULL);
147 EVEL_DEBUG("Adding name=%s value=%s", name, value);
148 addlInfo = malloc(sizeof(VOICE_QUALITY_ADDL_INFO));
149 assert(addlInfo != NULL);
150 memset(addlInfo, 0, sizeof(VOICE_QUALITY_ADDL_INFO));
151 addlInfo->name = strdup(name);
152 addlInfo->value = strdup(value);
153 assert(addlInfo->name != NULL);
154 assert(addlInfo->value != NULL);
156 dlist_push_last(&voiceQ->additionalInformation, addlInfo);
161 /**************************************************************************//**
162 * Set the Callee side codec for Call for domain Voice Quality
164 * @note The property is treated as immutable: it is only valid to call
165 * the setter once. However, we don't assert if the caller tries to
166 * overwrite, just ignoring the update instead.
168 * @param voiceQuality Pointer to the Voice Quality Event.
169 * @param calleeCodecForCall The Callee Side Codec to be set. ASCIIZ
170 * string. The caller does not need to
171 * preserve the value once the function
173 *****************************************************************************/
174 void evel_voice_quality_callee_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
175 const char * const calleeCodecForCall) {
178 /***************************************************************************/
179 /* Check preconditions. */
180 /***************************************************************************/
181 assert(voiceQuality != NULL);
182 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
183 assert(calleeCodecForCall != NULL);
185 voiceQuality->calleeSideCodec = strdup(calleeCodecForCall);
190 /**************************************************************************//**
191 * Set the Caller side codec for Call for domain Voice Quality
193 * @note The property is treated as immutable: it is only valid to call
194 * the setter once. However, we don't assert if the caller tries to
195 * overwrite, just ignoring the update instead.
197 * @param voiceQuality Pointer to the Voice Quality Event.
198 * @param callerCodecForCall The Caller Side Codec to be set. ASCIIZ
199 * string. The caller does not need to
200 * preserve the value once the function
202 *****************************************************************************/
203 void evel_voice_quality_caller_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
204 const char * const callerCodecForCall) {
207 /***************************************************************************/
208 /* Check preconditions. */
209 /***************************************************************************/
210 assert(voiceQuality != NULL);
211 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
212 assert(callerCodecForCall != NULL);
214 voiceQuality->calleeSideCodec = strdup(callerCodecForCall);
219 /**************************************************************************//**
220 * Set the correlator for domain Voice Quality
222 * @note The property is treated as immutable: it is only valid to call
223 * the setter once. However, we don't assert if the caller tries to
224 * overwrite, just ignoring the update instead.
226 * @param voiceQuality Pointer to the Voice Quality Event.
227 * @param correlator The correlator value to be set. ASCIIZ
228 * string. The caller does not need to
229 * preserve the value once the function
231 *****************************************************************************/
232 void evel_voice_quality_correlator_set(EVENT_VOICE_QUALITY * voiceQuality,
233 const char * const vCorrelator) {
236 /***************************************************************************/
237 /* Check preconditions. */
238 /***************************************************************************/
239 assert(voiceQuality != NULL);
240 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
241 assert(vCorrelator != NULL);
243 voiceQuality->correlator = strdup(vCorrelator);
248 /**************************************************************************//**
249 * Set the RTCP Call Data for domain Voice Quality
251 * @note The property is treated as immutable: it is only valid to call
252 * the setter once. However, we don't assert if the caller tries to
253 * overwrite, just ignoring the update instead.
255 * @param voiceQuality Pointer to the Voice Quality Event.
256 * @param rtcpCallData The RTCP Call Data to be set. ASCIIZ
257 * string. The caller does not need to
258 * preserve the value once the function
260 *****************************************************************************/
261 void evel_voice_quality_rtcp_data_set(EVENT_VOICE_QUALITY * voiceQuality,
262 const char * const rtcpCallData) {
265 /***************************************************************************/
266 /* Check preconditions. */
267 /***************************************************************************/
268 assert(voiceQuality != NULL);
269 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
270 assert(rtcpCallData != NULL);
272 voiceQuality->midCallRtcp = strdup(rtcpCallData);
277 /**************************************************************************//**
278 * Set the Vendor VNF Name fields for domain Voice Quality
280 * @note The property is treated as immutable: it is only valid to call
281 * the setter once. However, we don't assert if the caller tries to
282 * overwrite, just ignoring the update instead.
284 * @param voiceQuality Pointer to the Voice Quality Event.
285 * @param modulename The Vendor, VNF and VfModule names to be set.
286 * ASCIIZ string. The caller does not need to
287 * preserve the value once the function
289 *****************************************************************************/
290 void evel_voice_quality_vnfmodule_name_set(EVENT_VOICE_QUALITY * voiceQuality,
291 const char * const module_name) {
294 /***************************************************************************/
295 /* Check preconditions. */
296 /***************************************************************************/
297 assert(voiceQuality != NULL);
298 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
299 assert(module_name != NULL);
301 evel_vendor_field_module_set(&voiceQuality->vendorVnfNameFields, module_name);
306 /**************************************************************************//**
307 * Set the Vendor VNF Name fields for domain Voice Quality
309 * @note The property is treated as immutable: it is only valid to call
310 * the setter once. However, we don't assert if the caller tries to
311 * overwrite, just ignoring the update instead.
313 * @param voiceQuality Pointer to the Voice Quality Event.
314 * @param modulename The Vendor, VNF and VfModule names to be set.
315 * ASCIIZ string. The caller does not need to
316 * preserve the value once the function
318 *****************************************************************************/
319 void evel_voice_quality_vnfname_set(EVENT_VOICE_QUALITY * voiceQuality,
320 const char * const vnfname) {
323 /***************************************************************************/
324 /* Check preconditions. */
325 /***************************************************************************/
326 assert(voiceQuality != NULL);
327 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
328 assert(vnfname != NULL);
330 evel_vendor_field_vnfname_set(&voiceQuality->vendorVnfNameFields, vnfname);
335 /**************************************************************************//**
336 * Set the Phone Number associated with the Correlator for domain Voice Quality
338 * @note The property is treated as immutable: it is only valid to call
339 * the setter once. However, we don't assert if the caller tries to
340 * overwrite, just ignoring the update instead.
342 * @param voiceQuality Pointer to the Voice Quality Event.
343 * @param calleeCodecForCall The Phone Number to be set. ASCIIZ
344 * string. The caller does not need to
345 * preserve the value once the function
347 *****************************************************************************/
348 void evel_voice_quality_phone_number_set(EVENT_VOICE_QUALITY * voiceQuality,
349 const char * const phoneNumber) {
352 /***************************************************************************/
353 /* Check preconditions. */
354 /***************************************************************************/
355 assert(voiceQuality != NULL);
356 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
357 assert(phoneNumber != NULL);
359 evel_set_option_string(&voiceQuality->phoneNumber, phoneNumber, "Phone_Number");
364 /**************************************************************************//**
365 * Add an End of Call Voice Quality Metrices
367 * The adjacencyName and endpointDescription is null delimited ASCII string.
368 * The library takes a copy so the caller does not have to preserve values
369 * after the function returns.
371 * @param voiceQuality Pointer to the measurement.
372 * @param adjacencyName Adjacency name
373 * @param endpointDescription Enumeration: ‘Caller’, ‘Callee’.
374 * @param endpointJitter Endpoint jitter
375 * @param endpointRtpOctetsDiscarded Endpoint RTP octets discarded.
376 * @param endpointRtpOctetsReceived Endpoint RTP octets received.
377 * @param endpointRtpOctetsSent Endpoint RTP octets sent
378 * @param endpointRtpPacketsDiscarded Endpoint RTP packets discarded.
379 * @param endpointRtpPacketsReceived Endpoint RTP packets received.
380 * @param endpointRtpPacketsSent Endpoint RTP packets sent.
381 * @param localJitter Local jitter.
382 * @param localRtpOctetsDiscarded Local RTP octets discarded.
383 * @param localRtpOctetsReceived Local RTP octets received.
384 * @param localRtpOctetsSent Local RTP octets sent.
385 * @param localRtpPacketsDiscarded Local RTP packets discarded.
386 * @param localRtpPacketsReceived Local RTP packets received.
387 * @param localRtpPacketsSent Local RTP packets sent.
388 * @param mosCqe Decimal range from 1 to 5
390 * @param packetsLost No Packets lost
391 * @param packetLossPercent Calculated percentage packet loss
392 * @param rFactor rFactor from 0 to 100
393 * @param roundTripDelay Round trip delay in milliseconds
394 *****************************************************************************/
395 void evel_voice_quality_end_metrics_add(EVENT_VOICE_QUALITY * voiceQuality,
396 const char * adjacencyName, EVEL_SERVICE_ENDPOINT_DESC endpointDescription,
398 int endpointRtpOctetsDiscarded,
399 int endpointRtpOctetsReceived,
400 int endpointRtpOctetsSent,
401 int endpointRtpPacketsDiscarded,
402 int endpointRtpPacketsReceived,
403 int endpointRtpPacketsSent,
405 int localRtpOctetsDiscarded,
406 int localRtpOctetsReceived,
407 int localRtpOctetsSent,
408 int localRtpPacketsDiscarded,
409 int localRtpPacketsReceived,
410 int localRtpPacketsSent,
413 int packetLossPercent,
415 int roundTripDelay) {
417 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL;
420 /***************************************************************************/
421 /* Check assumptions. */
422 /***************************************************************************/
423 assert(voiceQuality != NULL);
424 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
425 assert(adjacencyName != NULL);
426 assert(endpointDescription >= 0);
427 assert(mosCqe >= 1 && mosCqe <= 5);
428 assert(rFactor >= 0 && rFactor <= 100);
430 /***************************************************************************/
431 /* Allocate a container for the value and push onto the list. */
432 /***************************************************************************/
433 EVEL_DEBUG("Adding adjacencyName=%s endpointDescription=%d", adjacencyName, endpointDescription);
434 vQMetrices = malloc(sizeof(END_OF_CALL_VOICE_QUALITY_METRICS));
435 assert(vQMetrices != NULL);
436 memset(vQMetrices, 0, sizeof(END_OF_CALL_VOICE_QUALITY_METRICS));
438 vQMetrices->adjacencyName = strdup(adjacencyName);
439 vQMetrices->endpointDescription = evel_service_endpoint_desc(endpointDescription);
441 evel_set_option_int(&vQMetrices->endpointJitter, endpointJitter, "Endpoint jitter");
442 evel_set_option_int(&vQMetrices->endpointRtpOctetsDiscarded, endpointRtpOctetsDiscarded, "Endpoint RTP octets discarded");
443 evel_set_option_int(&vQMetrices->endpointRtpOctetsReceived, endpointRtpOctetsReceived, "Endpoint RTP octets received");
444 evel_set_option_int(&vQMetrices->endpointRtpOctetsSent, endpointRtpOctetsSent, "Endpoint RTP octets sent");
445 evel_set_option_int(&vQMetrices->endpointRtpPacketsDiscarded, endpointRtpPacketsDiscarded, "Endpoint RTP packets discarded");
446 evel_set_option_int(&vQMetrices->endpointRtpPacketsReceived, endpointRtpPacketsReceived, "Endpoint RTP packets received");
447 evel_set_option_int(&vQMetrices->endpointRtpPacketsSent, endpointRtpPacketsSent, "Endpoint RTP packets sent");
448 evel_set_option_int(&vQMetrices->localJitter, localJitter, "Local jitter");
449 evel_set_option_int(&vQMetrices->localRtpOctetsDiscarded, localRtpOctetsDiscarded, "Local RTP octets discarded");
450 evel_set_option_int(&vQMetrices->localRtpOctetsReceived, localRtpOctetsReceived, "Local RTP octets received");
451 evel_set_option_int(&vQMetrices->localRtpOctetsSent, localRtpOctetsSent, "Local RTP octets sent");
452 evel_set_option_int(&vQMetrices->localRtpPacketsDiscarded, localRtpPacketsDiscarded, "Local RTP packets discarded");
453 evel_set_option_int(&vQMetrices->localRtpPacketsReceived, localRtpPacketsReceived, "Local RTP packets received");
454 evel_set_option_int(&vQMetrices->localRtpPacketsSent, localRtpPacketsSent, "Local RTP packets sent");
455 evel_set_option_int(&vQMetrices->mosCqe, mosCqe, "Decimal range from 1 to 5 (1 decimal place)");
456 evel_set_option_int(&vQMetrices->packetsLost, packetsLost, "Packets lost");
457 evel_set_option_int(&vQMetrices->packetLossPercent, packetLossPercent, "Calculated percentage packet loss");
458 evel_set_option_int(&vQMetrices->rFactor, rFactor, "rFactor ");
459 evel_set_option_int(&vQMetrices->roundTripDelay, roundTripDelay, "Round trip delay in milliseconds ");
461 dlist_push_last(&voiceQuality->endOfCallVqmSummaries, vQMetrices);
466 /**************************************************************************//**
467 * Encode the Voce Quality in JSON according to AT&T's schema for the voice
470 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
471 * @param event Pointer to the ::EVENT_HEADER to encode.
472 *****************************************************************************/
473 void evel_json_encode_voice_quality(EVEL_JSON_BUFFER * jbuf,
474 EVENT_VOICE_QUALITY * event)
476 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
477 DLIST_ITEM * addlInfoItem = NULL;
479 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrics = NULL;
480 DLIST_ITEM * vQMetricsItem = NULL;
484 /***************************************************************************/
485 /* Check preconditions. */
486 /***************************************************************************/
487 assert(event != NULL);
488 assert(event->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
490 evel_json_encode_header(jbuf, &event->header);
491 evel_json_open_named_object(jbuf, "voiceQualityFields");
493 /***************************************************************************/
494 /* Mandatory fields. */
495 /***************************************************************************/
496 evel_enc_kv_string(jbuf, "calleeSideCodec", event->calleeSideCodec);
497 evel_enc_kv_string(jbuf, "callerSideCodec", event->callerSideCodec);
498 evel_enc_kv_string(jbuf, "correlator", event->correlator);
499 evel_enc_kv_string(jbuf, "midCallRtcp", event->midCallRtcp);
500 evel_json_encode_vendor_field(jbuf, &event->vendorVnfNameFields);
502 jbuf, "voiceQualityFieldsVersion", event->major_version, event->minor_version);
504 /***************************************************************************/
505 /* Optional fields. */
506 /***************************************************************************/
507 evel_enc_kv_opt_string(jbuf, "phoneNumber", &event->phoneNumber);
508 /***************************************************************************/
509 /* Checkpoint, so that we can wind back if all fields are suppressed. */
510 /***************************************************************************/
511 //additionalInformation for Voice Quality
512 bool item_added = false;
514 evel_json_checkpoint(jbuf);
515 if (evel_json_open_opt_named_list(jbuf, "additionalInformation"))
518 addlInfoItem = dlist_get_first(&event->additionalInformation);
519 while (addlInfoItem != NULL)
521 addlInfo = (VOICE_QUALITY_ADDL_INFO*)addlInfoItem->item;
522 assert(addlInfo != NULL);
524 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
525 "additionalInformation",
528 evel_json_open_object(jbuf);
529 evel_enc_kv_string(jbuf, "name", addlInfo->name);
530 evel_enc_kv_string(jbuf, "value", addlInfo->value);
531 evel_json_close_object(jbuf);
534 addlInfoItem = dlist_get_next(addlInfoItem);
536 evel_json_close_list(jbuf);
539 //endOfCallVqmSummaries
540 evel_json_checkpoint(jbuf);
541 if (evel_json_open_opt_named_list(jbuf, "endOfCallVqmSummaries"))
543 vQMetricsItem = dlist_get_first(&event->endOfCallVqmSummaries);
544 while (vQMetricsItem != NULL)
546 vQMetrics = (END_OF_CALL_VOICE_QUALITY_METRICS *)vQMetricsItem->item;
547 assert(vQMetrics != NULL);
549 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
550 "endOfCallVqmSummaries",
551 vQMetrics->adjacencyName))
553 evel_json_open_object(jbuf);
554 evel_enc_kv_string(jbuf, "adjacencyName", vQMetrics->adjacencyName);
555 evel_enc_kv_string(jbuf, "endpointDescription", vQMetrics->endpointDescription);
556 evel_enc_kv_opt_int(jbuf, "endpointJitter", &vQMetrics->endpointJitter);
557 evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsDiscarded", &vQMetrics->endpointRtpOctetsDiscarded);
558 evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsReceived", &vQMetrics->endpointRtpOctetsReceived);
559 evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsSent", &vQMetrics->endpointRtpOctetsSent);
560 evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsDiscarded", &vQMetrics->endpointRtpPacketsDiscarded);
561 evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsReceived", &vQMetrics->endpointRtpPacketsReceived);
562 evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsSent", &vQMetrics->endpointRtpPacketsSent);
563 evel_enc_kv_opt_int(jbuf, "localJitter", &vQMetrics->localJitter);
564 evel_enc_kv_opt_int(jbuf, "localRtpOctetsDiscarded", &vQMetrics->localRtpOctetsDiscarded);
565 evel_enc_kv_opt_int(jbuf, "localRtpOctetsReceived", &vQMetrics->localRtpOctetsReceived);
566 evel_enc_kv_opt_int(jbuf, "localRtpOctetsSent", &vQMetrics->localRtpOctetsSent);
567 evel_enc_kv_opt_int(jbuf, "localRtpPacketsDiscarded", &vQMetrics->localRtpPacketsDiscarded);
568 evel_enc_kv_opt_int(jbuf, "localRtpPacketsReceived", &vQMetrics->localRtpPacketsReceived);
569 evel_enc_kv_opt_int(jbuf, "localRtpPacketsSent", &vQMetrics->localRtpPacketsSent);
570 evel_enc_kv_opt_int(jbuf, "mosCqe", &vQMetrics->mosCqe);
571 evel_enc_kv_opt_int(jbuf, "packetsLost", &vQMetrics->packetsLost);
572 evel_enc_kv_opt_int(jbuf, "packetLossPercent", &vQMetrics->packetLossPercent);
573 evel_enc_kv_opt_int(jbuf, "rFactor", &vQMetrics->rFactor);
574 evel_enc_kv_opt_int(jbuf, "roundTripDelay", &vQMetrics->roundTripDelay);
576 evel_json_close_object(jbuf);
579 vQMetricsItem = dlist_get_next(vQMetricsItem);
581 evel_json_close_list(jbuf);
584 /*************************************************************************/
585 /* If we've not written anything, rewind to before we opened the list. */
586 /*************************************************************************/
589 evel_json_rewind(jbuf);
592 evel_json_close_object(jbuf);
597 /**************************************************************************//**
598 * Free a Voice Quality.
600 * Free off the Voce Quality supplied. Will free all the contained allocated
603 * @note It does not free the Voice Quality itself, since that may be part of a
605 *****************************************************************************/
606 void evel_free_voice_quality(EVENT_VOICE_QUALITY * voiceQuality) {
607 END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL;
608 VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
612 /***************************************************************************/
613 /* Check preconditions. As an internal API we don't allow freeing NULL */
614 /* events as we do on the public API. */
615 /***************************************************************************/
616 assert(voiceQuality != NULL);
617 assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
619 /***************************************************************************/
620 /* Free all internal strings then the header itself. */
621 /***************************************************************************/
623 //Additional Information
624 addlInfo = dlist_pop_last(&voiceQuality->additionalInformation);
625 while (addlInfo != NULL)
627 EVEL_DEBUG("Freeing Additional Info (%s, %s)",
630 free(addlInfo->name);
631 free(addlInfo->value);
633 addlInfo = dlist_pop_last(&voiceQuality->additionalInformation);
636 //Summary Information
637 vQMetrices = dlist_pop_last(&voiceQuality->endOfCallVqmSummaries);
638 while (vQMetrices != NULL)
640 EVEL_DEBUG("Freeing End of Call Voice Measurements Info (%s, %s)",
641 vQMetrices->adjacencyName,
642 vQMetrices->endpointDescription);
643 free(vQMetrices->adjacencyName);
645 vQMetrices = dlist_pop_last(&voiceQuality->endOfCallVqmSummaries);
649 free(voiceQuality->calleeSideCodec);
650 free(voiceQuality->callerSideCodec);
651 free(voiceQuality->correlator);
652 free(voiceQuality->midCallRtcp);
653 evel_free_option_string(&voiceQuality->phoneNumber);
654 evel_free_event_vendor_field(&voiceQuality->vendorVnfNameFields);
657 evel_free_header(&voiceQuality->header);