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