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