Initial VES for DANOS vRouter
[demo.git] / vnfs / VESreporting_vFW5.0_DANOS / evel / evel-library / code / evel_library / evel_sipsignaling.c
1 /*************************************************************************//**
2  *
3  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
4  *
5  * Unless otherwise specified, all software contained herein is
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and 
15  * limitations under the License.
16  *
17  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
18  ****************************************************************************/
19 /**************************************************************************//**
20  * @file
21  * Implementation of EVEL functions relating to Signaling.
22  *
23  ****************************************************************************/
24
25 #include <string.h>
26 #include <assert.h>
27 #include <stdlib.h>
28
29 #include "evel_throttle.h"
30
31 /**************************************************************************//**
32  * Create a new Signaling event.
33  *
34  * @note    The mandatory fields on the Signaling must be supplied to
35  *          this factory function and are immutable once set.  Optional fields
36  *          have explicit setter functions, but again values may only be set
37  *          once so that the event has immutable properties.
38  * @param event_name  Unique Event Name confirming Domain AsdcModel Description
39  * @param event_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
40  * @param vendor_name   The vendor id to encode in the event vnf field.
41  * @param module        The module to encode in the event.
42  * @param vnfname       The Virtual network function to encode in the event.
43  * @returns pointer to the newly manufactured ::EVENT_SIGNALING.  If the event
44  *          is not used (i.e. posted) it must be released using
45  *          ::evel_free_signaling.
46  * @retval  NULL  Failed to create the event.
47  *****************************************************************************/
48 EVENT_SIGNALING * evel_new_signaling(const char* ev_name, const char *ev_id,
49                                      const char * const vendor_name,
50                                      const char * const correlator,
51                                      const char * const local_ip_address,
52                                      const char * const local_port,
53                                      const char * const remote_ip_address,
54                                      const char * const remote_port)
55 {
56   EVENT_SIGNALING * event = NULL;
57
58   EVEL_ENTER();
59
60   /***************************************************************************/
61   /* Check preconditions.                                                    */
62   /***************************************************************************/
63   assert(vendor_name != NULL);
64
65   /***************************************************************************/
66   /* Allocate the Signaling event.                                           */
67   /***************************************************************************/
68   event = malloc(sizeof(EVENT_SIGNALING));
69   if (event == NULL)
70   {
71     log_error_state("Out of memory");
72     goto exit_label;
73   }
74   memset(event, 0, sizeof(EVENT_SIGNALING));
75   EVEL_DEBUG("New Signaling event is at %lp", event);
76
77   /***************************************************************************/
78   /* Initialize the header & the Signaling fields.                           */
79   /***************************************************************************/
80   evel_init_header_nameid(&event->header,ev_name,ev_id);
81   event->header.event_domain = EVEL_DOMAIN_SIPSIGNALING;
82   event->major_version = EVEL_SIGNALING_MAJOR_VERSION;
83   event->minor_version = EVEL_SIGNALING_MINOR_VERSION;
84   evel_init_vendor_field(&event->vnfname_field, vendor_name);
85   evel_set_option_string(&event->correlator,correlator,"Init correlator");
86   evel_set_option_string(&event->local_ip_address,local_ip_address,"Init correlator");
87   evel_set_option_string(&event->local_port,local_port,"Init local port");
88   evel_set_option_string(&event->remote_ip_address,remote_ip_address,"Init remote ip");
89   evel_set_option_string(&event->remote_port,remote_port,"Init remote port");
90   evel_init_option_string(&event->compressed_sip);
91   evel_init_option_string(&event->summary_sip);
92   dlist_initialize(&event->additional_info);
93
94 exit_label:
95
96   EVEL_EXIT();
97   return event;
98 }
99
100 /**************************************************************************//**
101  * Add an additional value name/value pair to the SIP signaling.
102  *
103  * The name and value are null delimited ASCII strings.  The library takes
104  * a copy so the caller does not have to preserve values after the function
105  * returns.
106  *
107  * @param event     Pointer to the fault.
108  * @param name      ASCIIZ string with the attribute's name.  The caller
109  *                  does not need to preserve the value once the function
110  *                  returns.
111  * @param value     ASCIIZ string with the attribute's value.  The caller
112  *                  does not need to preserve the value once the function
113  *                  returns.
114  *****************************************************************************/
115 void evel_signaling_addl_info_add(EVENT_SIGNALING * event, char * name, char * value)
116 {
117   FAULT_ADDL_INFO * addl_info = NULL;
118   EVEL_ENTER();
119
120   /***************************************************************************/
121   /* Check preconditions.                                                    */
122   /***************************************************************************/
123   assert(event != NULL);
124   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
125   assert(name != NULL);
126   assert(value != NULL);
127
128   EVEL_DEBUG("Adding name=%s value=%s", name, value);
129   addl_info = malloc(sizeof(SIGNALING_ADDL_FIELD));
130   assert(addl_info != NULL);
131   memset(addl_info, 0, sizeof(SIGNALING_ADDL_FIELD));
132   addl_info->name = strdup(name);
133   addl_info->value = strdup(value);
134   assert(addl_info->name != NULL);
135   assert(addl_info->value != NULL);
136
137   dlist_push_last(&event->additional_info, addl_info);
138
139   EVEL_EXIT();
140 }
141
142
143 /**************************************************************************//**
144  * Set the Event Type property of the Signaling event.
145  *
146  * @note  The property is treated as immutable: it is only valid to call
147  *        the setter once.  However, we don't assert if the caller tries to
148  *        overwrite, just ignoring the update instead.
149  *
150  * @param event         Pointer to the Signaling event.
151  * @param type          The Event Type to be set. ASCIIZ string. The caller
152  *                      does not need to preserve the value once the function
153  *                      returns.
154  *****************************************************************************/
155 void evel_signaling_type_set(EVENT_SIGNALING * const event,
156                              const char * const type)
157 {
158   EVEL_ENTER();
159
160   /***************************************************************************/
161   /* Check preconditions and call evel_header_type_set.                      */
162   /***************************************************************************/
163   assert(event != NULL);
164   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
165   evel_header_type_set(&event->header, type);
166
167   EVEL_EXIT();
168 }
169
170 /**************************************************************************//**
171  * Set the Local Ip Address property of the Signaling event.
172  *
173  * @note  The property is treated as immutable: it is only valid to call
174  *        the setter once.  However, we don't assert if the caller tries to
175  *        overwrite, just ignoring the update instead.
176  *
177  * @param event         Pointer to the Signaling event.
178  * @param local_ip_address
179  *                      The Local Ip Address to be set. ASCIIZ string. The
180  *                      caller does not need to preserve the value once the
181  *                      function returns.
182  *****************************************************************************/
183 void evel_signaling_local_ip_address_set(EVENT_SIGNALING * const event,
184                                          const char * const local_ip_address)
185 {
186   EVEL_ENTER();
187
188   /***************************************************************************/
189   /* Check preconditions.                                                    */
190   /***************************************************************************/
191   assert(event != NULL);
192   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
193   assert(local_ip_address != NULL);
194
195   evel_set_option_string(&event->local_ip_address,
196                          local_ip_address,
197                          "Local Ip Address");
198
199   EVEL_EXIT();
200 }
201
202 /**************************************************************************//**
203  * Set the Local Port property of the Signaling event.
204  *
205  * @note  The property is treated as immutable: it is only valid to call
206  *        the setter once.  However, we don't assert if the caller tries to
207  *        overwrite, just ignoring the update instead.
208  *
209  * @param event         Pointer to the Signaling event.
210  * @param local_port    The Local Port to be set. ASCIIZ string. The caller
211  *                      does not need to preserve the value once the function
212  *                      returns.
213  *****************************************************************************/
214 void evel_signaling_local_port_set(EVENT_SIGNALING * const event,
215                                    const char * const local_port)
216 {
217   EVEL_ENTER();
218
219   /***************************************************************************/
220   /* Check preconditions.                                                    */
221   /***************************************************************************/
222   assert(event != NULL);
223   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
224   assert(local_port != NULL);
225
226   evel_set_option_string(&event->local_port,
227                          local_port,
228                          "Local Port");
229
230   EVEL_EXIT();
231 }
232
233 /**************************************************************************//**
234  * Set the Remote Ip Address property of the Signaling event.
235  *
236  * @note  The property is treated as immutable: it is only valid to call
237  *        the setter once.  However, we don't assert if the caller tries to
238  *        overwrite, just ignoring the update instead.
239  *
240  * @param event         Pointer to the Signaling event.
241  * @param remote_ip_address
242  *                      The Remote Ip Address to be set. ASCIIZ string. The
243  *                      caller does not need to preserve the value once the
244  *                      function returns.
245  *****************************************************************************/
246 void evel_signaling_remote_ip_address_set(EVENT_SIGNALING * const event,
247                                           const char * const remote_ip_address)
248 {
249   EVEL_ENTER();
250
251   /***************************************************************************/
252   /* Check preconditions.                                                    */
253   /***************************************************************************/
254   assert(event != NULL);
255   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
256   assert(remote_ip_address != NULL);
257
258   evel_set_option_string(&event->remote_ip_address,
259                          remote_ip_address,
260                          "Remote Ip Address");
261
262   EVEL_EXIT();
263 }
264
265 /**************************************************************************//**
266  * Set the Remote Port property of the Signaling event.
267  *
268  * @note  The property is treated as immutable: it is only valid to call
269  *        the setter once.  However, we don't assert if the caller tries to
270  *        overwrite, just ignoring the update instead.
271  *
272  * @param event         Pointer to the Signaling event.
273  * @param remote_port   The Remote Port to be set. ASCIIZ string. The caller
274  *                      does not need to preserve the value once the function
275  *                      returns.
276  *****************************************************************************/
277 void evel_signaling_remote_port_set(EVENT_SIGNALING * const event,
278                                     const char * const remote_port)
279 {
280   EVEL_ENTER();
281
282   /***************************************************************************/
283   /* Check preconditions.                                                    */
284   /***************************************************************************/
285   assert(event != NULL);
286   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
287   assert(remote_port != NULL);
288
289   evel_set_option_string(&event->remote_port,
290                          remote_port,
291                          "Remote Port");
292
293   EVEL_EXIT();
294 }
295
296 /**************************************************************************//**
297  * Set the Vendor module property of the Signaling event.
298  *
299  * @note  The property is treated as immutable: it is only valid to call
300  *        the setter once.  However, we don't assert if the caller tries to
301  *        overwrite, just ignoring the update instead.
302  *
303  * @param event         Pointer to the Signaling event.
304  * @param modulename    The module name to be set. ASCIIZ string. The caller
305  *                      does not need to preserve the value once the function
306  *                      returns.
307  *****************************************************************************/
308 void evel_signaling_vnfmodule_name_set(EVENT_SIGNALING * const event,
309                                     const char * const module_name)
310 {
311   EVEL_ENTER();
312
313   /***************************************************************************/
314   /* Check preconditions.                                                    */
315   /***************************************************************************/
316   assert(event != NULL);
317   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
318   assert(module_name != NULL);
319
320   evel_vendor_field_module_set(&event->vnfname_field, module_name);
321
322   EVEL_EXIT();
323 }
324
325 /**************************************************************************//**
326  * Set the Vendor module property of the Signaling event.
327  *
328  * @note  The property is treated as immutable: it is only valid to call
329  *        the setter once.  However, we don't assert if the caller tries to
330  *        overwrite, just ignoring the update instead.
331  *
332  * @param event         Pointer to the Signaling event.
333  * @param vnfname       The Virtual Network function to be set. ASCIIZ string.
334  *                      The caller does not need to preserve the value once
335  *                      the function returns.
336  *****************************************************************************/
337 void evel_signaling_vnfname_set(EVENT_SIGNALING * const event,
338                                     const char * const vnfname)
339 {
340   EVEL_ENTER();
341
342   /***************************************************************************/
343   /* Check preconditions.                                                    */
344   /***************************************************************************/
345   assert(event != NULL);
346   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
347   assert(vnfname != NULL);
348
349   evel_vendor_field_vnfname_set(&event->vnfname_field, vnfname);
350
351   EVEL_EXIT();
352 }
353
354 /**************************************************************************//**
355  * Set the Compressed SIP property of the Signaling event.
356  *
357  * @note  The property is treated as immutable: it is only valid to call
358  *        the setter once.  However, we don't assert if the caller tries to
359  *        overwrite, just ignoring the update instead.
360  *
361  * @param event         Pointer to the Signaling event.
362  * @param compressed_sip
363  *                      The Compressed SIP to be set. ASCIIZ string. The caller
364  *                      does not need to preserve the value once the function
365  *                      returns.
366  *****************************************************************************/
367 void evel_signaling_compressed_sip_set(EVENT_SIGNALING * const event,
368                                        const char * const compressed_sip)
369 {
370   EVEL_ENTER();
371
372   /***************************************************************************/
373   /* Check preconditions.                                                    */
374   /***************************************************************************/
375   assert(event != NULL);
376   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
377   assert(compressed_sip != NULL);
378
379   evel_set_option_string(&event->compressed_sip,
380                          compressed_sip,
381                          "Compressed SIP");
382
383   EVEL_EXIT();
384 }
385
386 /**************************************************************************//**
387  * Set the Summary SIP property of the Signaling event.
388  *
389  * @note  The property is treated as immutable: it is only valid to call
390  *        the setter once.  However, we don't assert if the caller tries to
391  *        overwrite, just ignoring the update instead.
392  *
393  * @param event         Pointer to the Signaling event.
394  * @param summary_sip   The Summary SIP to be set. ASCIIZ string. The caller
395  *                      does not need to preserve the value once the function
396  *                      returns.
397  *****************************************************************************/
398 void evel_signaling_summary_sip_set(EVENT_SIGNALING * const event,
399                                     const char * const summary_sip)
400 {
401   EVEL_ENTER();
402
403   /***************************************************************************/
404   /* Check preconditions.                                                    */
405   /***************************************************************************/
406   assert(event != NULL);
407   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
408   assert(summary_sip != NULL);
409
410   evel_set_option_string(&event->summary_sip,
411                          summary_sip,
412                          "Summary SIP");
413
414   EVEL_EXIT();
415 }
416
417 /**************************************************************************//**
418  * Set the Correlator property of the Signaling event.
419  *
420  * @note  The property is treated as immutable: it is only valid to call
421  *        the setter once.  However, we don't assert if the caller tries to
422  *        overwrite, just ignoring the update instead.
423  *
424  * @param event         Pointer to the Signaling event.
425  * @param correlator    The correlator to be set. ASCIIZ string. The caller
426  *                      does not need to preserve the value once the function
427  *                      returns.
428  *****************************************************************************/
429 void evel_signaling_correlator_set(EVENT_SIGNALING * const event,
430                                    const char * const correlator)
431 {
432   EVEL_ENTER();
433
434   /***************************************************************************/
435   /* Check preconditions and call evel_header_type_set.                      */
436   /***************************************************************************/
437   assert(event != NULL);
438   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
439   evel_set_option_string(&event->correlator,
440                          correlator,
441                          "Correlator");
442
443   EVEL_EXIT();
444 }
445
446 /**************************************************************************//**
447  * Encode the Signaling in JSON according to AT&T's schema for the
448  * event type.
449  *
450  * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
451  * @param event         Pointer to the ::EVENT_HEADER to encode.
452  *****************************************************************************/
453 void evel_json_encode_signaling(EVEL_JSON_BUFFER * const jbuf,
454                                 EVENT_SIGNALING * const event)
455 {
456   SIGNALING_ADDL_FIELD * addl_info = NULL;
457   DLIST_ITEM * addl_info_item = NULL;
458
459   EVEL_ENTER();
460
461   /***************************************************************************/
462   /* Check preconditions.                                                    */
463   /***************************************************************************/
464   assert(event != NULL);
465   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
466
467   evel_json_encode_header(jbuf, &event->header);
468   evel_json_open_named_object(jbuf, "signalingFields");
469
470   /***************************************************************************/
471   /* Mandatory fields                                                        */
472   /***************************************************************************/
473
474   /***************************************************************************/
475   /* Optional fields                                                         */
476   /***************************************************************************/
477   evel_enc_kv_opt_string(jbuf, "compressedSip", &event->compressed_sip);
478   evel_enc_kv_opt_string(jbuf, "correlator", &event->correlator);
479   evel_enc_kv_opt_string(jbuf, "localIpAddress", &event->local_ip_address);
480   evel_enc_kv_opt_string(jbuf, "localPort", &event->local_port);
481   evel_enc_kv_opt_string(jbuf, "remoteIpAddress", &event->remote_ip_address);
482   evel_enc_kv_opt_string(jbuf, "remotePort", &event->remote_port);
483   evel_enc_version(jbuf, "signalingFieldsVersion", event->major_version,event->minor_version);
484   evel_enc_kv_opt_string(jbuf, "summarySip", &event->summary_sip);
485   evel_json_encode_vendor_field(jbuf, &event->vnfname_field);
486
487
488   /***************************************************************************/
489   /* Checkpoint, so that we can wind back if all fields are suppressed.      */
490   /***************************************************************************/
491   evel_json_checkpoint(jbuf);
492   if (evel_json_open_opt_named_list(jbuf, "additionalInformation"))
493   {
494     bool item_added = false;
495
496     addl_info_item = dlist_get_first(&event->additional_info);
497     while (addl_info_item != NULL)
498     { 
499       addl_info = (SIGNALING_ADDL_FIELD*) addl_info_item->item;
500       assert(addl_info != NULL);
501
502       if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
503                                           "additionalInformation",
504                                           addl_info->name))
505       {
506         evel_json_open_object(jbuf);
507         evel_enc_kv_string(jbuf, "name", addl_info->name);
508         evel_enc_kv_string(jbuf, "value", addl_info->value);
509         evel_json_close_object(jbuf);
510         item_added = true;
511       }
512       addl_info_item = dlist_get_next(addl_info_item);
513     }
514     evel_json_close_list(jbuf);
515     
516     /*************************************************************************/
517     /* If we've not written anything, rewind to before we opened the list.   */
518     /*************************************************************************/
519     if (!item_added)
520     {
521       evel_json_rewind(jbuf);
522     }
523   }
524
525   evel_json_close_object(jbuf);
526
527   EVEL_EXIT();
528 }
529
530 /**************************************************************************//**
531  * Free a Signaling event.
532  *
533  * Free off the event supplied.  Will free all the contained allocated memory.
534  *
535  * @note It does not free the event itself, since that may be part of a larger
536  * structure.
537  *****************************************************************************/
538 void evel_free_signaling(EVENT_SIGNALING * const event)
539 {
540   SIGNALING_ADDL_FIELD * addl_info = NULL;
541   EVEL_ENTER();
542
543   /***************************************************************************/
544   /* Check preconditions.  As an internal API we don't allow freeing NULL    */
545   /* events as we do on the public API.                                      */
546   /***************************************************************************/
547   assert(event != NULL);
548   assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
549
550  /***************************************************************************/
551   /* Free all internal strings then the header itself.                       */
552   /***************************************************************************/
553   addl_info = dlist_pop_last(&event->additional_info);
554   while (addl_info != NULL)
555   {
556     EVEL_DEBUG("Freeing Additional Info (%s, %s)",
557                addl_info->name,
558                addl_info->value);
559     free(addl_info->name);
560     free(addl_info->value);
561     free(addl_info);
562     addl_info = dlist_pop_last(&event->additional_info);
563   }
564
565   evel_free_event_vendor_field(&event->vnfname_field);
566   evel_free_option_string(&event->correlator);
567   evel_free_option_string(&event->local_ip_address);
568   evel_free_option_string(&event->local_port);
569   evel_free_option_string(&event->remote_ip_address);
570   evel_free_option_string(&event->remote_port);
571   evel_free_option_string(&event->compressed_sip);
572   evel_free_option_string(&event->summary_sip);
573   evel_free_header(&event->header);
574
575   EVEL_EXIT();
576 }