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