From f38476aee48fb808b453ebd029150f984b0b0e81 Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Fri, 20 May 2016 15:27:14 +0200
Subject: [PATCH] import VCD into the T

---
 common/utils/T/T.h                     |  40 ++
 common/utils/T/T_defs.h                |  12 +
 common/utils/T/T_messages.txt          | 762 +++++++++++++++++++++++++
 common/utils/T/tracer/event.c          |   4 +
 common/utils/T/tracer/event.h          |   2 +
 common/utils/T/tracer/logger/textlog.c |   4 +-
 common/utils/T/tracer/logger/ttilog.c  |   1 +
 common/utils/T/tracer/utils.c          |   7 +
 common/utils/T/tracer/utils.h          |   1 +
 openair2/UTIL/LOG/vcd_signal_dumper.h  |  12 +
 10 files changed, 844 insertions(+), 1 deletion(-)

diff --git a/common/utils/T/T.h b/common/utils/T/T.h
index 1e1a45779b..58e0d5a885 100644
--- a/common/utils/T/T.h
+++ b/common/utils/T/T.h
@@ -32,6 +32,14 @@
     T_LOCAL_size += sizeof(int); \
   } while (0)
 
+#define T_PUT_ulong(argnum, val) \
+  do { \
+    unsigned long T_PUT_var = (val); \
+    T_CHECK_SIZE(sizeof(unsigned long), argnum); \
+    memcpy(T_LOCAL_buf + T_LOCAL_size, &T_PUT_var, sizeof(unsigned long)); \
+    T_LOCAL_size += sizeof(unsigned long); \
+  } while (0)
+
 #define T_PUT_float(argnum, val) \
   do { \
     float T_PUT_var = (val); \
@@ -535,6 +543,38 @@ extern T_cache_t *T_cache;
 #define T30(...) T_CALL_ERROR
 #define T32(...) T_CALL_ERROR
 
+/* special cases for VCD logs */
+
+#define T_VCD_VARIABLE(var, val) \
+  do { \
+    if (T_ACTIVE(((var) + VCD_FIRST_VARIABLE))) { \
+      if ((var) > VCD_NUM_VARIABLES) { \
+        printf("%s:%d:%s: VCD data out of synch for the T, contact" \
+               " the authors!\n", __FILE__, __LINE__, __FUNCTION__); \
+        abort(); \
+      } \
+      T_LOCAL_DATA \
+      T_HEADER(T_ID((var) + VCD_FIRST_VARIABLE)); \
+      T_PUT_ulong(1, (val)); \
+      T_SEND(); \
+    } \
+  } while (0)
+
+#define T_VCD_FUNCTION(fun, val) \
+  do { \
+    if (T_ACTIVE(((fun) + VCD_FIRST_FUNCTION))) { \
+      if ((fun) > VCD_NUM_FUNCTIONS) { \
+        printf("%s:%d:%s: VCD data out of synch for the T, contact" \
+               " the authors!\n", __FILE__, __LINE__, __FUNCTION__); \
+        abort(); \
+      } \
+      T_LOCAL_DATA \
+      T_HEADER(T_ID((fun) + VCD_FIRST_FUNCTION)); \
+      T_PUT_int(1, (val)); \
+      T_SEND(); \
+    } \
+  } while (0)
+
 #ifndef T_USE_SHARED_MEMORY
 
 #include <stdio.h>
diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h
index faeff507e8..ffd35ad9af 100644
--- a/common/utils/T/T_defs.h
+++ b/common/utils/T/T_defs.h
@@ -21,4 +21,16 @@ typedef struct {
 
 #define T_SHM_FILENAME "/T_shm_segment"
 
+/* number of VCD functions (to be kept up to date! see in T_messages.txt) */
+#define VCD_NUM_FUNCTIONS 139
+
+/* number of VCD variables (to be kept up to date! see in T_messages.txt) */
+#define VCD_NUM_VARIABLES 45
+
+/* first VCD function (to be kept up to date! see in T_messages.txt) */
+#define VCD_FIRST_FUNCTION    ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP)
+
+/* first VCD variable (to be kept up to date! see in T_messages.txt) */
+#define VCD_FIRST_VARIABLE    ((uintptr_t)T_VCD_VARIABLE_FRAME_NUMBER_TX_ENB)
+
 #endif /* _T_defs_H_ */
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
index e437f7f2b9..9f1587db0c 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -573,3 +573,765 @@ ID = LEGACY_CLI_TRACE
 #for debug/test - not used
 ID = first
 ID = buf_test
+
+#VCD variables and functions
+
+#be careful! this must be synchronized with the code!
+#also keep up to date VCD_NUM_VARIABLES and VCD_NUM_FUNCTIONS in T_defs.h
+
+#to synchronize: copy/paste from openair2/UTIL/LOG/vcd_signal_dumper.h
+#the variables and functions name, replace "SIGNAL_DUMPER_VARIABLES" by
+#"VARIABLE" and "SIGNAL_DUMPER_FUNCTIONS" by "FUNCTION" (check that
+#everything is fine! for example we have
+#VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG that has VARIABLE without S)
+#and then process with sed
+
+#to generate variables:
+#sed -e "s/  VCD_VARIABLE_\(.*\)/ID = VCD_VARIABLE_\1\n    DESC = VCD variable \1\n    GROUP = ALL:VCD:ENB\n    FORMAT = ulong,value/" < VCD >> T_messages.txt
+
+#to generate functions:
+#sed -e "s/  VCD_FUNCTION_\(.*\)/ID = VCD_FUNCTION_\1\n    DESC = VCD function \1\n    GROUP = ALL:VCD:ENB\n    FORMAT = int,value/" < VCD.functions >> T_messages.txt
+
+#you may want to manually edit groups for UE instead of eNB
+
+#then count functions and variables and update VCD_NUM_FUNCTIONS and
+#VCD_NUM_VARIABLES in T_defs.h
+
+#also verify that VCD_FIRST_FUNCTION and VCD_FIRST_VARIABLE are correct
+#in T_defs.h. They have to point to the first function and variable
+#as defined below. Note also that the order of the VCD functions
+#and variables must be the same as in the code.
+
+#variables
+
+ID = VCD_VARIABLE_FRAME_NUMBER_TX_ENB
+    DESC = VCD variable FRAME_NUMBER_TX_ENB
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_FRAME_NUMBER_RX_ENB
+    DESC = VCD variable FRAME_NUMBER_RX_ENB
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_RUNTIME_TX_ENB
+    DESC = VCD variable RUNTIME_TX_ENB
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_RUNTIME_RX_ENB
+    DESC = VCD variable RUNTIME_RX_ENB
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_FRAME_NUMBER_TX_UE
+    DESC = VCD variable FRAME_NUMBER_TX_UE
+    GROUP = ALL:VCD:UE
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_FRAME_NUMBER_RX_UE
+    DESC = VCD variable FRAME_NUMBER_RX_UE
+    GROUP = ALL:VCD:UE
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_SLOT_NUMBER_TX_UE
+    DESC = VCD variable SLOT_NUMBER_TX_UE
+    GROUP = ALL:VCD:UE
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_SLOT_NUMBER_RX_UE
+    DESC = VCD variable SLOT_NUMBER_RX_UE
+    GROUP = ALL:VCD:UE
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_SUBFRAME_NUMBER_TX_UE
+    DESC = VCD variable SUBFRAME_NUMBER_TX_UE
+    GROUP = ALL:VCD:UE
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_SUBFRAME_NUMBER_RX_UE
+    DESC = VCD variable SUBFRAME_NUMBER_RX_UE
+    GROUP = ALL:VCD:UE
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_MISSED_SLOTS_ENB
+    DESC = VCD variable MISSED_SLOTS_ENB
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_DAQ_MBOX
+    DESC = VCD variable DAQ_MBOX
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_UE_OFFSET_MBOX
+    DESC = VCD variable UE_OFFSET_MBOX
+    GROUP = ALL:VCD:UE
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_UE_RX_OFFSET
+    DESC = VCD variable UE_RX_OFFSET
+    GROUP = ALL:VCD:UE
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_DIFF
+    DESC = VCD variable DIFF
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_HW_SUBFRAME
+    DESC = VCD variable HW_SUBFRAME
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_HW_FRAME
+    DESC = VCD variable HW_FRAME
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_HW_SUBFRAME_RX
+    DESC = VCD variable HW_SUBFRAME_RX
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_HW_FRAME_RX
+    DESC = VCD variable HW_FRAME_RX
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_TXCNT
+    DESC = VCD variable TXCNT
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_RXCNT
+    DESC = VCD variable RXCNT
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_TRX_TS
+    DESC = VCD variable TRX_TS
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_TRX_TST
+    DESC = VCD variable TRX_TST
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_TX_TS
+    DESC = VCD variable TX_TS
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_RX_TS
+    DESC = VCD variable RX_TS
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_RX_HWCNT
+    DESC = VCD variable RX_HWCNT
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_RX_LHWCNT
+    DESC = VCD variable RX_LHWCNT
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_TX_HWCNT
+    DESC = VCD variable TX_HWCNT
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_TX_LHWCNT
+    DESC = VCD variable TX_LHWCNT
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_RX_PCK
+    DESC = VCD variable RX_PCK
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_TX_PCK
+    DESC = VCD variable TX_PCK
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_RX_SEQ_NUM
+    DESC = VCD variable RX_SEQ_NUM
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_RX_SEQ_NUM_PRV
+    DESC = VCD variable RX_SEQ_NUM_PRV
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_TX_SEQ_NUM
+    DESC = VCD variable TX_SEQ_NUM
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_CNT
+    DESC = VCD variable CNT
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_DUMMY_DUMP
+    DESC = VCD variable DUMMY_DUMP
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_ITTI_SEND_MSG
+    DESC = VCD variable ITTI_SEND_MSG
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_ITTI_POLL_MSG
+    DESC = VCD variable ITTI_POLL_MSG
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_ITTI_RECV_MSG
+    DESC = VCD variable ITTI_RECV_MSG
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_ITTI_ALLOC_MSG
+    DESC = VCD variable ITTI_ALLOC_MSG
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_MP_ALLOC
+    DESC = VCD variable MP_ALLOC
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_MP_FREE
+    DESC = VCD variable MP_FREE
+    GROUP = ALL:VCD:ENB
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_UE_INST_CNT_RX
+    DESC = VCD variable UE_INST_CNT_RX
+    GROUP = ALL:VCD:UE
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_UE_INST_CNT_TX
+    DESC = VCD variable UE_INST_CNT_TX
+    GROUP = ALL:VCD:UE
+    FORMAT = ulong,value
+
+#functions
+
+ID = VCD_FUNCTION_RT_SLEEP
+    DESC = VCD function RT_SLEEP
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_TRX_READ
+    DESC = VCD function TRX_READ
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_TRX_WRITE
+    DESC = VCD function TRX_WRITE
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_TX0
+    DESC = VCD function eNB_PROC_TX0
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_RX0
+    DESC = VCD function eNB_PROC_RX0
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_TX1
+    DESC = VCD function eNB_PROC_TX1
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_RX1
+    DESC = VCD function eNB_PROC_RX1
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_TX2
+    DESC = VCD function eNB_PROC_TX2
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_RX2
+    DESC = VCD function eNB_PROC_RX2
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_TX3
+    DESC = VCD function eNB_PROC_TX3
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_RX3
+    DESC = VCD function eNB_PROC_RX3
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_TX4
+    DESC = VCD function eNB_PROC_TX4
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_RX4
+    DESC = VCD function eNB_PROC_RX4
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_TX5
+    DESC = VCD function eNB_PROC_TX5
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_RX5
+    DESC = VCD function eNB_PROC_RX5
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_TX6
+    DESC = VCD function eNB_PROC_TX6
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_RX6
+    DESC = VCD function eNB_PROC_RX6
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_TX7
+    DESC = VCD function eNB_PROC_TX7
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_RX7
+    DESC = VCD function eNB_PROC_RX7
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_TX8
+    DESC = VCD function eNB_PROC_TX8
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_RX8
+    DESC = VCD function eNB_PROC_RX8
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_TX9
+    DESC = VCD function eNB_PROC_TX9
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_RX9
+    DESC = VCD function eNB_PROC_RX9
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_THREAD_TX
+    DESC = VCD function UE_THREAD_TX
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_THREAD_RX
+    DESC = VCD function UE_THREAD_RX
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_TX
+    DESC = VCD function eNB_TX
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_RX
+    DESC = VCD function eNB_RX
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_TRX
+    DESC = VCD function eNB_TRX
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_TM
+    DESC = VCD function eNB_TM
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_RX_SLEEP
+    DESC = VCD function eNB_RX_SLEEP
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_TX_SLEEP
+    DESC = VCD function eNB_TX_SLEEP
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_eNB_PROC_SLEEP
+    DESC = VCD function eNB_PROC_SLEEP
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_TRX_READ_RF
+    DESC = VCD function TRX_READ_RF
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_TRX_WRITE_RF
+    DESC = VCD function TRX_WRITE_RF
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_SYNCH
+    DESC = VCD function UE_SYNCH
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_SLOT_FEP
+    DESC = VCD function UE_SLOT_FEP
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_RRC_MEASUREMENTS
+    DESC = VCD function UE_RRC_MEASUREMENTS
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_GAIN_CONTROL
+    DESC = VCD function UE_GAIN_CONTROL
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_ADJUST_SYNCH
+    DESC = VCD function UE_ADJUST_SYNCH
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_MEASUREMENT_PROCEDURES
+    DESC = VCD function UE_MEASUREMENT_PROCEDURES
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_PDCCH_PROCEDURES
+    DESC = VCD function UE_PDCCH_PROCEDURES
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_PBCH_PROCEDURES
+    DESC = VCD function UE_PBCH_PROCEDURES
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_TX
+    DESC = VCD function PHY_PROCEDURES_ENB_TX
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_RX
+    DESC = VCD function PHY_PROCEDURES_ENB_RX
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_PROCEDURES_UE_TX
+    DESC = VCD function PHY_PROCEDURES_UE_TX
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_PROCEDURES_UE_RX
+    DESC = VCD function PHY_PROCEDURES_UE_RX
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_LTE
+    DESC = VCD function PHY_PROCEDURES_ENB_LTE
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_PROCEDURES_UE_LTE
+    DESC = VCD function PHY_PROCEDURES_UE_LTE
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_PDSCH_THREAD
+    DESC = VCD function PDSCH_THREAD
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_THREAD0
+    DESC = VCD function DLSCH_THREAD0
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_THREAD1
+    DESC = VCD function DLSCH_THREAD1
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_THREAD2
+    DESC = VCD function DLSCH_THREAD2
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_THREAD3
+    DESC = VCD function DLSCH_THREAD3
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_THREAD4
+    DESC = VCD function DLSCH_THREAD4
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_THREAD5
+    DESC = VCD function DLSCH_THREAD5
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_THREAD6
+    DESC = VCD function DLSCH_THREAD6
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_THREAD7
+    DESC = VCD function DLSCH_THREAD7
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_DECODING0
+    DESC = VCD function DLSCH_DECODING0
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_DECODING1
+    DESC = VCD function DLSCH_DECODING1
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_DECODING2
+    DESC = VCD function DLSCH_DECODING2
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_DECODING3
+    DESC = VCD function DLSCH_DECODING3
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_DECODING4
+    DESC = VCD function DLSCH_DECODING4
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_DECODING5
+    DESC = VCD function DLSCH_DECODING5
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_DECODING6
+    DESC = VCD function DLSCH_DECODING6
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_DECODING7
+    DESC = VCD function DLSCH_DECODING7
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_RX_PDCCH
+    DESC = VCD function RX_PDCCH
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DCI_DECODING
+    DESC = VCD function DCI_DECODING
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_RX_PHICH
+    DESC = VCD function RX_PHICH
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_UE_CONFIG_SIB2
+    DESC = VCD function PHY_UE_CONFIG_SIB2
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_CONFIG_SIB1_ENB
+    DESC = VCD function PHY_CONFIG_SIB1_ENB
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_CONFIG_SIB2_ENB
+    DESC = VCD function PHY_CONFIG_SIB2_ENB
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_CONFIG_DEDICATED_ENB
+    DESC = VCD function PHY_CONFIG_DEDICATED_ENB
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_UE_COMPUTE_PRACH
+    DESC = VCD function PHY_UE_COMPUTE_PRACH
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_ENB_ULSCH_DECODING
+    DESC = VCD function PHY_ENB_ULSCH_DECODING
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_ENB_SFGEN
+    DESC = VCD function PHY_ENB_SFGEN
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_ENB_PRACH_RX
+    DESC = VCD function PHY_ENB_PRACH_RX
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_ENB_PDCCH_TX
+    DESC = VCD function PHY_ENB_PDCCH_TX
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PHY_ENB_RS_TX
+    DESC = VCD function PHY_ENB_RS_TX
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_GENERATE_PRACH
+    DESC = VCD function UE_GENERATE_PRACH
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_ULSCH_MODULATION
+    DESC = VCD function UE_ULSCH_MODULATION
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_ULSCH_ENCODING
+    DESC = VCD function UE_ULSCH_ENCODING
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_ULSCH_SCRAMBLING
+    DESC = VCD function UE_ULSCH_SCRAMBLING
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_ENB_DLSCH_MODULATION
+    DESC = VCD function ENB_DLSCH_MODULATION
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_ENB_DLSCH_ENCODING
+    DESC = VCD function ENB_DLSCH_ENCODING
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_ENB_DLSCH_SCRAMBLING
+    DESC = VCD function ENB_DLSCH_SCRAMBLING
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_MACPHY_INIT
+    DESC = VCD function MACPHY_INIT
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_MACPHY_EXIT
+    DESC = VCD function MACPHY_EXIT
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER
+    DESC = VCD function ENB_DLSCH_ULSCH_SCHEDULER
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_FILL_RAR
+    DESC = VCD function FILL_RAR
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_TERMINATE_RA_PROC
+    DESC = VCD function TERMINATE_RA_PROC
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_INITIATE_RA_PROC
+    DESC = VCD function INITIATE_RA_PROC
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_CANCEL_RA_PROC
+    DESC = VCD function CANCEL_RA_PROC
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_GET_DCI_SDU
+    DESC = VCD function GET_DCI_SDU
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_GET_DLSCH_SDU
+    DESC = VCD function GET_DLSCH_SDU
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_RX_SDU
+    DESC = VCD function RX_SDU
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_MRBCH_PHY_SYNC_FAILURE
+    DESC = VCD function MRBCH_PHY_SYNC_FAILURE
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_SR_INDICATION
+    DESC = VCD function SR_INDICATION
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_DLSCH_PREPROCESSOR
+    DESC = VCD function DLSCH_PREPROCESSOR
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_SCHEDULE_DLSCH
+    DESC = VCD function SCHEDULE_DLSCH
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_FILL_DLSCH_DCI
+    DESC = VCD function FILL_DLSCH_DCI
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_OUT_OF_SYNC_IND
+    DESC = VCD function OUT_OF_SYNC_IND
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_DECODE_SI
+    DESC = VCD function UE_DECODE_SI
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_DECODE_CCCH
+    DESC = VCD function UE_DECODE_CCCH
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_DECODE_BCCH
+    DESC = VCD function UE_DECODE_BCCH
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_SEND_SDU
+    DESC = VCD function UE_SEND_SDU
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_GET_SDU
+    DESC = VCD function UE_GET_SDU
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_GET_RACH
+    DESC = VCD function UE_GET_RACH
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_PROCESS_RAR
+    DESC = VCD function UE_PROCESS_RAR
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_SCHEDULER
+    DESC = VCD function UE_SCHEDULER
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_GET_SR
+    DESC = VCD function UE_GET_SR
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_UE_SEND_MCH_SDU
+    DESC = VCD function UE_SEND_MCH_SDU
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_RLC_DATA_REQ
+    DESC = VCD function RLC_DATA_REQ
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_MAC_RLC_STATUS_IND
+    DESC = VCD function MAC_RLC_STATUS_IND
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_MAC_RLC_DATA_REQ
+    DESC = VCD function MAC_RLC_DATA_REQ
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_MAC_RLC_DATA_IND
+    DESC = VCD function MAC_RLC_DATA_IND
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_RLC_UM_TRY_REASSEMBLY
+    DESC = VCD function RLC_UM_TRY_REASSEMBLY
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_RLC_UM_CHECK_TIMER_DAR_TIME_OUT
+    DESC = VCD function RLC_UM_CHECK_TIMER_DAR_TIME_OUT
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_RLC_UM_RECEIVE_PROCESS_DAR
+    DESC = VCD function RLC_UM_RECEIVE_PROCESS_DAR
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PDCP_RUN
+    DESC = VCD function PDCP_RUN
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PDCP_DATA_REQ
+    DESC = VCD function PDCP_DATA_REQ
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PDCP_DATA_IND
+    DESC = VCD function PDCP_DATA_IND
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PDCP_APPLY_SECURITY
+    DESC = VCD function PDCP_APPLY_SECURITY
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_PDCP_VALIDATE_SECURITY
+    DESC = VCD function PDCP_VALIDATE_SECURITY
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_RRC_RX_TX
+    DESC = VCD function RRC_RX_TX
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_RRC_MAC_CONFIG
+    DESC = VCD function RRC_MAC_CONFIG
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_RRC_UE_DECODE_SIB1
+    DESC = VCD function RRC_UE_DECODE_SIB1
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_RRC_UE_DECODE_SI
+    DESC = VCD function RRC_UE_DECODE_SI
+    GROUP = ALL:VCD:UE
+    FORMAT = int,value
+ID = VCD_FUNCTION_GTPV1U_ENB_TASK
+    DESC = VCD function GTPV1U_ENB_TASK
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_GTPV1U_PROCESS_UDP_REQ
+    DESC = VCD function GTPV1U_PROCESS_UDP_REQ
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_GTPV1U_PROCESS_TUNNEL_DATA_REQ
+    DESC = VCD function GTPV1U_PROCESS_TUNNEL_DATA_REQ
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_UDP_ENB_TASK
+    DESC = VCD function UDP_ENB_TASK
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_EMU_TRANSPORT
+    DESC = VCD function EMU_TRANSPORT
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_LOG_RECORD
+    DESC = VCD function LOG_RECORD
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_ITTI_ENQUEUE_MESSAGE
+    DESC = VCD function ITTI_ENQUEUE_MESSAGE
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_ITTI_DUMP_ENQUEUE_MESSAGE
+    DESC = VCD function ITTI_DUMP_ENQUEUE_MESSAGE
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_ITTI_DUMP_ENQUEUE_MESSAGE_MALLOC
+    DESC = VCD function ITTI_DUMP_ENQUEUE_MESSAGE_MALLOC
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_ITTI_RELAY_THREAD
+    DESC = VCD function ITTI_RELAY_THREAD
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
+ID = VCD_FUNCTION_TEST
+    DESC = VCD function TEST
+    GROUP = ALL:VCD:ENB
+    FORMAT = int,value
diff --git a/common/utils/T/tracer/event.c b/common/utils/T/tracer/event.c
index 2071c90356..1d9f3a4081 100644
--- a/common/utils/T/tracer/event.c
+++ b/common/utils/T/tracer/event.c
@@ -36,6 +36,10 @@ event new_event(int type, int length, char *buffer, void *database)
       e.e[i].type = EVENT_INT;
       e.e[i].i = *(int *)(&buffer[offset]);
       offset += 4;
+    } else if (!strcmp(f.type[i], "ulong")) {
+      e.e[i].type = EVENT_ULONG;
+      e.e[i].ul = *(unsigned long *)(&buffer[offset]);
+      offset += sizeof(unsigned long);
     } else if (!strcmp(f.type[i], "string")) {
       e.e[i].type = EVENT_STRING;
       e.e[i].s = &buffer[offset];
diff --git a/common/utils/T/tracer/event.h b/common/utils/T/tracer/event.h
index 0cecca3265..32abee4ead 100644
--- a/common/utils/T/tracer/event.h
+++ b/common/utils/T/tracer/event.h
@@ -8,6 +8,7 @@
 
 enum event_arg_type {
   EVENT_INT,
+  EVENT_ULONG,
   EVENT_STRING,
   EVENT_BUFFER
 };
@@ -17,6 +18,7 @@ typedef struct {
   //int offset;
   union {
     int i;
+    unsigned long ul;
     char *s;
     struct {
       int bsize;
diff --git a/common/utils/T/tracer/logger/textlog.c b/common/utils/T/tracer/logger/textlog.c
index 4a69a9619a..ea7f9c8a93 100644
--- a/common/utils/T/tracer/logger/textlog.c
+++ b/common/utils/T/tracer/logger/textlog.c
@@ -10,7 +10,7 @@
 
 enum format_item_type {
   INSTRING,
-  INT, STRING, BUFFER };
+  INT, ULONG, STRING, BUFFER };
 
 struct format_item {
   enum format_item_type type;
@@ -56,6 +56,7 @@ static void _event(void *p, event e)
   switch(l->f[i].type) {
   case INSTRING: PUTS(&l->o, l->f[i].s); break;
   case INT:      PUTI(&l->o, e.e[l->f[i].event_arg].i); break;
+  case ULONG:    PUTUL(&l->o, e.e[l->f[i].event_arg].ul); break;
   case STRING:   PUTS_CLEAN(&l->o, e.e[l->f[i].event_arg].s); break;
   case BUFFER:
     PUTS(&l->o, "{buffer size:");
@@ -86,6 +87,7 @@ static int find_argument(char *name, database_event_format f,
   if (i == f.count) return 0;
   *event_arg = i;
   if (!strcmp(f.type[i], "int"))         *it = INT;
+  else if (!strcmp(f.type[i], "ulong"))  *it = ULONG;
   else if (!strcmp(f.type[i], "string")) *it = STRING;
   else if (!strcmp(f.type[i], "buffer")) *it = BUFFER;
   else return 0;
diff --git a/common/utils/T/tracer/logger/ttilog.c b/common/utils/T/tracer/logger/ttilog.c
index 649c4b497a..172d0eeb2d 100644
--- a/common/utils/T/tracer/logger/ttilog.c
+++ b/common/utils/T/tracer/logger/ttilog.c
@@ -29,6 +29,7 @@ static void _event(void *p, event e)
   subframe = e.e[l->subframe_arg].i;
   switch (e.e[l->data_arg].type) {
   case EVENT_INT: value = e.e[l->data_arg].i; break;
+  case EVENT_ULONG: value = e.e[l->data_arg].ul; break;
   default: printf("%s:%d: unsupported type\n", __FILE__, __LINE__); abort();
   }
 
diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c
index f4bcd1243c..95b4084822 100644
--- a/common/utils/T/tracer/utils.c
+++ b/common/utils/T/tracer/utils.c
@@ -115,3 +115,10 @@ void PUTI(OBUF *o, int i)
   sprintf(s, "%d", i);
   PUTS(o, s);
 }
+
+void PUTUL(OBUF *o, unsigned long l)
+{
+  char s[128];
+  sprintf(s, "%ld", l);
+  PUTS(o, s);
+}
diff --git a/common/utils/T/tracer/utils.h b/common/utils/T/tracer/utils.h
index dd96d39941..f7e3a6d256 100644
--- a/common/utils/T/tracer/utils.h
+++ b/common/utils/T/tracer/utils.h
@@ -36,5 +36,6 @@ void PUTC(OBUF *o, char c);
 void PUTS(OBUF *o, char *s);
 void PUTS_CLEAN(OBUF *o, char *s);
 void PUTI(OBUF *o, int i);
+void PUTUL(OBUF *o, unsigned long i);
 
 #endif /* _UTILS_H_ */
diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.h b/openair2/UTIL/LOG/vcd_signal_dumper.h
index 9ca55846fd..8ba56d4bd2 100644
--- a/openair2/UTIL/LOG/vcd_signal_dumper.h
+++ b/openair2/UTIL/LOG/vcd_signal_dumper.h
@@ -312,6 +312,16 @@ void vcd_signal_dumper_dump_function_by_name(vcd_signal_dump_functions  function
 
 extern int ouput_vcd;
 
+#if T_TRACER
+
+#define VCD_SIGNAL_DUMPER_INIT(x)         /* nothing */
+#define VCD_SIGNAL_DUMPER_CLOSE()         /* nothing */
+#define VCD_SIGNAL_DUMPER_CREATE_HEADER() /* nothing */
+#define VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(var, val) T_VCD_VARIABLE(var, val)
+#define VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(var, val) T_VCD_FUNCTION(var, val)
+
+#else /* T_TRACER */
+
 #if defined(ENABLE_VCD)
    #define VCD_SIGNAL_DUMPER_INIT(aRgUmEnT)                   vcd_signal_dumper_init(aRgUmEnT)
    #define VCD_SIGNAL_DUMPER_CLOSE()                          vcd_signal_dumper_close()
@@ -326,5 +336,7 @@ extern int ouput_vcd;
    #define VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(vAr1,vAr2)
 #endif
 
+#endif /* T_TRACER */
+
 #endif /* !defined (VCD_SIGNAL_DUMPER_H_) */
 
-- 
GitLab