cf2ec8784dc2619b2296a3d9981f6c1ade24f1c8
[demo.git] / vnfs / VES5.0 / evel / evel-library / code / evel_library / evel_voicequality.c
1 /*************************************************************************//**
2  *
3  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
4  *
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
9  *
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.
15  *
16  ****************************************************************************/
17 /**************************************************************************//**
18  * @file
19  * Implementation of EVEL functions relating to the Voice Quality.
20  *****************************************************************************/
21
22 #include <string.h>
23 #include <assert.h>
24 #include <stdlib.h>
25
26 #include "evel.h"
27 #include "evel_internal.h"
28 #include "evel_throttle.h"
29
30 /**************************************************************************//**
31  * Create a new voice quality event.
32  *
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) {
54     
55     bool inError = false;
56     EVENT_VOICE_QUALITY *voiceQuality = NULL;
57     EVEL_ENTER();
58
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);
67
68     /***************************************************************************/
69     /* Allocate the Voice Quality.                                                     */
70     /***************************************************************************/
71     voiceQuality = malloc(sizeof(EVENT_VOICE_QUALITY));
72     
73     if (voiceQuality == NULL)
74     {
75         log_error_state("Out of memory");
76         inError = true;
77     }
78
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);
83
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;
92
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);
101     }
102
103     EVEL_EXIT();
104     return voiceQuality;
105
106 }
107
108 /**************************************************************************//**
109  * Add an additional value name/value pair to the Voice Quality.
110  *
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
113  * returns.
114  *
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
118  *                  returns.
119  * @param value     ASCIIZ string with the attribute's value.  The caller
120  *                  does not need to preserve the value once the function
121  *                  returns.
122  *****************************************************************************/
123 void evel_voice_quality_addl_info_add(EVENT_VOICE_QUALITY * voiceQ, char * name, char * value) {
124     VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
125     EVEL_ENTER();
126
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);
134
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);
143
144     dlist_push_last(&voiceQ->additionalInformation, addlInfo);
145
146     EVEL_EXIT();
147 }
148
149 /**************************************************************************//**
150  * Set the Callee side codec for Call for domain Voice Quality
151  *
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.
155  *
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
160  *                                  returns.
161  *****************************************************************************/
162 void evel_voice_quality_callee_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
163     const char * const calleeCodecForCall) {
164     EVEL_ENTER();
165
166     /***************************************************************************/
167     /* Check preconditions.                                                    */
168     /***************************************************************************/
169     assert(voiceQuality != NULL);
170     assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
171     assert(calleeCodecForCall != NULL);
172
173     voiceQuality->calleeSideCodec = strdup(calleeCodecForCall);
174
175     EVEL_EXIT();
176 }
177
178 /**************************************************************************//**
179  * Set the Caller side codec for Call for domain Voice Quality
180  *
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.
184  *
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
189  *                                  returns.
190  *****************************************************************************/
191 void evel_voice_quality_caller_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
192     const char * const callerCodecForCall) {
193     EVEL_ENTER();
194
195     /***************************************************************************/
196     /* Check preconditions.                                                    */
197     /***************************************************************************/
198     assert(voiceQuality != NULL);
199     assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
200     assert(callerCodecForCall != NULL);
201
202     voiceQuality->calleeSideCodec = strdup(callerCodecForCall);
203
204     EVEL_EXIT();
205 }
206
207 /**************************************************************************//**
208  * Set the correlator for domain Voice Quality
209  *
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.
213  *
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
218  *                                  returns.
219  *****************************************************************************/
220 void evel_voice_quality_correlator_set(EVENT_VOICE_QUALITY * voiceQuality,
221     const char * const vCorrelator) {
222     EVEL_ENTER();
223
224     /***************************************************************************/
225     /* Check preconditions.                                                    */
226     /***************************************************************************/
227     assert(voiceQuality != NULL);
228     assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
229     assert(vCorrelator != NULL);
230
231     voiceQuality->correlator = strdup(vCorrelator);
232
233     EVEL_EXIT();
234 }
235
236 /**************************************************************************//**
237  * Set the RTCP Call Data for domain Voice Quality
238  *
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.
242  *
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
247  *                                  returns.
248  *****************************************************************************/
249 void evel_voice_quality_rtcp_data_set(EVENT_VOICE_QUALITY * voiceQuality,
250     const char * const rtcpCallData) {
251     EVEL_ENTER();
252
253     /***************************************************************************/
254     /* Check preconditions.                                                    */
255     /***************************************************************************/
256     assert(voiceQuality != NULL);
257     assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
258     assert(rtcpCallData != NULL);
259
260     voiceQuality->midCallRtcp = strdup(rtcpCallData);
261
262     EVEL_EXIT();
263 }
264
265 /**************************************************************************//**
266  * Set the Vendor VNF Name fields for domain Voice Quality
267  *
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.
271  *
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
276  *                                  returns.
277  *****************************************************************************/
278 void evel_voice_quality_vnfmodule_name_set(EVENT_VOICE_QUALITY * voiceQuality,
279     const char * const module_name) {
280     EVEL_ENTER();
281
282     /***************************************************************************/
283     /* Check preconditions.                                                    */
284     /***************************************************************************/
285     assert(voiceQuality != NULL);
286     assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
287     assert(module_name != NULL);
288
289     evel_vendor_field_module_set(&voiceQuality->vendorVnfNameFields, module_name);
290
291     EVEL_EXIT();
292 }
293
294 /**************************************************************************//**
295  * Set the Vendor VNF Name fields for domain Voice Quality
296  *
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.
300  *
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
305  *                                  returns.
306  *****************************************************************************/
307 void evel_voice_quality_vnfname_set(EVENT_VOICE_QUALITY * voiceQuality,
308     const char * const vnfname) {
309     EVEL_ENTER();
310
311     /***************************************************************************/
312     /* Check preconditions.                                                    */
313     /***************************************************************************/
314     assert(voiceQuality != NULL);
315     assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
316     assert(vnfname != NULL);
317
318     evel_vendor_field_vnfname_set(&voiceQuality->vendorVnfNameFields, vnfname);
319
320     EVEL_EXIT();
321 }
322
323 /**************************************************************************//**
324  * Set the Phone Number associated with the Correlator for domain Voice Quality
325  *
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.
329  *
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
334  *                                  returns.
335  *****************************************************************************/
336 void evel_voice_quality_phone_number_set(EVENT_VOICE_QUALITY * voiceQuality,
337     const char * const phoneNumber) {
338     EVEL_ENTER();
339
340     /***************************************************************************/
341     /* Check preconditions.                                                    */
342     /***************************************************************************/
343     assert(voiceQuality != NULL);
344     assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
345     assert(phoneNumber != NULL);
346
347     evel_set_option_string(&voiceQuality->phoneNumber, phoneNumber, "Phone_Number");
348
349     EVEL_EXIT();
350 }
351
352 /**************************************************************************//**
353  * Add an End of Call Voice Quality Metrices
354
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.
358  *
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
377  *                                          (1 decimal place)
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,
385     int endpointJitter,
386     int endpointRtpOctetsDiscarded,
387     int endpointRtpOctetsReceived,
388     int endpointRtpOctetsSent,
389     int endpointRtpPacketsDiscarded,
390     int endpointRtpPacketsReceived,
391     int endpointRtpPacketsSent,
392     int localJitter,
393     int localRtpOctetsDiscarded,
394     int localRtpOctetsReceived,
395     int localRtpOctetsSent,
396     int localRtpPacketsDiscarded,
397     int localRtpPacketsReceived,
398     int localRtpPacketsSent,
399     int mosCqe,
400     int packetsLost,
401     int packetLossPercent,
402     int rFactor,
403     int roundTripDelay) {
404     
405     END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL;
406     EVEL_ENTER();
407
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);
418     
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));
426
427     vQMetrices->adjacencyName = strdup(adjacencyName);
428     vQMetrices->endpointDescription = evel_service_endpoint_desc(endpointDescription);
429
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 ");
449
450     voiceQuality->endOfCallVqmSummaries = vQMetrices;
451
452     EVEL_EXIT();
453 }
454
455 /**************************************************************************//**
456  * Encode the Voce Quality in JSON according to AT&T's schema for the voice
457  * quality type.
458  *
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)
464 {
465   VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
466   DLIST_ITEM * addlInfoItem = NULL;
467
468   END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrics = NULL;
469   DLIST_ITEM * vQMetricsItem = NULL;
470
471   EVEL_ENTER();
472
473   /***************************************************************************/
474   /* Check preconditions.                                                    */
475   /***************************************************************************/
476   assert(event != NULL);
477   assert(event->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
478
479   evel_json_encode_header(jbuf, &event->header);
480   evel_json_open_named_object(jbuf, "voiceQualityFields");
481
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);
490   evel_enc_version(
491     jbuf, "voiceQualityFieldsVersion", event->major_version, event->minor_version);
492
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;
502  
503   evel_json_checkpoint(jbuf);
504   if (evel_json_open_opt_named_list(jbuf, "additionalInformation"))
505   {
506
507     addlInfoItem = dlist_get_first(&event->additionalInformation);
508     while (addlInfoItem != NULL)
509     {
510       addlInfo = (VOICE_QUALITY_ADDL_INFO*)addlInfoItem->item;
511       assert(addlInfo != NULL);
512
513       if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
514                                           "additionalInformation",
515                                           addlInfo->name))
516       {
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);
521         item_added = true;
522       }
523       addlInfoItem = dlist_get_next(addlInfoItem);
524     }
525     evel_json_close_list(jbuf);
526     /*************************************************************************/
527     /* If we've not written anything, rewind to before we opened the list.   */
528     /*************************************************************************/
529     if (!item_added)
530     {
531       evel_json_rewind(jbuf);
532     }
533   }
534
535     //endOfCallVqmSummaries
536   if( event->endOfCallVqmSummaries != NULL )
537   {
538      evel_json_open_named_object(jbuf, "endOfCallVqmSummaries");
539      vQMetrics = event->endOfCallVqmSummaries;
540      assert(vQMetrics != NULL);
541
542             if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
543                 "endOfCallVqmSummaries", vQMetrics->adjacencyName))
544             {
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);
566
567             }
568
569     evel_json_close_object(jbuf);
570   }
571
572   evel_json_close_object(jbuf);
573
574   EVEL_EXIT();
575 }
576
577 /**************************************************************************//**
578  * Free a Voice Quality.
579  *
580  * Free off the Voce Quality supplied.  Will free all the contained allocated
581  * memory.
582  *
583  * @note It does not free the Voice Quality itself, since that may be part of a
584  * larger structure.
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;
589
590     EVEL_ENTER();
591
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);
598
599     /***************************************************************************/
600     /* Free all internal strings then the header itself.                       */
601     /***************************************************************************/
602     
603     //Additional Information
604     addlInfo = dlist_pop_last(&voiceQuality->additionalInformation);
605     while (addlInfo != NULL)
606     {
607         EVEL_DEBUG("Freeing Additional Info (%s, %s)",
608             addlInfo->name,
609             addlInfo->value);
610         free(addlInfo->name);
611         free(addlInfo->value);
612         free(addlInfo);
613         addlInfo = dlist_pop_last(&voiceQuality->additionalInformation);
614     }
615
616     //Summary Information
617     if(voiceQuality->endOfCallVqmSummaries != NULL)
618     {
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);
624         free(vQMetrices);
625     }
626
627     //Members
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);
634
635     //header
636     evel_free_header(&voiceQuality->header);
637
638     EVEL_EXIT();
639 }
640