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