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