Initial OpenECOMP Demo commit
[demo.git] / vnfs / VES / code / evel_library / evel_mobile_flow.c
1 /**************************************************************************//**
2  * @file
3  * Implementation of EVEL functions relating to the Mobile Flow.
4  *
5  * License
6  * -------
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  *    this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  *    this list of conditions and the following disclaimer in the documentation
15  *    and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:  This product includes
18  *    software developed by the AT&T.
19  * 4. Neither the name of AT&T nor the names of its contributors may be used to
20  *    endorse or promote products derived from this software without specific
21  *    prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY ''AS IS'' AND ANY
24  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY
27  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *****************************************************************************/
34
35 #include <string.h>
36 #include <assert.h>
37 #include <stdlib.h>
38 #include <time.h>
39
40 #include "evel.h"
41 #include "evel_internal.h"
42
43 /*****************************************************************************/
44 /* Array of strings to use when encoding TCP flags.                          */
45 /*****************************************************************************/
46 static char * evel_tcp_flag_strings[EVEL_MAX_TCP_FLAGS] = {
47   "NS",
48   "CWR",
49   "ECE",
50   "URG",
51   "ACK",
52   "PSH",
53   "RST",
54   "SYN",
55   "FIN"
56 };
57
58 /*****************************************************************************/
59 /* Array of strings to use when encoding QCI COS.                            */
60 /*****************************************************************************/
61 static char * evel_qci_cos_strings[EVEL_MAX_QCI_COS_TYPES] = {
62   "conversational",
63   "streaming",
64   "interactive",
65   "background",
66   "1",
67   "2",
68   "3",
69   "4",
70   "65",
71   "66",
72   "5",
73   "6",
74   "7",
75   "8",
76   "9",
77   "69",
78   "70"
79 };
80
81 /*****************************************************************************/
82 /* Local prototypes                                                          */
83 /*****************************************************************************/
84 void evel_json_encode_mobile_flow_gtp_flow_metrics(
85                                         EVEL_JSON_BUFFER * jbuf,
86                                         MOBILE_GTP_PER_FLOW_METRICS * metrics);
87
88 /**************************************************************************//**
89  * Create a new Mobile Flow event.
90  *
91  * @note    The mandatory fields on the Mobile Flow must be supplied to this
92  *          factory function and are immutable once set.  Optional fields have
93  *          explicit setter functions, but again values may only be set once so
94  *          that the Mobile Flow has immutable properties.
95  * @param   flow_direction              Flow direction.
96  * @param   gtp_per_flow_metrics        GTP per-flow metrics.
97  * @param   ip_protocol_type            IP protocol type.
98  * @param   ip_version                  IP protocol version.
99  * @param   other_endpoint_ip_address   IP address of the other endpoint.
100  * @param   other_endpoint_port         IP port of the other endpoint.
101  * @param   reporting_endpoint_ip_addr  IP address of the reporting endpoint.
102  * @param   reporting_endpoint_port     IP port of the reporting endpoint.
103  * @returns pointer to the newly manufactured ::EVENT_MOBILE_FLOW.  If the
104  *          event is not used (i.e. posted) it must be released using
105  *          ::evel_free_mobile_flow.
106  * @retval  NULL  Failed to create the event.
107  *****************************************************************************/
108 EVENT_MOBILE_FLOW * evel_new_mobile_flow(
109                             const char * const flow_direction,
110                             MOBILE_GTP_PER_FLOW_METRICS * gtp_per_flow_metrics,
111                             const char * const ip_protocol_type,
112                             const char * const ip_version,
113                             const char * const other_endpoint_ip_address,
114                             int other_endpoint_port,
115                             const char * const reporting_endpoint_ip_addr,
116                             int reporting_endpoint_port)
117 {
118   EVENT_MOBILE_FLOW * mobile_flow = NULL;
119   EVEL_ENTER();
120
121   /***************************************************************************/
122   /* Check preconditions.                                                    */
123   /***************************************************************************/
124   assert(flow_direction != NULL);
125   assert(gtp_per_flow_metrics != NULL);
126   assert(ip_protocol_type != NULL);
127   assert(ip_version != NULL);
128   assert(other_endpoint_ip_address != NULL);
129   assert(other_endpoint_port > 0);
130   assert(reporting_endpoint_ip_addr != NULL);
131   assert(reporting_endpoint_port > 0);
132
133   /***************************************************************************/
134   /* Allocate the Mobile Flow.                                               */
135   /***************************************************************************/
136   mobile_flow = malloc(sizeof(EVENT_MOBILE_FLOW));
137   if (mobile_flow == NULL)
138   {
139     log_error_state("Out of memory");
140     goto exit_label;
141   }
142   memset(mobile_flow, 0, sizeof(EVENT_MOBILE_FLOW));
143   EVEL_DEBUG("New Mobile Flow is at %lp", mobile_flow);
144
145   /***************************************************************************/
146   /* Initialize the header & the Mobile Flow fields.  Optional string values */
147   /* are uninitialized (NULL).                                               */
148   /***************************************************************************/
149   evel_init_header(&mobile_flow->header);
150   mobile_flow->header.event_domain = EVEL_DOMAIN_MOBILE_FLOW;
151   mobile_flow->major_version = EVEL_MOBILE_FLOW_MAJOR_VERSION;
152   mobile_flow->minor_version = EVEL_MOBILE_FLOW_MINOR_VERSION;
153   mobile_flow->flow_direction = strdup(flow_direction);
154   mobile_flow->gtp_per_flow_metrics = gtp_per_flow_metrics;
155   mobile_flow->ip_protocol_type = strdup(ip_protocol_type);
156   mobile_flow->ip_version = strdup(ip_version);
157   mobile_flow->other_endpoint_ip_address = strdup(other_endpoint_ip_address);
158   mobile_flow->other_endpoint_port = other_endpoint_port;
159   mobile_flow->reporting_endpoint_ip_addr = strdup(reporting_endpoint_ip_addr);
160   mobile_flow->reporting_endpoint_port = reporting_endpoint_port;
161   evel_init_option_string(&mobile_flow->application_type);
162   evel_init_option_string(&mobile_flow->app_protocol_type);
163   evel_init_option_string(&mobile_flow->app_protocol_version);
164   evel_init_option_string(&mobile_flow->cid);
165   evel_init_option_string(&mobile_flow->connection_type);
166   evel_init_option_string(&mobile_flow->ecgi);
167   evel_init_option_string(&mobile_flow->gtp_protocol_type);
168   evel_init_option_string(&mobile_flow->gtp_version);
169   evel_init_option_string(&mobile_flow->http_header);
170   evel_init_option_string(&mobile_flow->imei);
171   evel_init_option_string(&mobile_flow->imsi);
172   evel_init_option_string(&mobile_flow->lac);
173   evel_init_option_string(&mobile_flow->mcc);
174   evel_init_option_string(&mobile_flow->mnc);
175   evel_init_option_string(&mobile_flow->msisdn);
176   evel_init_option_string(&mobile_flow->other_functional_role);
177   evel_init_option_string(&mobile_flow->rac);
178   evel_init_option_string(&mobile_flow->radio_access_technology);
179   evel_init_option_string(&mobile_flow->sac);
180   evel_init_option_int(&mobile_flow->sampling_algorithm);
181   evel_init_option_string(&mobile_flow->tac);
182   evel_init_option_string(&mobile_flow->tunnel_id);
183   evel_init_option_string(&mobile_flow->vlan_id);
184
185 exit_label:
186   EVEL_EXIT();
187   return mobile_flow;
188 }
189
190 /**************************************************************************//**
191  * Set the Event Type property of the Mobile Flow.
192  *
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.
196  *
197  * @param mobile_flow Pointer to the Mobile Flow.
198  * @param type        The Event Type to be set. ASCIIZ string. The caller
199  *                    does not need to preserve the value once the function
200  *                    returns.
201  *****************************************************************************/
202 void evel_mobile_flow_type_set(EVENT_MOBILE_FLOW * mobile_flow,
203                                const char * const type)
204 {
205   EVEL_ENTER();
206
207   /***************************************************************************/
208   /* Check preconditions and call evel_header_type_set.                      */
209   /***************************************************************************/
210   assert(mobile_flow != NULL);
211   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
212   evel_header_type_set(&mobile_flow->header, type);
213
214   EVEL_EXIT();
215 }
216
217 /**************************************************************************//**
218  * Set the Application Type property of the Mobile Flow.
219  *
220  * @note  The property is treated as immutable: it is only valid to call
221  *        the setter once.  However, we don't assert if the caller tries to
222  *        overwrite, just ignoring the update instead.
223  *
224  * @param mobile_flow Pointer to the Mobile Flow.
225  * @param type        The Application Type to be set. ASCIIZ string. The caller
226  *                    does not need to preserve the value once the function
227  *                    returns.
228  *****************************************************************************/
229 void evel_mobile_flow_app_type_set(EVENT_MOBILE_FLOW * mobile_flow,
230                                    const char * const type)
231 {
232   EVEL_ENTER();
233
234   /***************************************************************************/
235   /* Check preconditions.                                                    */
236   /***************************************************************************/
237   assert(mobile_flow != NULL);
238   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
239   assert(type != NULL);
240
241   evel_set_option_string(&mobile_flow->application_type,
242                          type,
243                          "Application Type");
244   EVEL_EXIT();
245 }
246
247 /**************************************************************************//**
248  * Set the Application Protocol Type property of the Mobile Flow.
249  *
250  * @note  The property is treated as immutable: it is only valid to call
251  *        the setter once.  However, we don't assert if the caller tries to
252  *        overwrite, just ignoring the update instead.
253  *
254  * @param mobile_flow Pointer to the Mobile Flow.
255  * @param type        The Application Protocol Type to be set. ASCIIZ string.
256  *                    The caller does not need to preserve the value once the
257  *                    function returns.
258  *****************************************************************************/
259 void evel_mobile_flow_app_prot_type_set(EVENT_MOBILE_FLOW * mobile_flow,
260                                         const char * const type)
261 {
262   EVEL_ENTER();
263
264   /***************************************************************************/
265   /* Check preconditions.                                                    */
266   /***************************************************************************/
267   assert(mobile_flow != NULL);
268   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
269   assert(type != NULL);
270
271   evel_set_option_string(&mobile_flow->app_protocol_type,
272                          type,
273                          "Application Protocol Type");
274   EVEL_EXIT();
275 }
276
277 /**************************************************************************//**
278  * Set the Application Protocol Version property of the Mobile Flow.
279  *
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.
283  *
284  * @param mobile_flow Pointer to the Mobile Flow.
285  * @param version     The Application Protocol Version to be set. ASCIIZ
286  *                    string.  The caller does not need to preserve the value
287  *                    once the function returns.
288  *****************************************************************************/
289 void evel_mobile_flow_app_prot_ver_set(EVENT_MOBILE_FLOW * mobile_flow,
290                                        const char * const version)
291 {
292   EVEL_ENTER();
293
294   /***************************************************************************/
295   /* Check preconditions.                                                    */
296   /***************************************************************************/
297   assert(mobile_flow != NULL);
298   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
299   assert(version != NULL);
300
301   evel_set_option_string(&mobile_flow->app_protocol_version,
302                          version,
303                          "Application Protocol Version");
304   EVEL_EXIT();
305 }
306
307 /**************************************************************************//**
308  * Set the CID property of the Mobile Flow.
309  *
310  * @note  The property is treated as immutable: it is only valid to call
311  *        the setter once.  However, we don't assert if the caller tries to
312  *        overwrite, just ignoring the update instead.
313  *
314  * @param mobile_flow Pointer to the Mobile Flow.
315  * @param cid         The CID to be set. ASCIIZ string.  The caller does not
316  *                    need to preserve the value once the function returns.
317  *****************************************************************************/
318 void evel_mobile_flow_cid_set(EVENT_MOBILE_FLOW * mobile_flow,
319                               const char * const cid)
320 {
321   EVEL_ENTER();
322
323   /***************************************************************************/
324   /* Check preconditions.                                                    */
325   /***************************************************************************/
326   assert(mobile_flow != NULL);
327   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
328   assert(cid != NULL);
329
330   evel_set_option_string(&mobile_flow->cid,
331                          cid,
332                          "CID");
333   EVEL_EXIT();
334 }
335
336 /**************************************************************************//**
337  * Set the Connection Type property of the Mobile Flow.
338  *
339  * @note  The property is treated as immutable: it is only valid to call
340  *        the setter once.  However, we don't assert if the caller tries to
341  *        overwrite, just ignoring the update instead.
342  *
343  * @param mobile_flow Pointer to the Mobile Flow.
344  * @param type        The Connection Type to be set. ASCIIZ string. The caller
345  *                    does not need to preserve the value once the function
346  *                    returns.
347  *****************************************************************************/
348 void evel_mobile_flow_con_type_set(EVENT_MOBILE_FLOW * mobile_flow,
349                                    const char * const type)
350 {
351   EVEL_ENTER();
352
353   /***************************************************************************/
354   /* Check preconditions.                                                    */
355   /***************************************************************************/
356   assert(mobile_flow != NULL);
357   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
358   assert(type != NULL);
359
360   evel_set_option_string(&mobile_flow->connection_type,
361                          type,
362                          "Connection Type");
363   EVEL_EXIT();
364 }
365
366 /**************************************************************************//**
367  * Set the ECGI property of the Mobile Flow.
368  *
369  * @note  The property is treated as immutable: it is only valid to call
370  *        the setter once.  However, we don't assert if the caller tries to
371  *        overwrite, just ignoring the update instead.
372  *
373  * @param mobile_flow Pointer to the Mobile Flow.
374  * @param ecgi        The ECGI to be set. ASCIIZ string.  The caller does not
375  *                    need to preserve the value once the function returns.
376  *****************************************************************************/
377 void evel_mobile_flow_ecgi_set(EVENT_MOBILE_FLOW * mobile_flow,
378                                const char * const ecgi)
379 {
380   EVEL_ENTER();
381
382   /***************************************************************************/
383   /* Check preconditions.                                                    */
384   /***************************************************************************/
385   assert(mobile_flow != NULL);
386   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
387   assert(ecgi != NULL);
388
389   evel_set_option_string(&mobile_flow->ecgi,
390                          ecgi,
391                          "ECGI");
392   EVEL_EXIT();
393 }
394
395 /**************************************************************************//**
396  * Set the GTP Protocol Type property of the Mobile Flow.
397  *
398  * @note  The property is treated as immutable: it is only valid to call
399  *        the setter once.  However, we don't assert if the caller tries to
400  *        overwrite, just ignoring the update instead.
401  *
402  * @param mobile_flow Pointer to the Mobile Flow.
403  * @param type        The GTP Protocol Type to be set. ASCIIZ string.  The
404  *                    caller does not need to preserve the value once the
405  *                    function returns.
406  *****************************************************************************/
407 void evel_mobile_flow_gtp_prot_type_set(EVENT_MOBILE_FLOW * mobile_flow,
408                                         const char * const type)
409 {
410   EVEL_ENTER();
411
412   /***************************************************************************/
413   /* Check preconditions.                                                    */
414   /***************************************************************************/
415   assert(mobile_flow != NULL);
416   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
417   assert(type != NULL);
418
419   evel_set_option_string(&mobile_flow->gtp_protocol_type,
420                          type,
421                          "GTP Protocol Type");
422   EVEL_EXIT();
423 }
424
425 /**************************************************************************//**
426  * Set the GTP Protocol Version property of the Mobile Flow.
427  *
428  * @note  The property is treated as immutable: it is only valid to call
429  *        the setter once.  However, we don't assert if the caller tries to
430  *        overwrite, just ignoring the update instead.
431  *
432  * @param mobile_flow Pointer to the Mobile Flow.
433  * @param version     The GTP Protocol Version to be set. ASCIIZ string.  The
434  *                    caller does not need to preserve the value once the
435  *                    function returns.
436  *****************************************************************************/
437 void evel_mobile_flow_gtp_prot_ver_set(EVENT_MOBILE_FLOW * mobile_flow,
438                                        const char * const version)
439 {
440   EVEL_ENTER();
441
442   /***************************************************************************/
443   /* Check preconditions.                                                    */
444   /***************************************************************************/
445   assert(mobile_flow != NULL);
446   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
447   assert(version != NULL);
448
449   evel_set_option_string(&mobile_flow->gtp_version,
450                          version,
451                          "GTP Protocol Version");
452   EVEL_EXIT();
453 }
454
455 /**************************************************************************//**
456  * Set the HTTP Header property of the Mobile Flow.
457  *
458  * @note  The property is treated as immutable: it is only valid to call
459  *        the setter once.  However, we don't assert if the caller tries to
460  *        overwrite, just ignoring the update instead.
461  *
462  * @param mobile_flow Pointer to the Mobile Flow.
463  * @param header      The HTTP header to be set. ASCIIZ string. The caller does
464  *                    not need to preserve the value once the function returns.
465  *****************************************************************************/
466 void evel_mobile_flow_http_header_set(EVENT_MOBILE_FLOW * mobile_flow,
467                                       const char * const header)
468 {
469   EVEL_ENTER();
470
471   /***************************************************************************/
472   /* Check preconditions.                                                    */
473   /***************************************************************************/
474   assert(mobile_flow != NULL);
475   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
476   assert(header != NULL);
477
478   evel_set_option_string(&mobile_flow->http_header,
479                          header,
480                          "HTTP Header");
481   EVEL_EXIT();
482 }
483
484 /**************************************************************************//**
485  * Set the IMEI property of the Mobile Flow.
486  *
487  * @note  The property is treated as immutable: it is only valid to call
488  *        the setter once.  However, we don't assert if the caller tries to
489  *        overwrite, just ignoring the update instead.
490  *
491  * @param mobile_flow Pointer to the Mobile Flow.
492  * @param imei        The IMEI to be set. ASCIIZ string.  The caller does not
493  *                    need to preserve the value once the function returns.
494  *****************************************************************************/
495 void evel_mobile_flow_imei_set(EVENT_MOBILE_FLOW * mobile_flow,
496                                const char * const imei)
497 {
498   EVEL_ENTER();
499
500   /***************************************************************************/
501   /* Check preconditions.                                                    */
502   /***************************************************************************/
503   assert(mobile_flow != NULL);
504   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
505   assert(imei != NULL);
506
507   evel_set_option_string(&mobile_flow->imei,
508                          imei,
509                          "IMEI");
510   EVEL_EXIT();
511 }
512
513 /**************************************************************************//**
514  * Set the IMSI property of the Mobile Flow.
515  *
516  * @note  The property is treated as immutable: it is only valid to call
517  *        the setter once.  However, we don't assert if the caller tries to
518  *        overwrite, just ignoring the update instead.
519  *
520  * @param mobile_flow Pointer to the Mobile Flow.
521  * @param imsi        The IMSI to be set. ASCIIZ string.  The caller does not
522  *                    need to preserve the value once the function returns.
523  *****************************************************************************/
524 void evel_mobile_flow_imsi_set(EVENT_MOBILE_FLOW * mobile_flow,
525                                const char * const imsi)
526 {
527   EVEL_ENTER();
528
529   /***************************************************************************/
530   /* Check preconditions.                                                    */
531   /***************************************************************************/
532   assert(mobile_flow != NULL);
533   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
534   assert(imsi != NULL);
535
536   evel_set_option_string(&mobile_flow->imsi,
537                          imsi,
538                          "IMSI");
539   EVEL_EXIT();
540 }
541
542 /**************************************************************************//**
543  * Set the LAC property of the Mobile Flow.
544  *
545  * @note  The property is treated as immutable: it is only valid to call
546  *        the setter once.  However, we don't assert if the caller tries to
547  *        overwrite, just ignoring the update instead.
548  *
549  * @param mobile_flow Pointer to the Mobile Flow.
550  * @param lac         The LAC to be set. ASCIIZ string.  The caller does not
551  *                    need to preserve the value once the function returns.
552  *****************************************************************************/
553 void evel_mobile_flow_lac_set(EVENT_MOBILE_FLOW * mobile_flow,
554                               const char * const lac)
555 {
556   EVEL_ENTER();
557
558   /***************************************************************************/
559   /* Check preconditions.                                                    */
560   /***************************************************************************/
561   assert(mobile_flow != NULL);
562   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
563   assert(lac != NULL);
564
565   evel_set_option_string(&mobile_flow->lac,
566                          lac,
567                          "LAC");
568   EVEL_EXIT();
569 }
570
571 /**************************************************************************//**
572  * Set the MCC property of the Mobile Flow.
573  *
574  * @note  The property is treated as immutable: it is only valid to call
575  *        the setter once.  However, we don't assert if the caller tries to
576  *        overwrite, just ignoring the update instead.
577  *
578  * @param mobile_flow Pointer to the Mobile Flow.
579  * @param mcc         The MCC to be set. ASCIIZ string.  The caller does not
580  *                    need to preserve the value once the function returns.
581  *****************************************************************************/
582 void evel_mobile_flow_mcc_set(EVENT_MOBILE_FLOW * mobile_flow,
583                               const char * const mcc)
584 {
585   EVEL_ENTER();
586
587   /***************************************************************************/
588   /* Check preconditions.                                                    */
589   /***************************************************************************/
590   assert(mobile_flow != NULL);
591   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
592   assert(mcc != NULL);
593
594   evel_set_option_string(&mobile_flow->mcc,
595                          mcc,
596                          "MCC");
597   EVEL_EXIT();
598 }
599
600 /**************************************************************************//**
601  * Set the MNC property of the Mobile Flow.
602  *
603  * @note  The property is treated as immutable: it is only valid to call
604  *        the setter once.  However, we don't assert if the caller tries to
605  *        overwrite, just ignoring the update instead.
606  *
607  * @param mobile_flow Pointer to the Mobile Flow.
608  * @param mnc         The MNC to be set. ASCIIZ string.  The caller does not
609  *                    need to preserve the value once the function returns.
610  *****************************************************************************/
611 void evel_mobile_flow_mnc_set(EVENT_MOBILE_FLOW * mobile_flow,
612                               const char * const mnc)
613 {
614   EVEL_ENTER();
615
616   /***************************************************************************/
617   /* Check preconditions.                                                    */
618   /***************************************************************************/
619   assert(mobile_flow != NULL);
620   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
621   assert(mnc != NULL);
622
623   evel_set_option_string(&mobile_flow->mnc,
624                          mnc,
625                          "MNC");
626   EVEL_EXIT();
627 }
628
629 /**************************************************************************//**
630  * Set the MSISDN property of the Mobile Flow.
631  *
632  * @note  The property is treated as immutable: it is only valid to call
633  *        the setter once.  However, we don't assert if the caller tries to
634  *        overwrite, just ignoring the update instead.
635  *
636  * @param mobile_flow Pointer to the Mobile Flow.
637  * @param msisdn      The MSISDN to be set. ASCIIZ string.  The caller does not
638  *                    need to preserve the value once the function returns.
639  *****************************************************************************/
640 void evel_mobile_flow_msisdn_set(EVENT_MOBILE_FLOW * mobile_flow,
641                                  const char * const msisdn)
642 {
643   EVEL_ENTER();
644
645   /***************************************************************************/
646   /* Check preconditions.                                                    */
647   /***************************************************************************/
648   assert(mobile_flow != NULL);
649   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
650   assert(msisdn != NULL);
651
652   evel_set_option_string(&mobile_flow->msisdn,
653                          msisdn,
654                          "MSISDN");
655   EVEL_EXIT();
656 }
657
658 /**************************************************************************//**
659  * Set the Other Functional Role property of the Mobile Flow.
660  *
661  * @note  The property is treated as immutable: it is only valid to call
662  *        the setter once.  However, we don't assert if the caller tries to
663  *        overwrite, just ignoring the update instead.
664  *
665  * @param mobile_flow Pointer to the Mobile Flow.
666  * @param role        The Other Functional Role to be set. ASCIIZ string. The
667  *                    caller does not need to preserve the value once the
668  *                    function returns.
669  *****************************************************************************/
670 void evel_mobile_flow_other_func_role_set(EVENT_MOBILE_FLOW * mobile_flow,
671                                           const char * const role)
672 {
673   EVEL_ENTER();
674
675   /***************************************************************************/
676   /* Check preconditions.                                                    */
677   /***************************************************************************/
678   assert(mobile_flow != NULL);
679   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
680   assert(role != NULL);
681
682   evel_set_option_string(&mobile_flow->other_functional_role,
683                          role,
684                          "Other Functional Role");
685   EVEL_EXIT();
686 }
687
688 /**************************************************************************//**
689  * Set the RAC property of the Mobile Flow.
690  *
691  * @note  The property is treated as immutable: it is only valid to call
692  *        the setter once.  However, we don't assert if the caller tries to
693  *        overwrite, just ignoring the update instead.
694  *
695  * @param mobile_flow Pointer to the Mobile Flow.
696  * @param rac         The RAC to be set. ASCIIZ string.  The caller does not
697  *                    need to preserve the value once the function returns.
698  *****************************************************************************/
699 void evel_mobile_flow_rac_set(EVENT_MOBILE_FLOW * mobile_flow,
700                               const char * const rac)
701 {
702   EVEL_ENTER();
703
704   /***************************************************************************/
705   /* Check preconditions.                                                    */
706   /***************************************************************************/
707   assert(mobile_flow != NULL);
708   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
709   assert(rac != NULL);
710
711   evel_set_option_string(&mobile_flow->rac,
712                          rac,
713                          "RAC");
714   EVEL_EXIT();
715 }
716
717 /**************************************************************************//**
718  * Set the Radio Access Technology property of the Mobile Flow.
719  *
720  * @note  The property is treated as immutable: it is only valid to call
721  *        the setter once.  However, we don't assert if the caller tries to
722  *        overwrite, just ignoring the update instead.
723  *
724  * @param mobile_flow Pointer to the Mobile Flow.
725  * @param tech        The Radio Access Technology to be set. ASCIIZ string. The
726  *                    caller does not need to preserve the value once the
727  *                    function returns.
728  *****************************************************************************/
729 void evel_mobile_flow_radio_acc_tech_set(EVENT_MOBILE_FLOW * mobile_flow,
730                                          const char * const tech)
731 {
732   EVEL_ENTER();
733
734   /***************************************************************************/
735   /* Check preconditions.                                                    */
736   /***************************************************************************/
737   assert(mobile_flow != NULL);
738   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
739   assert(tech != NULL);
740
741   evel_set_option_string(&mobile_flow->radio_access_technology,
742                          tech,
743                          "Radio Access Technology");
744   EVEL_EXIT();
745 }
746
747 /**************************************************************************//**
748  * Set the SAC property of the Mobile Flow.
749  *
750  * @note  The property is treated as immutable: it is only valid to call
751  *        the setter once.  However, we don't assert if the caller tries to
752  *        overwrite, just ignoring the update instead.
753  *
754  * @param mobile_flow Pointer to the Mobile Flow.
755  * @param sac         The SAC to be set. ASCIIZ string.  The caller does not
756  *                    need to preserve the value once the function returns.
757  *****************************************************************************/
758 void evel_mobile_flow_sac_set(EVENT_MOBILE_FLOW * mobile_flow,
759                               const char * const sac)
760 {
761   EVEL_ENTER();
762
763   /***************************************************************************/
764   /* Check preconditions.                                                    */
765   /***************************************************************************/
766   assert(mobile_flow != NULL);
767   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
768   assert(sac != NULL);
769
770   evel_set_option_string(&mobile_flow->sac,
771                          sac,
772                          "SAC");
773   EVEL_EXIT();
774 }
775
776 /**************************************************************************//**
777  * Set the Sampling Algorithm property of the Mobile Flow.
778  *
779  * @note  The property is treated as immutable: it is only valid to call
780  *        the setter once.  However, we don't assert if the caller tries to
781  *        overwrite, just ignoring the update instead.
782  *
783  * @param mobile_flow Pointer to the Mobile Flow.
784  * @param algorithm   The Sampling Algorithm to be set.
785  *****************************************************************************/
786 void evel_mobile_flow_samp_alg_set(EVENT_MOBILE_FLOW * mobile_flow,
787                                    int algorithm)
788 {
789   EVEL_ENTER();
790
791   /***************************************************************************/
792   /* Check preconditions.                                                    */
793   /***************************************************************************/
794   assert(mobile_flow != NULL);
795   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
796   assert(algorithm >= 0);
797
798   evel_set_option_int(&mobile_flow->sampling_algorithm,
799                       algorithm,
800                       "Sampling Algorithm");
801   EVEL_EXIT();
802 }
803
804 /**************************************************************************//**
805  * Set the TAC property of the Mobile Flow.
806  *
807  * @note  The property is treated as immutable: it is only valid to call
808  *        the setter once.  However, we don't assert if the caller tries to
809  *        overwrite, just ignoring the update instead.
810  *
811  * @param mobile_flow Pointer to the Mobile Flow.
812  * @param tac         The TAC to be set. ASCIIZ string.  The caller does not
813  *                    need to preserve the value once the function returns.
814  *****************************************************************************/
815 void evel_mobile_flow_tac_set(EVENT_MOBILE_FLOW * mobile_flow,
816                               const char * const tac)
817 {
818   EVEL_ENTER();
819
820   /***************************************************************************/
821   /* Check preconditions.                                                    */
822   /***************************************************************************/
823   assert(mobile_flow != NULL);
824   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
825   assert(tac != NULL);
826
827   evel_set_option_string(&mobile_flow->tac,
828                          tac,
829                          "TAC");
830   EVEL_EXIT();
831 }
832
833 /**************************************************************************//**
834  * Set the Tunnel ID property of the Mobile Flow.
835  *
836  * @note  The property is treated as immutable: it is only valid to call
837  *        the setter once.  However, we don't assert if the caller tries to
838  *        overwrite, just ignoring the update instead.
839  *
840  * @param mobile_flow Pointer to the Mobile Flow.
841  * @param tunnel_id   The Tunnel ID to be set. ASCIIZ string.  The caller does
842  *                    not need to preserve the value once the function returns.
843  *****************************************************************************/
844 void evel_mobile_flow_tunnel_id_set(EVENT_MOBILE_FLOW * mobile_flow,
845                                     const char * const tunnel_id)
846 {
847   EVEL_ENTER();
848
849   /***************************************************************************/
850   /* Check preconditions.                                                    */
851   /***************************************************************************/
852   assert(mobile_flow != NULL);
853   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
854   assert(tunnel_id != NULL);
855
856   evel_set_option_string(&mobile_flow->tunnel_id,
857                          tunnel_id,
858                          "Tunnel ID");
859   EVEL_EXIT();
860 }
861
862 /**************************************************************************//**
863  * Set the VLAN ID property of the Mobile Flow.
864  *
865  * @note  The property is treated as immutable: it is only valid to call
866  *        the setter once.  However, we don't assert if the caller tries to
867  *        overwrite, just ignoring the update instead.
868  *
869  * @param mobile_flow Pointer to the Mobile Flow.
870  * @param vlan_id     The VLAN ID to be set. ASCIIZ string.  The caller does
871  *                    not need to preserve the value once the function returns.
872  *****************************************************************************/
873 void evel_mobile_flow_vlan_id_set(EVENT_MOBILE_FLOW * mobile_flow,
874                                   const char * const vlan_id)
875 {
876   EVEL_ENTER();
877
878   /***************************************************************************/
879   /* Check preconditions.                                                    */
880   /***************************************************************************/
881   assert(mobile_flow != NULL);
882   assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
883   assert(vlan_id != NULL);
884
885   evel_set_option_string(&mobile_flow->vlan_id,
886                          vlan_id,
887                          "VLAN ID");
888   EVEL_EXIT();
889 }
890
891 /**************************************************************************//**
892  * Encode the Mobile Flow in JSON according to AT&T's schema for the event
893  * type.
894  *
895  * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
896  * @param event         Pointer to the ::EVENT_HEADER to encode.
897  *****************************************************************************/
898 void evel_json_encode_mobile_flow(EVEL_JSON_BUFFER * jbuf,
899                                   EVENT_MOBILE_FLOW * event)
900 {
901   EVEL_ENTER();
902
903   /***************************************************************************/
904   /* Check preconditions.                                                    */
905   /***************************************************************************/
906   assert(event != NULL);
907   assert(event->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
908
909   evel_json_encode_header(jbuf, &event->header);
910   evel_json_open_named_object(jbuf, "mobileFlowFields");
911
912   /***************************************************************************/
913   /* Mandatory parameters.                                                   */
914   /***************************************************************************/
915   evel_enc_kv_string(jbuf, "flowDirection", event->flow_direction);
916   evel_json_encode_mobile_flow_gtp_flow_metrics(
917     jbuf, event->gtp_per_flow_metrics);
918   evel_enc_kv_string(jbuf, "ipProtocolType", event->ip_protocol_type);
919   evel_enc_kv_string(jbuf, "ipVersion", event->ip_version);
920   evel_enc_kv_string(
921     jbuf, "otherEndpointIpAddress", event->other_endpoint_ip_address);
922   evel_enc_kv_int(jbuf, "otherEndpointPort", event->other_endpoint_port);
923   evel_enc_kv_string(
924     jbuf, "reportingEndpointIpAddr", event->reporting_endpoint_ip_addr);
925   evel_enc_kv_int(
926     jbuf, "reportingEndpointPort", event->reporting_endpoint_port);
927
928   /***************************************************************************/
929   /* Optional parameters.                                                    */
930   /***************************************************************************/
931   evel_enc_kv_opt_string(jbuf, "applicationType", &event->application_type);
932   evel_enc_kv_opt_string(jbuf, "appProtocolType", &event->app_protocol_type);
933   evel_enc_kv_opt_string(
934     jbuf, "appProtocolVersion", &event->app_protocol_version);
935   evel_enc_kv_opt_string(jbuf, "cid", &event->cid);
936   evel_enc_kv_opt_string(jbuf, "connectionType", &event->connection_type);
937   evel_enc_kv_opt_string(jbuf, "ecgi", &event->ecgi);
938   evel_enc_kv_opt_string(jbuf, "gtpProtocolType", &event->gtp_protocol_type);
939   evel_enc_kv_opt_string(jbuf, "gtpVersion", &event->gtp_version);
940   evel_enc_kv_opt_string(jbuf, "httpHeader", &event->http_header);
941   evel_enc_kv_opt_string(jbuf, "imei", &event->imei);
942   evel_enc_kv_opt_string(jbuf, "imsi", &event->imsi);
943   evel_enc_kv_opt_string(jbuf, "lac", &event->lac);
944   evel_enc_kv_opt_string(jbuf, "mcc", &event->mcc);
945   evel_enc_kv_opt_string(jbuf, "mnc", &event->mnc);
946   evel_enc_kv_opt_string(jbuf, "msisdn", &event->msisdn);
947   evel_enc_kv_opt_string(
948     jbuf, "otherFunctionalRole", &event->other_functional_role);
949   evel_enc_kv_opt_string(jbuf, "rac", &event->rac);
950   evel_enc_kv_opt_string(
951     jbuf, "radioAccessTechnology", &event->radio_access_technology);
952   evel_enc_kv_opt_string(jbuf, "sac", &event->sac);
953   evel_enc_kv_opt_int(jbuf, "samplingAlgorithm", &event->sampling_algorithm);
954   evel_enc_kv_opt_string(jbuf, "tac", &event->tac);
955   evel_enc_kv_opt_string(jbuf, "tunnelId", &event->tunnel_id);
956   evel_enc_kv_opt_string(jbuf, "vlanId", &event->vlan_id);
957 #if 0
958   /***************************************************************************/
959   /* Not in schema.                                                          */
960   /***************************************************************************/
961   evel_enc_version(jbuf,
962                    "mobileFlowFieldsVersion",
963                    event->major_version,
964                    event->minor_version);
965 #endif
966   evel_json_close_object(jbuf);
967
968   EVEL_EXIT();
969 }
970
971 /**************************************************************************//**
972  * Free a Mobile Flow.
973  *
974  * Free off the Mobile Flow supplied.  Will free all the contained allocated
975  * memory.
976  *
977  * @note It does not free the Mobile Flow itself, since that may be part of a
978  * larger structure.
979  *****************************************************************************/
980 void evel_free_mobile_flow(EVENT_MOBILE_FLOW * event)
981 {
982   EVEL_ENTER();
983
984   /***************************************************************************/
985   /* Check preconditions.  As an internal API we don't allow freeing NULL    */
986   /* events as we do on the public API.                                      */
987   /***************************************************************************/
988   assert(event != NULL);
989   assert(event->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
990
991   /***************************************************************************/
992   /* Free all internal strings then the header itself.                       */
993   /***************************************************************************/
994   free(event->flow_direction);
995
996   evel_free_mobile_gtp_flow_metrics(event->gtp_per_flow_metrics);
997   free(event->gtp_per_flow_metrics);
998   free(event->ip_protocol_type);
999   free(event->ip_version);
1000   free(event->other_endpoint_ip_address);
1001   free(event->reporting_endpoint_ip_addr);
1002   evel_free_option_string(&event->application_type);
1003   evel_free_option_string(&event->app_protocol_type);
1004   evel_free_option_string(&event->app_protocol_version);
1005   evel_free_option_string(&event->cid);
1006   evel_free_option_string(&event->connection_type);
1007   evel_free_option_string(&event->ecgi);
1008   evel_free_option_string(&event->gtp_protocol_type);
1009   evel_free_option_string(&event->gtp_version);
1010   evel_free_option_string(&event->http_header);
1011   evel_free_option_string(&event->imei);
1012   evel_free_option_string(&event->imsi);
1013   evel_free_option_string(&event->lac);
1014   evel_free_option_string(&event->mcc);
1015   evel_free_option_string(&event->mnc);
1016   evel_free_option_string(&event->msisdn);
1017   evel_free_option_string(&event->other_functional_role);
1018   evel_free_option_string(&event->rac);
1019   evel_free_option_string(&event->radio_access_technology);
1020   evel_free_option_string(&event->sac);
1021   evel_free_option_string(&event->tac);
1022   evel_free_option_string(&event->tunnel_id);
1023   evel_free_option_string(&event->vlan_id);
1024
1025   evel_free_header(&event->header);
1026
1027   EVEL_EXIT();
1028 }
1029
1030 /**************************************************************************//**
1031  * Create a new Mobile GTP Per Flow Metrics.
1032  *
1033  * @note    The mandatory fields on the Mobile GTP Per Flow Metrics must be
1034  *          supplied to this factory function and are immutable once set.
1035  *          Optional fields have explicit setter functions, but again values
1036  *          may only be set once so that the Mobile GTP Per Flow Metrics has
1037  *          immutable properties.
1038  *
1039  * @param   avg_bit_error_rate          Average bit error rate.
1040  * @param   avg_packet_delay_variation  Average delay or jitter in ms.
1041  * @param   avg_packet_latency          Average delivery latency.
1042  * @param   avg_receive_throughput      Average receive throughput.
1043  * @param   avg_transmit_throughput     Average transmit throughput.
1044  * @param   flow_activation_epoch       Time the connection is activated.
1045  * @param   flow_activation_microsec    Microseconds for the start of the flow
1046  *                                      connection.
1047  * @param   flow_deactivation_epoch     Time for the end of the connection.
1048  * @param   flow_deactivation_microsec  Microseconds for the end of the flow
1049  *                                      connection.
1050  * @param   flow_deactivation_time      Transmission time of the first packet.
1051  * @param   flow_status                 Connection status.
1052  * @param   max_packet_delay_variation  Maximum packet delay or jitter in ms.
1053  * @param   num_activation_failures     Number of failed activation requests.
1054  * @param   num_bit_errors              Number of errored bits.
1055  * @param   num_bytes_received          Number of bytes received.
1056  * @param   num_bytes_transmitted       Number of bytes transmitted.
1057  * @param   num_dropped_packets         Number of received packets dropped.
1058  * @param   num_l7_bytes_received       Number of tunneled Layer 7 bytes
1059  *                                      received.
1060  * @param   num_l7_bytes_transmitted    Number of tunneled Layer 7 bytes
1061  *                                      transmitted.
1062  * @param   num_lost_packets            Number of lost packets.
1063  * @param   num_out_of_order_packets    Number of out-of-order packets.
1064  * @param   num_packet_errors           Number of errored packets.
1065  * @param   num_packets_received_excl_retrans  Number of packets received,
1066  *                                             excluding retransmits.
1067  * @param   num_packets_received_incl_retrans  Number of packets received.
1068  * @param   num_packets_transmitted_incl_retrans  Number of packets
1069  *                                                transmitted.
1070  * @param   num_retries                 Number of packet retries.
1071  * @param   num_timeouts                Number of packet timeouts.
1072  * @param   num_tunneled_l7_bytes_received  Number of tunneled Layer 7 bytes
1073  *                                          received, excluding retransmits.
1074  * @param   round_trip_time             Round trip time.
1075  * @param   time_to_first_byte          Time in ms between connection
1076  *                                      activation and first byte received.
1077  *
1078  * @returns pointer to the newly manufactured ::MOBILE_GTP_PER_FLOW_METRICS.
1079  *          If the structure is not used it must be released using
1080  *          ::evel_free_mobile_gtp_flow_metrics.
1081  * @retval  NULL  Failed to create the event.
1082  *****************************************************************************/
1083 MOBILE_GTP_PER_FLOW_METRICS * evel_new_mobile_gtp_flow_metrics(
1084                                       double avg_bit_error_rate,
1085                                       double avg_packet_delay_variation,
1086                                       int avg_packet_latency,
1087                                       int avg_receive_throughput,
1088                                       int avg_transmit_throughput,
1089                                       int flow_activation_epoch,
1090                                       int flow_activation_microsec,
1091                                       int flow_deactivation_epoch,
1092                                       int flow_deactivation_microsec,
1093                                       time_t flow_deactivation_time,
1094                                       const char * const flow_status,
1095                                       int max_packet_delay_variation,
1096                                       int num_activation_failures,
1097                                       int num_bit_errors,
1098                                       int num_bytes_received,
1099                                       int num_bytes_transmitted,
1100                                       int num_dropped_packets,
1101                                       int num_l7_bytes_received,
1102                                       int num_l7_bytes_transmitted,
1103                                       int num_lost_packets,
1104                                       int num_out_of_order_packets,
1105                                       int num_packet_errors,
1106                                       int num_packets_received_excl_retrans,
1107                                       int num_packets_received_incl_retrans,
1108                                       int num_packets_transmitted_incl_retrans,
1109                                       int num_retries,
1110                                       int num_timeouts,
1111                                       int num_tunneled_l7_bytes_received,
1112                                       int round_trip_time,
1113                                       int time_to_first_byte)
1114 {
1115   MOBILE_GTP_PER_FLOW_METRICS * metrics = NULL;
1116   int ii;
1117
1118   EVEL_ENTER();
1119
1120   /***************************************************************************/
1121   /* Check preconditions.                                                    */
1122   /***************************************************************************/
1123   assert(avg_bit_error_rate >= 0.0);
1124   assert(avg_packet_delay_variation >= 0.0);
1125   assert(avg_packet_latency >= 0);
1126   assert(avg_receive_throughput >= 0);
1127   assert(avg_transmit_throughput >= 0);
1128   assert(flow_activation_epoch > 0);
1129   assert(flow_activation_microsec >= 0);
1130   assert(flow_deactivation_epoch > 0);
1131   assert(flow_deactivation_microsec >= 0);
1132   assert(flow_status != NULL);
1133   assert(max_packet_delay_variation >= 0);
1134   assert(num_activation_failures >= 0);
1135   assert(num_bit_errors >= 0);
1136   assert(num_bytes_received >= 0);
1137   assert(num_bytes_transmitted >= 0);
1138   assert(num_dropped_packets >= 0);
1139   assert(num_l7_bytes_received >= 0);
1140   assert(num_l7_bytes_transmitted >= 0);
1141   assert(num_lost_packets >= 0);
1142   assert(num_out_of_order_packets >= 0);
1143   assert(num_packet_errors >= 0);
1144   assert(num_packets_received_excl_retrans >= 0);
1145   assert(num_packets_received_incl_retrans >= 0);
1146   assert(num_packets_transmitted_incl_retrans >= 0);
1147   assert(num_retries >= 0);
1148   assert(num_timeouts >= 0);
1149   assert(num_tunneled_l7_bytes_received >= 0);
1150   assert(round_trip_time >= 0);
1151   assert(time_to_first_byte >= 0);
1152
1153   /***************************************************************************/
1154   /* Allocate the Mobile Flow GTP Per Flow Metrics.                          */
1155   /***************************************************************************/
1156   metrics = malloc(sizeof(MOBILE_GTP_PER_FLOW_METRICS));
1157   if (metrics == NULL)
1158   {
1159     log_error_state("Out of memory");
1160     goto exit_label;
1161   }
1162   memset(metrics, 0, sizeof(MOBILE_GTP_PER_FLOW_METRICS));
1163   EVEL_DEBUG("New Mobile Flow GTP Per Flow Metrics is at %lp", metrics);
1164
1165   /***************************************************************************/
1166   /* Initialize the Mobile Flow GTP Per Flow Metrics fields.  Optional       */
1167   /* string values are uninitialized (NULL).                                 */
1168   /***************************************************************************/
1169   metrics->avg_bit_error_rate = avg_bit_error_rate;
1170   metrics->avg_packet_delay_variation = avg_packet_delay_variation;
1171   metrics->avg_packet_latency = avg_packet_latency;
1172   metrics->avg_receive_throughput = avg_receive_throughput;
1173   metrics->avg_transmit_throughput = avg_transmit_throughput;
1174   metrics->flow_activation_epoch = flow_activation_epoch;
1175   metrics->flow_activation_microsec = flow_activation_microsec;
1176   metrics->flow_deactivation_epoch = flow_deactivation_epoch;
1177   metrics->flow_deactivation_microsec = flow_deactivation_microsec;
1178   metrics->flow_deactivation_time = flow_deactivation_time;
1179   metrics->flow_status = strdup(flow_status);
1180   metrics->max_packet_delay_variation = max_packet_delay_variation;
1181   metrics->num_activation_failures = num_activation_failures;
1182   metrics->num_bit_errors = num_bit_errors;
1183   metrics->num_bytes_received = num_bytes_received;
1184   metrics->num_bytes_transmitted = num_bytes_transmitted;
1185   metrics->num_dropped_packets = num_dropped_packets;
1186   metrics->num_l7_bytes_received = num_l7_bytes_received;
1187   metrics->num_l7_bytes_transmitted = num_l7_bytes_transmitted;
1188   metrics->num_lost_packets = num_lost_packets;
1189   metrics->num_out_of_order_packets = num_out_of_order_packets;
1190   metrics->num_packet_errors = num_packet_errors;
1191   metrics->num_packets_received_excl_retrans =
1192                                              num_packets_received_excl_retrans;
1193   metrics->num_packets_received_incl_retrans =
1194                                              num_packets_received_incl_retrans;
1195   metrics->num_packets_transmitted_incl_retrans =
1196                                           num_packets_transmitted_incl_retrans;
1197   metrics->num_retries = num_retries;
1198   metrics->num_timeouts = num_timeouts;
1199   metrics->num_tunneled_l7_bytes_received = num_tunneled_l7_bytes_received;
1200   metrics->round_trip_time = round_trip_time;
1201   metrics->time_to_first_byte = time_to_first_byte;
1202   for (ii = 0; ii < EVEL_TOS_SUPPORTED; ii++)
1203   {
1204     evel_init_option_int(&metrics->ip_tos_counts[ii]);
1205   }
1206   for (ii = 0; ii < EVEL_MAX_TCP_FLAGS; ii++)
1207   {
1208     evel_init_option_int(&metrics->tcp_flag_counts[ii]);
1209   }
1210   for (ii = 0; ii < EVEL_MAX_QCI_COS_TYPES; ii++)
1211   {
1212     evel_init_option_int(&metrics->qci_cos_counts[ii]);
1213   }
1214   evel_init_option_int(&metrics->dur_connection_failed_status);
1215   evel_init_option_int(&metrics->dur_tunnel_failed_status);
1216   evel_init_option_string(&metrics->flow_activated_by);
1217   evel_init_option_time(&metrics->flow_activation_time);
1218   evel_init_option_string(&metrics->flow_deactivated_by);
1219   evel_init_option_string(&metrics->gtp_connection_status);
1220   evel_init_option_string(&metrics->gtp_tunnel_status);
1221   evel_init_option_int(&metrics->large_packet_rtt);
1222   evel_init_option_double(&metrics->large_packet_threshold);
1223   evel_init_option_int(&metrics->max_receive_bit_rate);
1224   evel_init_option_int(&metrics->max_transmit_bit_rate);
1225   evel_init_option_int(&metrics->num_gtp_echo_failures);
1226   evel_init_option_int(&metrics->num_gtp_tunnel_errors);
1227   evel_init_option_int(&metrics->num_http_errors);
1228
1229 exit_label:
1230   EVEL_EXIT();
1231   return metrics;
1232 }
1233
1234 /**************************************************************************//**
1235  * Set the Duration of Connection Failed Status property of the Mobile GTP Per
1236  * Flow Metrics.
1237  *
1238  * @note  The property is treated as immutable: it is only valid to call
1239  *        the setter once.  However, we don't assert if the caller tries to
1240  *        overwrite, just ignoring the update instead.
1241  *
1242  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1243  * @param duration    The Duration of Connection Failed Status to be set.
1244  *****************************************************************************/
1245 void evel_mobile_gtp_metrics_dur_con_fail_set(
1246                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1247                                          int duration)
1248 {
1249   EVEL_ENTER();
1250
1251   /***************************************************************************/
1252   /* Check preconditions.                                                    */
1253   /***************************************************************************/
1254   assert(metrics != NULL);
1255   assert(duration >= 0);
1256
1257   evel_set_option_int(&metrics->dur_connection_failed_status,
1258                       duration,
1259                       "Duration of Connection Failed Status");
1260   EVEL_EXIT();
1261 }
1262
1263 /**************************************************************************//**
1264  * Set the Duration of Tunnel Failed Status property of the Mobile GTP Per Flow
1265  * Metrics.
1266  *
1267  * @note  The property is treated as immutable: it is only valid to call
1268  *        the setter once.  However, we don't assert if the caller tries to
1269  *        overwrite, just ignoring the update instead.
1270  *
1271  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1272  * @param duration    The Duration of Tunnel Failed Status to be set.
1273  *****************************************************************************/
1274 void evel_mobile_gtp_metrics_dur_tun_fail_set(
1275                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1276                                          int duration)
1277 {
1278   EVEL_ENTER();
1279
1280   /***************************************************************************/
1281   /* Check preconditions.                                                    */
1282   /***************************************************************************/
1283   assert(metrics != NULL);
1284   assert(duration >= 0);
1285
1286   evel_set_option_int(&metrics->dur_tunnel_failed_status,
1287                       duration,
1288                       "Duration of Tunnel Failed Status");
1289   EVEL_EXIT();
1290 }
1291
1292 /**************************************************************************//**
1293  * Set the Activated By property of the Mobile GTP Per Flow metrics.
1294  *
1295  * @note  The property is treated as immutable: it is only valid to call
1296  *        the setter once.  However, we don't assert if the caller tries to
1297  *        overwrite, just ignoring the update instead.
1298  *
1299  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1300  * @param act_by      The Activated By to be set.  ASCIIZ string. The caller
1301  *                    does not need to preserve the value once the function
1302  *                    returns.
1303  *****************************************************************************/
1304 void evel_mobile_gtp_metrics_act_by_set(MOBILE_GTP_PER_FLOW_METRICS * metrics,
1305                                         const char * const act_by)
1306 {
1307   EVEL_ENTER();
1308
1309   /***************************************************************************/
1310   /* Check preconditions.                                                    */
1311   /***************************************************************************/
1312   assert(metrics != NULL);
1313   assert(act_by != NULL);
1314
1315   evel_set_option_string(&metrics->flow_activated_by,
1316                          act_by,
1317                          "Activated By");
1318   EVEL_EXIT();
1319 }
1320
1321 /**************************************************************************//**
1322  * Set the Activation Time property of the Mobile GTP Per Flow metrics.
1323  *
1324  * @note  The property is treated as immutable: it is only valid to call
1325  *        the setter once.  However, we don't assert if the caller tries to
1326  *        overwrite, just ignoring the update instead.
1327  *
1328  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1329  * @param act_time    The Activation Time to be set.  ASCIIZ string. The caller
1330  *                    does not need to preserve the value once the function
1331  *                    returns.
1332  *****************************************************************************/
1333 void evel_mobile_gtp_metrics_act_time_set(
1334                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1335                                          time_t act_time)
1336 {
1337   EVEL_ENTER();
1338
1339   /***************************************************************************/
1340   /* Check preconditions.                                                    */
1341   /***************************************************************************/
1342   assert(metrics != NULL);
1343   assert(act_time > 0);
1344
1345   evel_set_option_time(&metrics->flow_activation_time,
1346                        act_time,
1347                        "Activation Time");
1348   EVEL_EXIT();
1349 }
1350
1351 /**************************************************************************//**
1352  * Set the Deactivated By property of the Mobile GTP Per Flow metrics.
1353  *
1354  * @note  The property is treated as immutable: it is only valid to call
1355  *        the setter once.  However, we don't assert if the caller tries to
1356  *        overwrite, just ignoring the update instead.
1357  *
1358  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1359  * @param deact_by    The Deactivated By to be set.  ASCIIZ string. The caller
1360  *                    does not need to preserve the value once the function
1361  *                    returns.
1362  *****************************************************************************/
1363 void evel_mobile_gtp_metrics_deact_by_set(
1364                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1365                                          const char * const deact_by)
1366 {
1367   EVEL_ENTER();
1368
1369   /***************************************************************************/
1370   /* Check preconditions.                                                    */
1371   /***************************************************************************/
1372   assert(metrics != NULL);
1373   assert(deact_by != NULL);
1374
1375   evel_set_option_string(&metrics->flow_deactivated_by,
1376                          deact_by,
1377                          "Deactivated By");
1378   EVEL_EXIT();
1379 }
1380
1381 /**************************************************************************//**
1382  * Set the GTP Connection Status property of the Mobile GTP Per Flow metrics.
1383  *
1384  * @note  The property is treated as immutable: it is only valid to call
1385  *        the setter once.  However, we don't assert if the caller tries to
1386  *        overwrite, just ignoring the update instead.
1387  *
1388  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1389  * @param status      The GTP Connection Status to be set.  ASCIIZ string. The
1390  *                    caller does not need to preserve the value once the
1391  *                    function returns.
1392  *****************************************************************************/
1393 void evel_mobile_gtp_metrics_con_status_set(
1394                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1395                                          const char * const status)
1396 {
1397   EVEL_ENTER();
1398
1399   /***************************************************************************/
1400   /* Check preconditions.                                                    */
1401   /***************************************************************************/
1402   assert(metrics != NULL);
1403   assert(status != NULL);
1404
1405   evel_set_option_string(&metrics->gtp_connection_status,
1406                          status,
1407                          "GTP Connection Status");
1408   EVEL_EXIT();
1409 }
1410
1411 /**************************************************************************//**
1412  * Set the GTP Tunnel Status property of the Mobile GTP Per Flow metrics.
1413  *
1414  * @note  The property is treated as immutable: it is only valid to call
1415  *        the setter once.  However, we don't assert if the caller tries to
1416  *        overwrite, just ignoring the update instead.
1417  *
1418  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1419  * @param status      The GTP Tunnel Status to be set.  ASCIIZ string. The
1420  *                    caller does not need to preserve the value once the
1421  *                    function returns.
1422  *****************************************************************************/
1423 void evel_mobile_gtp_metrics_tun_status_set(
1424                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1425                                          const char * const status)
1426 {
1427   EVEL_ENTER();
1428
1429   /***************************************************************************/
1430   /* Check preconditions.                                                    */
1431   /***************************************************************************/
1432   assert(metrics != NULL);
1433   assert(status != NULL);
1434
1435   evel_set_option_string(&metrics->gtp_tunnel_status,
1436                          status,
1437                          "GTP Tunnel Status");
1438   EVEL_EXIT();
1439 }
1440
1441 /**************************************************************************//**
1442  * Set an IP Type-of-Service count property of the Mobile GTP Per Flow metrics.
1443  *
1444  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1445  * @param index       The index of the IP Type-of-Service.
1446  * @param count       The count.
1447  *****************************************************************************/
1448 void evel_mobile_gtp_metrics_iptos_set(MOBILE_GTP_PER_FLOW_METRICS * metrics,
1449                                        int index,
1450                                        int count)
1451 {
1452   EVEL_ENTER();
1453
1454   /***************************************************************************/
1455   /* Check preconditions.                                                    */
1456   /***************************************************************************/
1457   assert(metrics != NULL);
1458   assert(index >= 0);
1459   assert(index < EVEL_TOS_SUPPORTED);
1460   assert(count >= 0);
1461   assert(count <= 255);
1462
1463   EVEL_DEBUG("IP Type-of-Service %d", index);
1464   evel_set_option_int(&metrics->ip_tos_counts[index],
1465                       count,
1466                       "IP Type-of-Service");
1467   EVEL_EXIT();
1468 }
1469
1470 /**************************************************************************//**
1471  * Set the Large Packet Round-Trip Time property of the Mobile GTP Per Flow
1472  * Metrics.
1473  *
1474  * @note  The property is treated as immutable: it is only valid to call
1475  *        the setter once.  However, we don't assert if the caller tries to
1476  *        overwrite, just ignoring the update instead.
1477  *
1478  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1479  * @param rtt         The Large Packet Round-Trip Time to be set.
1480  *****************************************************************************/
1481 void evel_mobile_gtp_metrics_large_pkt_rtt_set(
1482                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1483                                          int rtt)
1484 {
1485   EVEL_ENTER();
1486
1487   /***************************************************************************/
1488   /* Check preconditions.                                                    */
1489   /***************************************************************************/
1490   assert(metrics != NULL);
1491   assert(rtt >= 0);
1492
1493   evel_set_option_int(&metrics->large_packet_rtt,
1494                       rtt,
1495                       "Large Packet Round-Trip Time");
1496   EVEL_EXIT();
1497 }
1498
1499 /**************************************************************************//**
1500  * Set the Large Packet Threshold property of the Mobile GTP Per Flow Metrics.
1501  *
1502  * @note  The property is treated as immutable: it is only valid to call
1503  *        the setter once.  However, we don't assert if the caller tries to
1504  *        overwrite, just ignoring the update instead.
1505  *
1506  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1507  * @param threshold   The Large Packet Threshold to be set.
1508  *****************************************************************************/
1509 void evel_mobile_gtp_metrics_large_pkt_thresh_set(
1510                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1511                                          double threshold)
1512 {
1513   EVEL_ENTER();
1514
1515   /***************************************************************************/
1516   /* Check preconditions.                                                    */
1517   /***************************************************************************/
1518   assert(metrics != NULL);
1519   assert(threshold >= 0.0);
1520
1521   evel_set_option_double(&metrics->large_packet_threshold,
1522                          threshold,
1523                          "Large Packet Threshold");
1524   EVEL_EXIT();
1525 }
1526
1527 /**************************************************************************//**
1528  * Set the Max Receive Bit Rate property of the Mobile GTP Per Flow Metrics.
1529  *
1530  * @note  The property is treated as immutable: it is only valid to call
1531  *        the setter once.  However, we don't assert if the caller tries to
1532  *        overwrite, just ignoring the update instead.
1533  *
1534  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1535  * @param rate        The Max Receive Bit Rate to be set.
1536  *****************************************************************************/
1537 void evel_mobile_gtp_metrics_max_rcv_bit_rate_set(
1538                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1539                                          int rate)
1540 {
1541   EVEL_ENTER();
1542
1543   /***************************************************************************/
1544   /* Check preconditions.                                                    */
1545   /***************************************************************************/
1546   assert(metrics != NULL);
1547   assert(rate >= 0);
1548
1549   evel_set_option_int(&metrics->max_receive_bit_rate,
1550                       rate,
1551                       "Max Receive Bit Rate");
1552   EVEL_EXIT();
1553 }
1554
1555 /**************************************************************************//**
1556  * Set the Max Transmit Bit Rate property of the Mobile GTP Per Flow Metrics.
1557  *
1558  * @note  The property is treated as immutable: it is only valid to call
1559  *        the setter once.  However, we don't assert if the caller tries to
1560  *        overwrite, just ignoring the update instead.
1561  *
1562  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1563  * @param rate        The Max Transmit Bit Rate to be set.
1564  *****************************************************************************/
1565 void evel_mobile_gtp_metrics_max_trx_bit_rate_set(
1566                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1567                                          int rate)
1568 {
1569   EVEL_ENTER();
1570
1571   /***************************************************************************/
1572   /* Check preconditions.                                                    */
1573   /***************************************************************************/
1574   assert(metrics != NULL);
1575   assert(rate >= 0);
1576
1577   evel_set_option_int(&metrics->max_transmit_bit_rate,
1578                       rate,
1579                       "Max Transmit Bit Rate");
1580   EVEL_EXIT();
1581 }
1582
1583 /**************************************************************************//**
1584  * Set the Number of GTP Echo Failures property of the Mobile GTP Per Flow
1585  * Metrics.
1586  *
1587  * @note  The property is treated as immutable: it is only valid to call
1588  *        the setter once.  However, we don't assert if the caller tries to
1589  *        overwrite, just ignoring the update instead.
1590  *
1591  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1592  * @param num         The Number of GTP Echo Failures to be set.
1593  *****************************************************************************/
1594 void evel_mobile_gtp_metrics_num_echo_fail_set(
1595                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1596                                          int num)
1597 {
1598   EVEL_ENTER();
1599
1600   /***************************************************************************/
1601   /* Check preconditions.                                                    */
1602   /***************************************************************************/
1603   assert(metrics != NULL);
1604   assert(num >= 0);
1605
1606   evel_set_option_int(&metrics->num_gtp_echo_failures,
1607                       num,
1608                       "Number of GTP Echo Failures");
1609   EVEL_EXIT();
1610 }
1611
1612 /**************************************************************************//**
1613  * Set the Number of GTP Tunnel Errors property of the Mobile GTP Per Flow
1614  * Metrics.
1615  *
1616  * @note  The property is treated as immutable: it is only valid to call
1617  *        the setter once.  However, we don't assert if the caller tries to
1618  *        overwrite, just ignoring the update instead.
1619  *
1620  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1621  * @param num         The Number of GTP Tunnel Errors to be set.
1622  *****************************************************************************/
1623 void evel_mobile_gtp_metrics_num_tun_fail_set(
1624                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1625                                          int num)
1626 {
1627   EVEL_ENTER();
1628
1629   /***************************************************************************/
1630   /* Check preconditions.                                                    */
1631   /***************************************************************************/
1632   assert(metrics != NULL);
1633   assert(num >= 0);
1634
1635   evel_set_option_int(&metrics->num_gtp_tunnel_errors,
1636                       num,
1637                       "Number of GTP Tunnel Errors");
1638   EVEL_EXIT();
1639 }
1640
1641 /**************************************************************************//**
1642  * Set the Number of HTTP Errors property of the Mobile GTP Per Flow Metrics.
1643  *
1644  * @note  The property is treated as immutable: it is only valid to call
1645  *        the setter once.  However, we don't assert if the caller tries to
1646  *        overwrite, just ignoring the update instead.
1647  *
1648  * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
1649  * @param num         The Number of HTTP Errors to be set.
1650  *****************************************************************************/
1651 void evel_mobile_gtp_metrics_num_http_errors_set(
1652                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1653                                          int num)
1654 {
1655   EVEL_ENTER();
1656
1657   /***************************************************************************/
1658   /* Check preconditions.                                                    */
1659   /***************************************************************************/
1660   assert(metrics != NULL);
1661   assert(num >= 0);
1662
1663   evel_set_option_int(&metrics->num_http_errors,
1664                       num,
1665                       "Number of HTTP Errors");
1666   EVEL_EXIT();
1667 }
1668
1669 /**************************************************************************//**
1670  * Add a TCP flag count to the metrics.
1671  *
1672  * @note  The property is treated as immutable: it is only valid to call
1673  *        the setter once.  However, we don't assert if the caller tries to
1674  *        overwrite, just ignoring the update instead.
1675  *
1676  * @param metrics       Pointer to the Mobile GTP Per Flow Metrics.
1677  * @param tcp_flag      The TCP flag to be updated.
1678  * @param count         The associated flag count, which must be nonzero.
1679  *****************************************************************************/
1680 void evel_mobile_gtp_metrics_tcp_flag_count_add(
1681                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1682                                          const EVEL_TCP_FLAGS tcp_flag,
1683                                          const int count)
1684 {
1685   EVEL_ENTER();
1686
1687   /***************************************************************************/
1688   /* Check preconditions.                                                    */
1689   /***************************************************************************/
1690   assert(metrics != NULL);
1691   assert(tcp_flag >= 0);
1692   assert(tcp_flag < EVEL_MAX_TCP_FLAGS);
1693   assert(count >= 0);
1694
1695   EVEL_DEBUG("TCP Flag: %d", tcp_flag);
1696   evel_set_option_int(&metrics->tcp_flag_counts[tcp_flag],
1697                       count,
1698                       "TCP flag");
1699   EVEL_EXIT();
1700 }
1701
1702 /**************************************************************************//**
1703  * Add a QCI COS count to the metrics.
1704  *
1705  * @note  The property is treated as immutable: it is only valid to call
1706  *        the setter once.  However, we don't assert if the caller tries to
1707  *        overwrite, just ignoring the update instead.
1708  *
1709  * @param metrics       Pointer to the Mobile GTP Per Flow Metrics.
1710  * @param qci_cos       The QCI COS count to be updated.
1711  * @param count         The associated QCI COS count.
1712  *****************************************************************************/
1713 void evel_mobile_gtp_metrics_qci_cos_count_add(
1714                                          MOBILE_GTP_PER_FLOW_METRICS * metrics,
1715                                          const EVEL_QCI_COS_TYPES qci_cos,
1716                                          const int count)
1717 {
1718   EVEL_ENTER();
1719
1720   /***************************************************************************/
1721   /* Check preconditions.                                                    */
1722   /***************************************************************************/
1723   assert(metrics != NULL);
1724   assert(qci_cos >= 0);
1725   assert(qci_cos < EVEL_MAX_QCI_COS_TYPES);
1726   assert(count >= 0);
1727
1728   EVEL_DEBUG("QCI COS: %d", qci_cos);
1729   evel_set_option_int(&metrics->qci_cos_counts[qci_cos],
1730                       count,
1731                       "QCI COS");
1732   EVEL_EXIT();
1733 }
1734
1735 /**************************************************************************//**
1736  * Encode the Mobile Flow GTP Per Flow Metrics as a JSON object.
1737  *
1738  * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
1739  * @param metrics       Pointer to the ::EVENT_MOBILE_FLOW to encode.
1740  * @returns Number of bytes actually written.
1741  *****************************************************************************/
1742 void evel_json_encode_mobile_flow_gtp_flow_metrics(
1743                                         EVEL_JSON_BUFFER * jbuf,
1744                                         MOBILE_GTP_PER_FLOW_METRICS * metrics)
1745 {
1746   int index;
1747   bool found_ip_tos;
1748   bool found_tcp_flag;
1749   bool found_qci_cos;
1750
1751   EVEL_ENTER();
1752
1753   /***************************************************************************/
1754   /* Check preconditions.                                                    */
1755   /***************************************************************************/
1756   assert(jbuf != NULL);
1757   assert(metrics != NULL);
1758
1759   evel_json_open_named_object(jbuf, "gtpPerFlowMetrics");
1760
1761   /***************************************************************************/
1762   /* Mandatory parameters.                                                   */
1763   /***************************************************************************/
1764   evel_enc_kv_double(jbuf, "avgBitErrorRate", metrics->avg_bit_error_rate);
1765   evel_enc_kv_double(
1766     jbuf, "avgPacketDelayVariation", metrics->avg_packet_delay_variation);
1767   evel_enc_kv_int(jbuf, "avgPacketLatency", metrics->avg_packet_latency);
1768   evel_enc_kv_int(
1769     jbuf, "avgReceiveThroughput", metrics->avg_receive_throughput);
1770   evel_enc_kv_int(
1771     jbuf, "avgTransmitThroughput", metrics->avg_transmit_throughput);
1772   evel_enc_kv_int(jbuf, "flowActivationEpoch", metrics->flow_activation_epoch);
1773   evel_enc_kv_int(
1774     jbuf, "flowActivationMicrosec", metrics->flow_activation_microsec);
1775   evel_enc_kv_int(
1776     jbuf, "flowDeactivationEpoch", metrics->flow_deactivation_epoch);
1777   evel_enc_kv_int(
1778     jbuf, "flowDeactivationMicrosec", metrics->flow_deactivation_microsec);
1779   evel_enc_kv_time(
1780     jbuf, "flowDeactivationTime", &metrics->flow_deactivation_time);
1781   evel_enc_kv_string(jbuf, "flowStatus", metrics->flow_status);
1782   evel_enc_kv_int(
1783     jbuf, "maxPacketDelayVariation", metrics->max_packet_delay_variation);
1784   evel_enc_kv_int(
1785     jbuf, "numActivationFailures", metrics->num_activation_failures);
1786   evel_enc_kv_int(jbuf, "numBitErrors", metrics->num_bit_errors);
1787   evel_enc_kv_int(jbuf, "numBytesReceived", metrics->num_bytes_received);
1788   evel_enc_kv_int(jbuf, "numBytesTransmitted", metrics->num_bytes_transmitted);
1789   evel_enc_kv_int(jbuf, "numDroppedPackets", metrics->num_dropped_packets);
1790   evel_enc_kv_int(jbuf, "numL7BytesReceived", metrics->num_l7_bytes_received);
1791   evel_enc_kv_int(
1792     jbuf, "numL7BytesTransmitted", metrics->num_l7_bytes_transmitted);
1793   evel_enc_kv_int(jbuf, "numLostPackets", metrics->num_lost_packets);
1794   evel_enc_kv_int(
1795     jbuf, "numOutOfOrderPackets", metrics->num_out_of_order_packets);
1796   evel_enc_kv_int(jbuf, "numPacketErrors", metrics->num_packet_errors);
1797   evel_enc_kv_int(jbuf,
1798                   "numPacketsReceivedExclRetrans",
1799                   metrics->num_packets_received_excl_retrans);
1800   evel_enc_kv_int(jbuf,
1801                   "numPacketsReceivedInclRetrans",
1802                   metrics->num_packets_received_incl_retrans);
1803   evel_enc_kv_int(jbuf,
1804                   "numPacketsTransmittedInclRetrans",
1805                   metrics->num_packets_transmitted_incl_retrans);
1806   evel_enc_kv_int(jbuf, "numRetries", metrics->num_retries);
1807   evel_enc_kv_int(jbuf, "numTimeouts", metrics->num_timeouts);
1808   evel_enc_kv_int(jbuf,
1809                   "numTunneledL7BytesReceived",
1810                   metrics->num_tunneled_l7_bytes_received);
1811   evel_enc_kv_int(jbuf, "roundTripTime", metrics->round_trip_time);
1812   evel_enc_kv_int(jbuf, "timeToFirstByte", metrics->time_to_first_byte);
1813
1814   /***************************************************************************/
1815   /* Optional parameters.                                                    */
1816   /***************************************************************************/
1817   found_ip_tos = false;
1818   for (index = 0; index < EVEL_TOS_SUPPORTED; index++)
1819   {
1820     if (metrics->ip_tos_counts[index].is_set)
1821     {
1822       found_ip_tos = true;
1823       break;
1824     }
1825   }
1826
1827   if (found_ip_tos)
1828   {
1829     evel_json_open_named_list(jbuf, "ipTosCountList");
1830     for (index = 0; index < EVEL_TOS_SUPPORTED; index++)
1831     {
1832       if (metrics->ip_tos_counts[index].is_set)
1833       {
1834         evel_enc_list_item(jbuf,
1835                            "[\"%d\", %d]",
1836                            index,
1837                            metrics->ip_tos_counts[index].value);
1838       }
1839     }
1840     evel_json_close_list(jbuf);
1841   }
1842
1843   if (found_ip_tos)
1844   {
1845     evel_json_open_named_list(jbuf, "ipTosList");
1846     for (index = 0; index < EVEL_TOS_SUPPORTED; index++)
1847     {
1848       if (metrics->ip_tos_counts[index].is_set)
1849       {
1850         evel_enc_list_item(jbuf, "\"%d\"", index);
1851       }
1852     }
1853     evel_json_close_list(jbuf);
1854   }
1855
1856   /***************************************************************************/
1857   /* Make some compile-time assertions about EVEL_TCP_FLAGS.  If you update  */
1858   /* these, make sure you update evel_tcp_flag_strings to match the enum.    */
1859   /***************************************************************************/
1860   EVEL_CT_ASSERT(EVEL_TCP_NS == 0);
1861   EVEL_CT_ASSERT(EVEL_TCP_CWR == 1);
1862   EVEL_CT_ASSERT(EVEL_TCP_ECE == 2);
1863   EVEL_CT_ASSERT(EVEL_TCP_URG == 3);
1864   EVEL_CT_ASSERT(EVEL_TCP_ACK == 4);
1865   EVEL_CT_ASSERT(EVEL_TCP_PSH == 5);
1866   EVEL_CT_ASSERT(EVEL_TCP_RST == 6);
1867   EVEL_CT_ASSERT(EVEL_TCP_SYN == 7);
1868   EVEL_CT_ASSERT(EVEL_TCP_FIN == 8);
1869   EVEL_CT_ASSERT(EVEL_MAX_TCP_FLAGS == 9);
1870
1871   found_tcp_flag = false;
1872   for (index = 0; index < EVEL_MAX_TCP_FLAGS; index++)
1873   {
1874     if (metrics->tcp_flag_counts[index].is_set)
1875     {
1876       found_tcp_flag = true;
1877       break;
1878     }
1879   }
1880
1881   if (found_tcp_flag)
1882   {
1883     evel_json_open_named_list(jbuf, "tcpFlagList");
1884     for (index = 0; index < EVEL_MAX_TCP_FLAGS; index++)
1885     {
1886       if (metrics->tcp_flag_counts[index].is_set)
1887       {
1888         evel_enc_list_item(jbuf,
1889                            "\"%s\"",
1890                            evel_tcp_flag_strings[index]);
1891       }
1892     }
1893     evel_json_close_list(jbuf);
1894   }
1895
1896   if (found_tcp_flag)
1897   {
1898     evel_json_open_named_list(jbuf, "tcpFlagCountList");
1899     for (index = 0; index < EVEL_MAX_TCP_FLAGS; index++)
1900     {
1901       if (metrics->tcp_flag_counts[index].is_set)
1902       {
1903         evel_enc_list_item(jbuf,
1904                            "[\"%s\", %d]",
1905                            evel_tcp_flag_strings[index],
1906                            metrics->tcp_flag_counts[index].value);
1907       }
1908     }
1909     evel_json_close_list(jbuf);
1910   }
1911
1912   /***************************************************************************/
1913   /* Make some compile-time assertions about EVEL_QCI_COS_TYPES.  If you     */
1914   /* update these, make sure you update evel_qci_cos_strings to match the    */
1915   /* enum.                                                                   */
1916   /***************************************************************************/
1917   EVEL_CT_ASSERT(EVEL_QCI_COS_UMTS_CONVERSATIONAL ==0);
1918   EVEL_CT_ASSERT(EVEL_QCI_COS_UMTS_STREAMING == 1);
1919   EVEL_CT_ASSERT(EVEL_QCI_COS_UMTS_INTERACTIVE == 2);
1920   EVEL_CT_ASSERT(EVEL_QCI_COS_UMTS_BACKGROUND == 3);
1921   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_1 == 4);
1922   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_2 == 5);
1923   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_3 == 6);
1924   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_4 == 7);
1925   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_65 == 8);
1926   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_66 == 9);
1927   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_5 == 10);
1928   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_6 == 11);
1929   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_7 == 12);
1930   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_8 == 13);
1931   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_9 == 14);
1932   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_69 == 15);
1933   EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_70 == 16);
1934   EVEL_CT_ASSERT(EVEL_MAX_QCI_COS_TYPES == 17);
1935
1936   found_qci_cos = false;
1937   for (index = 0; index < EVEL_MAX_QCI_COS_TYPES; index++)
1938   {
1939     if (metrics->qci_cos_counts[index].is_set)
1940     {
1941       found_qci_cos = true;
1942       break;
1943     }
1944   }
1945
1946   if (found_qci_cos)
1947   {
1948     evel_json_open_named_list(jbuf, "mobileQciCosList");
1949     for (index = 0; index < EVEL_MAX_QCI_COS_TYPES; index++)
1950     {
1951       if (metrics->qci_cos_counts[index].is_set)
1952       {
1953         evel_enc_list_item(jbuf,
1954                            "\"%s\"",
1955                            evel_qci_cos_strings[index]);
1956       }
1957     }
1958     evel_json_close_list(jbuf);
1959   }
1960
1961   if (found_qci_cos)
1962   {
1963     evel_json_open_named_list(jbuf, "mobileQciCosCountList");
1964     for (index = 0; index < EVEL_MAX_QCI_COS_TYPES; index++)
1965     {
1966       if (metrics->qci_cos_counts[index].is_set)
1967       {
1968         evel_enc_list_item(jbuf,
1969                            "[\"%s\", %d]",
1970                            evel_qci_cos_strings[index],
1971                            metrics->qci_cos_counts[index].value);
1972       }
1973     }
1974     evel_json_close_list(jbuf);
1975   }
1976
1977   evel_enc_kv_opt_int(
1978     jbuf, "durConnectionFailedStatus", &metrics->dur_connection_failed_status);
1979   evel_enc_kv_opt_int(
1980     jbuf, "durTunnelFailedStatus", &metrics->dur_tunnel_failed_status);
1981   evel_enc_kv_opt_string(jbuf, "flowActivatedBy", &metrics->flow_activated_by);
1982   evel_enc_kv_opt_time(
1983     jbuf, "flowActivationTime", &metrics->flow_activation_time);
1984   evel_enc_kv_opt_string(
1985     jbuf, "flowDeactivatedBy", &metrics->flow_deactivated_by);
1986   evel_enc_kv_opt_string(
1987     jbuf, "gtpConnectionStatus", &metrics->gtp_connection_status);
1988   evel_enc_kv_opt_string(jbuf, "gtpTunnelStatus", &metrics->gtp_tunnel_status);
1989   evel_enc_kv_opt_int(jbuf, "largePacketRtt", &metrics->large_packet_rtt);
1990   evel_enc_kv_opt_double(
1991     jbuf, "largePacketThreshold", &metrics->large_packet_threshold);
1992   evel_enc_kv_opt_int(
1993     jbuf, "maxReceiveBitRate", &metrics->max_receive_bit_rate);
1994   evel_enc_kv_opt_int(
1995     jbuf, "maxTransmitBitRate", &metrics->max_transmit_bit_rate);
1996   evel_enc_kv_opt_int(
1997     jbuf, "numGtpEchoFailures", &metrics->num_gtp_echo_failures);
1998   evel_enc_kv_opt_int(
1999     jbuf, "numGtpTunnelErrors", &metrics->num_gtp_tunnel_errors);
2000   evel_enc_kv_opt_int(jbuf, "numHttpErrors", &metrics->num_http_errors);
2001
2002   evel_json_close_object(jbuf);
2003
2004   EVEL_EXIT();
2005 }
2006
2007 /**************************************************************************//**
2008  * Free a Mobile GTP Per Flow Metrics.
2009  *
2010  * Free off the Mobile GTP Per Flow Metrics supplied.  Will free all the
2011  * contained allocated memory.
2012  *
2013  * @note It does not free the Mobile GTP Per Flow Metrics itself, since that
2014  * may be part of a larger structure.
2015  *****************************************************************************/
2016 void evel_free_mobile_gtp_flow_metrics(MOBILE_GTP_PER_FLOW_METRICS * metrics)
2017 {
2018   EVEL_ENTER();
2019
2020   /***************************************************************************/
2021   /* Check preconditions.                                                    */
2022   /***************************************************************************/
2023   assert(metrics != NULL);
2024
2025   /***************************************************************************/
2026   /* Free all internal strings.                                              */
2027   /***************************************************************************/
2028   free(metrics->flow_status);
2029
2030   evel_free_option_string(&metrics->flow_activated_by);
2031   evel_free_option_string(&metrics->flow_deactivated_by);
2032   evel_free_option_string(&metrics->gtp_connection_status);
2033   evel_free_option_string(&metrics->gtp_tunnel_status);
2034
2035   EVEL_EXIT();
2036 }