Adding C and Java VES Vendor libs 19/14319/1
authorGokul Singaraju <goksing@gmail.com>
Thu, 21 Sep 2017 16:51:55 +0000 (12:51 -0400)
committerGokul Singaraju <goksing@gmail.com>
Thu, 21 Sep 2017 16:55:40 +0000 (12:55 -0400)
Issue-Id: VNFRQTS-94
Change-Id: Iee0e154a94f3ef4ea43efcd474acacb0fa54c43f
Signed-Off-by: Gokul Singaraju <goksing@gmail.com>
116 files changed:
veslibrary/.README.swp [new file with mode: 0644]
veslibrary/Package_instructions [new file with mode: 0644]
veslibrary/README [new file with mode: 0644]
veslibrary/ves_clibrary/LICENSE.TXT [new file with mode: 0644]
veslibrary/ves_clibrary/VESreporting_vFW/LICENSE.TXT [new file with mode: 0644]
veslibrary/ves_clibrary/VESreporting_vFW/Makefile [new file with mode: 0644]
veslibrary/ves_clibrary/VESreporting_vFW/README.md [new file with mode: 0644]
veslibrary/ves_clibrary/VESreporting_vFW/dep.xml [new file with mode: 0644]
veslibrary/ves_clibrary/VESreporting_vFW/go-client.sh [new file with mode: 0755]
veslibrary/ves_clibrary/VESreporting_vFW/pom.xml [new file with mode: 0644]
veslibrary/ves_clibrary/VESreporting_vFW/vpp_measurement_reporter.c [new file with mode: 0644]
veslibrary/ves_clibrary/VESreporting_vLB/LICENSE.TXT [new file with mode: 0644]
veslibrary/ves_clibrary/VESreporting_vLB/Makefile [new file with mode: 0644]
veslibrary/ves_clibrary/VESreporting_vLB/README.md [new file with mode: 0644]
veslibrary/ves_clibrary/VESreporting_vLB/dep.xml [new file with mode: 0644]
veslibrary/ves_clibrary/VESreporting_vLB/go-client.sh [new file with mode: 0755]
veslibrary/ves_clibrary/VESreporting_vLB/pom.xml [new file with mode: 0644]
veslibrary/ves_clibrary/VESreporting_vLB/vpp_measurement_reporter.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/LICENSE.TXT [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/bldjobs/Makefile [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/double_list.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/double_list.h [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.h [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event_mgr.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_fault.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_heartbeat_fields.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal.h [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal_event.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_json_buffer.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_jsonobject.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_logging.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_mobile_flow.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_option.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_other.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_reporting_measurement.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_scaling_measurement.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_sipsignaling.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_state_change.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_strings.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_syslog.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_threshold_cross.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_throttle.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_throttle.h [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_voicequality.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/hashtable.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/hashtable.h [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/jsmn.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/jsmn.h [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/license.md [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/metadata.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/metadata.h [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/quickstart.md [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/readme.md [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/ring_buffer.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_library/ring_buffer.h [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/code/evel_unit/evel_unit.c [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/docs/source/evel/README [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/libs/x86_64/README [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/output/x86_64/README [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-library/readme.md [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/LICENSE.md [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/README.md [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/LICENSE.TXT [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/__init__.py [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/collector.py [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/rest_dispatcher.py [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/test_control.py [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/config/collector.conf [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/LICENSE.TXT [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/base_schema.json [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/event_format_updated.json [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/test_control_schema.json [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/throttle_schema.json [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/docs/test_collector_user_guide/LICENSE.TXT [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/docs/test_collector_user_guide/images/architecture.png [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/docs/test_collector_user_guide/test_collector_user_guide.md [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/scripts/linux/go-collector.sh [new file with mode: 0644]
veslibrary/ves_clibrary/evel/evel-test-collector/scripts/windows/go-collector.bat [new file with mode: 0644]
veslibrary/ves_clibrary/libs/x86_64/README [new file with mode: 0644]
veslibrary/ves_clibrary/output/x86_64/README [new file with mode: 0644]
veslibrary/ves_clibrary/readme.md [new file with mode: 0644]
veslibrary/ves_javalibrary/.classpath [new file with mode: 0644]
veslibrary/ves_javalibrary/.gitignore [new file with mode: 0644]
veslibrary/ves_javalibrary/.project [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/.classpath [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/.project [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/.settings/org.eclipse.m2e.core.prefs [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/java/com/javacodegeeks/AppTest.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/pom.xml [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/AgentMain.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelFault.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelHeader.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelHeartbeatField.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelMobileFlow.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOption.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionDouble.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionInt.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionIntHeader.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionLong.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionString.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionTime.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOther.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelScalingMeasurement.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelSipSignaling.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelStateChange.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelSyslog.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelThresholdCross.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelVoiceQuality.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/RingBuffer.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/src_test/maindir/Main.java [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/target/maven-archiver/pom.properties [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst [new file with mode: 0644]
veslibrary/ves_javalibrary/evel_javalib2/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst [new file with mode: 0644]

diff --git a/veslibrary/.README.swp b/veslibrary/.README.swp
new file mode 100644 (file)
index 0000000..67e26f3
Binary files /dev/null and b/veslibrary/.README.swp differ
diff --git a/veslibrary/Package_instructions b/veslibrary/Package_instructions
new file mode 100644 (file)
index 0000000..5ba9faa
--- /dev/null
@@ -0,0 +1,54 @@
+ #
+ # ============LICENSE_START==========================================
+ # ===================================================================
+ # Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ # ===================================================================
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+ # You may obtain a copy of the License at
+ #
+ #        http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+ # ============LICENSE_END============================================
+ #
+ # ECOMP and OpenECOMP are trademarks
+ # and service marks of AT&T Intellectual Property.
+ #
+ # 
+
+For support queries reach out to Gokul Singaraju gs244f@att.com
+
+To build CSAR Package with VES C or Java Library
+
+Clone the git vnfsdk/pkgtools repository
+
+Edit requirements.txt input file
+
+For C Library
+  include libevel.so shared library and VES agent artifacts
+
+include <path>/ves_clibrary/evel/evel-library/libs/x86_64/libevel.so
+include <path>/ves_agent
+
+Include the ves_agent in VM startup with appropriate collector ip and port
+
+For Java Library
+  include all dependent java libraries and VES agent artifacts
+
+include <path>/log4j-1.2.17.jar
+include <path>/javax.json-api-1.1.jar
+include <path>/slf4j-api-1.7.5.jar
+include <path>/slf4j-log4j12-1.7.5.jar
+include <path>/javax.json-1.0.4.jar
+include <path>/ves_agent
+
+
+Include the ves_agent in VM startup with appropriate collector ip and port
+
+
diff --git a/veslibrary/README b/veslibrary/README
new file mode 100644 (file)
index 0000000..039a266
--- /dev/null
@@ -0,0 +1,109 @@
+ #
+ # ============LICENSE_START==========================================
+ # ===================================================================
+ # Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ # ===================================================================
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+ # You may obtain a copy of the License at
+ #
+ #        http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+ # ============LICENSE_END============================================
+ #
+ # ECOMP and OpenECOMP are trademarks
+ # and service marks of AT&T Intellectual Property.
+ #
+ # 
+
+For support queries reach out to Gokul Singaraju gs244f@att.com
+
+VES Library is opensourced library provided for Virtual Event Streaming Agent
+development.
+
+The VES Library provides standard API for Data collector agents
+to interface with DCAE. This VES Library supports 5.x version of API.
+   The Vendor related documentation is provided in
+         https://github.com/att/evel-test-collector/tree/master/docs/att_interface_definition
+   VES preliminary documentation is under
+         https://wiki.opnfv.org/display/ves/VES+Home
+
+
+To compile C Library
+   C compiler would be needed for Linux and Windows.
+
+  Ubuntu platform dependencies are
+              sudo apt-get install update
+              sudo apt-get install upgrade
+              sudo apt-get install build-essential
+  For Redhat/CentOS it would be
+              sudo yum groupinstall "Development Tools"
+
+  Compile:
+              cd veslibrary/ves_clibrary/evel/evel-library/bldjobs;make clean;make all
+  Install VES Library:
+              cd veslibrary/ves_clibrary/evel/evel-library/bldjobs;make install
+
+For Running the VES Agent
+      pthread, curl and libcurl3 packages will neeed to be installed
+    Sample agents Firewall (vFW) and Loadbalancer (vLB) are provided as development examples
+    Modify per your agent requirements
+     Reporting DCAE/VES collector ip and port also need to be setup
+
+
+To compile Java library
+
+  On Windows
+   Load the Maven project into Eclipse
+    Select evel_javalib2 project Right click
+      Select Maven > Download Sources 
+      Select Maven > Update Project
+   then
+    Select pom.xml Right click > Run As > Maven Clean
+    Select pom.xml Right click > Run As > Maven Build
+   to compile and build the jar
+
+  On Ubuntu platform dependencies are
+   sudo apt-get install openjdk-8-jre
+   sudo apt-get install openjdk-8-jdk
+
+  Maven build utility
+   sudo apt-get install mvn
+
+  On Redhat/Centos
+   sudo yum install java-1.8.0-openjdk
+   sudo yum install java-1.8.0-openjdk-devel
+
+  Maven
+   sudo yum install maven2
+
+  Compile library:
+   cd  veslibrary/ves_javalibrary/evel_javalib2;mvn clean install
+
+
+  Copy the evel_javalib2-0.0.1-SNAPSHOT.jar into directory
+
+  Dependent classpath jars that are needed to compile and Run
+   log4j-1.2.17.jar
+   javax.json-api-1.1.jar
+   slf4j-api-1.7.5.jar
+   slf4j-log4j12-1.7.5.jar
+   javax.json-1.0.4.jar
+
+  Sample Agent application is at src_test/maindir/Main.java
+     mkdir ./evel_javalibrary/att/com/maindir
+     copy the agent code into this directory and modify per your agent requirements
+     Reporting DCAE/VES collector ip and port also need to be setup
+
+
+  Compile Sample VES agent
+   javac -cp <.:dependent jars> ./evel_javalibrary/att/com/maindir
+  Run VES agent
+   java -cp <.:dependent jars> evel_javalibrary.att.com.maindir.Main
+
+
diff --git a/veslibrary/ves_clibrary/LICENSE.TXT b/veslibrary/ves_clibrary/LICENSE.TXT
new file mode 100644 (file)
index 0000000..ae12da2
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * ============LICENSE_START==========================================
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ *
+ * ECOMP and OpenECOMP are trademarks 
+ * and service marks of AT&T Intellectual Property.
+ *
+ */
diff --git a/veslibrary/ves_clibrary/VESreporting_vFW/LICENSE.TXT b/veslibrary/ves_clibrary/VESreporting_vFW/LICENSE.TXT
new file mode 100644 (file)
index 0000000..ae12da2
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * ============LICENSE_START==========================================
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ *
+ * ECOMP and OpenECOMP are trademarks 
+ * and service marks of AT&T Intellectual Property.
+ *
+ */
diff --git a/veslibrary/ves_clibrary/VESreporting_vFW/Makefile b/veslibrary/ves_clibrary/VESreporting_vFW/Makefile
new file mode 100644 (file)
index 0000000..e7ac57b
--- /dev/null
@@ -0,0 +1,45 @@
+#############################################################################
+#
+# Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#############################################################################
+
+CC=gcc
+ARCH=$(shell getconf LONG_BIT)
+#CODE_ROOT=$(CURDIR)/../../..
+CODE_ROOT=../VES5.0/evel/evel-library
+LIBS_DIR=$(CODE_ROOT)/libs/x86_$(ARCH)
+INCLUDE_DIR=$(CODE_ROOT)/code/evel_library
+
+#******************************************************************************
+# Standard compiler flags.                                                    *
+#******************************************************************************
+CPPFLAGS=
+CFLAGS=-Wall -g -fPIC
+
+all:   vpp_measurement_reporter
+
+clean:
+       rm -f vpp_measurement_reporter
+
+vpp_measurement_reporter: vpp_measurement_reporter.c
+       $(CC) $(CPPFLAGS) $(CFLAGS) -o vpp_measurement_reporter \
+                                    -L $(LIBS_DIR) \
+                                    -I $(INCLUDE_DIR) \
+                               vpp_measurement_reporter.c \
+                              -lpthread \
+                              -level \
+                              -lcurl
+
+
diff --git a/veslibrary/ves_clibrary/VESreporting_vFW/README.md b/veslibrary/ves_clibrary/VESreporting_vFW/README.md
new file mode 100644 (file)
index 0000000..ff6ba25
--- /dev/null
@@ -0,0 +1,28 @@
+
+PROJECT DESCRIPTION
+
+“The content of this directory is currently under development and, at this stage, is not intended for demonstration and/or testing.”
+
+---
+This project contains the source code and scripts for the periodic generation of network measurement reports. The folder contains:
+
+ - README.md: this file.
+
+ - LICENSE.TXT: the license text.
+
+ - vpp_measurement_reporter.c: source code that uses the ECOMP Vendor Event Listener Library (VES) to read metrics from the network interface and send periodic measurement reports to the VES collector in DCAE. The VES library used here has been cloned from the GitHub repository at https://github.com/att/evel-library on February 1, 2017.
+
+ - Makefile: makefile that compiles vpp_measurement_reporter.c and generates vpp_measurement_reporter binary.
+
+ - go-client.sh: bash script that starts up the vpp_measurement_reporter binary generated by Makefile. It reads input parameters like DCAE IP address and port from configuration files contained in /opt/config.
+
+
+USAGE
+---
+To run the vpp_measurement_reporter, please execute the following steps:
+
+ - Make the go-client.sh script executable
+        chmod +x go-client.sh
+
+ - Run the go-client.sh script
+        ./go-client.sh  
diff --git a/veslibrary/ves_clibrary/VESreporting_vFW/dep.xml b/veslibrary/ves_clibrary/VESreporting_vFW/dep.xml
new file mode 100644 (file)
index 0000000..fc18229
--- /dev/null
@@ -0,0 +1,25 @@
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" 
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+  <id>demo</id>
+  <formats>
+    <format>tar.gz</format>
+  </formats>
+  <fileSets>
+
+    <fileSet>
+      <directory>.</directory>
+      <outputDirectory>/</outputDirectory>
+      <includes>
+        <include>*.sh</include>
+       <include>*.md</include>
+       <include>*.TXT</include>
+       <include>*.c</include>
+       <include>Makefile</include>
+      </includes>
+    </fileSet>
+
+  </fileSets>
+</assembly>
+
+
diff --git a/veslibrary/ves_clibrary/VESreporting_vFW/go-client.sh b/veslibrary/ves_clibrary/VESreporting_vFW/go-client.sh
new file mode 100755 (executable)
index 0000000..3d1b159
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+export LD_LIBRARY_PATH="/opt/VES/libs/x86_64/"
+DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt)
+DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt)
+./vpp_measurement_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT eth1
diff --git a/veslibrary/ves_clibrary/VESreporting_vFW/pom.xml b/veslibrary/ves_clibrary/VESreporting_vFW/pom.xml
new file mode 100644 (file)
index 0000000..9b89913
--- /dev/null
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ============LICENSE_START==========================================
+ ===================================================================
+ Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END============================================
+
+ ECOMP and OpenECOMP are trademarks
+ and service marks of AT&T Intellectual Property.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+<parent>
+    <groupId>org.openecomp.demo.vnf</groupId>
+    <artifactId>demo-aggregator</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.openecomp.demo.vnf.ves</groupId>
+  <artifactId>ves_vfw_reporting</artifactId>
+
+  <build>
+    <plugins>
+
+       <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.2</version>
+        <executions>
+          <execution>
+            <id>default-jar</id>
+            <phase>never</phase>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>2.5.3</version>
+        <configuration>
+          <descriptor>dep.xml</descriptor>
+        </configuration>
+        <executions>
+          <execution>
+            <id>create-archive</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+        <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>exec-maven-plugin</artifactId>
+            <executions>
+                <execution>
+                    <phase>none</phase>
+                </execution>
+            </executions>
+            <configuration>
+                <skip>true</skip>
+            </configuration>
+        </plugin>
+
+    </plugins>
+  </build>
+
+</project>
\ No newline at end of file
diff --git a/veslibrary/ves_clibrary/VESreporting_vFW/vpp_measurement_reporter.c b/veslibrary/ves_clibrary/VESreporting_vFW/vpp_measurement_reporter.c
new file mode 100644 (file)
index 0000000..8604d0c
--- /dev/null
@@ -0,0 +1,364 @@
+
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include "evel.h"
+
+#define BUFSIZE 128
+#define READ_INTERVAL 10
+
+typedef struct dummy_vpp_metrics_struct {
+  int bytes_in;
+  int bytes_out;
+  int packets_in;
+  int packets_out;
+} vpp_metrics_struct;
+
+void read_vpp_metrics(vpp_metrics_struct *, char *);
+
+unsigned long long epoch_start = 0;
+
+#ifdef DOCKER
+int measure_traffic() 
+{
+
+  EVEL_ERR_CODES evel_rc = EVEL_SUCCESS;
+  FILE *fp;
+  int status;
+  char count[10];
+  time_t rawtime;
+  struct tm * timeinfo;
+  char period [21];
+  char cmd [100];
+  int concurrent_sessions = 0;
+  int configured_entities = 0;
+  double mean_request_latency = 0;
+  double measurement_interval = 1;
+  double memory_configured = 0;
+  double memory_used = 0;
+  int request_rate=0;
+  char secs [3];
+  int sec;
+  double loadavg;
+
+  printf("Checking app traffic\n");
+  time (&rawtime);
+  timeinfo = localtime (&rawtime);
+  strftime(period,21,"%d/%b/%Y:%H:%M:",timeinfo);
+  strftime(secs,3,"%S",timeinfo);
+  sec = atoi(secs);
+  if (sec == 0) sec = 59;
+  sprintf(secs, "%02d", sec);
+  strncat(period, secs, 21);
+  // ....x....1....x....2.
+  // 15/Oct/2016:17:51:19
+  strcpy(cmd, "sudo docker logs vHello | grep -c ");
+  strncat(cmd, period, 100);
+
+  fp = popen(cmd, "r");
+  if (fp == NULL) {
+    EVEL_ERROR("popen failed to execute command");
+  }
+
+  if (fgets(count, 10, fp) != NULL) {
+    request_rate = atoi(count);
+    printf("Reporting request rate for second: %s as %d\n", period, request_rate);
+
+    }
+    else {
+      EVEL_ERROR("New Measurement failed");
+    }
+    printf("Processed measurement\n");
+  
+  status = pclose(fp);
+  if (status == -1) {
+    EVEL_ERROR("pclose returned an error");
+  }
+  return request_rate;
+}
+
+#endif
+
+
+
+/**************************************************************************//**
+ * tap live cpu stats
+ *****************************************************************************/
+void evel_get_cpu_stats(EVENT_MEASUREMENT * measurement)
+{
+  FILE *fp;
+  char path[1024];
+  double usage=0.0;
+  double idle;
+  double intrpt;
+  double nice;
+  double softirq;
+  double steal;
+  double sys;
+  double user;
+  double wait;
+  MEASUREMENT_CPU_USE *cpu_use = NULL;
+
+  /* Open the command for reading. */
+  //fp = popen("/bin/ls /etc/", "r");
+  fp = popen("/usr/bin/top -bn 2 -d 0.01 | grep '^%Cpu' | tail -n 1 ", "r");
+  if (fp == NULL) {
+    printf("Failed to run command\n" );
+    exit(1);
+  }
+
+  /* Read the output a line at a time - output it. */
+  while (fgets(path, sizeof(path)-1, fp) != NULL) {
+    printf("%s", path+10);
+    sscanf(path+10," %lf us, %lf sy,  %lf ni,  %lf id,  %lf wa,  %lf hi,  %lf si,  %lf st",
+    &user,&sys,&nice,&idle,&wait,&intrpt,&softirq,&steal);
+  }
+
+  /* close */
+  pclose(fp);
+
+  cpu_use = evel_measurement_new_cpu_use_add(measurement, "cpu1", usage);
+  if( cpu_use != NULL ){
+  evel_measurement_cpu_use_idle_set(cpu_use,idle);
+  //evel_measurement_cpu_use_interrupt_set(cpu_use,intrpt);
+  //evel_measurement_cpu_use_nice_set(cpu_use,nice);
+  //evel_measurement_cpu_use_softirq_set(cpu_use,softirq);
+  //evel_measurement_cpu_use_steal_set(cpu_use,steal);
+  evel_measurement_cpu_use_system_set(cpu_use,sys);
+  evel_measurement_cpu_use_usageuser_set(cpu_use,user);
+  //evel_measurement_cpu_use_wait_set(cpu_use,wait);
+  //evel_measurement_cpu_use_add(measurement, "cpu2", usage,idle,intrpt,nice,softirq,steal,sys,user,wait);
+  }
+}
+
+
+
+int main(int argc, char** argv)
+{
+  EVEL_ERR_CODES evel_rc = EVEL_SUCCESS;
+  EVENT_MEASUREMENT* vpp_m = NULL;
+  EVENT_HEADER* vpp_m_header = NULL;
+  int bytes_in_this_round;
+  int bytes_out_this_round;
+  int packets_in_this_round;
+  int packets_out_this_round;
+  vpp_metrics_struct* last_vpp_metrics = malloc(sizeof(vpp_metrics_struct));
+  vpp_metrics_struct* curr_vpp_metrics = malloc(sizeof(vpp_metrics_struct));
+  struct timeval time_val;
+  //time_t start_epoch;
+  //time_t last_epoch;
+  char hostname[BUFSIZE];
+  char* fqdn = argv[1];
+  int port = atoi(argv[2]);
+  char* vnic = argv[3];
+  MEASUREMENT_VNIC_PERFORMANCE * vnic_performance = NULL;
+  //struct timeval tv_start;
+
+  printf("\nVector Packet Processing (VPP) measurement collection\n");
+  fflush(stdout);
+
+  if (argc != 4)
+  {
+    fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <interface>\n", argv[0]);
+    exit(-1);
+  }
+  srand(time(NULL));
+
+  /**************************************************************************/
+  /* Initialize                                                             */
+  /**************************************************************************/
+  if(evel_initialize(fqdn,                         /* FQDN                  */
+                     port,                        /* Port                  */
+                     NULL,                         /* optional path         */
+                     NULL,                         /* optional topic        */
+                     0,                            /* HTTPS?                */
+                     "",                           /* Username              */
+                     "",                           /* Password              */
+                     EVEL_SOURCE_VIRTUAL_MACHINE,  /* Source type           */
+                     "vFirewall",                         /* Role                  */
+                     1))                           /* Verbosity             */
+  {
+    fprintf(stderr, "\nFailed to initialize the EVEL library!!!\n");
+    exit(-1);
+  }
+  else
+  {
+    printf("\nInitialization completed\n");
+  }
+
+  gethostname(hostname, BUFSIZE);
+  memset(last_vpp_metrics, 0, sizeof(vpp_metrics_struct));
+  read_vpp_metrics(last_vpp_metrics, vnic);
+  gettimeofday(&time_val, NULL);
+  epoch_start = time_val.tv_sec * 1000000 + time_val.tv_usec;
+  sleep(READ_INTERVAL);
+
+  /***************************************************************************/
+  /* Collect metrics from the VNIC                                           */
+  /***************************************************************************/
+  while(1) {
+    memset(curr_vpp_metrics, 0, sizeof(vpp_metrics_struct));
+    read_vpp_metrics(curr_vpp_metrics, vnic);
+
+    if(curr_vpp_metrics->bytes_in - last_vpp_metrics->bytes_in > 0) {
+      bytes_in_this_round = curr_vpp_metrics->bytes_in - last_vpp_metrics->bytes_in;
+    }
+    else {
+      bytes_in_this_round = 0;
+    }
+    if(curr_vpp_metrics->bytes_out - last_vpp_metrics->bytes_out > 0) {
+      bytes_out_this_round = curr_vpp_metrics->bytes_out - last_vpp_metrics->bytes_out;
+    }
+    else {
+      bytes_out_this_round = 0;
+    }
+    if(curr_vpp_metrics->packets_in - last_vpp_metrics->packets_in > 0) {
+      packets_in_this_round = curr_vpp_metrics->packets_in - last_vpp_metrics->packets_in;
+    }
+    else {
+      packets_in_this_round = 0;
+    }
+    if(curr_vpp_metrics->packets_out - last_vpp_metrics->packets_out > 0) {
+      packets_out_this_round = curr_vpp_metrics->packets_out - last_vpp_metrics->packets_out;
+    }
+    else {
+      packets_out_this_round = 0;
+    }
+
+    vpp_m = evel_new_measurement(READ_INTERVAL,"Measurement_vVNF","TrafficStats_1.2.3.4");
+    vnic_performance = (MEASUREMENT_VNIC_PERFORMANCE *)evel_measurement_new_vnic_performance("eth0", "true");
+    evel_meas_vnic_performance_add(vpp_m, vnic_performance);
+
+    if(vpp_m != NULL) {
+      printf("New measurement report created...\n");
+
+      evel_measurement_type_set(vpp_m, "HTTP request rate");
+      evel_measurement_request_rate_set(vpp_m, rand()%10000);
+
+      evel_vnic_performance_rx_total_pkt_delta_set(vnic_performance, packets_in_this_round);
+      evel_vnic_performance_tx_total_pkt_delta_set(vnic_performance, packets_out_this_round);
+
+      evel_vnic_performance_rx_octets_delta_set(vnic_performance, bytes_in_this_round);
+      evel_vnic_performance_tx_octets_delta_set(vnic_performance, bytes_out_this_round);
+      evel_get_cpu_stats(vpp_m);
+
+      /***************************************************************************/
+      /* Set parameters in the MEASUREMENT header packet                         */
+      /***************************************************************************/
+      struct timeval tv_now;
+      gettimeofday(&tv_now, NULL);
+      unsigned long long epoch_now = tv_now.tv_usec + 1000000 * tv_now.tv_sec;
+
+      //last_epoch = start_epoch + READ_INTERVAL * 1000000;
+      vpp_m_header = (EVENT_HEADER *)vpp_m;
+      //vpp_m_header->start_epoch_microsec = start_epoch;
+      //vpp_m_header->last_epoch_microsec = last_epoch;
+      evel_start_epoch_set(&vpp_m->header, epoch_start);
+      evel_last_epoch_set(&vpp_m->header, epoch_now);
+      epoch_start = epoch_now;
+
+      evel_nfcnamingcode_set(&vpp_m->header, "vVNF");
+      evel_nfnamingcode_set(&vpp_m->header, "vVNF");
+      //strcpy(vpp_m_header->reporting_entity_id.value, "No UUID available");
+      //strcpy(vpp_m_header->reporting_entity_name, hostname);
+      evel_reporting_entity_name_set(&vpp_m->header, "fwll");
+      evel_reporting_entity_id_set(&vpp_m->header, "No UUID available");
+      evel_rc = evel_post_event(vpp_m_header);
+
+      if(evel_rc == EVEL_SUCCESS) {
+        printf("Measurement report correctly sent to the collector!\n");
+      }
+      else {
+        printf("Post failed %d (%s)\n", evel_rc, evel_error_string());
+      }
+    }
+    else {
+      printf("New measurement report failed (%s)\n", evel_error_string());
+    }
+
+    last_vpp_metrics->bytes_in = curr_vpp_metrics->bytes_in;
+    last_vpp_metrics->bytes_out = curr_vpp_metrics->bytes_out;
+    last_vpp_metrics->packets_in = curr_vpp_metrics->packets_in;
+    last_vpp_metrics->packets_out = curr_vpp_metrics->packets_out;
+    //gettimeofday(&time_val, NULL);
+    //start_epoch = time_val.tv_sec * 1000000 + time_val.tv_usec;
+
+    sleep(READ_INTERVAL);
+  }
+
+  /***************************************************************************/
+  /* Terminate                                                               */
+  /***************************************************************************/
+  sleep(1);
+  free(last_vpp_metrics);
+  free(curr_vpp_metrics);
+  evel_terminate();
+  printf("Terminated\n");
+
+  return 0;
+}
+
+void read_vpp_metrics(vpp_metrics_struct *vpp_metrics, char *vnic) {
+  // Define an array of char that contains the parameters of the unix 'cut' command
+  char* params[] = {"-f3", "-f11", "-f4", "-f12"};
+  // Define the unix command to execute in order to read metrics from the vNIC
+  char* cmd_prefix = "sudo cat /proc/net/dev | grep \"";
+  char* cmd_mid = "\" | tr -s \' \' | cut -d\' \' ";
+  char cmd[BUFSIZE];
+  // Define other variables
+  char buf[BUFSIZE];           /* buffer used to store VPP metrics     */
+  int temp[] = {0, 0, 0, 0};   /* temp array that contains VPP values  */
+  FILE *fp;                    /* file descriptor to pipe cmd to shell */
+  int i;
+
+  for(i = 0; i < 4; i++) {
+    // Clear buffers
+    memset(buf, 0, BUFSIZE);
+    memset(cmd, 0, BUFSIZE);
+    // Build shell command to read metrics from the vNIC
+    strcat(cmd, cmd_prefix);
+    strcat(cmd, vnic);
+    strcat(cmd, cmd_mid);
+    strcat(cmd, params[i]);
+    
+    // Open a pipe and read VPP values
+    if ((fp = popen(cmd, "r")) == NULL) {
+        printf("Error opening pipe!\n");
+        return;
+    }
+
+    while (fgets(buf, BUFSIZE, fp) != NULL);
+    temp[i] = atoi(buf);
+
+    if(pclose(fp))  {
+        printf("Command not found or exited with error status\n");
+        return;
+    }
+  }
+
+  // Store metrics read from the vNIC in the struct passed from the main function
+  vpp_metrics->bytes_in = temp[0];
+  vpp_metrics->bytes_out = temp[1];
+  vpp_metrics->packets_in = temp[2];
+  vpp_metrics->packets_out = temp[3];
+}
diff --git a/veslibrary/ves_clibrary/VESreporting_vLB/LICENSE.TXT b/veslibrary/ves_clibrary/VESreporting_vLB/LICENSE.TXT
new file mode 100644 (file)
index 0000000..ae12da2
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * ============LICENSE_START==========================================
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ *
+ * ECOMP and OpenECOMP are trademarks 
+ * and service marks of AT&T Intellectual Property.
+ *
+ */
diff --git a/veslibrary/ves_clibrary/VESreporting_vLB/Makefile b/veslibrary/ves_clibrary/VESreporting_vLB/Makefile
new file mode 100644 (file)
index 0000000..faf004c
--- /dev/null
@@ -0,0 +1,41 @@
+
+#############################################################################
+#
+# Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#############################################################################
+
+CC=gcc
+ARCH=$(shell getconf LONG_BIT)
+#CODE_ROOT=$(CURDIR)/../../..
+CODE_ROOT=../VES5.0/evel/evel-library
+LIBS_DIR=$(CODE_ROOT)/libs/x86_$(ARCH)
+INCLUDE_DIR=$(CODE_ROOT)/code/evel_library
+
+#******************************************************************************
+# Standard compiler flags.                                                    *
+#******************************************************************************
+CPPFLAGS=
+CFLAGS=-Wall -g -fPIC
+
+all:   vpp_measurement_reporter
+
+clean:
+       rm -f vpp_measurement_reporter
+
+vpp_measurement_reporter: vpp_measurement_reporter.c
+       $(CC) $(CPPFLAGS) $(CFLAGS) -o vpp_measurement_reporter \
+                                    -L $(LIBS_DIR) \
+                                    -I $(INCLUDE_DIR) \
+                               vpp_measurement_reporter.c -lm -lpthread -level -lcurl
diff --git a/veslibrary/ves_clibrary/VESreporting_vLB/README.md b/veslibrary/ves_clibrary/VESreporting_vLB/README.md
new file mode 100644 (file)
index 0000000..ff6ba25
--- /dev/null
@@ -0,0 +1,28 @@
+
+PROJECT DESCRIPTION
+
+“The content of this directory is currently under development and, at this stage, is not intended for demonstration and/or testing.”
+
+---
+This project contains the source code and scripts for the periodic generation of network measurement reports. The folder contains:
+
+ - README.md: this file.
+
+ - LICENSE.TXT: the license text.
+
+ - vpp_measurement_reporter.c: source code that uses the ECOMP Vendor Event Listener Library (VES) to read metrics from the network interface and send periodic measurement reports to the VES collector in DCAE. The VES library used here has been cloned from the GitHub repository at https://github.com/att/evel-library on February 1, 2017.
+
+ - Makefile: makefile that compiles vpp_measurement_reporter.c and generates vpp_measurement_reporter binary.
+
+ - go-client.sh: bash script that starts up the vpp_measurement_reporter binary generated by Makefile. It reads input parameters like DCAE IP address and port from configuration files contained in /opt/config.
+
+
+USAGE
+---
+To run the vpp_measurement_reporter, please execute the following steps:
+
+ - Make the go-client.sh script executable
+        chmod +x go-client.sh
+
+ - Run the go-client.sh script
+        ./go-client.sh  
diff --git a/veslibrary/ves_clibrary/VESreporting_vLB/dep.xml b/veslibrary/ves_clibrary/VESreporting_vLB/dep.xml
new file mode 100644 (file)
index 0000000..fc18229
--- /dev/null
@@ -0,0 +1,25 @@
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" 
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+  <id>demo</id>
+  <formats>
+    <format>tar.gz</format>
+  </formats>
+  <fileSets>
+
+    <fileSet>
+      <directory>.</directory>
+      <outputDirectory>/</outputDirectory>
+      <includes>
+        <include>*.sh</include>
+       <include>*.md</include>
+       <include>*.TXT</include>
+       <include>*.c</include>
+       <include>Makefile</include>
+      </includes>
+    </fileSet>
+
+  </fileSets>
+</assembly>
+
+
diff --git a/veslibrary/ves_clibrary/VESreporting_vLB/go-client.sh b/veslibrary/ves_clibrary/VESreporting_vLB/go-client.sh
new file mode 100755 (executable)
index 0000000..3d1b159
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+export LD_LIBRARY_PATH="/opt/VES/libs/x86_64/"
+DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt)
+DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt)
+./vpp_measurement_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT eth1
diff --git a/veslibrary/ves_clibrary/VESreporting_vLB/pom.xml b/veslibrary/ves_clibrary/VESreporting_vLB/pom.xml
new file mode 100644 (file)
index 0000000..65ee26b
--- /dev/null
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ============LICENSE_START==========================================
+ ===================================================================
+ Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END============================================
+
+ ECOMP and OpenECOMP are trademarks
+ and service marks of AT&T Intellectual Property.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <parent>
+    <groupId>org.openecomp.demo.vnf</groupId>
+    <artifactId>demo-aggregator</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.openecomp.demo.vnf.ves</groupId>
+  <artifactId>ves_vlb_reporting</artifactId>
+
+  <build>
+    <plugins>
+
+       <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.2</version>
+        <executions>
+          <execution>
+            <id>default-jar</id>
+            <phase>never</phase>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>2.5.3</version>
+        <configuration>
+          <descriptor>dep.xml</descriptor>
+        </configuration>
+        <executions>
+          <execution>
+            <id>create-archive</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>none</phase>
+          </execution>
+        </executions>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+
+    </plugins>
+  </build>
+
+</project>
diff --git a/veslibrary/ves_clibrary/VESreporting_vLB/vpp_measurement_reporter.c b/veslibrary/ves_clibrary/VESreporting_vLB/vpp_measurement_reporter.c
new file mode 100644 (file)
index 0000000..98450f0
--- /dev/null
@@ -0,0 +1,325 @@
+
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <math.h>
+
+#include "evel.h"
+
+#define BUFSIZE 128
+#define READ_INTERVAL 10
+
+typedef struct dummy_vpp_metrics_struct {
+  int bytes_in;
+  int bytes_out;
+  int packets_in;
+  int packets_out;
+} vpp_metrics_struct;
+
+void read_vpp_metrics(vpp_metrics_struct *, char *);
+
+unsigned long long epoch_start = 0;
+
+
+#ifdef DOCKER
+int measure_traffic() 
+{
+
+  EVEL_ERR_CODES evel_rc = EVEL_SUCCESS;
+  FILE *fp;
+  int status;
+  char count[10];
+  time_t rawtime;
+  struct tm * timeinfo;
+  char period [21];
+  char cmd [100];
+  int concurrent_sessions = 0;
+  int configured_entities = 0;
+  double mean_request_latency = 0;
+  double measurement_interval = 1;
+  double memory_configured = 0;
+  double memory_used = 0;
+  int request_rate=0;
+  char secs [3];
+  int sec;
+  double loadavg;
+
+  printf("Checking app traffic\n");
+  time (&rawtime);
+  timeinfo = localtime (&rawtime);
+  strftime(period,21,"%d/%b/%Y:%H:%M:",timeinfo);
+  strftime(secs,3,"%S",timeinfo);
+  sec = atoi(secs);
+  if (sec == 0) sec = 59;
+  sprintf(secs, "%02d", sec);
+  strncat(period, secs, 21);
+  // ....x....1....x....2.
+  // 15/Oct/2016:17:51:19
+  strcpy(cmd, "sudo docker logs vHello | grep -c ");
+  strncat(cmd, period, 100);
+
+  fp = popen(cmd, "r");
+  if (fp == NULL) {
+    EVEL_ERROR("popen failed to execute command");
+  }
+
+  if (fgets(count, 10, fp) != NULL) {
+    request_rate = atoi(count);
+    printf("Reporting request rate for second: %s as %d\n", period, request_rate);
+
+    }
+    else {
+      EVEL_ERROR("New Measurement failed");
+    }
+    printf("Processed measurement\n");
+  
+  status = pclose(fp);
+  if (status == -1) {
+    EVEL_ERROR("pclose returned an error");
+  }
+  return request_rate;
+}
+
+#endif
+
+
+int main(int argc, char** argv)
+{
+  EVEL_ERR_CODES evel_rc = EVEL_SUCCESS;
+  EVENT_MEASUREMENT* vpp_m = NULL;
+  EVENT_HEADER* vpp_m_header = NULL;
+  int bytes_in_this_round;
+  int bytes_out_this_round;
+  int packets_in_this_round;
+  int packets_out_this_round;
+  vpp_metrics_struct* last_vpp_metrics = malloc(sizeof(vpp_metrics_struct));
+  vpp_metrics_struct* curr_vpp_metrics = malloc(sizeof(vpp_metrics_struct));
+  struct timeval time_val;
+  //time_t start_epoch;
+  //time_t last_epoch;
+  char hostname[BUFSIZE];
+  char* fqdn = argv[1];
+  int port = atoi(argv[2]);
+  char* vnic = argv[3];
+  MEASUREMENT_VNIC_PERFORMANCE * vnic_performance = NULL;
+
+  printf("\nVector Packet Processing (VPP) measurement collection\n");
+  fflush(stdout);
+
+  if (argc != 4)
+  {
+    fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <interface>\n", argv[0]);
+    exit(-1);
+  }
+  srand(time(NULL));
+
+  /**************************************************************************/
+  /* Initialize                                                             */
+  /**************************************************************************/
+  if(evel_initialize(fqdn,                         /* FQDN                  */
+                     port,                        /* Port                  */
+                     NULL,                         /* optional path         */
+                     NULL,                         /* optional topic        */
+                     0,                            /* HTTPS?                */
+                     "",                           /* Username              */
+                     "",                           /* Password              */
+                     EVEL_SOURCE_VIRTUAL_MACHINE,  /* Source type           */
+                     "vLoadBalancer",              /* Role                  */
+                     1))                           /* Verbosity             */
+  {
+    fprintf(stderr, "\nFailed to initialize the EVEL library!!!\n");
+    exit(-1);
+  }
+  else
+  {
+    printf("\nInitialization completed\n");
+  }
+
+  gethostname(hostname, BUFSIZE);
+  memset(last_vpp_metrics, 0, sizeof(vpp_metrics_struct));
+  read_vpp_metrics(last_vpp_metrics, vnic);
+  gettimeofday(&time_val, NULL);
+  epoch_start = time_val.tv_sec * 1000000 + time_val.tv_usec;
+  sleep(READ_INTERVAL);
+
+  /***************************************************************************/
+  /* Collect metrics from the VNIC                                           */
+  /***************************************************************************/
+  while(1) {
+    // Read the number of vDNSs currently active
+    int active_dns = 0;
+    FILE* fd = fopen("active_dns.txt", "r");
+    while(!feof(fd)) {
+      if(fscanf(fd, "%d", &active_dns) != 1) /* Avoid infinite loops if the file doesn't contain exactly one number */
+        break;
+    }
+
+    if(fclose(fd))  {
+      printf("Error when closing file\n");
+      return 1;
+    }
+
+    memset(curr_vpp_metrics, 0, sizeof(vpp_metrics_struct));
+    read_vpp_metrics(curr_vpp_metrics, vnic);
+
+    if(active_dns > 0 && (curr_vpp_metrics->bytes_in - last_vpp_metrics->bytes_in > 0)) {
+      bytes_in_this_round = (int) round((curr_vpp_metrics->bytes_in - last_vpp_metrics->bytes_in) / active_dns);
+    }
+    else {
+      bytes_in_this_round = 0;
+    }
+    if(active_dns > 0 && (curr_vpp_metrics->bytes_out - last_vpp_metrics->bytes_out > 0)) {
+      bytes_out_this_round = (int) round((curr_vpp_metrics->bytes_out - last_vpp_metrics->bytes_out) / active_dns);
+    }
+    else {
+      bytes_out_this_round = 0;
+    }
+    if(active_dns > 0 && (curr_vpp_metrics->packets_in - last_vpp_metrics->packets_in > 0)) {
+      packets_in_this_round = (int) round((curr_vpp_metrics->packets_in - last_vpp_metrics->packets_in) / active_dns);
+    }
+    else {
+      packets_in_this_round = 0;
+    }
+    if(active_dns > 0 && (curr_vpp_metrics->packets_out - last_vpp_metrics->packets_out > 0)) {
+      packets_out_this_round = (int) round((curr_vpp_metrics->packets_out - last_vpp_metrics->packets_out) / active_dns);
+    }
+    else {
+      packets_out_this_round = 0;
+    }
+
+    vpp_m = evel_new_measurement(READ_INTERVAL,"Measurement_vVNF","TrafficStats_1.2.3.4");
+    vnic_performance = (MEASUREMENT_VNIC_PERFORMANCE *)evel_measurement_new_vnic_performance("eth0", "true");
+    evel_meas_vnic_performance_add(vpp_m, vnic_performance);
+
+    if(vpp_m != NULL) {
+      printf("New measurement report created...\n");
+
+      evel_measurement_type_set(vpp_m, "HTTP request rate");
+      evel_measurement_request_rate_set(vpp_m, rand()%10000);
+
+      evel_vnic_performance_rx_total_pkt_delta_set(vnic_performance, packets_in_this_round);
+      evel_vnic_performance_tx_total_pkt_delta_set(vnic_performance, packets_out_this_round);
+
+      evel_vnic_performance_rx_octets_delta_set(vnic_performance, bytes_in_this_round);
+      evel_vnic_performance_tx_octets_delta_set(vnic_performance, bytes_out_this_round);
+
+      /***************************************************************************/
+      /* Set parameters in the MEASUREMENT header packet                         */
+      /***************************************************************************/
+      struct timeval tv_now;
+      gettimeofday(&tv_now, NULL);
+      unsigned long long epoch_now = tv_now.tv_usec + 1000000 * tv_now.tv_sec;
+
+      //last_epoch = start_epoch + READ_INTERVAL * 1000000;
+      vpp_m_header = (EVENT_HEADER *)vpp_m;
+      //vpp_m_header->start_epoch_microsec = start_epoch;
+      //vpp_m_header->last_epoch_microsec = last_epoch;
+      evel_start_epoch_set(&vpp_m->header, epoch_start);
+      evel_last_epoch_set(&vpp_m->header, epoch_now);
+      epoch_start = epoch_now;
+
+      evel_nfcnamingcode_set(&vpp_m->header, "vVNF");
+      evel_nfnamingcode_set(&vpp_m->header, "vVNF");
+      //strcpy(vpp_m_header->reporting_entity_id.value, "No UUID available");
+      //strcpy(vpp_m_header->reporting_entity_name, hostname);
+      evel_reporting_entity_name_set(&vpp_m->header, "lbll");
+      evel_reporting_entity_id_set(&vpp_m->header, "No UUID available");
+      evel_rc = evel_post_event(vpp_m_header);
+
+      if(evel_rc == EVEL_SUCCESS) {
+        printf("Measurement report correctly sent to the collector!\n");
+      }
+      else {
+        printf("Post failed %d (%s)\n", evel_rc, evel_error_string());
+      }
+    }
+    else {
+      printf("New measurement report failed (%s)\n", evel_error_string());
+    }
+
+    last_vpp_metrics->bytes_in = curr_vpp_metrics->bytes_in;
+    last_vpp_metrics->bytes_out = curr_vpp_metrics->bytes_out;
+    last_vpp_metrics->packets_in = curr_vpp_metrics->packets_in;
+    last_vpp_metrics->packets_out = curr_vpp_metrics->packets_out;
+    //gettimeofday(&time_val, NULL);
+    //start_epoch = time_val.tv_sec * 1000000 + time_val.tv_usec;
+
+    sleep(READ_INTERVAL);
+  }
+
+  /***************************************************************************/
+  /* Terminate                                                               */
+  /***************************************************************************/
+  sleep(1);
+  evel_free_measurement(vpp_m);
+  free(last_vpp_metrics);
+  free(curr_vpp_metrics);
+  evel_terminate();
+  printf("Terminated\n");
+
+  return 0;
+}
+
+void read_vpp_metrics(vpp_metrics_struct *vpp_metrics, char *vnic) {
+  // Define an array of char that contains the parameters of the unix 'cut' command
+  char* params[] = {"-f3", "-f11", "-f4", "-f12"};
+  // Define the unix command to execute in order to read metrics from the vNIC
+  char* cmd_prefix = "sudo cat /proc/net/dev | grep \"";
+  char* cmd_mid = "\" | tr -s \' \' | cut -d\' \' ";
+  char cmd[BUFSIZE];
+  // Define other variables
+  char buf[BUFSIZE];           /* buffer used to store VPP metrics     */
+  int temp[] = {0, 0, 0, 0};   /* temp array that contains VPP values  */
+  FILE *fp;                    /* file descriptor to pipe cmd to shell */
+  int i;
+
+  for(i = 0; i < 4; i++) {
+    // Clear buffers
+    memset(buf, 0, BUFSIZE);
+    memset(cmd, 0, BUFSIZE);
+    // Build shell command to read metrics from the vNIC
+    strcat(cmd, cmd_prefix);
+    strcat(cmd, vnic);
+    strcat(cmd, cmd_mid);
+    strcat(cmd, params[i]);
+    
+    // Open a pipe and read VPP values
+    if ((fp = popen(cmd, "r")) == NULL) {
+      printf("Error opening pipe!\n");
+      return;
+    }
+
+    while (fgets(buf, BUFSIZE, fp) != NULL);
+    temp[i] = atoi(buf);
+
+    if(pclose(fp))  {
+      printf("Command not found or exited with error status\n");
+      return;
+    }
+  }
+
+  // Store metrics read from the vNIC in the struct passed from the main function
+  vpp_metrics->bytes_in = temp[0];
+  vpp_metrics->bytes_out = temp[1];
+  vpp_metrics->packets_in = temp[2];
+  vpp_metrics->packets_out = temp[3];
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/LICENSE.TXT b/veslibrary/ves_clibrary/evel/evel-library/LICENSE.TXT
new file mode 100644 (file)
index 0000000..ae12da2
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * ============LICENSE_START==========================================
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ *
+ * ECOMP and OpenECOMP are trademarks 
+ * and service marks of AT&T Intellectual Property.
+ *
+ */
diff --git a/veslibrary/ves_clibrary/evel/evel-library/bldjobs/Makefile b/veslibrary/ves_clibrary/evel/evel-library/bldjobs/Makefile
new file mode 100644 (file)
index 0000000..5a3a111
--- /dev/null
@@ -0,0 +1,289 @@
+#*************************************************************************//**
+#*
+#* Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+#*
+#* Licensed under the Apache License, Version 2.0 (the "License");
+#* you may not use this file except in compliance with the License.
+#* You may obtain a copy of the License at
+#*        http://www.apache.org/licenses/LICENSE-2.0
+#*
+#* Unless required by applicable law or agreed to in writing, software
+#* distributed under the License is distributed on an "AS IS" BASIS,
+#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#* See the License for the specific language governing permissions and 
+#* limitations under the License.
+#*
+#****************************************************************************/
+
+#******************************************************************************
+# The ECOMP Vendor Event Listener (EVEL) API client library Makefile.
+#
+# Make the various targets associated with housekeeping functions as part of
+# Event Reporting library.
+#
+# NOTE: because Makefiles assign special meaning to the TAB character you
+#       will need to set tabstops to 2 characters for the layout to look OK.
+#****************************************************************************/
+
+ARCH=$(shell getconf LONG_BIT)
+CODE_ROOT=$(CURDIR)/..
+EVELLIB_ROOT=$(CODE_ROOT)/code/evel_library
+EVELUNIT_ROOT=$(CODE_ROOT)/code/evel_unit
+LIBS_DIR=$(CODE_ROOT)/libs/x86_$(ARCH)
+OUTPUT_DIR=$(CODE_ROOT)/output/x86_$(ARCH)
+DOCS_ROOT=$(CODE_ROOT)/docs
+CC=gcc
+SCP=scp
+SSH=ssh
+JAVA=java
+DOXYGEN=doxygen
+PLANTUML=/usr/local/bin/plantuml.jar
+PLANTFLAGS=-tsvg
+
+#******************************************************************************
+# Standard compiler flags.                                                    *
+#******************************************************************************
+CPPFLAGS=-I $(EVELLIB_ROOT)
+CFLAGS=-Wall -Wextra -m$(ARCH) -g -fPIC
+LIBCFLAGS=-Wall -Wextra -m$(ARCH) -g -shared -fPIC
+
+#******************************************************************************
+# The testbed is a VM instance where we can install the EVEL example under    *
+# CentOS.                                                                     *
+#******************************************************************************
+VNF_TESTBED_CENTOS=172.18.152.180
+VNF_TESTBED_CENTOS_USER=centos
+TESTBED_CENTOS_DOWNLOAD_PATH=/home/centos/download/evel_lib
+TESTBED_CENTOS_INSTALL_PATH=/home/centos/evel
+
+#******************************************************************************
+# The testbed is a VM instance where we can install the EVEL example under    *
+# Ubuntu.                                                                     *
+#******************************************************************************
+VNF_TESTBED_UBUNTU=172.18.152.179
+VNF_TESTBED_UBUNTU_USER=ubuntu
+TESTBED_UBUNTU_DOWNLOAD_PATH=/home/ubuntu/Downloads/evel_lib
+TESTBED_UBUNTU_INSTALL_PATH=/home/ubuntu/evel
+
+#******************************************************************************
+# The test-collector is where we can send events to be consumed and checked   *
+# during tests.                                                               *
+#******************************************************************************
+VNF_COLLECTOR_HOST=172.18.152.185
+VNF_COLLECTOR_PORT=30000
+
+#******************************************************************************
+# A documentation server used by the team where we can install documentation. *
+#******************************************************************************
+TEAM_DOCS_SERVER=covlx8
+DOCS_SERVER_PATH=/var/www/html/evel
+
+#******************************************************************************
+# Implicit rule to make dependency files.  Recipe copied from Gnu docs at:    *
+# https://www.gnu.org/software/make/manual/html_node/Automatic-Prerequisites.html                                      *
+#******************************************************************************
+%.d: %.c
+       @echo Making dependency file $(notdir $@) for $(notdir $<)
+       @set -e; rm -f $@; \
+         $(CC) -MM -MT $(<:.c=.o) $(CPPFLAGS) $< > $@.$$$$; \
+         sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+         rm -f $@.$$$$
+
+#******************************************************************************
+# Implicit rule to make object files.                                         *
+#******************************************************************************
+%.o: %.c
+       @echo Making $(notdir $@) from $(notdir $<)
+       @$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
+
+#******************************************************************************
+# Implicit rule to make diagram files using PlantUML.                         *
+#******************************************************************************
+%.svg : %.plantuml
+       @echo Making $(notdir $@)
+       $(JAVA) -jar $(PLANTUML) $(PLANTFLAGS) $<
+
+all:     api_library \
+
+clean:   api_library_clean \
+         evel_unit_clean \
+
+install: api_library
+       @echo Copying $(LIBS_DIR)/libevel.so
+       sudo cp $(LIBS_DIR)/libevel.so /usr/lib
+       sudo ldconfig -n -v /usr/lib
+
+test: evel_test_centos evel_test_ubuntu
+
+docs:    docs_clean doxygen_docs
+
+
+#******************************************************************************
+# Build the EVEL libraries.                                                   *
+#******************************************************************************
+API_SOURCES=$(EVELLIB_ROOT)/evel.c \
+            $(EVELLIB_ROOT)/metadata.c \
+            $(EVELLIB_ROOT)/ring_buffer.c \
+            $(EVELLIB_ROOT)/double_list.c \
+            $(EVELLIB_ROOT)/hashtable.c \
+            $(EVELLIB_ROOT)/evel_event.c \
+            $(EVELLIB_ROOT)/evel_fault.c \
+            $(EVELLIB_ROOT)/evel_mobile_flow.c \
+            $(EVELLIB_ROOT)/evel_option.c \
+            $(EVELLIB_ROOT)/evel_jsonobject.c \
+            $(EVELLIB_ROOT)/evel_other.c \
+            $(EVELLIB_ROOT)/evel_json_buffer.c \
+            $(EVELLIB_ROOT)/evel_reporting_measurement.c \
+            $(EVELLIB_ROOT)/evel_heartbeat_fields.c \
+            $(EVELLIB_ROOT)/evel_sipsignaling.c \
+            $(EVELLIB_ROOT)/evel_scaling_measurement.c \
+            $(EVELLIB_ROOT)/evel_state_change.c \
+            $(EVELLIB_ROOT)/evel_strings.c \
+            $(EVELLIB_ROOT)/evel_syslog.c \
+            $(EVELLIB_ROOT)/evel_throttle.c \
+            $(EVELLIB_ROOT)/evel_internal_event.c \
+            $(EVELLIB_ROOT)/evel_event_mgr.c \
+            $(EVELLIB_ROOT)/evel_threshold_cross.c \
+            $(EVELLIB_ROOT)/evel_voicequality.c \
+            $(EVELLIB_ROOT)/evel_logging.c \
+            $(EVELLIB_ROOT)/jsmn.c
+API_OBJECTS=$(API_SOURCES:.c=.o)
+-include $(API_SOURCES:.c=.d)
+
+api_library: $(LIBS_DIR)/libevel.so \
+             $(LIBS_DIR)/libevel.a
+
+$(LIBS_DIR)/libevel.a: $(API_OBJECTS)
+       @echo   Linking API Static Library
+       @$(CC) $(LIBCFLAGS) -o $@ $+
+
+$(LIBS_DIR)/libevel.so: $(API_OBJECTS)
+       @echo   Linking API Shared Library
+       @$(CC) $(LIBCFLAGS) -L $(QLIBCLIBSDIR) -lqlibc -o $@ $+
+
+api_library_clean:
+       @echo   Cleaning API Library
+       @$(RM) $(LIBS_DIR)/libevel.so
+       @$(RM) $(API_OBJECTS)
+       @$(RM) $(EVELLIB_ROOT)/*.d
+
+#******************************************************************************
+# Build the EVEL library unit test.                                           *
+#******************************************************************************
+UNIT_SOURCES=$(EVELUNIT_ROOT)/evel_unit.c
+UNIT_OBJECTS=$(UNIT_SOURCES:.c=.o)
+-include $(UNIT_SOURCES:.c=.d)
+
+evel_unit: api_library \
+           $(OUTPUT_DIR)/evel_unit
+
+$(OUTPUT_DIR)/evel_unit: $(UNIT_OBJECTS)
+       @echo   Linking EVEL unit test
+       $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ \
+                          -L $(LIBS_DIR) \
+                          $(UNIT_OBJECTS) \
+                          -level \
+                          -lpthread \
+                          -lcurl
+
+evel_unit_clean:
+       @echo   Cleaning EVEL unit test
+       @$(RM) $(OUTPUT_DIR)/evel_unit
+       @$(RM) $(API_OBJECTS)
+       @$(RM) $(UNIT_OBJECTS)
+       @$(RM) $(EVELLIB_ROOT)/*.d
+       @$(RM) $(EVELUNIT_ROOT)/*.d
+
+#******************************************************************************
+# Copy the EVEL demo onto the CentOS testbed as a package and build it.       *
+#******************************************************************************
+evel_install_centos: delivery
+       @echo Installing EVEL library on CentOS testbed...
+       @$(SSH) $(VNF_TESTBED_CENTOS_USER)@$(VNF_TESTBED_CENTOS) \
+          rm -rf $(TESTBED_CENTOS_DOWNLOAD_PATH) \; \
+          mkdir -p $(TESTBED_CENTOS_DOWNLOAD_PATH) \; \
+          mkdir -p $(TESTBED_CENTOS_INSTALL_PATH)
+       @$(SCP) -r $(CODE_ROOT)/output/evel-library-package.tgz \
+           $(VNF_TESTBED_CENTOS_USER)@$(VNF_TESTBED_CENTOS):$(TESTBED_CENTOS_DOWNLOAD_PATH)
+       @$(SSH) $(VNF_TESTBED_CENTOS_USER)@$(VNF_TESTBED_CENTOS) \
+          tar zx --directory $(TESTBED_CENTOS_INSTALL_PATH) \
+                 --file $(TESTBED_CENTOS_DOWNLOAD_PATH)/evel-library-package.tgz
+       @echo Making EVEL library on testbed...
+       @$(SSH) $(VNF_TESTBED_CENTOS_USER)@$(VNF_TESTBED_CENTOS) \
+           cd $(TESTBED_CENTOS_INSTALL_PATH)/bldjobs \; \
+           make clean all
+
+#******************************************************************************
+# Copy the EVEL demo onto the Ubuntu testbed as a package and build it.       *
+#******************************************************************************
+evel_install_ubuntu: delivery
+       @echo Installing EVEL library on Ubuntu testbed...
+       @$(SSH) $(VNF_TESTBED_UBUNTU_USER)@$(VNF_TESTBED_UBUNTU) \
+          rm -rf $(TESTBED_UBUNTU_DOWNLOAD_PATH) \; \
+          mkdir -p $(TESTBED_UBUNTU_DOWNLOAD_PATH) \; \
+          mkdir -p $(TESTBED_UBUNTU_INSTALL_PATH)
+       @$(SCP) -r $(CODE_ROOT)/output/evel-library-package.tgz \
+           $(VNF_TESTBED_UBUNTU_USER)@$(VNF_TESTBED_UBUNTU):$(TESTBED_UBUNTU_DOWNLOAD_PATH)
+       @$(SSH) $(VNF_TESTBED_UBUNTU_USER)@$(VNF_TESTBED_UBUNTU) \
+          tar zx --directory $(TESTBED_UBUNTU_INSTALL_PATH) \
+                 --file $(TESTBED_UBUNTU_DOWNLOAD_PATH)/evel-library-package.tgz
+       @echo Making EVEL library on testbed...
+       @$(SSH) $(VNF_TESTBED_UBUNTU_USER)@$(VNF_TESTBED_UBUNTU) \
+           cd $(TESTBED_UBUNTU_INSTALL_PATH)/bldjobs \; \
+           make clean all
+
+#******************************************************************************
+# Make sure that the Centos platform is up to date and then run the software  *
+# against a test collector.  Validating correct operation is not presently    *
+# automated.                                                                  *
+#******************************************************************************
+evel_test_centos: evel_install_centos
+       @echo Testing EVEL Demo application on CentOS...
+       @$(SSH) $(VNF_TESTBED_CENTOS_USER)@$(VNF_TESTBED_CENTOS) \
+           source .bash_profile \; \
+           $(TESTBED_CENTOS_INSTALL_PATH)/output/x86_$(ARCH)/evel_demo \
+                                                 --fqdn $(VNF_COLLECTOR_HOST) \
+                                                 --port $(VNF_COLLECTOR_PORT) \
+                                                 --verbose
+
+#******************************************************************************
+# Make sure that the Ubuntu platform is up to date and then run the software  *
+# against a test collector.  Validating correct operation is not presently    *
+# automated.                                                                  *
+#******************************************************************************
+evel_test_ubuntu: evel_install_ubuntu
+       @echo Testing EVEL Demo application on Ubuntu...
+       @$(SSH) $(VNF_TESTBED_UBUNTU_USER)@$(VNF_TESTBED_UBUNTU) \
+           source .profile \; \
+           $(TESTBED_UBUNTU_INSTALL_PATH)/output/x86_$(ARCH)/evel_demo \
+                                                 --fqdn $(VNF_COLLECTOR_HOST) \
+                                                 --port $(VNF_COLLECTOR_PORT) \
+                                                 --verbose
+
+#******************************************************************************
+# Making a clean delivery has some very specific dependencies which are order *
+# dependent, so we recursively make a series of targets to do a clean  build  *
+# of all of the required deliverables and then finally zipping up.            *
+#******************************************************************************
+delivery:
+       @$(MAKE) -s delivery_baseline
+       @$(MAKE) -s package
+
+delivery_baseline:     docs
+
+#******************************************************************************
+# Package the software for delivery.                                          *
+#******************************************************************************
+package: api_library_clean \
+         evel_unit_clean
+       @echo Packaging the software for delivery
+       @cd $(CODE_ROOT) && tar cfz output/evel-library-package.tgz  bldjobs \
+                                                      code \
+                                                      docs \
+                                                      libs/x86_64/README \
+                                                      output/x86_64/README \
+                                                      readme.md
+
+package_clean:
+       @echo Clean delivery packages
+       @$(RM) $(OUTPUTDIR)/*.tgz
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/double_list.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/double_list.c
new file mode 100644 (file)
index 0000000..6ce8a80
--- /dev/null
@@ -0,0 +1,182 @@
+
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * A simple double-linked list.
+ *
+ * @note  No thread protection so you will need to use appropriate
+ * synchronization if use spans multiple threads.
+ *
+ ****************************************************************************/
+
+#include <assert.h>
+#include <malloc.h>
+
+#include "double_list.h"
+#include "evel.h"
+
+/**************************************************************************//**
+ * List initialization.
+ *
+ * Initialize the list supplied to be empty.
+ *
+ * @param   list    Pointer to the list to be initialized.
+
+ * @returns Nothing
+******************************************************************************/
+void dlist_initialize(DLIST * list)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(list != NULL);
+
+  /***************************************************************************/
+  /* Initialize the list as empty.                                           */
+  /***************************************************************************/
+  list->head = NULL;
+  list->tail = NULL;
+
+  EVEL_EXIT();
+}
+
+void * dlist_pop_last(DLIST * list)
+{
+  void *item = NULL;
+  DLIST_ITEM *current_tail = NULL;
+  DLIST_ITEM *new_tail = NULL;
+
+  assert(list != NULL);
+
+  current_tail = list->tail;
+  if (current_tail != NULL)
+  {
+    item = current_tail->item;
+    new_tail = current_tail->previous;
+    if (new_tail == NULL)
+    {
+      list->head = NULL;
+      list->tail = NULL;
+    }
+    else
+    {
+      new_tail->next = NULL;
+      list->tail = new_tail;
+    }
+    free(current_tail);
+  }
+
+  return item;
+}
+
+void dlist_push_first(DLIST * list, void * item)
+{
+  DLIST_ITEM * new_element = NULL;
+  DLIST_ITEM * current_head = NULL;
+
+  /***************************************************************************/
+  /* Check assumptions.  Note that we do allow putting NULL pointers into    */
+  /* the list - not sure you'd want to, but let it happen.                   */
+  /***************************************************************************/
+  assert(list != NULL);
+
+  current_head = list->head;
+
+  new_element = malloc(sizeof(DLIST_ITEM));
+  assert(new_element != NULL);
+  new_element->next = current_head;
+  new_element->previous = NULL;
+  new_element->item = item;
+  list->head = new_element;
+
+  if (current_head != NULL)
+  {
+    current_head->previous = new_element;
+  }
+  else
+  {
+    list->tail = new_element;
+  }
+}
+
+void dlist_push_last(DLIST * list, void * item)
+{
+  DLIST_ITEM * new_element = NULL;
+  DLIST_ITEM * current_tail = NULL;
+
+  /***************************************************************************/
+  /* Check assumptions.  Note that we do allow putting NULL pointers into    */
+  /* the list - not sure you'd want to, but let it happen.                   */
+  /***************************************************************************/
+  assert(list != NULL);
+
+  current_tail = list->tail;
+
+  new_element = malloc(sizeof(DLIST_ITEM));
+  assert(new_element != NULL);
+  new_element->next = NULL;
+  new_element->previous = current_tail;
+  new_element->item = item;
+  list->tail = new_element;
+
+  if (current_tail != NULL)
+  {
+    current_tail->next = new_element;
+  }
+  else
+  {
+    list->head = new_element;
+  }
+}
+
+DLIST_ITEM * dlist_get_first(DLIST * list)
+{
+  return list->head;
+}
+
+DLIST_ITEM * dlist_get_last(DLIST * list)
+{
+  return list->tail;
+}
+
+DLIST_ITEM * dlist_get_next(DLIST_ITEM * item)
+{
+  return item->next;
+}
+
+int dlist_is_empty(DLIST * list)
+{
+  return (list->head == NULL);
+}
+
+int dlist_count(DLIST * list)
+{
+  int count = 0;
+  DLIST_ITEM * item = list->head;
+
+  while (item != NULL)
+  {
+    count++;
+    item = item->next;
+  }
+
+  return count;
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/double_list.h b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/double_list.h
new file mode 100644 (file)
index 0000000..5cf7e1a
--- /dev/null
@@ -0,0 +1,57 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * A simple double-linked list.
+ *
+ * @note  No thread protection so you will need to use appropriate
+ * synchronization if use spans multiple threads.
+ *
+ ****************************************************************************/
+
+#ifndef DOUBLE_LIST_INCLUDED
+#define DOUBLE_LIST_INCLUDED
+
+typedef struct dlist_item
+{
+  struct dlist_item * previous;
+  struct dlist_item * next;
+  void * item;
+} DLIST_ITEM;
+
+/**************************************************************************//**
+ * Double-linked list structure
+ *****************************************************************************/
+typedef struct dlist
+{
+  DLIST_ITEM * head;
+  DLIST_ITEM * tail;
+} DLIST;
+
+
+void dlist_initialize(DLIST * list);
+void * dlist_pop_last(DLIST * list);
+void dlist_push_first(DLIST * list, void * item);
+void dlist_push_last(DLIST * list, void * item);
+DLIST_ITEM * dlist_get_first(DLIST * list);
+DLIST_ITEM * dlist_get_last(DLIST * list);
+DLIST_ITEM * dlist_get_next(DLIST_ITEM * item);
+int dlist_is_empty(DLIST * list);
+int dlist_count(DLIST * list);
+
+#endif
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.c
new file mode 100644 (file)
index 0000000..20b386d
--- /dev/null
@@ -0,0 +1,396 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Source module isolating the ECOMP Vendor Event Listener (EVEL) API.
+ *
+ * This file implements the EVEL library which is intended to provide a
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so
+ * that VNFs can use it without worrying about details of:
+ *
+ *  *   The API's encoding into JSON.
+ *  *   The API's transport over HTTP/HTTPS.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <curl/curl.h>
+
+#include "evel.h"
+#include "evel_internal.h"
+#include "evel_throttle.h"
+#include "metadata.h"
+
+/**************************************************************************//**
+ * The type of equipment represented by this VNF.
+ *****************************************************************************/
+EVEL_SOURCE_TYPES event_source_type = EVEL_SOURCE_OTHER;
+
+/**************************************************************************//**
+ * The Functional Role of the equipment represented by this VNF.
+ *****************************************************************************/
+char *functional_role = NULL;
+
+/**************************************************************************//**
+ * Library initialization.
+ *
+ * Initialize the EVEL library.
+ *
+ * @note  This function initializes the cURL library.  Applications making use
+ *        of libcurl may need to pull the initialization out of here.  Note
+ *        also that this function is not threadsafe as a result - refer to
+ *        libcurl's API documentation for relevant warnings.
+ *
+ * @sa  Matching Term function.
+ *
+ * @param   fqdn    The API's FQDN or IP address.
+ * @param   port    The API's port.
+ * @param   path    The optional path (may be NULL).
+ * @param   topic   The optional topic part of the URL (may be NULL).
+ * @param   secure  Whether to use HTTPS (0=HTTP, 1=HTTPS)
+ * @param   username  Username for Basic Authentication of requests.
+ * @param   password  Password for Basic Authentication of requests.
+ * @param   source_type The kind of node we represent.
+ * @param   role    The role this node undertakes.
+ * @param   verbosity  0 for normal operation, positive values for chattier
+ *                        logs.
+ *
+ * @returns Status code
+ * @retval  EVEL_SUCCESS      On success
+ * @retval  ::EVEL_ERR_CODES  On failure.
+ *****************************************************************************/
+EVEL_ERR_CODES evel_initialize(const char * const fqdn,
+                               int port,
+                               const char * const path,
+                               const char * const topic,
+                               int secure,
+                               const char * const username,
+                               const char * const password,
+                               EVEL_SOURCE_TYPES source_type,
+                               const char * const role,
+                               int verbosity
+                               )
+{
+  EVEL_ERR_CODES rc = EVEL_SUCCESS;
+  char base_api_url[EVEL_MAX_URL_LEN + 1] = {0};
+  char event_api_url[EVEL_MAX_URL_LEN + 1] = {0};
+  char throt_api_url[EVEL_MAX_URL_LEN + 1] = {0};
+  char path_url[EVEL_MAX_URL_LEN + 1] = {0};
+  char topic_url[EVEL_MAX_URL_LEN + 1] = {0};
+  char version_string[10] = {0};
+  int offset;
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(fqdn != NULL);
+  assert(port > 0 && port <= 65535);
+  assert(source_type < EVEL_MAX_SOURCE_TYPES);
+  assert(role != NULL);
+
+  /***************************************************************************/
+  /* Start logging so we can report on progress.                             */
+  /***************************************************************************/
+  log_initialize(verbosity == 0 ? EVEL_LOG_INFO : EVEL_LOG_DEBUG, "EVEL");
+  EVEL_INFO("EVEL started");
+  EVEL_INFO("API server is: %s", fqdn);
+  EVEL_INFO("API port is: %d", port);
+
+  if (path != NULL)
+  {
+    EVEL_INFO("API path is: %s", path);
+  }
+  else
+  {
+    EVEL_INFO("No API path");
+  }
+
+  if (topic != NULL)
+  {
+    EVEL_INFO("API topic is: %s", topic);
+  }
+  else
+  {
+    EVEL_INFO("No API topic");
+  }
+
+  EVEL_INFO("API transport is: %s", secure ? "HTTPS" : "HTTP");
+  EVEL_INFO("Event Source Type is: %d", source_type);
+  EVEL_INFO("Functional Role is: %s", role);
+  EVEL_INFO("Log verbosity is: %d", verbosity);
+
+  /***************************************************************************/
+  /* Initialize event throttling to the default state.                       */
+  /***************************************************************************/
+  evel_throttle_initialize();
+
+  /***************************************************************************/
+  /* Save values we will need during operation.                              */
+  /***************************************************************************/
+  event_source_type = source_type;
+  functional_role = strdup(role);
+
+  /***************************************************************************/
+  /* Ensure there are no trailing zeroes and unnecessary decimal points in   */
+  /* the version.                                                            */
+  /***************************************************************************/
+  offset = sprintf(version_string, "%d", EVEL_API_MAJOR_VERSION);
+
+  if (EVEL_API_MINOR_VERSION != 0)
+  {
+    sprintf(version_string + offset, ".%d", EVEL_API_MINOR_VERSION);
+  }
+
+  /***************************************************************************/
+  /* Build a common base of the API URLs.                                    */
+  /***************************************************************************/
+  strcpy(path_url, "/");
+  snprintf(base_api_url,
+           EVEL_MAX_URL_LEN,
+           "%s://%s:%d%s/eventListener/v%s",
+           secure ? "https" : "http",
+           fqdn,
+           port,
+           (((path != NULL) && (strlen(path) > 0)) ?
+            strncat(path_url, path, EVEL_MAX_URL_LEN) : ""),
+           version_string);
+
+  /***************************************************************************/
+  /* Build the URL to the event API.                                         */
+  /***************************************************************************/
+  strcpy(topic_url, "/");
+  snprintf(event_api_url,
+           EVEL_MAX_URL_LEN,
+           "%s%s",
+           base_api_url,
+           (((topic != NULL) && (strlen(topic) > 0)) ?
+            strncat(topic_url, topic, EVEL_MAX_URL_LEN) : ""));
+  EVEL_INFO("Vendor Event Listener API is located at: %s", event_api_url);
+
+  /***************************************************************************/
+  /* Build the URL to the throttling API.                                    */
+  /***************************************************************************/
+  snprintf(throt_api_url,
+           EVEL_MAX_URL_LEN,
+           "%s/clientThrottlingState",
+           base_api_url);
+  EVEL_INFO("Vendor Event Throttling API is located at: %s", throt_api_url);
+
+  /***************************************************************************/
+  /* Spin-up the event-handler, which gets cURL readied for use.             */
+  /***************************************************************************/
+  rc = event_handler_initialize(event_api_url,
+                                throt_api_url,
+                                username,
+                                password,
+                                verbosity);
+  if (rc != EVEL_SUCCESS)
+  {
+    log_error_state("Failed to initialize event handler (including cURL)");
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Extract the metadata from OpenStack. If we fail to extract it, we       */
+  /* record that in the logs, but carry on, assuming we're in a test         */
+  /* without a metadata service.                                             */
+  /***************************************************************************/
+  rc = openstack_metadata(verbosity);
+  if (rc != EVEL_SUCCESS)
+  {
+    EVEL_INFO("Failed to load OpenStack metadata - assuming test environment");
+    rc = EVEL_SUCCESS;
+  }
+
+  /***************************************************************************/
+  /* Start the event handler thread.                                         */
+  /***************************************************************************/
+  rc = event_handler_run();
+  if (rc != EVEL_SUCCESS)
+  {
+    log_error_state("Failed to start event handler thread. "
+                    "Error code=%d", rc);
+    goto exit_label;
+  }
+
+exit_label:
+  return(rc);
+}
+
+/**************************************************************************//**
+ * Clean up the EVEL library.
+ *
+ * @note that at present don't expect Init/Term cycling not to leak memory!
+ *
+ * @returns Status code
+ * @retval  EVEL_SUCCESS On success
+ * @retval  "One of ::EVEL_ERR_CODES" On failure.
+ *****************************************************************************/
+EVEL_ERR_CODES evel_terminate(void)
+{
+  int rc = EVEL_SUCCESS;
+
+  /***************************************************************************/
+  /* First terminate any pending transactions in the event-posting thread.   */
+  /***************************************************************************/
+  rc = event_handler_terminate();
+  if (rc != EVEL_SUCCESS)
+  {
+    log_error_state("Failed to terminate EVEL library cleanly!");
+  }
+
+  /***************************************************************************/
+  /* Shut down the Event Handler library in a tidy manner.                   */
+  /***************************************************************************/
+  curl_global_cleanup();
+
+  /***************************************************************************/
+  /* Clean up allocated memory.                                              */
+  /***************************************************************************/
+  free(functional_role);
+
+  /***************************************************************************/
+  /* Clean up event throttling.                                              */
+  /***************************************************************************/
+  evel_throttle_terminate();
+
+  EVEL_INFO("EVEL stopped");
+  return(rc);
+}
+
+/**************************************************************************//**
+ * Free an event.
+ *
+ * Free off the event supplied.  Will free all the contained allocated memory.
+ *
+ * @note  It is safe to free a NULL pointer.
+ *****************************************************************************/
+void evel_free_event(void * event)
+{
+  EVENT_HEADER * evt_ptr = event;
+  EVEL_ENTER();
+
+  if (event != NULL)
+  {
+    /*************************************************************************/
+    /* Work out what kind of event we're dealing with so we can cast it      */
+    /* appropriately.                                                        */
+    /*************************************************************************/
+    switch (evt_ptr->event_domain)
+    {
+    case EVEL_DOMAIN_INTERNAL:
+      EVEL_DEBUG("Event is an Internal event at %lp", evt_ptr);
+      evel_free_internal_event((EVENT_INTERNAL *) evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_INTERNAL));
+      free(evt_ptr);
+      break;
+
+    case EVEL_DOMAIN_HEARTBEAT:
+      EVEL_DEBUG("Event is a Heartbeat at %lp", evt_ptr);
+      evel_free_header(evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_HEADER));
+      free(evt_ptr);
+      break;
+
+    case EVEL_DOMAIN_FAULT:
+      EVEL_DEBUG("Event is a Fault at %lp", evt_ptr);
+      evel_free_fault((EVENT_FAULT *)evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_FAULT));
+      free(evt_ptr);
+      break;
+
+    case EVEL_DOMAIN_MEASUREMENT:
+      EVEL_DEBUG("Event is a Measurement at %lp", evt_ptr);
+      evel_free_measurement((EVENT_MEASUREMENT *)evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_MEASUREMENT));
+      free(evt_ptr);
+      break;
+
+    case EVEL_DOMAIN_MOBILE_FLOW:
+      EVEL_DEBUG("Event is a Mobile Flow at %lp", evt_ptr);
+      evel_free_mobile_flow((EVENT_MOBILE_FLOW *)evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_MOBILE_FLOW));
+      free(evt_ptr);
+      break;
+
+    case EVEL_DOMAIN_REPORT:
+      EVEL_DEBUG("Event is a Report at %lp", evt_ptr);
+      evel_free_report((EVENT_REPORT *)evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_REPORT));
+      free(evt_ptr);
+      break;
+
+    case EVEL_DOMAIN_HEARTBEAT_FIELD:
+      EVEL_DEBUG("Event is a Heartbeat Field Event at %lp", evt_ptr);
+      evel_free_hrtbt_field((EVENT_HEARTBEAT_FIELD *)evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_HEARTBEAT_FIELD));
+      free(evt_ptr);
+      break;
+
+    case EVEL_DOMAIN_SIPSIGNALING:
+      EVEL_DEBUG("Event is a Signaling at %lp", evt_ptr);
+      evel_free_signaling((EVENT_SIGNALING *)evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_SIGNALING));
+      free(evt_ptr);
+      break;
+
+    case EVEL_DOMAIN_STATE_CHANGE:
+      EVEL_DEBUG("Event is a State Change at %lp", evt_ptr);
+      evel_free_state_change((EVENT_STATE_CHANGE *)evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_STATE_CHANGE));
+      free(evt_ptr);
+      break;
+
+    case EVEL_DOMAIN_SYSLOG:
+      EVEL_DEBUG("Event is a Syslog at %lp", evt_ptr);
+      evel_free_syslog((EVENT_SYSLOG *)evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_SYSLOG));
+      free(evt_ptr);
+      break;
+
+    case EVEL_DOMAIN_OTHER:
+      EVEL_DEBUG("Event is an Other at %lp", evt_ptr);
+      evel_free_other((EVENT_OTHER *)evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_OTHER));
+      free(evt_ptr);
+      break;
+
+    case EVEL_DOMAIN_VOICE_QUALITY:
+      EVEL_DEBUG("Event is an VoiceQuality at %lp", evt_ptr);
+      evel_free_voice_quality((EVENT_VOICE_QUALITY *)evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_VOICE_QUALITY));
+      free(evt_ptr);
+      break;
+
+    case EVEL_DOMAIN_THRESHOLD_CROSS:
+      EVEL_DEBUG("Event is a Threshold crossing at %lp", evt_ptr);
+      evel_free_threshold_cross((EVENT_THRESHOLD_CROSS *)evt_ptr);
+      memset(evt_ptr, 0, sizeof(EVENT_THRESHOLD_CROSS));
+      free(evt_ptr);
+      break;
+
+    default:
+      EVEL_ERROR("Unexpected event domain (%d)", evt_ptr->event_domain);
+      assert(0);
+    }
+  }
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.h b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.h
new file mode 100644 (file)
index 0000000..0ae1713
--- /dev/null
@@ -0,0 +1,4494 @@
+#ifndef EVEL_INCLUDED
+#define EVEL_INCLUDED
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Header for EVEL library
+ *
+ * This file implements the EVEL library which is intended to provide a
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so
+ * that VNFs can use it without worrying about details of the API transport.
+ *
+ * Zero return value is success (::EVEL_SUCCESS), non-zero is failure and will
+ * be one of ::EVEL_ERR_CODES.
+ *****************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+
+#include "jsmn.h"
+#include "double_list.h"
+#include "hashtable.h"
+
+/*****************************************************************************/
+/* Supported API version.                                                    */
+/*****************************************************************************/
+#define EVEL_API_MAJOR_VERSION 5
+#define EVEL_API_MINOR_VERSION 0
+
+/**************************************************************************//**
+ * Error codes
+ *
+ * Error codes for EVEL low level interface
+ *****************************************************************************/
+typedef enum {
+  EVEL_SUCCESS,                   /** The operation was successful.          */
+  EVEL_ERR_GEN_FAIL,              /** Non-specific failure.                  */
+  EVEL_CURL_LIBRARY_FAIL,         /** A cURL library operation failed.       */
+  EVEL_PTHREAD_LIBRARY_FAIL,      /** A Posix threads operation failed.      */
+  EVEL_OUT_OF_MEMORY,             /** A memory allocation failure occurred.  */
+  EVEL_EVENT_BUFFER_FULL,         /** Too many events in the ring-buffer.    */
+  EVEL_EVENT_HANDLER_INACTIVE,    /** Attempt to raise event when inactive.  */
+  EVEL_NO_METADATA,               /** Failed to retrieve OpenStack metadata. */
+  EVEL_BAD_METADATA,              /** OpenStack metadata invalid format.     */
+  EVEL_BAD_JSON_FORMAT,           /** JSON failed to parse correctly.        */
+  EVEL_JSON_KEY_NOT_FOUND,        /** Failed to find the specified JSON key. */
+  EVEL_MAX_ERROR_CODES            /** Maximum number of valid error codes.   */
+} EVEL_ERR_CODES;
+
+/**************************************************************************//**
+ * Logging levels
+ *
+ * Variable levels of verbosity in the logging functions.
+ *****************************************************************************/
+typedef enum {
+  EVEL_LOG_MIN               = 0,
+  EVEL_LOG_SPAMMY            = 30,
+  EVEL_LOG_DEBUG             = 40,
+  EVEL_LOG_INFO              = 50,
+  EVEL_LOG_ERROR             = 60,
+  EVEL_LOG_MAX               = 101
+} EVEL_LOG_LEVELS;
+
+/*****************************************************************************/
+/* Maximum string lengths.                                                   */
+/*****************************************************************************/
+#define EVEL_MAX_STRING_LEN          4096
+#define EVEL_MAX_JSON_BODY           16000
+#define EVEL_MAX_ERROR_STRING_LEN    255
+#define EVEL_MAX_URL_LEN             511
+
+/**************************************************************************//**
+ * This value represents there being no restriction on the reporting interval.
+ *****************************************************************************/
+static const int EVEL_MEASUREMENT_INTERVAL_UKNOWN = 0;
+
+/**************************************************************************//**
+ * How many events can be backed-up before we start dropping events on the
+ * floor.
+ *
+ * @note  This value should be tuned in accordance with expected burstiness of
+ *        the event load and the expected response time of the ECOMP event
+ *        listener so that the probability of the buffer filling is suitably
+ *        low.
+ *****************************************************************************/
+static const int EVEL_EVENT_BUFFER_DEPTH = 100;
+
+/*****************************************************************************/
+/* How many different IP Types-of-Service are supported.                     */
+/*****************************************************************************/
+#define EVEL_TOS_SUPPORTED      256
+
+/**************************************************************************//**
+ * Event domains for the various events we support.
+ * JSON equivalent field: domain
+ *****************************************************************************/
+typedef enum {
+  EVEL_DOMAIN_INTERNAL,       /** Internal event, not for external routing.  */
+  EVEL_DOMAIN_HEARTBEAT,      /** A Heartbeat event (event header only).     */
+  EVEL_DOMAIN_FAULT,          /** A Fault event.                             */
+  EVEL_DOMAIN_MEASUREMENT,    /** A Measurement for VF Scaling event.        */
+  EVEL_DOMAIN_MOBILE_FLOW,    /** A Mobile Flow event.                       */
+  EVEL_DOMAIN_REPORT,         /** A Measurement for VF Reporting event.      */
+  EVEL_DOMAIN_HEARTBEAT_FIELD,/** A Heartbeat field event.                   */
+  EVEL_DOMAIN_SIPSIGNALING,   /** A Signaling event.                         */
+  EVEL_DOMAIN_STATE_CHANGE,   /** A State Change event.                      */
+  EVEL_DOMAIN_SYSLOG,         /** A Syslog event.                            */
+  EVEL_DOMAIN_OTHER,          /** Another event.                             */
+  EVEL_DOMAIN_THRESHOLD_CROSS,  /** A Threshold Crossing  Event                     */
+  EVEL_DOMAIN_VOICE_QUALITY,  /** A Voice Quality Event                             */
+  EVEL_MAX_DOMAINS            /** Maximum number of recognized Event types.  */
+} EVEL_EVENT_DOMAINS;
+
+/**************************************************************************//**
+ * Event priorities.
+ * JSON equivalent field: priority
+ *****************************************************************************/
+typedef enum {
+  EVEL_PRIORITY_HIGH,
+  EVEL_PRIORITY_MEDIUM,
+  EVEL_PRIORITY_NORMAL,
+  EVEL_PRIORITY_LOW,
+  EVEL_MAX_PRIORITIES
+} EVEL_EVENT_PRIORITIES;
+
+/**************************************************************************//**
+ * Fault / Threshold severities.
+ * JSON equivalent field: eventSeverity
+ *****************************************************************************/
+typedef enum {
+  EVEL_SEVERITY_CRITICAL,
+  EVEL_SEVERITY_MAJOR,
+  EVEL_SEVERITY_MINOR,
+  EVEL_SEVERITY_WARNING,
+  EVEL_SEVERITY_NORMAL,
+  EVEL_MAX_SEVERITIES
+} EVEL_SEVERITIES;
+
+/**************************************************************************//**
+ * Fault source types.
+ * JSON equivalent field: eventSourceType
+ *****************************************************************************/
+typedef enum {
+  EVEL_SOURCE_OTHER,
+  EVEL_SOURCE_ROUTER,
+  EVEL_SOURCE_SWITCH,
+  EVEL_SOURCE_HOST,
+  EVEL_SOURCE_CARD,
+  EVEL_SOURCE_PORT,
+  EVEL_SOURCE_SLOT_THRESHOLD,
+  EVEL_SOURCE_PORT_THRESHOLD,
+  EVEL_SOURCE_VIRTUAL_MACHINE,
+  EVEL_SOURCE_VIRTUAL_NETWORK_FUNCTION,
+  /***************************************************************************/
+  /* START OF VENDOR-SPECIFIC VALUES                                         */
+  /*                                                                         */
+  /* Vendor-specific values should be added here, and handled appropriately  */
+  /* in evel_event.c.                                                        */
+  /***************************************************************************/
+
+  /***************************************************************************/
+  /* END OF VENDOR-SPECIFIC VALUES                                           */
+  /***************************************************************************/
+  EVEL_MAX_SOURCE_TYPES
+} EVEL_SOURCE_TYPES;
+
+/**************************************************************************//**
+ * Fault VNF Status.
+ * JSON equivalent field: vfStatus
+ *****************************************************************************/
+typedef enum {
+  EVEL_VF_STATUS_ACTIVE,
+  EVEL_VF_STATUS_IDLE,
+  EVEL_VF_STATUS_PREP_TERMINATE,
+  EVEL_VF_STATUS_READY_TERMINATE,
+  EVEL_VF_STATUS_REQ_TERMINATE,
+  EVEL_MAX_VF_STATUSES
+} EVEL_VF_STATUSES;
+
+/**************************************************************************//**
+ * Counter criticalities.
+ * JSON equivalent field: criticality
+ *****************************************************************************/
+typedef enum {
+  EVEL_COUNTER_CRITICALITY_CRIT,
+  EVEL_COUNTER_CRITICALITY_MAJ,
+  EVEL_MAX_COUNTER_CRITICALITIES
+} EVEL_COUNTER_CRITICALITIES;
+
+/**************************************************************************//**
+ * Alert actions.
+ * JSON equivalent field: alertAction
+ *****************************************************************************/
+typedef enum {
+  EVEL_ALERT_ACTION_CLEAR,
+  EVEL_ALERT_ACTION_CONT,
+  EVEL_ALERT_ACTION_SET,
+  EVEL_MAX_ALERT_ACTIONS
+} EVEL_ALERT_ACTIONS;
+
+/**************************************************************************//**
+ * Alert types.
+ * JSON equivalent field: alertType
+ *****************************************************************************/
+typedef enum {
+  EVEL_ALERT_TYPE_CARD,
+  EVEL_ALERT_TYPE_ELEMENT,
+  EVEL_ALERT_TYPE_INTERFACE,
+  EVEL_ALERT_TYPE_SERVICE,
+  EVEL_MAX_ALERT_TYPES
+} EVEL_ALERT_TYPES;
+
+/**************************************************************************//**
+ * Alert types.
+ * JSON equivalent fields: newState, oldState
+ *****************************************************************************/
+typedef enum {
+  EVEL_ENTITY_STATE_IN_SERVICE,
+  EVEL_ENTITY_STATE_MAINTENANCE,
+  EVEL_ENTITY_STATE_OUT_OF_SERVICE,
+  EVEL_MAX_ENTITY_STATES
+} EVEL_ENTITY_STATE;
+
+/**************************************************************************//**
+ * Syslog facilities.
+ * JSON equivalent field: syslogFacility
+ *****************************************************************************/
+typedef enum {
+  EVEL_SYSLOG_FACILITY_KERNEL,
+  EVEL_SYSLOG_FACILITY_USER,
+  EVEL_SYSLOG_FACILITY_MAIL,
+  EVEL_SYSLOG_FACILITY_SYSTEM_DAEMON,
+  EVEL_SYSLOG_FACILITY_SECURITY_AUTH,
+  EVEL_SYSLOG_FACILITY_INTERNAL,
+  EVEL_SYSLOG_FACILITY_LINE_PRINTER,
+  EVEL_SYSLOG_FACILITY_NETWORK_NEWS,
+  EVEL_SYSLOG_FACILITY_UUCP,
+  EVEL_SYSLOG_FACILITY_CLOCK_DAEMON,
+  EVEL_SYSLOG_FACILITY_SECURITY_AUTH2,
+  EVEL_SYSLOG_FACILITY_FTP_DAEMON,
+  EVEL_SYSLOG_FACILITY_NTP,
+  EVEL_SYSLOG_FACILITY_LOG_AUDIT,
+  EVEL_SYSLOG_FACILITY_LOG_ALERT,
+  EVEL_SYSLOG_FACILITY_CLOCK_DAEMON2,
+  EVEL_SYSLOG_FACILITY_LOCAL0,
+  EVEL_SYSLOG_FACILITY_LOCAL1,
+  EVEL_SYSLOG_FACILITY_LOCAL2,
+  EVEL_SYSLOG_FACILITY_LOCAL3,
+  EVEL_SYSLOG_FACILITY_LOCAL4,
+  EVEL_SYSLOG_FACILITY_LOCAL5,
+  EVEL_SYSLOG_FACILITY_LOCAL6,
+  EVEL_SYSLOG_FACILITY_LOCAL7,
+  EVEL_MAX_SYSLOG_FACILITIES
+} EVEL_SYSLOG_FACILITIES;
+
+/**************************************************************************//**
+ * TCP flags.
+ * JSON equivalent fields: tcpFlagCountList, tcpFlagList
+ *****************************************************************************/
+typedef enum {
+  EVEL_TCP_NS,
+  EVEL_TCP_CWR,
+  EVEL_TCP_ECE,
+  EVEL_TCP_URG,
+  EVEL_TCP_ACK,
+  EVEL_TCP_PSH,
+  EVEL_TCP_RST,
+  EVEL_TCP_SYN,
+  EVEL_TCP_FIN,
+  EVEL_MAX_TCP_FLAGS
+} EVEL_TCP_FLAGS;
+
+/**************************************************************************//**
+ * Mobile QCI Classes of Service.
+ * JSON equivalent fields: mobileQciCosCountList, mobileQciCosList
+ *****************************************************************************/
+typedef enum {
+
+  /***************************************************************************/
+  /* UMTS Classes of Service.                                                */
+  /***************************************************************************/
+  EVEL_QCI_COS_UMTS_CONVERSATIONAL,
+  EVEL_QCI_COS_UMTS_STREAMING,
+  EVEL_QCI_COS_UMTS_INTERACTIVE,
+  EVEL_QCI_COS_UMTS_BACKGROUND,
+
+  /***************************************************************************/
+  /* LTE Classes of Service.                                                 */
+  /***************************************************************************/
+  EVEL_QCI_COS_LTE_1,
+  EVEL_QCI_COS_LTE_2,
+  EVEL_QCI_COS_LTE_3,
+  EVEL_QCI_COS_LTE_4,
+  EVEL_QCI_COS_LTE_65,
+  EVEL_QCI_COS_LTE_66,
+  EVEL_QCI_COS_LTE_5,
+  EVEL_QCI_COS_LTE_6,
+  EVEL_QCI_COS_LTE_7,
+  EVEL_QCI_COS_LTE_8,
+  EVEL_QCI_COS_LTE_9,
+  EVEL_QCI_COS_LTE_69,
+  EVEL_QCI_COS_LTE_70,
+  EVEL_MAX_QCI_COS_TYPES
+} EVEL_QCI_COS_TYPES;
+
+/**************************************************************************//**
+ * Service Event endpoint description
+ * JSON equivalent field: endpointDesc
+ *****************************************************************************/
+typedef enum {
+  EVEL_SERVICE_ENDPOINT_CALLEE,
+  EVEL_SERVICE_ENDPOINT_CALLER,
+  EVEL_MAX_SERVICE_ENDPOINT_DESC
+} EVEL_SERVICE_ENDPOINT_DESC;
+
+/**************************************************************************//**
+ * Boolean type for EVEL library.
+ *****************************************************************************/
+typedef enum {
+  EVEL_FALSE,
+  EVEL_TRUE
+} EVEL_BOOLEAN;
+
+/**************************************************************************//**
+ * Optional parameter holder for double.
+ *****************************************************************************/
+typedef struct evel_option_double
+{
+  double value;
+  EVEL_BOOLEAN is_set;
+} EVEL_OPTION_DOUBLE;
+
+/**************************************************************************//**
+ * Optional parameter holder for string.
+ *****************************************************************************/
+typedef struct evel_option_string
+{
+  char * value;
+  EVEL_BOOLEAN is_set;
+} EVEL_OPTION_STRING;
+
+/**************************************************************************//**
+ * Optional parameter holder for int.
+ *****************************************************************************/
+typedef struct evel_option_int
+{
+  int value;
+  EVEL_BOOLEAN is_set;
+} EVEL_OPTION_INT;
+
+/**************************************************************************//**
+ * Optional parameter holder for unsigned long long.
+ *****************************************************************************/
+typedef struct evel_option_ull
+{
+  unsigned long long value;
+  EVEL_BOOLEAN is_set;
+} EVEL_OPTION_ULL;
+
+/**************************************************************************//**
+ * Optional parameter holder for time_t.
+ *****************************************************************************/
+typedef struct evel_option_time
+{
+  time_t value;
+  EVEL_BOOLEAN is_set;
+} EVEL_OPTION_TIME;
+
+/**************************************************************************//**
+ * enrichment fields for internal VES Event Listener service use only,
+ * not supplied by event sources
+ *****************************************************************************/
+typedef struct internal_header_fields
+{
+  void *object;
+  EVEL_BOOLEAN is_set;
+} EVEL_OPTION_INTHEADER_FIELDS;
+
+/*****************************************************************************/
+/* Supported Common Event Header version.                                    */
+/*****************************************************************************/
+#define EVEL_HEADER_MAJOR_VERSION 1
+#define EVEL_HEADER_MINOR_VERSION 2
+
+/**************************************************************************//**
+ * Event header.
+ * JSON equivalent field: commonEventHeader
+ *****************************************************************************/
+typedef struct event_header {
+  /***************************************************************************/
+  /* Version                                                                 */
+  /***************************************************************************/
+  int major_version;
+  int minor_version;
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  EVEL_EVENT_DOMAINS event_domain;
+  char * event_id;
+  char * event_name;
+  char * source_name;
+  char * reporting_entity_name;
+  EVEL_EVENT_PRIORITIES priority;
+  unsigned long long start_epoch_microsec;
+  unsigned long long last_epoch_microsec;
+  int sequence;
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  EVEL_OPTION_STRING event_type;
+  EVEL_OPTION_STRING source_id;
+  EVEL_OPTION_STRING reporting_entity_id;
+  EVEL_OPTION_INTHEADER_FIELDS internal_field;
+  EVEL_OPTION_STRING nfcnaming_code;
+  EVEL_OPTION_STRING nfnaming_code;
+
+} EVENT_HEADER;
+
+/*****************************************************************************/
+/* Supported Fault version.                                                  */
+/*****************************************************************************/
+#define EVEL_FAULT_MAJOR_VERSION 2
+#define EVEL_FAULT_MINOR_VERSION 1
+
+/**************************************************************************//**
+ * Fault.
+ * JSON equivalent field: faultFields
+ *****************************************************************************/
+typedef struct event_fault {
+  /***************************************************************************/
+  /* Header and version                                                      */
+  /***************************************************************************/
+  EVENT_HEADER header;
+  int major_version;
+  int minor_version;
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  EVEL_SEVERITIES event_severity;
+  EVEL_SOURCE_TYPES event_source_type;
+  char * alarm_condition;
+  char * specific_problem;
+  EVEL_VF_STATUSES vf_status;
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  EVEL_OPTION_STRING category;
+  EVEL_OPTION_STRING alarm_interface_a;
+  DLIST additional_info;
+
+} EVENT_FAULT;
+
+/**************************************************************************//**
+ * Fault Additional Info.
+ * JSON equivalent field: alarmAdditionalInformation
+ *****************************************************************************/
+typedef struct fault_additional_info {
+  char * name;
+  char * value;
+} FAULT_ADDL_INFO;
+
+
+/**************************************************************************//**
+ * optional field block for fields specific to heartbeat events
+ *****************************************************************************/
+typedef struct event_heartbeat_fields
+{
+  /***************************************************************************/
+  /* Header and version                                                      */
+  /***************************************************************************/
+  EVENT_HEADER header;
+  int major_version;
+  int minor_version;
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  double heartbeat_version;
+  int    heartbeat_interval;
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  DLIST additional_info;
+
+} EVENT_HEARTBEAT_FIELD;
+
+/**************************************************************************//**
+ * tuple which provides the name of a key along with its value and
+ * relative order
+ *****************************************************************************/
+typedef struct internal_key
+{
+  char                *keyname;
+  EVEL_OPTION_INT      keyorder;
+  EVEL_OPTION_STRING   keyvalue;
+} EVEL_INTERNAL_KEY;
+
+/**************************************************************************//**
+ * meta-information about an instance of a jsonObject along with
+ * the actual object instance
+ *****************************************************************************/
+typedef struct json_object_instance
+{
+
+  char *jsonstring;
+  unsigned long long objinst_epoch_microsec;
+  DLIST object_keys; /*EVEL_INTERNAL_KEY list */
+
+} EVEL_JSON_OBJECT_INSTANCE;
+#define MAX_JSON_TOKENS 128
+/**************************************************************************//**
+ * Create a new json object instance.
+ *
+ * @note    The mandatory fields on the Other must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Other has immutable properties.
+ * @param   yourjson       json string.
+ * @returns pointer to the newly manufactured ::EVEL_JSON_OBJECT_INSTANCE.
+ *          not used (i.e. posted) it must be released using ::evel_free_jsonobjectinstance.
+ * @retval  NULL  Failed to create the json object instance.
+ *****************************************************************************/
+EVEL_JSON_OBJECT_INSTANCE * evel_new_jsonobjinstance(const char *const yourjson);
+/**************************************************************************//**
+ * Free an json object instance.
+ *
+ * Free off the json object instance supplied.
+ *  Will free all the contained allocated memory.
+ *
+ *****************************************************************************/
+void evel_free_jsonobjinst(EVEL_JSON_OBJECT_INSTANCE * objinst);
+
+/**************************************************************************//**
+ * enrichment fields for internal VES Event Listener service use only,
+ * not supplied by event sources
+ *****************************************************************************/
+typedef struct json_object
+{
+
+  char *object_name;
+  EVEL_OPTION_STRING objectschema;
+  EVEL_OPTION_STRING objectschemaurl;
+  EVEL_OPTION_STRING nfsubscribedobjname;
+  EVEL_OPTION_STRING nfsubscriptionid;
+  DLIST jsonobjectinstances;  /* EVEL_JSON_OBJECT_INSTANCE list */
+
+} EVEL_JSON_OBJECT;
+
+/**************************************************************************//**
+ * Create a new json object.
+ *
+ * @note    The mandatory fields on the Other must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Other has immutable properties.
+ * @param name       name of the object.
+ * @returns pointer to the newly manufactured ::EVEL_JSON_OBJECT.
+ *          not used (i.e. posted) it must be released using ::evel_free_jsonobject.
+ * @retval  NULL  Failed to create the json object.
+ *****************************************************************************/
+EVEL_JSON_OBJECT * evel_new_jsonobject(const char *const name);
+/**************************************************************************//**
+ * Free an json object.
+ *
+ * Free off the json object instance supplied.
+ *  Will free all the contained allocated memory.
+ *
+ *****************************************************************************/
+void evel_free_jsonobject(EVEL_JSON_OBJECT * jsobj);
+/*****************************************************************************/
+/* Supported Measurement version.                                            */
+/*****************************************************************************/
+#define EVEL_MEASUREMENT_MAJOR_VERSION 2
+#define EVEL_MEASUREMENT_MINOR_VERSION 1
+
+/**************************************************************************//**
+ * Errors.
+ * JSON equivalent field: errors
+ *****************************************************************************/
+typedef struct measurement_errors {
+  int receive_discards;
+  int receive_errors;
+  int transmit_discards;
+  int transmit_errors;
+} MEASUREMENT_ERRORS;
+
+/**************************************************************************//**
+ * Measurement.
+ * JSON equivalent field: measurementsForVfScalingFields
+ *****************************************************************************/
+typedef struct event_measurement {
+  /***************************************************************************/
+  /* Header and version                                                      */
+  /***************************************************************************/
+  EVENT_HEADER header;
+  int major_version;
+  int minor_version;
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  double measurement_interval;
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  DLIST additional_info;
+  DLIST additional_measurements;
+  DLIST additional_objects;
+  DLIST codec_usage;
+  EVEL_OPTION_INT concurrent_sessions;
+  EVEL_OPTION_INT configured_entities;
+  DLIST cpu_usage;
+  DLIST disk_usage;
+  MEASUREMENT_ERRORS * errors;
+  DLIST feature_usage;
+  DLIST filesystem_usage;
+  DLIST latency_distribution;
+  EVEL_OPTION_DOUBLE mean_request_latency;
+  DLIST mem_usage;
+  EVEL_OPTION_INT media_ports_in_use;
+  EVEL_OPTION_INT request_rate;
+  EVEL_OPTION_INT vnfc_scaling_metric;
+  DLIST vnic_usage;
+
+} EVENT_MEASUREMENT;
+
+/**************************************************************************//**
+ * CPU Usage.
+ * JSON equivalent field: cpuUsage
+ *****************************************************************************/
+typedef struct measurement_cpu_use {
+  char * id;
+  double usage;
+  EVEL_OPTION_DOUBLE idle;
+  EVEL_OPTION_DOUBLE intrpt;
+  EVEL_OPTION_DOUBLE nice;
+  EVEL_OPTION_DOUBLE softirq;
+  EVEL_OPTION_DOUBLE steal;
+  EVEL_OPTION_DOUBLE sys;
+  EVEL_OPTION_DOUBLE user;
+  EVEL_OPTION_DOUBLE wait;
+} MEASUREMENT_CPU_USE;
+
+
+/**************************************************************************//**
+ * Disk Usage.
+ * JSON equivalent field: diskUsage
+ *****************************************************************************/
+typedef struct measurement_disk_use {
+  char * id;
+  EVEL_OPTION_DOUBLE iotimeavg;
+  EVEL_OPTION_DOUBLE iotimelast;
+  EVEL_OPTION_DOUBLE iotimemax;
+  EVEL_OPTION_DOUBLE iotimemin;
+  EVEL_OPTION_DOUBLE mergereadavg;
+  EVEL_OPTION_DOUBLE mergereadlast;
+  EVEL_OPTION_DOUBLE mergereadmax;
+  EVEL_OPTION_DOUBLE mergereadmin;
+  EVEL_OPTION_DOUBLE mergewriteavg;
+  EVEL_OPTION_DOUBLE mergewritelast;
+  EVEL_OPTION_DOUBLE mergewritemax;
+  EVEL_OPTION_DOUBLE mergewritemin;
+  EVEL_OPTION_DOUBLE octetsreadavg;
+  EVEL_OPTION_DOUBLE octetsreadlast;
+  EVEL_OPTION_DOUBLE octetsreadmax;
+  EVEL_OPTION_DOUBLE octetsreadmin;
+  EVEL_OPTION_DOUBLE octetswriteavg;
+  EVEL_OPTION_DOUBLE octetswritelast;
+  EVEL_OPTION_DOUBLE octetswritemax;
+  EVEL_OPTION_DOUBLE octetswritemin;
+  EVEL_OPTION_DOUBLE opsreadavg;
+  EVEL_OPTION_DOUBLE opsreadlast;
+  EVEL_OPTION_DOUBLE opsreadmax;
+  EVEL_OPTION_DOUBLE opsreadmin;
+  EVEL_OPTION_DOUBLE opswriteavg;
+  EVEL_OPTION_DOUBLE opswritelast;
+  EVEL_OPTION_DOUBLE opswritemax;
+  EVEL_OPTION_DOUBLE opswritemin;
+  EVEL_OPTION_DOUBLE pendingopsavg;
+  EVEL_OPTION_DOUBLE pendingopslast;
+  EVEL_OPTION_DOUBLE pendingopsmax;
+  EVEL_OPTION_DOUBLE pendingopsmin;
+  EVEL_OPTION_DOUBLE timereadavg;
+  EVEL_OPTION_DOUBLE timereadlast;
+  EVEL_OPTION_DOUBLE timereadmax;
+  EVEL_OPTION_DOUBLE timereadmin;
+  EVEL_OPTION_DOUBLE timewriteavg;
+  EVEL_OPTION_DOUBLE timewritelast;
+  EVEL_OPTION_DOUBLE timewritemax;
+  EVEL_OPTION_DOUBLE timewritemin;
+
+} MEASUREMENT_DISK_USE;
+
+/**************************************************************************//**
+ * Add an additional Disk usage value name/value pair to the Measurement.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement   Pointer to the measurement.
+ * @param id            ASCIIZ string with the CPU's identifier.
+ * @param usage         Disk utilization.
+ *****************************************************************************/
+MEASUREMENT_DISK_USE * evel_measurement_new_disk_use_add(EVENT_MEASUREMENT * measurement, char * id);
+
+/**************************************************************************//**
+ * Filesystem Usage.
+ * JSON equivalent field: filesystemUsage
+ *****************************************************************************/
+typedef struct measurement_fsys_use {
+  char * filesystem_name;
+  double block_configured;
+  double block_iops;
+  double block_used;
+  double ephemeral_configured;
+  double ephemeral_iops;
+  double ephemeral_used;
+} MEASUREMENT_FSYS_USE;
+
+/**************************************************************************//**
+ * Memory Usage.
+ * JSON equivalent field: memoryUsage
+ *****************************************************************************/
+typedef struct measurement_mem_use {
+  char * id;
+  char * vmid;
+  double membuffsz;
+  EVEL_OPTION_DOUBLE memcache;
+  EVEL_OPTION_DOUBLE memconfig;
+  EVEL_OPTION_DOUBLE memfree;
+  EVEL_OPTION_DOUBLE slabrecl;
+  EVEL_OPTION_DOUBLE slabunrecl;
+  EVEL_OPTION_DOUBLE memused;
+} MEASUREMENT_MEM_USE;
+
+/**************************************************************************//**
+ * Add an additional Memory usage value name/value pair to the Measurement.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement   Pointer to the measurement.
+ * @param id            ASCIIZ string with the Memory identifier.
+ * @param vmidentifier  ASCIIZ string with the VM's identifier.
+ * @param membuffsz     Memory Size.
+ *
+ * @return  Returns pointer to memory use structure in measurements
+ *****************************************************************************/
+MEASUREMENT_MEM_USE * evel_measurement_new_mem_use_add(EVENT_MEASUREMENT * measurement,
+                                 char * id,  char *vmidentifier,  double membuffsz);
+
+/**************************************************************************//**
+ * Set kilobytes of memory used for cache
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mem_use      Pointer to the Memory Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_mem_use_memcache_set(MEASUREMENT_MEM_USE * const mem_use,
+                                    const double val);
+/**************************************************************************//**
+ * Set kilobytes of memory configured in the virtual machine on which the VNFC reporting
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mem_use      Pointer to the Memory Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_mem_use_memconfig_set(MEASUREMENT_MEM_USE * const mem_use,
+                                    const double val);
+/**************************************************************************//**
+ * Set kilobytes of physical RAM left unused by the system
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mem_use      Pointer to the Memory Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_mem_use_memfree_set(MEASUREMENT_MEM_USE * const mem_use,
+                                    const double val);
+/**************************************************************************//**
+ * Set the part of the slab that can be reclaimed such as caches measured in kilobytes
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mem_use      Pointer to the Memory Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_mem_use_slab_reclaimed_set(MEASUREMENT_MEM_USE * const mem_use,
+                                    const double val);
+/**************************************************************************//**
+ * Set the part of the slab that cannot be reclaimed such as caches measured in kilobytes
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mem_use      Pointer to the Memory Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_mem_use_slab_unreclaimable_set(MEASUREMENT_MEM_USE * const mem_use,
+                                    const double val);
+/**************************************************************************//**
+ * Set the total memory minus the sum of free, buffered, cached and slab memory in kilobytes
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mem_use      Pointer to the Memory Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_mem_use_usedup_set(MEASUREMENT_MEM_USE * const mem_use,
+                                    const double val);
+/**************************************************************************//**
+ * Latency Bucket.
+ * JSON equivalent field: latencyBucketMeasure
+ *****************************************************************************/
+typedef struct measurement_latency_bucket {
+  int count;
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  EVEL_OPTION_DOUBLE high_end;
+  EVEL_OPTION_DOUBLE low_end;
+
+} MEASUREMENT_LATENCY_BUCKET;
+
+/**************************************************************************//**
+ * Virtual NIC usage.
+ * JSON equivalent field: vNicUsage
+ *****************************************************************************/
+typedef struct measurement_vnic_performance {
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  /*Cumulative count of broadcast packets received as read at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_bcast_packets_acc;
+  /*Count of broadcast packets received within the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_bcast_packets_delta;
+  /*Cumulative count of discarded packets received as read at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_discarded_packets_acc;
+  /*Count of discarded packets received within the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_discarded_packets_delta;
+  /*Cumulative count of error packets received as read at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_error_packets_acc;
+  /*Count of error packets received within the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_error_packets_delta;
+  /*Cumulative count of multicast packets received as read at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_mcast_packets_acc;
+  /*Count of mcast packets received within the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_mcast_packets_delta;
+  /*Cumulative count of octets received as read at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_octets_acc;
+  /*Count of octets received within the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_octets_delta;
+  /*Cumulative count of all packets received as read at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_total_packets_acc;
+  /*Count of all packets received within the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_total_packets_delta;
+  /*Cumulative count of unicast packets received as read at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_ucast_packets_acc;
+  /*Count of unicast packets received within the measurement interval*/
+  EVEL_OPTION_DOUBLE recvd_ucast_packets_delta;
+  /*Cumulative count of transmitted broadcast packets at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_bcast_packets_acc;
+  /*Count of transmitted broadcast packets within the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_bcast_packets_delta;
+  /*Cumulative count of transmit discarded packets at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_discarded_packets_acc;
+  /*Count of transmit discarded packets within the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_discarded_packets_delta;
+  /*Cumulative count of transmit error packets at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_error_packets_acc;
+  /*Count of transmit error packets within the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_error_packets_delta;
+  /*Cumulative count of transmit multicast packets at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_mcast_packets_acc;
+  /*Count of transmit multicast packets within the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_mcast_packets_delta;
+  /*Cumulative count of transmit octets at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_octets_acc;
+  /*Count of transmit octets received within the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_octets_delta;
+  /*Cumulative count of all transmit packets at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_total_packets_acc;
+  /*Count of transmit packets within the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_total_packets_delta;
+  /*Cumulative count of all transmit unicast packets at the end of
+   the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_ucast_packets_acc;
+  /*Count of transmit unicast packets within the measurement interval*/
+  EVEL_OPTION_DOUBLE tx_ucast_packets_delta;
+  /* Indicates whether vNicPerformance values are likely inaccurate
+           due to counter overflow or other condtions*/
+  char *valuesaresuspect;
+  char *vnic_id;
+
+} MEASUREMENT_VNIC_PERFORMANCE;
+
+/**************************************************************************//**
+ * Codec Usage.
+ * JSON equivalent field: codecsInUse
+ *****************************************************************************/
+typedef struct measurement_codec_use {
+  char * codec_id;
+  int number_in_use;
+} MEASUREMENT_CODEC_USE;
+
+/**************************************************************************//**
+ * Feature Usage.
+ * JSON equivalent field: featuresInUse
+ *****************************************************************************/
+typedef struct measurement_feature_use {
+  char * feature_id;
+  int feature_utilization;
+} MEASUREMENT_FEATURE_USE;
+
+/**************************************************************************//**
+ * Measurement Group.
+ * JSON equivalent field: additionalMeasurements
+ *****************************************************************************/
+typedef struct measurement_group {
+  char * name;
+  DLIST measurements;
+} MEASUREMENT_GROUP;
+
+/**************************************************************************//**
+ * Custom Defined Measurement.
+ * JSON equivalent field: measurements
+ *****************************************************************************/
+typedef struct custom_measurement {
+  char * name;
+  char * value;
+} CUSTOM_MEASUREMENT;
+
+/*****************************************************************************/
+/* Supported Report version.                                                 */
+/*****************************************************************************/
+#define EVEL_REPORT_MAJOR_VERSION 1
+#define EVEL_REPORT_MINOR_VERSION 1
+
+/**************************************************************************//**
+ * Report.
+ * JSON equivalent field: measurementsForVfReportingFields
+ *
+ * @note  This is an experimental event type and is not currently a formal part
+ *        of AT&T's specification.
+ *****************************************************************************/
+typedef struct event_report {
+  /***************************************************************************/
+  /* Header and version                                                      */
+  /***************************************************************************/
+  EVENT_HEADER header;
+  int major_version;
+  int minor_version;
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  double measurement_interval;
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  DLIST feature_usage;
+  DLIST measurement_groups;
+
+} EVENT_REPORT;
+
+/**************************************************************************//**
+ * Mobile GTP Per Flow Metrics.
+ * JSON equivalent field: gtpPerFlowMetrics
+ *****************************************************************************/
+typedef struct mobile_gtp_per_flow_metrics {
+  double avg_bit_error_rate;
+  double avg_packet_delay_variation;
+  int avg_packet_latency;
+  int avg_receive_throughput;
+  int avg_transmit_throughput;
+  int flow_activation_epoch;
+  int flow_activation_microsec;
+  int flow_deactivation_epoch;
+  int flow_deactivation_microsec;
+  time_t flow_deactivation_time;
+  char * flow_status;
+  int max_packet_delay_variation;
+  int num_activation_failures;
+  int num_bit_errors;
+  int num_bytes_received;
+  int num_bytes_transmitted;
+  int num_dropped_packets;
+  int num_l7_bytes_received;
+  int num_l7_bytes_transmitted;
+  int num_lost_packets;
+  int num_out_of_order_packets;
+  int num_packet_errors;
+  int num_packets_received_excl_retrans;
+  int num_packets_received_incl_retrans;
+  int num_packets_transmitted_incl_retrans;
+  int num_retries;
+  int num_timeouts;
+  int num_tunneled_l7_bytes_received;
+  int round_trip_time;
+  int time_to_first_byte;
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  EVEL_OPTION_INT ip_tos_counts[EVEL_TOS_SUPPORTED];
+  EVEL_OPTION_INT tcp_flag_counts[EVEL_MAX_TCP_FLAGS];
+  EVEL_OPTION_INT qci_cos_counts[EVEL_MAX_QCI_COS_TYPES];
+  EVEL_OPTION_INT dur_connection_failed_status;
+  EVEL_OPTION_INT dur_tunnel_failed_status;
+  EVEL_OPTION_STRING flow_activated_by;
+  EVEL_OPTION_TIME flow_activation_time;
+  EVEL_OPTION_STRING flow_deactivated_by;
+  EVEL_OPTION_STRING gtp_connection_status;
+  EVEL_OPTION_STRING gtp_tunnel_status;
+  EVEL_OPTION_INT large_packet_rtt;
+  EVEL_OPTION_DOUBLE large_packet_threshold;
+  EVEL_OPTION_INT max_receive_bit_rate;
+  EVEL_OPTION_INT max_transmit_bit_rate;
+  EVEL_OPTION_INT num_gtp_echo_failures;
+  EVEL_OPTION_INT num_gtp_tunnel_errors;
+  EVEL_OPTION_INT num_http_errors;
+
+} MOBILE_GTP_PER_FLOW_METRICS;
+
+/*****************************************************************************/
+/* Supported Mobile Flow version.                                            */
+/*****************************************************************************/
+#define EVEL_MOBILE_FLOW_MAJOR_VERSION 1
+#define EVEL_MOBILE_FLOW_MINOR_VERSION 2
+
+/**************************************************************************//**
+ * Mobile Flow.
+ * JSON equivalent field: mobileFlow
+ *****************************************************************************/
+typedef struct event_mobile_flow {
+  /***************************************************************************/
+  /* Header and version                                                      */
+  /***************************************************************************/
+  EVENT_HEADER header;
+  int major_version;
+  int minor_version;
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  char * flow_direction;
+  MOBILE_GTP_PER_FLOW_METRICS * gtp_per_flow_metrics;
+  char * ip_protocol_type;
+  char * ip_version;
+  char * other_endpoint_ip_address;
+  int other_endpoint_port;
+  char * reporting_endpoint_ip_addr;
+  int reporting_endpoint_port;
+  DLIST additional_info;                         /* JSON: additionalFields */
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  EVEL_OPTION_STRING application_type;
+  EVEL_OPTION_STRING app_protocol_type;
+  EVEL_OPTION_STRING app_protocol_version;
+  EVEL_OPTION_STRING cid;
+  EVEL_OPTION_STRING connection_type;
+  EVEL_OPTION_STRING ecgi;
+  EVEL_OPTION_STRING gtp_protocol_type;
+  EVEL_OPTION_STRING gtp_version;
+  EVEL_OPTION_STRING http_header;
+  EVEL_OPTION_STRING imei;
+  EVEL_OPTION_STRING imsi;
+  EVEL_OPTION_STRING lac;
+  EVEL_OPTION_STRING mcc;
+  EVEL_OPTION_STRING mnc;
+  EVEL_OPTION_STRING msisdn;
+  EVEL_OPTION_STRING other_functional_role;
+  EVEL_OPTION_STRING rac;
+  EVEL_OPTION_STRING radio_access_technology;
+  EVEL_OPTION_STRING sac;
+  EVEL_OPTION_INT sampling_algorithm;
+  EVEL_OPTION_STRING tac;
+  EVEL_OPTION_STRING tunnel_id;
+  EVEL_OPTION_STRING vlan_id;
+
+} EVENT_MOBILE_FLOW;
+
+/*****************************************************************************/
+/* Supported Other field version.                                            */
+/*****************************************************************************/
+#define EVEL_OTHER_EVENT_MAJOR_VERSION 1
+#define EVEL_OTHER_EVENT_MINOR_VERSION 1
+
+/**************************************************************************//**
+ * Other.
+ * JSON equivalent field: otherFields
+ *****************************************************************************/
+typedef struct event_other {
+  EVENT_HEADER header;
+  int major_version;
+  int minor_version;
+
+  HASHTABLE_T *namedarrays; /* HASHTABLE_T */
+  DLIST jsonobjects; /* DLIST of EVEL_JSON_OBJECT */
+  DLIST namedvalues;
+} EVENT_OTHER;
+
+/**************************************************************************//**
+ * Other Field.
+ * JSON equivalent field: otherFields
+ *****************************************************************************/
+typedef struct other_field {
+  char * name;
+  char * value;
+} OTHER_FIELD;
+
+
+/*****************************************************************************/
+/* Supported Service Events version.                                         */
+/*****************************************************************************/
+#define EVEL_HEARTBEAT_FIELD_MAJOR_VERSION 1
+#define EVEL_HEARTBEAT_FIELD_MINOR_VERSION 1
+
+
+/*****************************************************************************/
+/* Supported Signaling version.                                              */
+/*****************************************************************************/
+#define EVEL_SIGNALING_MAJOR_VERSION 2
+#define EVEL_SIGNALING_MINOR_VERSION 1
+
+/**************************************************************************//**
+ * Vendor VNF Name fields.
+ * JSON equivalent field: vendorVnfNameFields
+ *****************************************************************************/
+typedef struct vendor_vnfname_field {
+  char * vendorname;
+  EVEL_OPTION_STRING vfmodule;
+  EVEL_OPTION_STRING vnfname;
+} VENDOR_VNFNAME_FIELD;
+
+/**************************************************************************//**
+ * Signaling.
+ * JSON equivalent field: signalingFields
+ *****************************************************************************/
+typedef struct event_signaling {
+  /***************************************************************************/
+  /* Header and version                                                      */
+  /***************************************************************************/
+  EVENT_HEADER header;
+  int major_version;
+  int minor_version;
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  VENDOR_VNFNAME_FIELD vnfname_field;
+  EVEL_OPTION_STRING correlator;                         /* JSON: correlator */
+  EVEL_OPTION_STRING local_ip_address;               /* JSON: localIpAddress */
+  EVEL_OPTION_STRING local_port;                          /* JSON: localPort */
+  EVEL_OPTION_STRING remote_ip_address;             /* JSON: remoteIpAddress */
+  EVEL_OPTION_STRING remote_port;                        /* JSON: remotePort */
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  EVEL_OPTION_STRING compressed_sip;                  /* JSON: compressedSip */
+  EVEL_OPTION_STRING summary_sip;                        /* JSON: summarySip */
+  DLIST additional_info;
+
+} EVENT_SIGNALING;
+
+/**************************************************************************//**
+ * Sgnaling Additional Field.
+ * JSON equivalent field: additionalFields
+ *****************************************************************************/
+typedef struct signaling_additional_field {
+  char * name;
+  char * value;
+} SIGNALING_ADDL_FIELD;
+
+/*****************************************************************************/
+/* Supported State Change version.                                           */
+/*****************************************************************************/
+#define EVEL_STATE_CHANGE_MAJOR_VERSION 1
+#define EVEL_STATE_CHANGE_MINOR_VERSION 2
+
+/**************************************************************************//**
+ * State Change.
+ * JSON equivalent field: stateChangeFields
+ *****************************************************************************/
+typedef struct event_state_change {
+  /***************************************************************************/
+  /* Header and version                                                      */
+  /***************************************************************************/
+  EVENT_HEADER header;
+  int major_version;
+  int minor_version;
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  EVEL_ENTITY_STATE new_state;
+  EVEL_ENTITY_STATE old_state;
+  char * state_interface;
+  double version;
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  DLIST additional_fields;
+
+} EVENT_STATE_CHANGE;
+
+/**************************************************************************//**
+ * State Change Additional Field.
+ * JSON equivalent field: additionalFields
+ *****************************************************************************/
+typedef struct state_change_additional_field {
+  char * name;
+  char * value;
+} STATE_CHANGE_ADDL_FIELD;
+
+/*****************************************************************************/
+/* Supported Syslog version.                                                 */
+/*****************************************************************************/
+#define EVEL_SYSLOG_MAJOR_VERSION 1
+#define EVEL_SYSLOG_MINOR_VERSION 2
+
+/**************************************************************************//**
+ * Syslog.
+ * JSON equivalent field: syslogFields
+ *****************************************************************************/
+typedef struct event_syslog {
+  /***************************************************************************/
+  /* Header and version                                                      */
+  /***************************************************************************/
+  EVENT_HEADER header;
+  int major_version;
+  int minor_version;
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  EVEL_SOURCE_TYPES event_source_type;
+  char * syslog_msg;
+  char * syslog_tag;
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  EVEL_OPTION_STRING additional_filters;
+  EVEL_OPTION_STRING event_source_host;
+  EVEL_OPTION_INT syslog_facility;
+  EVEL_OPTION_INT syslog_priority;
+  EVEL_OPTION_STRING syslog_proc;
+  EVEL_OPTION_INT syslog_proc_id;
+  EVEL_OPTION_STRING syslog_s_data;
+  EVEL_OPTION_STRING syslog_sdid;
+  EVEL_OPTION_STRING syslog_severity;
+  double syslog_fver;
+  EVEL_OPTION_INT syslog_ver;
+
+} EVENT_SYSLOG;
+
+/**************************************************************************//**
+ * Copyright.
+ * JSON equivalent object: attCopyrightNotice
+ *****************************************************************************/
+typedef struct copyright {
+  char * useAndRedistribution;
+  char * condition1;
+  char * condition2;
+  char * condition3;
+  char * condition4;
+  char * disclaimerLine1;
+  char * disclaimerLine2;
+  char * disclaimerLine3;
+  char * disclaimerLine4;
+} COPYRIGHT;
+
+/**************************************************************************//**
+ * Library initialization.
+ *
+ * Initialize the EVEL library.
+ *
+ * @note  This function initializes the cURL library.  Applications making use
+ *        of libcurl may need to pull the initialization out of here.  Note
+ *        also that this function is not threadsafe as a result - refer to
+ *        libcurl's API documentation for relevant warnings.
+ *
+ * @sa  Matching Term function.
+ *
+ * @param   fqdn    The API's FQDN or IP address.
+ * @param   port    The API's port.
+ * @param   path    The optional path (may be NULL).
+ * @param   topic   The optional topic part of the URL (may be NULL).
+ * @param   secure  Whether to use HTTPS (0=HTTP, 1=HTTPS).
+ * @param   username  Username for Basic Authentication of requests.
+ * @param   password  Password for Basic Authentication of requests.
+ * @param   source_type The kind of node we represent.
+ * @param   role    The role this node undertakes.
+ * @param   verbosity  0 for normal operation, positive values for chattier
+ *                     logs.
+ *
+ * @returns Status code
+ * @retval  EVEL_SUCCESS      On success
+ * @retval  ::EVEL_ERR_CODES  On failure.
+ *****************************************************************************/
+EVEL_ERR_CODES evel_initialize(const char * const fqdn,
+                               int port,
+                               const char * const path,
+                               const char * const topic,
+                               int secure,
+                               const char * const username,
+                               const char * const password,
+                               EVEL_SOURCE_TYPES source_type,
+                               const char * const role,
+                               int verbosity
+                               );
+
+/**************************************************************************//**
+ * Clean up the EVEL library.
+ *
+ * @note that at present don't expect Init/Term cycling not to leak memory!
+ *
+ * @returns Status code
+ * @retval  EVEL_SUCCESS On success
+ * @retval  "One of ::EVEL_ERR_CODES" On failure.
+ *****************************************************************************/
+EVEL_ERR_CODES evel_terminate(void);
+
+EVEL_ERR_CODES evel_post_event(EVENT_HEADER * event);
+const char * evel_error_string(void);
+
+
+/**************************************************************************//**
+ * Free an event.
+ *
+ * Free off the event supplied.  Will free all the contained allocated memory.
+ *
+ * @note  It is safe to free a NULL pointer.
+ *****************************************************************************/
+void evel_free_event(void * event);
+
+/**************************************************************************//**
+ * Encode the event as a JSON event object according to AT&T's schema.
+ *
+ * @param json      Pointer to where to store the JSON encoded data.
+ * @param max_size  Size of storage available in json_body.
+ * @param event     Pointer to the ::EVENT_HEADER to encode.
+ * @returns Number of bytes actually written.
+ *****************************************************************************/
+int evel_json_encode_event(char * json,
+                           int max_size,
+                           EVENT_HEADER * event);
+
+/**************************************************************************//**
+ * Initialize an event instance id.
+ *
+ * @param vfield        Pointer to the event vnfname field being initialized.
+ * @param vendor_id     The vendor id to encode in the event instance id.
+ * @param event_id      The event id to encode in the event instance id.
+ *****************************************************************************/
+void evel_init_vendor_field(VENDOR_VNFNAME_FIELD * const vfield,
+                                 const char * const vendor_name);
+
+/**************************************************************************//**
+ * Set the Vendor module property of the Vendor.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vfield        Pointer to the Vendor field.
+ * @param module_name   The module name to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_vendor_field_module_set(VENDOR_VNFNAME_FIELD * const vfield,
+                                    const char * const module_name);
+/**************************************************************************//**
+ * Set the Vendor module property of the Vendor.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vfield        Pointer to the Vendor field.
+ * @param module_name   The module name to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_vendor_field_vnfname_set(VENDOR_VNFNAME_FIELD * const vfield,
+                                    const char * const vnfname);
+/**************************************************************************//**
+ * Free an event instance id.
+ *
+ * @param vfield   Pointer to the event vnfname_field being freed.
+ *****************************************************************************/
+void evel_free_event_vendor_field(VENDOR_VNFNAME_FIELD * const vfield);
+
+/**************************************************************************//**
+ * Callback function to provide returned data.
+ *
+ * Copy data into the supplied buffer, write_callback::ptr, checking size
+ * limits.
+ *
+ * @returns   Number of bytes placed into write_callback::ptr. 0 for EOF.
+ *****************************************************************************/
+size_t evel_write_callback(void *contents,
+                           size_t size,
+                           size_t nmemb,
+                           void *userp);
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*                                                                           */
+/*   HEARTBEAT - (includes common header, too)                               */
+/*                                                                           */
+/*****************************************************************************/
+/*****************************************************************************/
+
+/**************************************************************************//**
+ * Create a new heartbeat event.
+ *
+ * @note that the heartbeat is just a "naked" commonEventHeader!
+ *
+ * @returns pointer to the newly manufactured ::EVENT_HEADER.  If the event is
+ *          not used it must be released using ::evel_free_event
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_HEADER * evel_new_heartbeat(void);
+
+/**************************************************************************//**
+ * Create a new heartbeat event of given name and type.
+ *
+ * @note that the heartbeat is just a "naked" commonEventHeader!
+ *
+ * @param event_name  Unique Event Name confirming Domain AsdcModel Description
+ * @param event_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
+ *
+ * @returns pointer to the newly manufactured ::EVENT_HEADER.  If the event is
+ *          not used it must be released using ::evel_free_event
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_HEADER * evel_new_heartbeat_nameid(const char* ev_name, const char *ev_id);
+
+
+/**************************************************************************//**
+ * Free an event header.
+ *
+ * Free off the event header supplied.  Will free all the contained allocated
+ * memory.
+ *
+ * @note It does not free the header itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_header(EVENT_HEADER * const event);
+
+/**************************************************************************//**
+ * Initialize a newly created event header.
+ *
+ * @param header  Pointer to the header being initialized.
+ *****************************************************************************/
+void evel_init_header(EVENT_HEADER * const header,const char *const eventname);
+
+/**************************************************************************//**
+ * Set the Event Type property of the event header.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param type          The Event Type to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_header_type_set(EVENT_HEADER * const header,
+                          const char * const type);
+
+/**************************************************************************//**
+ * Set the Start Epoch property of the event header.
+ *
+ * @note The Start Epoch defaults to the time of event creation.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param start_epoch_microsec
+ *                      The start epoch to set, in microseconds.
+ *****************************************************************************/
+void evel_start_epoch_set(EVENT_HEADER * const header,
+                          const unsigned long long start_epoch_microsec);
+
+/**************************************************************************//**
+ * Set the Last Epoch property of the event header.
+ *
+ * @note The Last Epoch defaults to the time of event creation.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param last_epoch_microsec
+ *                      The last epoch to set, in microseconds.
+ *****************************************************************************/
+void evel_last_epoch_set(EVENT_HEADER * const header,
+                         const unsigned long long last_epoch_microsec);
+
+/**************************************************************************//**
+ * Set the Reporting Entity Name property of the event header.
+ *
+ * @note The Reporting Entity Name defaults to the OpenStack VM Name.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param entity_name   The entity name to set.
+ *****************************************************************************/
+void evel_reporting_entity_name_set(EVENT_HEADER * const header,
+                                    const char * const entity_name);
+
+/**************************************************************************//**
+ * Set the Reporting Entity Id property of the event header.
+ *
+ * @note The Reporting Entity Id defaults to the OpenStack VM UUID.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param entity_id     The entity id to set.
+ *****************************************************************************/
+void evel_reporting_entity_id_set(EVENT_HEADER * const header,
+                                  const char * const entity_id);
+
+/**************************************************************************//**
+ * Set the NFC Naming code property of the event header.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param nfcnamingcode String
+ *****************************************************************************/
+void evel_nfcnamingcode_set(EVENT_HEADER * const header,
+                         const char * const nfcnam);
+/**************************************************************************//**
+ * Set the NF Naming code property of the event header.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param nfnamingcode String
+ *****************************************************************************/
+void evel_nfnamingcode_set(EVENT_HEADER * const header,
+                         const char * const nfnam);
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*                                                                           */
+/*   FAULT                                                                   */
+/*                                                                           */
+/*****************************************************************************/
+/*****************************************************************************/
+
+/**************************************************************************//**
+ * Create a new fault event.
+ *
+ * @note    The mandatory fields on the Fault must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Fault has immutable properties.
+ * @param event_name    Unique Event Name
+ * @param event_id    A universal identifier of the event for analysis etc
+ * @param   condition   The condition indicated by the Fault.
+ * @param   specific_problem  The specific problem triggering the fault.
+ * @param   priority    The priority of the event.
+ * @param   severity    The severity of the Fault.
+ * @param   ev_source_type    Source of Alarm event
+ * @param   version     fault version
+ * @param   status      status of Virtual Function
+ * @returns pointer to the newly manufactured ::EVENT_FAULT.  If the event is
+ *          not used (i.e. posted) it must be released using ::evel_free_fault.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_FAULT * evel_new_fault(const char* ev_name, const char *ev_id,
+                            const char * const condition,
+                             const char * const specific_problem,
+                             EVEL_EVENT_PRIORITIES priority,
+                             EVEL_SEVERITIES severity,
+                             EVEL_SOURCE_TYPES ev_source_type,
+                             EVEL_VF_STATUSES status);
+
+/**************************************************************************//**
+ * Free a Fault.
+ *
+ * Free off the Fault supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the Fault itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_fault(EVENT_FAULT * event);
+
+/**************************************************************************//**
+ * Set the Fault Category property of the Fault.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param fault      Pointer to the fault.
+ * @param category   Category : license, link, routing, security, signaling.
+ *                       ASCIIZ string. The caller
+ *                   does not need to preserve the value once the function
+ *                   returns.
+ *****************************************************************************/
+void evel_fault_category_set(EVENT_FAULT * fault,
+                              const char * const category);
+
+/**************************************************************************//**
+ * Set the Alarm Interface A property of the Fault.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param fault      Pointer to the fault.
+ * @param interface  The Alarm Interface A to be set. ASCIIZ string. The caller
+ *                   does not need to preserve the value once the function
+ *                   returns.
+ *****************************************************************************/
+void evel_fault_interface_set(EVENT_FAULT * fault,
+                              const char * const interface);
+
+/**************************************************************************//**
+ * Add an additional value name/value pair to the Fault.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param fault     Pointer to the fault.
+ * @param name      ASCIIZ string with the attribute's name.
+ * @param value     ASCIIZ string with the attribute's value.
+ *****************************************************************************/
+void evel_fault_addl_info_add(EVENT_FAULT * fault, char * name, char * value);
+
+/**************************************************************************//**
+ * Set the Event Type property of the Fault.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param fault      Pointer to the fault.
+ * @param type       The Event Type to be set. ASCIIZ string. The caller
+ *                   does not need to preserve the value once the function
+ *                   returns.
+ *****************************************************************************/
+void evel_fault_type_set(EVENT_FAULT * fault, const char * const type);
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*                                                                           */
+/*   MEASUREMENT                                                             */
+/*                                                                           */
+/*****************************************************************************/
+/*****************************************************************************/
+
+/**************************************************************************//**
+ * Create a new Measurement event.
+ *
+ * @note    The mandatory fields on the Measurement must be supplied to this
+ *          factory function and are immutable once set.  Optional fields have
+ *          explicit setter functions, but again values may only be set once so
+ *          that the Measurement has immutable properties.
+ *
+ * @param   measurement_interval
+ * @param event_name    Unique Event Name
+ * @param event_id    A universal identifier of the event for analysis etc
+ *
+ * @returns pointer to the newly manufactured ::EVENT_MEASUREMENT.  If the
+ *          event is not used (i.e. posted) it must be released using
+ *          ::evel_free_event.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_MEASUREMENT * evel_new_measurement(double measurement_interval,const char* ev_name, const char *ev_id);
+
+/**************************************************************************//**
+ * Free a Measurement.
+ *
+ * Free off the Measurement supplied.  Will free all the contained allocated
+ * memory.
+ *
+ * @note It does not free the Measurement itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_measurement(EVENT_MEASUREMENT * event);
+
+/**************************************************************************//**
+ * Set the Event Type property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement Pointer to the Measurement.
+ * @param type        The Event Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_measurement_type_set(EVENT_MEASUREMENT * measurement,
+                               const char * const type);
+
+/**************************************************************************//**
+ * Set the Concurrent Sessions property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement         Pointer to the Measurement.
+ * @param concurrent_sessions The Concurrent Sessions to be set.
+ *****************************************************************************/
+void evel_measurement_conc_sess_set(EVENT_MEASUREMENT * measurement,
+                                    int concurrent_sessions);
+
+/**************************************************************************//**
+ * Set the Configured Entities property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement         Pointer to the Measurement.
+ * @param configured_entities The Configured Entities to be set.
+ *****************************************************************************/
+void evel_measurement_cfg_ents_set(EVENT_MEASUREMENT * measurement,
+                                   int configured_entities);
+
+/**************************************************************************//**
+ * Add an additional set of Errors to the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement       Pointer to the measurement.
+ * @param receive_discards  The number of receive discards.
+ * @param receive_errors    The number of receive errors.
+ * @param transmit_discards The number of transmit discards.
+ * @param transmit_errors   The number of transmit errors.
+ *****************************************************************************/
+void evel_measurement_errors_set(EVENT_MEASUREMENT * measurement,
+                                 int receive_discards,
+                                 int receive_errors,
+                                 int transmit_discards,
+                                 int transmit_errors);
+
+/**************************************************************************//**
+ * Set the Mean Request Latency property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement          Pointer to the Measurement.
+ * @param mean_request_latency The Mean Request Latency to be set.
+ *****************************************************************************/
+void evel_measurement_mean_req_lat_set(EVENT_MEASUREMENT * measurement,
+                                       double mean_request_latency);
+
+/**************************************************************************//**
+ * Set the Request Rate property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement  Pointer to the Measurement.
+ * @param request_rate The Request Rate to be set.
+ *****************************************************************************/
+void evel_measurement_request_rate_set(EVENT_MEASUREMENT * measurement,
+                                       int request_rate);
+
+/**************************************************************************//**
+ * Add an additional CPU usage value name/value pair to the Measurement.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement   Pointer to the measurement.
+ * @param id            ASCIIZ string with the CPU's identifier.
+ * @param usage         CPU utilization.
+ *****************************************************************************/
+MEASUREMENT_CPU_USE * evel_measurement_new_cpu_use_add(EVENT_MEASUREMENT * measurement, char * id, double usage);
+
+/**************************************************************************//**
+ * Set the CPU Idle value in measurement interval
+ *   percentage of CPU time spent in the idle task
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_idle_set(MEASUREMENT_CPU_USE *const cpu_use,
+                                    const double val);
+
+/**************************************************************************//**
+ * Set the percentage of time spent servicing interrupts
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_interrupt_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val);
+
+/**************************************************************************//**
+ * Set the percentage of time spent running user space processes that have been niced
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_nice_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val);
+
+/**************************************************************************//**
+ * Set the percentage of time spent handling soft irq interrupts
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_softirq_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val);
+/**************************************************************************//**
+ * Set the percentage of time spent in involuntary wait
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_steal_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val);
+/**************************************************************************//**
+ * Set the percentage of time spent on system tasks running the kernel
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_system_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val);
+/**************************************************************************//**
+ * Set the percentage of time spent running un-niced user space processes
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_usageuser_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val);
+/**************************************************************************//**
+ * Set the percentage of CPU time spent waiting for I/O operations to complete
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_wait_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val);
+
+/**************************************************************************//**
+ * Add an additional File System usage value name/value pair to the
+ * Measurement.
+ *
+ * The filesystem_name is null delimited ASCII string.  The library takes a
+ * copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement     Pointer to the measurement.
+ * @param filesystem_name   ASCIIZ string with the file-system's UUID.
+ * @param block_configured  Block storage configured.
+ * @param block_used        Block storage in use.
+ * @param block_iops        Block storage IOPS.
+ * @param ephemeral_configured  Ephemeral storage configured.
+ * @param ephemeral_used        Ephemeral storage in use.
+ * @param ephemeral_iops        Ephemeral storage IOPS.
+ *****************************************************************************/
+void evel_measurement_fsys_use_add(EVENT_MEASUREMENT * measurement,
+                                   char * filesystem_name,
+                                   double block_configured,
+                                   double block_used,
+                                   double block_iops,
+                                   double ephemeral_configured,
+                                   double ephemeral_used,
+                                   double ephemeral_iops);
+
+/**************************************************************************//**
+ * Add a Feature usage value name/value pair to the Measurement.
+ *
+ * The name is null delimited ASCII string.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement     Pointer to the measurement.
+ * @param feature         ASCIIZ string with the feature's name.
+ * @param utilization     Utilization of the feature.
+ *****************************************************************************/
+void evel_measurement_feature_use_add(EVENT_MEASUREMENT * measurement,
+                                      char * feature,
+                                      int utilization);
+
+/**************************************************************************//**
+ * Add a Additional Measurement value name/value pair to the Measurement.
+ *
+ * The name is null delimited ASCII string.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement   Pointer to the Measurement.
+ * @param group    ASCIIZ string with the measurement group's name.
+ * @param name     ASCIIZ string containing the measurement's name.
+ * @param name     ASCIIZ string containing the measurement's value.
+ *****************************************************************************/
+void evel_measurement_custom_measurement_add(EVENT_MEASUREMENT * measurement,
+                                             const char * const group,
+                                             const char * const name,
+                                             const char * const value);
+
+/**************************************************************************//**
+ * Add a Codec usage value name/value pair to the Measurement.
+ *
+ * The name is null delimited ASCII string.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement     Pointer to the measurement.
+ * @param codec           ASCIIZ string with the codec's name.
+ * @param utilization     Utilization of the feature.
+ *****************************************************************************/
+void evel_measurement_codec_use_add(EVENT_MEASUREMENT * measurement,
+                                    char * codec,
+                                    int utilization);
+
+/**************************************************************************//**
+ * Set the Media Ports in Use property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement         Pointer to the measurement.
+ * @param media_ports_in_use  The media port usage to set.
+ *****************************************************************************/
+void evel_measurement_media_port_use_set(EVENT_MEASUREMENT * measurement,
+                                         int media_ports_in_use);
+
+/**************************************************************************//**
+ * Set the VNFC Scaling Metric property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement     Pointer to the measurement.
+ * @param scaling_metric  The scaling metric to set.
+ *****************************************************************************/
+void evel_measurement_vnfc_scaling_metric_set(EVENT_MEASUREMENT * measurement,
+                                              int scaling_metric);
+
+/**************************************************************************//**
+ * Create a new Latency Bucket to be added to a Measurement event.
+ *
+ * @note    The mandatory fields on the ::MEASUREMENT_LATENCY_BUCKET must be
+ *          supplied to this factory function and are immutable once set.
+ *          Optional fields have explicit setter functions, but again values
+ *          may only be set once so that the ::MEASUREMENT_LATENCY_BUCKET has
+ *          immutable properties.
+ *
+ * @param count         Count of events in this bucket.
+ *
+ * @returns pointer to the newly manufactured ::MEASUREMENT_LATENCY_BUCKET.
+ * @retval  NULL  Failed to create the Latency Bucket.
+ *****************************************************************************/
+MEASUREMENT_LATENCY_BUCKET * evel_new_meas_latency_bucket(const int count);
+
+/**************************************************************************//**
+ * Set the High End property of the Measurement Latency Bucket.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param bucket        Pointer to the Measurement Latency Bucket.
+ * @param high_end      High end of the bucket's range.
+ *****************************************************************************/
+void evel_meas_latency_bucket_high_end_set(
+                                     MEASUREMENT_LATENCY_BUCKET * const bucket,
+                                     const double high_end);
+
+/**************************************************************************//**
+ * Set the Low End property of the Measurement Latency Bucket.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param bucket        Pointer to the Measurement Latency Bucket.
+ * @param low_end       Low end of the bucket's range.
+ *****************************************************************************/
+void evel_meas_latency_bucket_low_end_set(
+                                     MEASUREMENT_LATENCY_BUCKET * const bucket,
+                                     const double low_end);
+
+/**************************************************************************//**
+ * Add an additional Measurement Latency Bucket to the specified event.
+ *
+ * @param measurement   Pointer to the Measurement event.
+ * @param bucket        Pointer to the Measurement Latency Bucket to add.
+ *****************************************************************************/
+void evel_meas_latency_bucket_add(EVENT_MEASUREMENT * const measurement,
+                                  MEASUREMENT_LATENCY_BUCKET * const bucket);
+
+/**************************************************************************//**
+ * Add an additional Latency Distribution bucket to the Measurement.
+ *
+ * This function implements the previous API, purely for convenience.
+ *
+ * @param measurement   Pointer to the measurement.
+ * @param low_end       Low end of the bucket's range.
+ * @param high_end      High end of the bucket's range.
+ * @param count         Count of events in this bucket.
+ *****************************************************************************/
+void evel_measurement_latency_add(EVENT_MEASUREMENT * const measurement,
+                                  const double low_end,
+                                  const double high_end,
+                                  const int count);
+
+/**************************************************************************//**
+ * Create a new vNIC Use to be added to a Measurement event.
+ *
+ * @note    The mandatory fields on the ::MEASUREMENT_VNIC_PERFORMANCE must be supplied
+ *          to this factory function and are immutable once set. Optional
+ *          fields have explicit setter functions, but again values may only be
+ *          set once so that the ::MEASUREMENT_VNIC_PERFORMANCE has immutable
+ *          properties.
+ *
+ * @param vnic_id               ASCIIZ string with the vNIC's ID.
+ * @param val_suspect           True or false confidence in data.
+ *
+ * @returns pointer to the newly manufactured ::MEASUREMENT_VNIC_PERFORMANCE.
+ *          If the structure is not used it must be released using
+ *          ::evel_measurement_free_vnic_performance.
+ * @retval  NULL  Failed to create the vNIC Use.
+ *****************************************************************************/
+MEASUREMENT_VNIC_PERFORMANCE * evel_measurement_new_vnic_performance(char * const vnic_id, char * const val_suspect);
+
+/**************************************************************************//**
+ * Free a vNIC Use.
+ *
+ * Free off the ::MEASUREMENT_VNIC_PERFORMANCE supplied.  Will free all the contained
+ * allocated memory.
+ *
+ * @note It does not free the vNIC Use itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_measurement_free_vnic_performance(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance);
+
+/**************************************************************************//**
+ * Set the Accumulated Broadcast Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_bcast_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_bcast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_bcast_packets_acc);
+/**************************************************************************//**
+ * Set the Delta Broadcast Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_bcast_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_bcast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_bcast_packets_delta);
+/**************************************************************************//**
+ * Set the Discarded Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_discard_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_discard_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_discard_packets_acc);
+/**************************************************************************//**
+ * Set the Delta Discarded Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_discard_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_discard_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_discard_packets_delta);
+/**************************************************************************//**
+ * Set the Error Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_error_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_error_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_error_packets_acc);
+/**************************************************************************//**
+ * Set the Delta Error Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_error_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_error_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_error_packets_delta);
+/**************************************************************************//**
+ * Set the Accumulated Multicast Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_mcast_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_mcast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_mcast_packets_acc);
+/**************************************************************************//**
+ * Set the Delta Multicast Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_mcast_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_mcast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_mcast_packets_delta);
+/**************************************************************************//**
+ * Set the Accumulated Octets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_octets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_octets_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_octets_acc);
+/**************************************************************************//**
+ * Set the Delta Octets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_octets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_octets_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_octets_delta);
+/**************************************************************************//**
+ * Set the Accumulated Total Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_total_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_total_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_total_packets_acc);
+/**************************************************************************//**
+ * Set the Delta Total Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_total_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_total_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_total_packets_delta);
+/**************************************************************************//**
+ * Set the Accumulated Unicast Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_ucast_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_ucast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_ucast_packets_acc);
+/**************************************************************************//**
+ * Set the Delta Unicast packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_ucast_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_ucast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_ucast_packets_delta);
+/**************************************************************************//**
+ * Set the Transmitted Broadcast Packets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_bcast_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_bcast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_bcast_packets_acc);
+/**************************************************************************//**
+ * Set the Delta Broadcast packets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_bcast_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_bcast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_bcast_packets_delta);
+/**************************************************************************//**
+ * Set the Transmitted Discarded Packets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_discarded_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_discarded_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_discarded_packets_acc);
+/**************************************************************************//**
+ * Set the Delta Discarded packets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_discarded_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_discarded_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_discarded_packets_delta);
+/**************************************************************************//**
+ * Set the Transmitted Errored Packets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_error_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_error_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_error_packets_acc);
+/**************************************************************************//**
+ * Set the Delta Errored packets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_error_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_error_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_error_packets_delta);
+/**************************************************************************//**
+ * Set the Transmitted Multicast Packets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_mcast_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_mcast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_mcast_packets_acc);
+/**************************************************************************//**
+ * Set the Delta Multicast packets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_mcast_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_mcast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_mcast_packets_delta);
+/**************************************************************************//**
+ * Set the Transmitted Octets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_octets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_octets_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_octets_acc);
+/**************************************************************************//**
+ * Set the Delta Octets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_octets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_octets_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_octets_delta);
+/**************************************************************************//**
+ * Set the Transmitted Total Packets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_total_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_total_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_total_packets_acc);
+/**************************************************************************//**
+ * Set the Delta Total Packets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_total_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_total_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_total_packets_delta);
+/**************************************************************************//**
+ * Set the Transmitted Unicast Packets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_ucast_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_ucast_packets_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_ucast_packets_acc);
+/**************************************************************************//**
+ * Set the Delta Octets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_ucast_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_ucast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_ucast_packets_delta);
+
+/**************************************************************************//**
+ * Add an additional vNIC Use to the specified Measurement event.
+ *
+ * @param measurement   Pointer to the measurement.
+ * @param vnic_performance      Pointer to the vNIC Use to add.
+ *****************************************************************************/
+void evel_meas_vnic_performance_add(EVENT_MEASUREMENT * const measurement,
+                            MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance);
+
+/**************************************************************************//**
+ * Add an additional vNIC usage record Measurement.
+ *
+ * This function implements the previous API, purely for convenience.
+ *
+ * The ID is null delimited ASCII string.  The library takes a copy so the
+ * caller does not have to preserve values after the function returns.
+ *
+ * @param measurement           Pointer to the measurement.
+ * @param vnic_id               ASCIIZ string with the vNIC's ID.
+ * @param valset                true or false confidence level
+ * @param recvd_bcast_packets_acc         Recieved broadcast packets
+ * @param recvd_bcast_packets_delta       Received delta broadcast packets
+ * @param recvd_discarded_packets_acc     Recieved discarded packets
+ * @param recvd_discarded_packets_delta   Received discarded delta packets
+ * @param recvd_error_packets_acc         Received error packets
+ * @param recvd_error_packets_delta,      Received delta error packets
+ * @param recvd_mcast_packets_acc         Received multicast packets
+ * @param recvd_mcast_packets_delta       Received delta multicast packets
+ * @param recvd_octets_acc                Received octets
+ * @param recvd_octets_delta              Received delta octets
+ * @param recvd_total_packets_acc         Received total packets
+ * @param recvd_total_packets_delta       Received delta total packets
+ * @param recvd_ucast_packets_acc         Received Unicast packets
+ * @param recvd_ucast_packets_delta       Received delta unicast packets
+ * @param tx_bcast_packets_acc            Transmitted broadcast packets
+ * @param tx_bcast_packets_delta          Transmitted delta broadcast packets
+ * @param tx_discarded_packets_acc        Transmitted packets discarded
+ * @param tx_discarded_packets_delta      Transmitted delta discarded packets
+ * @param tx_error_packets_acc            Transmitted error packets
+ * @param tx_error_packets_delta          Transmitted delta error packets
+ * @param tx_mcast_packets_acc            Transmitted multicast packets accumulated
+ * @param tx_mcast_packets_delta          Transmitted delta multicast packets
+ * @param tx_octets_acc                   Transmitted octets
+ * @param tx_octets_delta                 Transmitted delta octets
+ * @param tx_total_packets_acc            Transmitted total packets
+ * @param tx_total_packets_delta          Transmitted delta total packets
+ * @param tx_ucast_packets_acc            Transmitted Unicast packets
+ * @param tx_ucast_packets_delta          Transmitted delta Unicast packets
+ *****************************************************************************/
+void evel_measurement_vnic_performance_add(EVENT_MEASUREMENT * const measurement,
+                               char * const vnic_id,
+                               char * valset,
+                               double recvd_bcast_packets_acc,
+                               double recvd_bcast_packets_delta,
+                               double recvd_discarded_packets_acc,
+                               double recvd_discarded_packets_delta,
+                               double recvd_error_packets_acc,
+                               double recvd_error_packets_delta,
+                               double recvd_mcast_packets_acc,
+                               double recvd_mcast_packets_delta,
+                               double recvd_octets_acc,
+                               double recvd_octets_delta,
+                               double recvd_total_packets_acc,
+                               double recvd_total_packets_delta,
+                               double recvd_ucast_packets_acc,
+                               double recvd_ucast_packets_delta,
+                               double tx_bcast_packets_acc,
+                               double tx_bcast_packets_delta,
+                               double tx_discarded_packets_acc,
+                               double tx_discarded_packets_delta,
+                               double tx_error_packets_acc,
+                               double tx_error_packets_delta,
+                               double tx_mcast_packets_acc,
+                               double tx_mcast_packets_delta,
+                               double tx_octets_acc,
+                               double tx_octets_delta,
+                               double tx_total_packets_acc,
+                               double tx_total_packets_delta,
+                               double tx_ucast_packets_acc,
+                               double tx_ucast_packets_delta);
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*                                                                           */
+/*   REPORT                                                                  */
+/*                                                                           */
+/*****************************************************************************/
+/*****************************************************************************/
+
+/**************************************************************************//**
+ * Create a new Report event.
+ *
+ * @note    The mandatory fields on the Report must be supplied to this
+ *          factory function and are immutable once set.  Optional fields have
+ *          explicit setter functions, but again values may only be set once so
+ *          that the Report has immutable properties.
+ *
+ * @param   measurement_interval
+ * @param event_name    Unique Event Name
+ * @param event_id    A universal identifier of the event for analysis etc
+ *
+ * @returns pointer to the newly manufactured ::EVENT_REPORT.  If the event is
+ *          not used (i.e. posted) it must be released using
+ *          ::evel_free_report.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_REPORT * evel_new_report(double measurement_interval,const char* ev_name, const char *ev_id);
+
+/**************************************************************************//**
+ * Free a Report.
+ *
+ * Free off the Report supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the Report itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_report(EVENT_REPORT * event);
+
+/**************************************************************************//**
+ * Set the Event Type property of the Report.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param report Pointer to the Report.
+ * @param type        The Event Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_report_type_set(EVENT_REPORT * report, const char * const type);
+
+/**************************************************************************//**
+ * Add a Feature usage value name/value pair to the Report.
+ *
+ * The name is null delimited ASCII string.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param report          Pointer to the report.
+ * @param feature         ASCIIZ string with the feature's name.
+ * @param utilization     Utilization of the feature.
+ *****************************************************************************/
+void evel_report_feature_use_add(EVENT_REPORT * report,
+                                 char * feature,
+                                 int utilization);
+
+/**************************************************************************//**
+ * Add a Additional Measurement value name/value pair to the Report.
+ *
+ * The name is null delimited ASCII string.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param report   Pointer to the report.
+ * @param group    ASCIIZ string with the measurement group's name.
+ * @param name     ASCIIZ string containing the measurement's name.
+ * @param value    ASCIIZ string containing the measurement's value.
+ *****************************************************************************/
+void evel_report_custom_measurement_add(EVENT_REPORT * report,
+                                        const char * const group,
+                                        const char * const name,
+                                        const char * const value);
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*                                                                           */
+/*   MOBILE_FLOW                                                             */
+/*                                                                           */
+/*****************************************************************************/
+/*****************************************************************************/
+
+/**************************************************************************//**
+ * Create a new Mobile Flow event.
+ *
+ * @note    The mandatory fields on the Mobile Flow must be supplied to this
+ *          factory function and are immutable once set.  Optional fields have
+ *          explicit setter functions, but again values may only be set once so
+ *          that the Mobile Flow has immutable properties.
+ *
+ * @param event_name    Unique Event Name
+ * @param event_id    A universal identifier of the event for analysis etc
+ * @param   flow_direction
+ * @param   gtp_per_flow_metrics
+ * @param   ip_protocol_type
+ * @param   ip_version
+ * @param   other_endpoint_ip_address
+ * @param   other_endpoint_port
+ * @param   reporting_endpoint_ip_addr
+ * @param   reporting_endpoint_port
+ *
+ * @returns pointer to the newly manufactured ::EVENT_MOBILE_FLOW.  If the
+ *          event is not used (i.e. posted) it must be released using
+ *          ::evel_free_mobile_flow.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_MOBILE_FLOW * evel_new_mobile_flow(
+                     const char* ev_name, const char *ev_id,
+                      const char * const flow_direction,
+                      MOBILE_GTP_PER_FLOW_METRICS * gtp_per_flow_metrics,
+                      const char * const ip_protocol_type,
+                      const char * const ip_version,
+                      const char * const other_endpoint_ip_address,
+                      int other_endpoint_port,
+                      const char * const reporting_endpoint_ip_addr,
+                      int reporting_endpoint_port);
+
+/**************************************************************************//**
+ * Free a Mobile Flow.
+ *
+ * Free off the Mobile Flow supplied.  Will free all the contained allocated
+ * memory.
+ *
+ * @note It does not free the Mobile Flow itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_mobile_flow(EVENT_MOBILE_FLOW * event);
+
+/**************************************************************************//**
+ * Set the Event Type property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param type        The Event Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_mobile_flow_type_set(EVENT_MOBILE_FLOW * mobile_flow,
+                               const char * const type);
+
+/**************************************************************************//**
+ * Set the Application Type property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param type        The Application Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_mobile_flow_app_type_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                   const char * const type);
+
+/**************************************************************************//**
+ * Set the Application Protocol Type property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param type        The Application Protocol Type to be set. ASCIIZ string.
+ *                    The caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_flow_app_prot_type_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                        const char * const type);
+
+/**************************************************************************//**
+ * Set the Application Protocol Version property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param version     The Application Protocol Version to be set. ASCIIZ
+ *                    string.  The caller does not need to preserve the value
+ *                    once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_app_prot_ver_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                       const char * const version);
+
+/**************************************************************************//**
+ * Set the CID property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param cid         The CID to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_cid_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const cid);
+
+/**************************************************************************//**
+ * Set the Connection Type property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param type        The Connection Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_mobile_flow_con_type_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                   const char * const type);
+
+/**************************************************************************//**
+ * Set the ECGI property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param ecgi        The ECGI to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_ecgi_set(EVENT_MOBILE_FLOW * mobile_flow,
+                               const char * const ecgi);
+
+/**************************************************************************//**
+ * Set the GTP Protocol Type property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param type        The GTP Protocol Type to be set. ASCIIZ string.  The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_flow_gtp_prot_type_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                        const char * const type);
+
+/**************************************************************************//**
+ * Set the GTP Protocol Version property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param version     The GTP Protocol Version to be set. ASCIIZ string.  The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_flow_gtp_prot_ver_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                       const char * const version);
+
+/**************************************************************************//**
+ * Set the HTTP Header property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param header      The HTTP header to be set. ASCIIZ string. The caller does
+ *                    not need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_http_header_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                      const char * const header);
+
+/**************************************************************************//**
+ * Set the IMEI property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param imei        The IMEI to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_imei_set(EVENT_MOBILE_FLOW * mobile_flow,
+                               const char * const imei);
+
+/**************************************************************************//**
+ * Set the IMSI property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param imsi        The IMSI to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_imsi_set(EVENT_MOBILE_FLOW * mobile_flow,
+                               const char * const imsi);
+
+/**************************************************************************//**
+ * Set the LAC property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param lac         The LAC to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_lac_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const lac);
+
+/**************************************************************************//**
+ * Set the MCC property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param mcc         The MCC to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_mcc_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const mcc);
+
+/**************************************************************************//**
+ * Set the MNC property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param mnc         The MNC to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_mnc_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const mnc);
+
+/**************************************************************************//**
+ * Set the MSISDN property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param msisdn      The MSISDN to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_msisdn_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                 const char * const msisdn);
+
+/**************************************************************************//**
+ * Set the Other Functional Role property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param role        The Other Functional Role to be set. ASCIIZ string. The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_flow_other_func_role_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                          const char * const role);
+
+/**************************************************************************//**
+ * Set the RAC property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param rac         The RAC to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_rac_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const rac);
+
+/**************************************************************************//**
+ * Set the Radio Access Technology property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param tech        The Radio Access Technology to be set. ASCIIZ string. The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_flow_radio_acc_tech_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                         const char * const tech);
+
+/**************************************************************************//**
+ * Set the SAC property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param sac         The SAC to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_sac_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const sac);
+
+/**************************************************************************//**
+ * Set the Sampling Algorithm property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param algorithm   The Sampling Algorithm to be set.
+ *****************************************************************************/
+void evel_mobile_flow_samp_alg_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                   int algorithm);
+
+/**************************************************************************//**
+ * Set the TAC property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param tac         The TAC to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_tac_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const tac);
+
+/**************************************************************************//**
+ * Set the Tunnel ID property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param tunnel_id   The Tunnel ID to be set. ASCIIZ string.  The caller does
+ *                    not need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_tunnel_id_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                    const char * const tunnel_id);
+
+/**************************************************************************//**
+ * Set the VLAN ID property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param vlan_id     The VLAN ID to be set. ASCIIZ string.  The caller does
+ *                    not need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_vlan_id_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                  const char * const vlan_id);
+
+/**************************************************************************//**
+ * Create a new Mobile GTP Per Flow Metrics.
+ *
+ * @note    The mandatory fields on the Mobile GTP Per Flow Metrics must be
+ *          supplied to this factory function and are immutable once set.
+ *          Optional fields have explicit setter functions, but again values
+ *          may only be set once so that the Mobile GTP Per Flow Metrics has
+ *          immutable properties.
+ *
+ * @param   avg_bit_error_rate
+ * @param   avg_packet_delay_variation
+ * @param   avg_packet_latency
+ * @param   avg_receive_throughput
+ * @param   avg_transmit_throughput
+ * @param   flow_activation_epoch
+ * @param   flow_activation_microsec
+ * @param   flow_deactivation_epoch
+ * @param   flow_deactivation_microsec
+ * @param   flow_deactivation_time
+ * @param   flow_status
+ * @param   max_packet_delay_variation
+ * @param   num_activation_failures
+ * @param   num_bit_errors
+ * @param   num_bytes_received
+ * @param   num_bytes_transmitted
+ * @param   num_dropped_packets
+ * @param   num_l7_bytes_received
+ * @param   num_l7_bytes_transmitted
+ * @param   num_lost_packets
+ * @param   num_out_of_order_packets
+ * @param   num_packet_errors
+ * @param   num_packets_received_excl_retrans
+ * @param   num_packets_received_incl_retrans
+ * @param   num_packets_transmitted_incl_retrans
+ * @param   num_retries
+ * @param   num_timeouts
+ * @param   num_tunneled_l7_bytes_received
+ * @param   round_trip_time
+ * @param   time_to_first_byte
+ *
+ * @returns pointer to the newly manufactured ::MOBILE_GTP_PER_FLOW_METRICS.
+ *          If the structure is not used it must be released using
+ *          ::evel_free_mobile_gtp_flow_metrics.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+MOBILE_GTP_PER_FLOW_METRICS * evel_new_mobile_gtp_flow_metrics(
+                                      double avg_bit_error_rate,
+                                      double avg_packet_delay_variation,
+                                      int avg_packet_latency,
+                                      int avg_receive_throughput,
+                                      int avg_transmit_throughput,
+                                      int flow_activation_epoch,
+                                      int flow_activation_microsec,
+                                      int flow_deactivation_epoch,
+                                      int flow_deactivation_microsec,
+                                      time_t flow_deactivation_time,
+                                      const char * const flow_status,
+                                      int max_packet_delay_variation,
+                                      int num_activation_failures,
+                                      int num_bit_errors,
+                                      int num_bytes_received,
+                                      int num_bytes_transmitted,
+                                      int num_dropped_packets,
+                                      int num_l7_bytes_received,
+                                      int num_l7_bytes_transmitted,
+                                      int num_lost_packets,
+                                      int num_out_of_order_packets,
+                                      int num_packet_errors,
+                                      int num_packets_received_excl_retrans,
+                                      int num_packets_received_incl_retrans,
+                                      int num_packets_transmitted_incl_retrans,
+                                      int num_retries,
+                                      int num_timeouts,
+                                      int num_tunneled_l7_bytes_received,
+                                      int round_trip_time,
+                                      int time_to_first_byte);
+
+/**************************************************************************//**
+ * Free a Mobile GTP Per Flow Metrics.
+ *
+ * Free off the Mobile GTP Per Flow Metrics supplied.  Will free all the
+ * contained allocated memory.
+ *
+ * @note It does not free the Mobile GTP Per Flow Metrics itself, since that
+ * may be part of a larger structure.
+ *****************************************************************************/
+void evel_free_mobile_gtp_flow_metrics(MOBILE_GTP_PER_FLOW_METRICS * metrics);
+
+/**************************************************************************//**
+ * Set the Duration of Connection Failed Status property of the Mobile GTP Per
+ * Flow Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param duration    The Duration of Connection Failed Status to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_dur_con_fail_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int duration);
+
+/**************************************************************************//**
+ * Set the Duration of Tunnel Failed Status property of the Mobile GTP Per Flow
+ * Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param duration    The Duration of Tunnel Failed Status to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_dur_tun_fail_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int duration);
+
+/**************************************************************************//**
+ * Set the Activated By property of the Mobile GTP Per Flow metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param act_by      The Activated By to be set.  ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_act_by_set(MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                        const char * const act_by);
+
+/**************************************************************************//**
+ * Set the Activation Time property of the Mobile GTP Per Flow metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param act_time    The Activation Time to be set.  ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_act_time_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         time_t act_time);
+
+/**************************************************************************//**
+ * Set the Deactivated By property of the Mobile GTP Per Flow metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param deact_by    The Deactivated By to be set.  ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_deact_by_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         const char * const deact_by);
+
+/**************************************************************************//**
+ * Set the GTP Connection Status property of the Mobile GTP Per Flow metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param status      The GTP Connection Status to be set.  ASCIIZ string. The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_con_status_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         const char * const status);
+
+/**************************************************************************//**
+ * Set the GTP Tunnel Status property of the Mobile GTP Per Flow metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param status      The GTP Tunnel Status to be set.  ASCIIZ string. The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_tun_status_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         const char * const status);
+
+/**************************************************************************//**
+ * Set an IP Type-of-Service count property of the Mobile GTP Per Flow metrics.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param index       The index of the IP Type-of-Service.
+ * @param count       The count.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_iptos_set(MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                       int index,
+                                       int count);
+
+/**************************************************************************//**
+ * Set the Large Packet Round-Trip Time property of the Mobile GTP Per Flow
+ * Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param rtt         The Large Packet Round-Trip Time to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_large_pkt_rtt_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int rtt);
+
+/**************************************************************************//**
+ * Set the Large Packet Threshold property of the Mobile GTP Per Flow Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param threshold   The Large Packet Threshold to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_large_pkt_thresh_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         double threshold);
+
+/**************************************************************************//**
+ * Set the Max Receive Bit Rate property of the Mobile GTP Per Flow Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param rate        The Max Receive Bit Rate to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_max_rcv_bit_rate_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int rate);
+
+/**************************************************************************//**
+ * Set the Max Transmit Bit Rate property of the Mobile GTP Per Flow Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param rate        The Max Transmit Bit Rate to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_max_trx_bit_rate_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int rate);
+
+/**************************************************************************//**
+ * Set the Number of GTP Echo Failures property of the Mobile GTP Per Flow
+ * Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param num         The Number of GTP Echo Failures to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_num_echo_fail_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int num);
+
+/**************************************************************************//**
+ * Set the Number of GTP Tunnel Errors property of the Mobile GTP Per Flow
+ * Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param num         The Number of GTP Tunnel Errors to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_num_tun_fail_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int num);
+
+/**************************************************************************//**
+ * Set the Number of HTTP Errors property of the Mobile GTP Per Flow Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param num         The Number of HTTP Errors to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_num_http_errors_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int num);
+
+/**************************************************************************//**
+ * Add a TCP flag count to the metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics       Pointer to the Mobile GTP Per Flow Metrics.
+ * @param tcp_flag      The TCP flag count to be updated.
+ * @param count         The associated flag count.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_tcp_flag_count_add(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         const EVEL_TCP_FLAGS tcp_flag,
+                                         const int count);
+
+/**************************************************************************//**
+ * Add a QCI COS count to the metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics       Pointer to the Mobile GTP Per Flow Metrics.
+ * @param qci_cos       The QCI COS count to be updated.
+ * @param count         The associated QCI COS count.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_qci_cos_count_add(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         const EVEL_QCI_COS_TYPES qci_cos,
+                                         const int count);
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*                                                                           */
+/*   SIGNALING                                                               */
+/*                                                                           */
+/*****************************************************************************/
+/*****************************************************************************/
+
+/**************************************************************************//**
+ * Create a new Signaling event.
+ *
+ * @note    The mandatory fields on the Signaling must be supplied to
+ *          this factory function and are immutable once set.  Optional fields
+ *          have explicit setter functions, but again values may only be set
+ *          once so that the event has immutable properties.
+ * @param event_name    Unique Event Name
+ * @param event_id    A universal identifier of the event for analysis etc
+ * @param vendor_name   The vendor id to encode in the event vnf field.
+ * @param module        The module to encode in the event.
+ * @param vnfname       The Virtual network function to encode in the event.
+ * @returns pointer to the newly manufactured ::EVENT_SIGNALING.  If the event
+ *          is not used (i.e. posted) it must be released using
+ *          ::evel_free_signaling.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_SIGNALING * evel_new_signaling(const char* ev_name, const char *ev_id,
+                                    const char * const vendor_name,
+                                     const char * const correlator,
+                                    const char * const local_ip_address,
+                                    const char * const local_port,
+                                    const char * const remote_ip_address,
+                                    const char * const remote_port);
+
+/**************************************************************************//**
+ * Free a Signaling event.
+ *
+ * Free off the event supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the event itself, since that may be part of a larger
+ * structure.
+ *****************************************************************************/
+void evel_free_signaling(EVENT_SIGNALING * const event);
+
+/**************************************************************************//**
+ * Set the Event Type property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param type          The Event Type to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_type_set(EVENT_SIGNALING * const event,
+                             const char * const type);
+
+/**************************************************************************//**
+ * Add an additional value name/value pair to the SIP signaling.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param event     Pointer to the fault.
+ * @param name      ASCIIZ string with the attribute's name.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ * @param value     ASCIIZ string with the attribute's value.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ *****************************************************************************/
+void evel_signaling_addl_info_add(EVENT_SIGNALING * event, char * name, char * value);
+
+/**************************************************************************//**
+ * Set the Correlator property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param correlator    The correlator to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_correlator_set(EVENT_SIGNALING * const event,
+                                   const char * const correlator);
+
+/**************************************************************************//**
+ * Set the Local Ip Address property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param local_ip_address
+ *                      The Local Ip Address to be set. ASCIIZ string. The
+ *                      caller does not need to preserve the value once the
+ *                      function returns.
+ *****************************************************************************/
+void evel_signaling_local_ip_address_set(EVENT_SIGNALING * const event,
+                                         const char * const local_ip_address);
+
+/**************************************************************************//**
+ * Set the Local Port property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param local_port    The Local Port to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_local_port_set(EVENT_SIGNALING * const event,
+                                   const char * const local_port);
+
+/**************************************************************************//**
+ * Set the Remote Ip Address property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param remote_ip_address
+ *                      The Remote Ip Address to be set. ASCIIZ string. The
+ *                      caller does not need to preserve the value once the
+ *                      function returns.
+ *****************************************************************************/
+void evel_signaling_remote_ip_address_set(EVENT_SIGNALING * const event,
+                                         const char * const remote_ip_address);
+
+/**************************************************************************//**
+ * Set the Remote Port property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param remote_port   The Remote Port to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_remote_port_set(EVENT_SIGNALING * const event,
+                                    const char * const remote_port);
+/**************************************************************************//**
+ * Set the Vendor module property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param modulename    The module name to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_vnfmodule_name_set(EVENT_SIGNALING * const event,
+                                    const char * const module_name);
+/**************************************************************************//**
+ * Set the Vendor module property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param vnfname       The Virtual Network function to be set. ASCIIZ string.
+ *                      The caller does not need to preserve the value once
+ *                      the function returns.
+ *****************************************************************************/
+void evel_signaling_vnfname_set(EVENT_SIGNALING * const event,
+                                    const char * const vnfname);
+
+/**************************************************************************//**
+ * Set the Compressed SIP property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param compressed_sip
+ *                      The Compressed SIP to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_compressed_sip_set(EVENT_SIGNALING * const event,
+                                       const char * const compressed_sip);
+
+/**************************************************************************//**
+ * Set the Summary SIP property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param summary_sip   The Summary SIP to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_summary_sip_set(EVENT_SIGNALING * const event,
+                                    const char * const summary_sip);
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*                                                                           */
+/*   STATE CHANGE                                                            */
+/*                                                                           */
+/*****************************************************************************/
+/*****************************************************************************/
+
+/**************************************************************************//**
+ * Create a new State Change event.
+ *
+ * @note    The mandatory fields on the Syslog must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Syslog has immutable properties.
+ *
+ * @param event_name    Unique Event Name
+ * @param event_id    A universal identifier of the event for analysis etc
+ * @param new_state     The new state of the reporting entity.
+ * @param old_state     The old state of the reporting entity.
+ * @param interface     The card or port name of the reporting entity.
+ *
+ * @returns pointer to the newly manufactured ::EVENT_STATE_CHANGE.  If the
+ *          event is not used it must be released using
+ *          ::evel_free_state_change
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_STATE_CHANGE * evel_new_state_change(const char* ev_name, const char *ev_id,
+                                          const EVEL_ENTITY_STATE new_state,
+                                           const EVEL_ENTITY_STATE old_state,
+                                           const char * const interface);
+
+/**************************************************************************//**
+ * Free a State Change.
+ *
+ * Free off the State Change supplied.  Will free all the contained allocated
+ * memory.
+ *
+ * @note It does not free the State Change itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_state_change(EVENT_STATE_CHANGE * const state_change);
+
+/**************************************************************************//**
+ * Set the Event Type property of the State Change.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param state_change  Pointer to the ::EVENT_STATE_CHANGE.
+ * @param type          The Event Type to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_state_change_type_set(EVENT_STATE_CHANGE * const state_change,
+                                const char * const type);
+
+/**************************************************************************//**
+ * Add an additional field name/value pair to the State Change.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param state_change  Pointer to the ::EVENT_STATE_CHANGE.
+ * @param name          ASCIIZ string with the attribute's name.  The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ * @param value         ASCIIZ string with the attribute's value.  The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_state_change_addl_field_add(EVENT_STATE_CHANGE * const state_change,
+                                      const char * const name,
+                                      const char * const value);
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*                                                                           */
+/*   SYSLOG                                                                  */
+/*                                                                           */
+/*****************************************************************************/
+/*****************************************************************************/
+
+/**************************************************************************//**
+ * Create a new syslog event.
+ *
+ * @note    The mandatory fields on the Syslog must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Syslog has immutable properties.
+ *
+ * @param event_name    Unique Event Name
+ * @param event_id    A universal identifier of the event for analysis etc
+ * @param   event_source_type
+ * @param   syslog_msg
+ * @param   syslog_tag
+ * @param   version
+ *
+ * @returns pointer to the newly manufactured ::EVENT_SYSLOG.  If the event is
+ *          not used it must be released using ::evel_free_syslog
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_SYSLOG * evel_new_syslog(const char* ev_name, const char *ev_id,
+                               EVEL_SOURCE_TYPES event_source_type,
+                               const char * const syslog_msg,
+                               const char * const syslog_tag);
+
+/**************************************************************************//**
+ * Set the Event Type property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog      Pointer to the syslog.
+ * @param type        The Event Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_syslog_type_set(EVENT_SYSLOG * syslog,
+                          const char * const type);
+
+/**************************************************************************//**
+ * Free a Syslog.
+ *
+ * Free off the Syslog supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the Syslog itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_syslog(EVENT_SYSLOG * event);
+
+/**************************************************************************//**
+ * Add an additional field name/value pair to the Syslog.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param syslog    Pointer to the syslog.
+ * @param name      ASCIIZ string with the attribute's name.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ * @param value     ASCIIZ string with the attribute's value.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ *****************************************************************************/
+void evel_syslog_addl_field_add(EVENT_SYSLOG * syslog,
+                                char * name,
+                                char * value);
+
+/**************************************************************************//**
+ * Set the Event Source Host property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog      Pointer to the Syslog.
+ * @param host        The Event Source Host to be set.  ASCIIZ string. The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_syslog_event_source_host_set(EVENT_SYSLOG * syslog,
+                                       const char * const host);
+
+/**************************************************************************//**
+ * Set the Syslog Facility property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog      Pointer to the Syslog.
+ * @param facility    The Syslog Facility to be set.  ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_syslog_facility_set(EVENT_SYSLOG * syslog,
+                              EVEL_SYSLOG_FACILITIES facility);
+
+/**************************************************************************//**
+ * Set the Process property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog      Pointer to the Syslog.
+ * @param proc        The Process to be set.  ASCIIZ string. The caller does
+ *                    not need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_syslog_proc_set(EVENT_SYSLOG * syslog, const char * const proc);
+
+/**************************************************************************//**
+ * Set the Process ID property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog      Pointer to the Syslog.
+ * @param proc_id     The Process ID to be set.
+ *****************************************************************************/
+void evel_syslog_proc_id_set(EVENT_SYSLOG * syslog, int proc_id);
+
+/**************************************************************************//**
+ * Set the Version property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog      Pointer to the Syslog.
+ * @param version     The Version to be set.
+ *****************************************************************************/
+void evel_syslog_version_set(EVENT_SYSLOG * syslog, int version);
+
+/**************************************************************************//**
+ * Set the Structured Data property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog      Pointer to the Syslog.
+ * @param s_data      The Structured Data to be set.  ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_syslog_s_data_set(EVENT_SYSLOG * syslog, const char * const s_data);
+
+/**************************************************************************//**
+ * Set the Structured SDID property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog     Pointer to the Syslog.
+ * @param sdid     The Structured Data to be set. ASCIIZ string. name@number
+ *                 Caller does not need to preserve the value once the function
+ *                   returns.
+ *****************************************************************************/
+void evel_syslog_sdid_set(EVENT_SYSLOG * syslog, const char * const sdid);
+
+/**************************************************************************//**
+ * Set the Structured Severity property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog     Pointer to the Syslog.
+ * @param sdid     The Structured Data to be set. ASCIIZ string. 
+ *                 Caller does not need to preserve the value once the function
+ *                   returns.
+ *****************************************************************************/
+void evel_syslog_severity_set(EVENT_SYSLOG * syslog, const char * const severty);
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*                                                                           */
+/*   OTHER                                                                   */
+/*                                                                           */
+/*****************************************************************************/
+/*****************************************************************************/
+
+/**************************************************************************//**
+ * Create a new other event.
+ *
+ * @param event_name    Unique Event Name
+ * @param event_id    A universal identifier of the event for analysis etc
+ *
+ * @returns pointer to the newly manufactured ::EVENT_OTHER.  If the event is
+ *          not used it must be released using ::evel_free_other.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_OTHER * evel_new_other(const char* ev_name, const char *ev_id);
+
+/**************************************************************************//**
+ * Free an Other.
+ *
+ * Free off the Other supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the Other itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_other(EVENT_OTHER * event);
+
+/**************************************************************************//**
+ * Set the Event Type property of the Other.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param other       Pointer to the Other.
+ * @param type        The Event Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_other_type_set(EVENT_OTHER * other,
+                         const char * const type);
+
+/**************************************************************************//**
+ * Add a value name/value pair to the Other.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param other     Pointer to the Other.
+ * @param name      ASCIIZ string with the attribute's name.
+ * @param value     ASCIIZ string with the attribute's value.
+ *****************************************************************************/
+void evel_other_field_add(EVENT_OTHER * other,
+                          char * name,
+                          char * value);
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*                                                                           */
+/*   THROTTLING                                                              */
+/*                                                                           */
+/*****************************************************************************/
+/*****************************************************************************/
+
+/**************************************************************************//**
+ * Return the current measurement interval provided by the Event Listener.
+ *
+ * @returns The current measurement interval
+ * @retval  EVEL_MEASUREMENT_INTERVAL_UKNOWN (0) - interval has not been
+ *          specified
+ *****************************************************************************/
+int evel_get_measurement_interval();
+
+/*****************************************************************************/
+/* Supported Report version.                                                 */
+/*****************************************************************************/
+#define EVEL_VOICEQ_MAJOR_VERSION 1
+#define EVEL_VOICEQ_MINOR_VERSION 1
+
+/**************************************************************************//**
+ * End of Call Voice Quality Metrices
+ * JSON equivalent field: endOfCallVqmSummaries
+ *****************************************************************************/
+typedef struct end_of_call_vqm_summaries {
+       /***************************************************************************/
+       /* Mandatory fields                                                        */
+       /***************************************************************************/
+       char* adjacencyName;
+       char* endpointDescription;
+
+       /***************************************************************************/
+       /* Optional fields                                                         */
+       /***************************************************************************/
+       EVEL_OPTION_INT endpointJitter;
+       EVEL_OPTION_INT endpointRtpOctetsDiscarded;
+       EVEL_OPTION_INT endpointRtpOctetsReceived;
+       EVEL_OPTION_INT endpointRtpOctetsSent;
+       EVEL_OPTION_INT endpointRtpPacketsDiscarded;
+       EVEL_OPTION_INT endpointRtpPacketsReceived;
+       EVEL_OPTION_INT endpointRtpPacketsSent;
+       EVEL_OPTION_INT localJitter;
+       EVEL_OPTION_INT localRtpOctetsDiscarded;
+       EVEL_OPTION_INT localRtpOctetsReceived;
+       EVEL_OPTION_INT localRtpOctetsSent;
+       EVEL_OPTION_INT localRtpPacketsDiscarded;
+       EVEL_OPTION_INT localRtpPacketsReceived;
+       EVEL_OPTION_INT localRtpPacketsSent;
+       EVEL_OPTION_INT mosCqe;
+       EVEL_OPTION_INT packetsLost;
+       EVEL_OPTION_INT packetLossPercent;
+       EVEL_OPTION_INT rFactor;
+       EVEL_OPTION_INT roundTripDelay;
+
+} END_OF_CALL_VOICE_QUALITY_METRICS;
+
+/**************************************************************************//**
+* Voice QUality.
+* JSON equivalent field: voiceQualityFields
+*****************************************************************************/
+
+typedef struct event_voiceQuality {
+       /***************************************************************************/
+       /* Header and version                                                      */
+       /***************************************************************************/
+       EVENT_HEADER header;
+       int major_version;
+       int minor_version;
+
+       /***************************************************************************/
+       /* Mandatory fields                                                        */
+       /***************************************************************************/
+       
+       char *calleeSideCodec;
+       char *callerSideCodec;
+       char *correlator;
+       char *midCallRtcp;
+       VENDOR_VNFNAME_FIELD vendorVnfNameFields;
+       END_OF_CALL_VOICE_QUALITY_METRICS *endOfCallVqmSummaries;
+
+       /***************************************************************************/
+       /* Optional fields                                                         */
+       /***************************************************************************/
+       EVEL_OPTION_STRING phoneNumber;
+       DLIST additionalInformation;
+
+} EVENT_VOICE_QUALITY;
+/**************************************************************************//**
+ * Voice Quality Additional Info.
+ * JSON equivalent field: additionalInformation
+ *****************************************************************************/
+typedef struct voice_quality_additional_info {
+  char * name;
+  char * value;
+} VOICE_QUALITY_ADDL_INFO;
+
+/**************************************************************************//**
+ * Create a new voice quality event.
+ *
+ * @note    The mandatory fields on the Voice Quality must be supplied to this 
+ *          factory function and are immutable once set.  Optional fields have 
+ *          explicit setter functions, but again values may only be set once 
+ *          so that the Voice Quality has immutable properties.
+ * @param event_name    Unique Event Name
+ * @param event_id    A universal identifier of the event for analysis etc
+ * @param   calleeSideCodec                    Callee codec for the call.
+ * @param   callerSideCodec                    Caller codec for the call.
+ * @param   correlator                         Constant across all events on this call.
+ * @param   midCallRtcp                                Base64 encoding of the binary RTCP data
+ *                                                                     (excluding Eth/IP/UDP headers).
+ * @param   vendorVnfNameFields                Vendor, VNF and VfModule names.
+ * @returns pointer to the newly manufactured ::EVENT_VOICE_QUALITY.  If the 
+ *          event is not used (i.e. posted) it must be released using
+                       ::evel_free_voice_quality.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_VOICE_QUALITY * evel_new_voice_quality(const char* ev_name, const char *ev_id,
+       const char * const calleeSideCodec,
+       const char * const callerSideCodec, const char * const correlator,
+       const char * const midCallRtcp, const char * const vendorVnfNameFields);
+
+/**************************************************************************//**
+ * Set the Callee side codec for Call for domain Voice Quality
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param voiceQuality                         Pointer to the Voice Quality Event.
+ * @param calleeCodecForCall           The Callee Side Codec to be set.  ASCIIZ 
+ *                                                                     string. The caller does not need to 
+ *                                                                     preserve the value once the function
+ *                                                                     returns.
+ *****************************************************************************/
+void evel_voice_quality_callee_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
+                                                                       const char * const calleeCodecForCall);
+
+/**************************************************************************//**
+ * Set the Caller side codec for Call for domain Voice Quality
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param voiceQuality                         Pointer to the Voice Quality Event.
+ * @param callerCodecForCall           The Caller Side Codec to be set.  ASCIIZ 
+ *                                                                     string. The caller does not need to 
+ *                                                                     preserve the value once the function
+ *                                                                     returns.
+ *****************************************************************************/
+void evel_voice_quality_caller_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
+                                                                       const char * const callerCodecForCall);
+
+/**************************************************************************//**
+ * Set the correlator for domain Voice Quality
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param voiceQuality                         Pointer to the Voice Quality Event.
+ * @param correlator                           The correlator value to be set.  ASCIIZ 
+ *                                                                     string. The caller does not need to 
+ *                                                                     preserve the value once the function
+ *                                                                     returns.
+ *****************************************************************************/
+void evel_voice_quality_correlator_set(EVENT_VOICE_QUALITY * voiceQuality,
+                                                                       const char * const vCorrelator);
+
+/**************************************************************************//**
+ * Set the RTCP Call Data for domain Voice Quality
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param voiceQuality                         Pointer to the Voice Quality Event.
+ * @param rtcpCallData                 The RTCP Call Data to be set.  ASCIIZ 
+ *                                                                     string. The caller does not need to 
+ *                                                                     preserve the value once the function
+ *                                                                     returns.
+ *****************************************************************************/
+void evel_voice_quality_rtcp_data_set(EVENT_VOICE_QUALITY * voiceQuality,
+                                                                       const char * const rtcpCallData);
+
+/**************************************************************************//**
+ * Set the Vendor VNF Name fields for domain Voice Quality
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param voiceQuality                         Pointer to the Voice Quality Event.
+ * @param nameFields                   The Vendor, VNF and VfModule names to be set.   
+ *                                                                     ASCIIZ string. The caller does not need to 
+ *                                                                     preserve the value once the function
+ *                                                                     returns.
+ *****************************************************************************/
+void evel_voice_quality_name_fields_set(EVENT_VOICE_QUALITY * voiceQuality,
+                                                                       const char * const nameFields);
+
+/**************************************************************************//**
+ * Add an End of Call Voice Quality Metrices
+
+ * The adjacencyName and endpointDescription is null delimited ASCII string.  
+ * The library takes a copy so the caller does not have to preserve values
+ * after the function returns.
+ *
+ * @param voiceQuality     Pointer to the measurement.
+ * @param adjacencyName                                                Adjacency name
+ * @param endpointDescription                          Enumeration: ‘Caller’, ‘Callee’.
+ * @param endpointJitter                                       Endpoint jitter
+ * @param endpointRtpOctetsDiscarded        Endpoint RTP octets discarded.
+ * @param endpointRtpOctetsReceived                    Endpoint RTP octets received.
+ * @param endpointRtpOctetsSent                                Endpoint RTP octets sent
+ * @param endpointRtpPacketsDiscarded          Endpoint RTP packets discarded.
+ * @param endpointRtpPacketsReceived           Endpoint RTP packets received.
+ * @param endpointRtpPacketsSent                       Endpoint RTP packets sent.
+ * @param localJitter                                          Local jitter.
+ * @param localRtpOctetsDiscarded                      Local RTP octets discarded.
+ * @param localRtpOctetsReceived                       Local RTP octets received.
+ * @param localRtpOctetsSent                           Local RTP octets sent.
+ * @param localRtpPacketsDiscarded                     Local RTP packets discarded.
+ * @param localRtpPacketsReceived                      Local RTP packets received.
+ * @param localRtpPacketsSent                          Local RTP packets sent.
+ * @param mosCqe                                                       Decimal range from 1 to 5
+ *                                                                                     (1 decimal place)
+ * @param packetsLost                                          No      Packets lost
+ * @param packetLossPercent                                    Calculated percentage packet loss 
+ * @param rFactor                                                      rFactor from 0 to 100
+ * @param roundTripDelay                                       Round trip delay in milliseconds
+ *****************************************************************************/
+void evel_voice_quality_end_metrics_add(EVENT_VOICE_QUALITY * voiceQuality,
+       const char * adjacencyName, EVEL_SERVICE_ENDPOINT_DESC endpointDescription,
+       int endpointJitter,
+       int endpointRtpOctetsDiscarded,
+       int endpointRtpOctetsReceived,
+       int endpointRtpOctetsSent,
+       int endpointRtpPacketsDiscarded,
+       int endpointRtpPacketsReceived,
+       int endpointRtpPacketsSent,
+       int localJitter,
+       int localRtpOctetsDiscarded,
+       int localRtpOctetsReceived,
+       int localRtpOctetsSent,
+       int localRtpPacketsDiscarded,
+       int localRtpPacketsReceived,
+       int localRtpPacketsSent,
+       int mosCqe,
+       int packetsLost,
+       int packetLossPercent,
+       int rFactor,
+       int roundTripDelay);
+
+/**************************************************************************//**
+ * Free a Voice Quality.
+ *
+ * Free off the Voce Quality supplied.  Will free all the contained allocated
+ * memory.
+ *
+ * @note It does not free the Voice Quality itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_voice_quality(EVENT_VOICE_QUALITY * voiceQuality);
+
+/**************************************************************************//**
+ * Add an additional value name/value pair to the Voice Quality.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param fault     Pointer to the fault.
+ * @param name      ASCIIZ string with the attribute's name.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ * @param value     ASCIIZ string with the attribute's value.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ *****************************************************************************/
+void evel_voice_quality_addl_info_add(EVENT_VOICE_QUALITY * voiceQuality, char * name, char * value);
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*                                                                           */
+/*   THRESHOLD CROSSING ALERT                                                */
+/*                                                                           */
+/*****************************************************************************/
+/*****************************************************************************/
+
+typedef enum evel_event_action {
+         EVEL_EVENT_ACTION_CLEAR,
+         EVEL_EVENT_ACTION_CONTINUE,
+         EVEL_EVENT_ACTION_SET,
+         EVEL_MAX_EVENT_ACTION
+}EVEL_EVENT_ACTION;
+       
+typedef enum evel_alert_type {
+         EVEL_CARD_ANOMALY, 
+        EVEL_ELEMENT_ANOMALY, 
+        EVEL_INTERFACE_ANOMALY, 
+        EVEL_SERVICE_ANOMALY,
+         EVEL_MAX_ANOMALY
+}EVEL_ALERT_TYPE;
+
+
+typedef struct perf_counter {
+       char * criticality;
+       char * name;
+       char * thresholdCrossed;
+       char * value;
+}PERF_COUNTER;
+
+
+/*****************************************************************************/
+/* Supported Threshold Crossing version.                                     */
+/*****************************************************************************/
+#define EVEL_THRESHOLD_CROSS_MAJOR_VERSION 1
+#define EVEL_THRESHOLD_CROSS_MINOR_VERSION 1
+
+/**************************************************************************//**
+ * Threshold Crossing.
+ * JSON equivalent field: Threshold Cross Fields
+ *****************************************************************************/
+typedef struct event_threshold_cross {
+  /***************************************************************************/
+  /* Header and version                                                      */
+  /***************************************************************************/
+  EVENT_HEADER header;
+  int major_version;
+  int minor_version;
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  PERF_COUNTER additionalParameters;
+  EVEL_EVENT_ACTION  alertAction;
+  char *             alertDescription; 
+  EVEL_ALERT_TYPE    alertType;
+  unsigned long long collectionTimestamp; 
+  EVEL_SEVERITIES    eventSeverity;
+  unsigned long long eventStartTimestamp;
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  DLIST additional_info;
+  EVEL_OPTION_STRING    alertValue;
+  DLIST     alertidList;
+  EVEL_OPTION_STRING    dataCollector;
+  EVEL_OPTION_STRING    elementType;
+  EVEL_OPTION_STRING    interfaceName;
+  EVEL_OPTION_STRING    networkService;
+  EVEL_OPTION_STRING    possibleRootCause;
+
+} EVENT_THRESHOLD_CROSS;
+
+
+/**************************************************************************//**
+ * Create a new Threshold Crossing Alert event.
+ *
+ * @note    The mandatory fields on the TCA must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          TCA has immutable properties.
+ *
+ * @param event_name    Unique Event Name
+ * @param event_id    A universal identifier of the event for analysis etc
+ * @param char* tcriticality   Performance Counter Criticality MAJ MIN,
+ * @param char* tname          Performance Counter Threshold name
+ * @param char* tthresholdCrossed  Counter Threshold crossed value
+ * @param char* tvalue             Counter actual value
+ * @param EVEL_EVENT_ACTION talertAction   Alert set continue or clear
+ * @param char*  talertDescription
+ * @param EVEL_ALERT_TYPE     talertType    Kind of anamoly
+ * @param unsigned long long  tcollectionTimestamp time at which alert was collected
+ * @param EVEL_SEVERITIES     teventSeverity  Severity of Alert
+ * @param unsigned long long  teventStartTimestamp Time when this alert started
+ *
+ * @returns pointer to the newly manufactured ::EVENT_THRESHOLD_CROSS.  If the
+ *          event is not used it must be released using
+ *          ::evel_free_threshold_cross
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_THRESHOLD_CROSS * evel_new_threshold_cross(
+                               const char* ev_name, const char *ev_id,
+                               char * tcriticality,
+                              char * tname,
+                              char * tthresholdCrossed,
+                              char * tvalue,
+                               EVEL_EVENT_ACTION  talertAction,
+                               char *             talertDescription, 
+                               EVEL_ALERT_TYPE    talertType,
+                               unsigned long long tcollectionTimestamp, 
+                               EVEL_SEVERITIES    teventSeverity,
+                               unsigned long long teventStartTimestamp);
+
+/**************************************************************************//**
+ * Free a Threshold cross event.
+ *
+ * Free off the Threshold crossing event supplied.  Will free all the contained allocated
+ * memory.
+ *
+ * @note It does not free the Threshold Cross itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_threshold_cross(EVENT_THRESHOLD_CROSS * const tcp);
+
+/**************************************************************************//**
+ * Set the Event Type property of the Threshold Cross.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param tcp  Pointer to the ::EVENT_THRESHOLD_CROSS.
+ * @param type          The Event Type to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_threshold_cross_type_set(EVENT_THRESHOLD_CROSS * const tcp, char * type);
+
+/**************************************************************************//**
+ * Add an optional additional alertid value to Alert.
+ *
+ * @param alertid  Adds Alert ID
+ *****************************************************************************/
+void evel_threshold_cross_alertid_add(EVENT_THRESHOLD_CROSS * const event,char *  alertid);
+
+  /**************************************************************************//**
+   * Set the TCA probable Root cause.
+   *
+   * @param sheader     Possible root cause to Threshold
+   *****************************************************************************/
+  void evel_threshold_cross_possible_rootcause_set(EVENT_THRESHOLD_CROSS * const event, char *  sheader);
+  /**************************************************************************//**
+   * Set the TCA networking cause.
+   *
+   * @param sheader     Possible networking service value to Threshold
+   *****************************************************************************/
+  void evel_threshold_cross_networkservice_set(EVENT_THRESHOLD_CROSS * const event, char *  sheader);
+  /**************************************************************************//**
+   * Set the TCA Interface name.
+   *
+   * @param sheader     Interface name to threshold
+   *****************************************************************************/
+  void evel_threshold_cross_interfacename_set(EVENT_THRESHOLD_CROSS * const event,char *  sheader);
+  /**************************************************************************//**
+   * Set the TCA Data element type.
+   *
+   * @param sheader     element type of Threshold
+   *****************************************************************************/
+  void evel_threshold_cross_data_elementtype_set(EVENT_THRESHOLD_CROSS * const event,char *  sheader);
+  /**************************************************************************//**
+   * Set the TCA Data collector value.
+   *
+   * @param sheader     Data collector value
+   *****************************************************************************/
+  void evel_threshold_cross_data_collector_set(EVENT_THRESHOLD_CROSS * const event,char *  sheader);
+  /**************************************************************************//**
+   * Set the TCA alert value.
+   *
+   * @param sheader     Possible alert value
+   *****************************************************************************/
+  void evel_threshold_cross_alertvalue_set(EVENT_THRESHOLD_CROSS * const event,char *  sheader);
+
+/**************************************************************************//**
+ * Add an additional field name/value pair to the THRESHOLD CROSS event.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param state_change  Pointer to the ::EVENT_THRESHOLD_CROSS.
+ * @param name          ASCIIZ string with the attribute's name.  The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ * @param value         ASCIIZ string with the attribute's value.  The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_threshold_cross_addl_info_add(EVENT_THRESHOLD_CROSS * const tcp,
+                                      const char * const name,
+                                      const char * const value);
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*                                                                           */
+/*   LOGGING                                                                 */
+/*                                                                           */
+/*****************************************************************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Debug macros.                                                             */
+/*****************************************************************************/
+#define EVEL_DEBUG(FMT, ...)   log_debug(EVEL_LOG_DEBUG, (FMT), ##__VA_ARGS__)
+#define EVEL_INFO(FMT, ...)    log_debug(EVEL_LOG_INFO, (FMT), ##__VA_ARGS__)
+#define EVEL_SPAMMY(FMT, ...)  log_debug(EVEL_LOG_SPAMMY, (FMT), ##__VA_ARGS__)
+#define EVEL_ERROR(FMT, ...)   log_debug(EVEL_LOG_ERROR, "ERROR: " FMT, \
+                                         ##__VA_ARGS__)
+#define EVEL_ENTER()                                                          \
+        {                                                                     \
+          log_debug(EVEL_LOG_DEBUG, "Enter %s {", __FUNCTION__);              \
+          debug_indent += 2;                                                  \
+        }
+#define EVEL_EXIT()                                                           \
+        {                                                                     \
+          debug_indent -= 2;                                                  \
+          log_debug(EVEL_LOG_DEBUG, "Exit %s }", __FUNCTION__);               \
+        }
+
+#define INDENT_SEPARATORS                                                     \
+        "| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | "
+
+extern EVEL_LOG_LEVELS debug_level;
+extern int debug_indent;
+extern FILE * fout;
+
+#define EVEL_DEBUG_ON() ((debug_level) >= EVEL_LOG_DEBUG)
+
+/**************************************************************************//**
+ * Initialize logging
+ *
+ * @param[in] level  The debugging level - one of ::EVEL_LOG_LEVELS.
+ * @param[in] ident  The identifier for our logs.
+ *****************************************************************************/
+void log_initialize(EVEL_LOG_LEVELS level, const char * ident);
+
+/**************************************************************************//**
+ * Log debug information
+ *
+ * Logs debugging information in a platform independent manner.
+ *
+ * @param[in] level   The debugging level - one of ::EVEL_LOG_LEVELS.
+ * @param[in] format  Log formatting string in printf format.
+ * @param[in] ...     Variable argument list.
+ *****************************************************************************/
+void log_debug(EVEL_LOG_LEVELS level, char * format, ...);
+
+/***************************************************************************//*
+ * Store the formatted string into the static error string and log the error.
+ *
+ * @param format  Error string in standard printf format.
+ * @param ...     Variable parameters to be substituted into the format string.
+ *****************************************************************************/
+void log_error_state(char * format, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event.c
new file mode 100644 (file)
index 0000000..ced29b2
--- /dev/null
@@ -0,0 +1,755 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to Event Headers - since
+ * Heartbeats only contain the Event Header, the Heartbeat factory function is
+ * here too.
+ *****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include "evel.h"
+#include "evel_internal.h"
+#include "evel_throttle.h"
+#include "metadata.h"
+
+/**************************************************************************//**
+ * Unique sequence number for events from this VNF.
+ *****************************************************************************/
+static int event_sequence = 1;
+
+/**************************************************************************//**
+ * Set the next event_sequence to use.
+ *
+ * @param sequence      The next sequence number to use.
+ *****************************************************************************/
+void evel_set_next_event_sequence(const int sequence)
+{
+  EVEL_ENTER();
+
+  EVEL_INFO("Setting event sequence to %d, was %d ", sequence, event_sequence);
+  event_sequence = sequence;
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Create a new heartbeat event of given name and type.
+ *
+ * @note that the heartbeat is just a "naked" commonEventHeader!
+ *
+ * @param event_name    Unique Event Name: in format
+ * {DomainAbbreviation}_{AsdcModel or ApplicationPlatform}_{DescriptionOfInfoBeingConveyed}
+ * @param event_id     Uniquely identify event for correlation and analysis
+ *
+ * @returns pointer to the newly manufactured ::EVENT_HEADER.  If the event is
+ *          not used it must be released using ::evel_free_event
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_HEADER * evel_new_heartbeat_nameid(const char* ev_name, const char *ev_id)
+{
+  EVENT_HEADER * heartbeat = NULL;
+  EVEL_ENTER();
+
+  assert(ev_name != NULL);
+  assert(ev_id != NULL);
+
+  /***************************************************************************/
+  /* Allocate the header.                                                    */
+  /***************************************************************************/
+  heartbeat = malloc(sizeof(EVENT_HEADER));
+  if (heartbeat == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(heartbeat, 0, sizeof(EVENT_HEADER));
+
+  /***************************************************************************/
+  /* Initialize the header.  Get a new event sequence number.  Note that if  */
+  /* any memory allocation fails in here we will fail gracefully because     */
+  /* everything downstream can cope with NULLs.                              */
+  /***************************************************************************/
+  evel_init_header_nameid(heartbeat,ev_name,ev_id);
+
+exit_label:
+  EVEL_EXIT();
+  return heartbeat;
+}
+
+/**************************************************************************//**
+ * Create a new heartbeat event.
+ *
+ * @note that the heartbeat is just a "naked" commonEventHeader!
+ *
+ * @returns pointer to the newly manufactured ::EVENT_HEADER.  If the event is
+ *          not used it must be released using ::evel_free_event
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_HEADER * evel_new_heartbeat()
+{
+  EVENT_HEADER * heartbeat = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Allocate the header.                                                    */
+  /***************************************************************************/
+  heartbeat = malloc(sizeof(EVENT_HEADER));
+  if (heartbeat == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(heartbeat, 0, sizeof(EVENT_HEADER));
+
+  /***************************************************************************/
+  /* Initialize the header.  Get a new event sequence number.  Note that if  */
+  /* any memory allocation fails in here we will fail gracefully because     */
+  /* everything downstream can cope with NULLs.                              */
+  /***************************************************************************/
+  evel_init_header(heartbeat,"Heartbeat");
+  evel_force_option_string(&heartbeat->event_type, "Autonomous heartbeat");
+
+exit_label:
+  EVEL_EXIT();
+  return heartbeat;
+}
+
+/**************************************************************************//**
+ * Initialize a newly created event header.
+ *
+ * @param header  Pointer to the header being initialized.
+ *****************************************************************************/
+void evel_init_header(EVENT_HEADER * const header,const char *const eventname)
+{
+  char scratchpad[EVEL_MAX_STRING_LEN + 1] = {0};
+  struct timeval tv;
+
+  EVEL_ENTER();
+
+  assert(header != NULL);
+
+  gettimeofday(&tv, NULL);
+
+  /***************************************************************************/
+  /* Initialize the header.  Get a new event sequence number.  Note that if  */
+  /* any memory allocation fails in here we will fail gracefully because     */
+  /* everything downstream can cope with NULLs.                              */
+  /***************************************************************************/
+  header->event_domain = EVEL_DOMAIN_HEARTBEAT;
+  snprintf(scratchpad, EVEL_MAX_STRING_LEN, "%d", event_sequence);
+  header->event_id = strdup(scratchpad);
+  if( eventname == NULL )
+     header->event_name = strdup(functional_role);
+  else
+     header->event_name = strdup(eventname);
+  header->last_epoch_microsec = tv.tv_usec + 1000000 * tv.tv_sec;
+  header->priority = EVEL_PRIORITY_NORMAL;
+  header->reporting_entity_name = strdup(openstack_vm_name());
+  header->source_name = strdup(openstack_vm_name());
+  header->sequence = event_sequence;
+  header->start_epoch_microsec = header->last_epoch_microsec;
+  header->major_version = EVEL_HEADER_MAJOR_VERSION;
+  header->minor_version = EVEL_HEADER_MINOR_VERSION;
+  event_sequence++;
+
+  /***************************************************************************/
+  /* Optional parameters.                                                    */
+  /***************************************************************************/
+  evel_init_option_string(&header->event_type);
+  evel_init_option_string(&header->nfcnaming_code);
+  evel_init_option_string(&header->nfnaming_code);
+  evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid());
+  evel_force_option_string(&header->source_id, openstack_vm_uuid());
+  evel_init_option_intheader(&header->internal_field);
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Initialize a newly created event header.
+ *
+ * @param header  Pointer to the header being initialized.
+ *****************************************************************************/
+void evel_init_header_nameid(EVENT_HEADER * const header,const char *const eventname, const char *eventid)
+{
+  struct timeval tv;
+
+  EVEL_ENTER();
+
+  assert(header != NULL);
+  assert(eventname != NULL);
+  assert(eventid != NULL);
+
+  gettimeofday(&tv, NULL);
+
+  /***************************************************************************/
+  /* Initialize the header.  Get a new event sequence number.  Note that if  */
+  /* any memory allocation fails in here we will fail gracefully because     */
+  /* everything downstream can cope with NULLs.                              */
+  /***************************************************************************/
+  header->event_domain = EVEL_DOMAIN_HEARTBEAT;
+  header->event_id = strdup(eventid);
+  header->event_name = strdup(eventname);
+  header->last_epoch_microsec = tv.tv_usec + 1000000 * tv.tv_sec;
+  header->priority = EVEL_PRIORITY_NORMAL;
+  header->reporting_entity_name = strdup(openstack_vm_name());
+  header->source_name = strdup(openstack_vm_name());
+  header->sequence = event_sequence;
+  header->start_epoch_microsec = header->last_epoch_microsec;
+  header->major_version = EVEL_HEADER_MAJOR_VERSION;
+  header->minor_version = EVEL_HEADER_MINOR_VERSION;
+  event_sequence++;
+
+  /***************************************************************************/
+  /* Optional parameters.                                                    */
+  /***************************************************************************/
+  evel_init_option_string(&header->event_type);
+  evel_init_option_string(&header->nfcnaming_code);
+  evel_init_option_string(&header->nfnaming_code);
+  evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid());
+  evel_force_option_string(&header->source_id, openstack_vm_uuid());
+  evel_init_option_intheader(&header->internal_field);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Event Type property of the event header.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param type          The Event Type to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_header_type_set(EVENT_HEADER * const header,
+                          const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(header != NULL);
+  assert(type != NULL);
+
+  evel_set_option_string(&header->event_type, type, "Event Type");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Start Epoch property of the event header.
+ *
+ * @note The Start Epoch defaults to the time of event creation.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param start_epoch_microsec
+ *                      The start epoch to set, in microseconds.
+ *****************************************************************************/
+void evel_start_epoch_set(EVENT_HEADER * const header,
+                          const unsigned long long start_epoch_microsec)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and assign the new value.                           */
+  /***************************************************************************/
+  assert(header != NULL);
+  header->start_epoch_microsec = start_epoch_microsec;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Last Epoch property of the event header.
+ *
+ * @note The Last Epoch defaults to the time of event creation.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param last_epoch_microsec
+ *                      The last epoch to set, in microseconds.
+ *****************************************************************************/
+void evel_last_epoch_set(EVENT_HEADER * const header,
+                         const unsigned long long last_epoch_microsec)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and assign the new value.                           */
+  /***************************************************************************/
+  assert(header != NULL);
+  header->last_epoch_microsec = last_epoch_microsec;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the NFC Naming code property of the event header.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param nfcnamingcode String
+ *****************************************************************************/
+void evel_nfcnamingcode_set(EVENT_HEADER * const header,
+                         const char * const nfcnam)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and assign the new value.                           */
+  /***************************************************************************/
+  assert(header != NULL);
+  assert(nfcnam != NULL);
+  evel_set_option_string(&header->nfcnaming_code, nfcnam, "NFC Naming Code");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the NF Naming code property of the event header.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param nfnamingcode String
+ *****************************************************************************/
+void evel_nfnamingcode_set(EVENT_HEADER * const header,
+                         const char * const nfnam)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and assign the new value.                           */
+  /***************************************************************************/
+  assert(header != NULL);
+  assert(nfnam != NULL);
+  evel_set_option_string(&header->nfnaming_code, nfnam, "NF Naming Code");
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Set the Reporting Entity Name property of the event header.
+ *
+ * @note The Reporting Entity Name defaults to the OpenStack VM Name.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param entity_name   The entity name to set.
+ *****************************************************************************/
+void evel_reporting_entity_name_set(EVENT_HEADER * const header,
+                                    const char * const entity_name)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and assign the new value.                           */
+  /***************************************************************************/
+  assert(header != NULL);
+  assert(entity_name != NULL);
+  assert(header->reporting_entity_name != NULL);
+
+  /***************************************************************************/
+  /* Free the previously allocated memory and replace it with a copy of the  */
+  /* provided one.                                                           */
+  /***************************************************************************/
+  free(header->reporting_entity_name);
+  header->reporting_entity_name = strdup(entity_name);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Reporting Entity Id property of the event header.
+ *
+ * @note The Reporting Entity Id defaults to the OpenStack VM UUID.
+ *
+ * @param header        Pointer to the ::EVENT_HEADER.
+ * @param entity_id     The entity id to set.
+ *****************************************************************************/
+void evel_reporting_entity_id_set(EVENT_HEADER * const header,
+                                  const char * const entity_id)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and assign the new value.                           */
+  /***************************************************************************/
+  assert(header != NULL);
+  assert(entity_id != NULL);
+
+  /***************************************************************************/
+  /* Free the previously allocated memory and replace it with a copy of the  */
+  /* provided one.  Note that evel_force_option_string strdups entity_id.    */
+  /***************************************************************************/
+  evel_free_option_string(&header->reporting_entity_id);
+  evel_force_option_string(&header->reporting_entity_id, entity_id);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the event as a JSON event object according to AT&T's schema.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_header(EVEL_JSON_BUFFER * jbuf,
+                             EVENT_HEADER * event)
+{
+  char * domain;
+  char * priority;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(jbuf->json != NULL);
+  assert(jbuf->max_size > 0);
+  assert(event != NULL);
+
+  domain = evel_event_domain(event->event_domain);
+  priority = evel_event_priority(event->priority);
+  evel_json_open_named_object(jbuf, "commonEventHeader");
+
+  /***************************************************************************/
+  /* Mandatory fields.                                                       */
+  /***************************************************************************/
+  evel_enc_kv_string(jbuf, "domain", domain);
+  evel_enc_kv_string(jbuf, "eventId", event->event_id);
+  evel_enc_kv_string(jbuf, "eventName", event->event_name);
+  evel_enc_kv_ull(jbuf, "lastEpochMicrosec", event->last_epoch_microsec);
+  evel_enc_kv_string(jbuf, "priority", priority);
+  evel_enc_kv_string(
+    jbuf, "reportingEntityName", event->reporting_entity_name);
+  evel_enc_kv_int(jbuf, "sequence", event->sequence);
+  evel_enc_kv_string(jbuf, "sourceName", event->source_name);
+  evel_enc_kv_ull(jbuf, "startEpochMicrosec", event->start_epoch_microsec);
+  evel_enc_version(
+    jbuf, "version", event->major_version, event->minor_version);
+
+  /***************************************************************************/
+  /* Optional fields.                                                        */
+  /***************************************************************************/
+  evel_enc_kv_opt_string(jbuf, "eventType", &event->event_type);
+  evel_enc_kv_opt_string(
+    jbuf, "reportingEntityId", &event->reporting_entity_id);
+  evel_enc_kv_opt_string(jbuf, "sourceId", &event->source_id);
+  evel_enc_kv_opt_string(jbuf, "nfcNamingCode", &event->nfcnaming_code);
+  evel_enc_kv_opt_string(jbuf, "nfNamingCode", &event->nfnaming_code);
+
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free an event header.
+ *
+ * Free off the event header supplied.  Will free all the contained allocated
+ * memory.
+ *
+ * @note It does not free the header itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_header(EVENT_HEADER * const event)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+  /* events as we do on the public API.                                      */
+  /***************************************************************************/
+  assert(event != NULL);
+
+  /***************************************************************************/
+  /* Free all internal strings.                                              */
+  /***************************************************************************/
+  free(event->event_id);
+  evel_free_option_string(&event->event_type);
+  free(event->event_name);
+  evel_free_option_string(&event->reporting_entity_id);
+  free(event->reporting_entity_name);
+  evel_free_option_string(&event->source_id);
+  evel_free_option_string(&event->nfcnaming_code);
+  evel_free_option_string(&event->nfnaming_code);
+  evel_free_option_intheader(&event->internal_field);
+  free(event->source_name);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the event as a JSON event object according to AT&T's schema.
+ *
+ * @param json      Pointer to where to store the JSON encoded data.
+ * @param max_size  Size of storage available in json_body.
+ * @param event     Pointer to the ::EVENT_HEADER to encode.
+ * @returns Number of bytes actually written.
+ *****************************************************************************/
+int evel_json_encode_event(char * json,
+                           int max_size,
+                           EVENT_HEADER * event)
+{
+  EVEL_JSON_BUFFER json_buffer;
+  EVEL_JSON_BUFFER * jbuf = &json_buffer;
+  EVEL_THROTTLE_SPEC * throttle_spec;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Get the latest throttle specification for the domain.                   */
+  /***************************************************************************/
+  throttle_spec = evel_get_throttle_spec(event->event_domain);
+
+  /***************************************************************************/
+  /* Initialize the JSON_BUFFER and open the top-level objects.              */
+  /***************************************************************************/
+  evel_json_buffer_init(jbuf, json, max_size, throttle_spec);
+  evel_json_open_object(jbuf);
+  evel_json_open_named_object(jbuf, "event");
+
+  switch (event->event_domain)
+  {
+    case EVEL_DOMAIN_HEARTBEAT:
+      evel_json_encode_header(jbuf, event);
+      break;
+
+    case EVEL_DOMAIN_FAULT:
+      evel_json_encode_fault(jbuf, (EVENT_FAULT *)event);
+      break;
+
+    case EVEL_DOMAIN_MEASUREMENT:
+      evel_json_encode_measurement(jbuf, (EVENT_MEASUREMENT *)event);
+      break;
+
+    case EVEL_DOMAIN_MOBILE_FLOW:
+      evel_json_encode_mobile_flow(jbuf, (EVENT_MOBILE_FLOW *)event);
+      break;
+
+    case EVEL_DOMAIN_REPORT:
+      evel_json_encode_report(jbuf, (EVENT_REPORT *)event);
+      break;
+
+    case EVEL_DOMAIN_HEARTBEAT_FIELD:
+      evel_json_encode_hrtbt_field(jbuf, (EVENT_HEARTBEAT_FIELD *)event);
+      break;
+
+    case EVEL_DOMAIN_SIPSIGNALING:
+      evel_json_encode_signaling(jbuf, (EVENT_SIGNALING *)event);
+      break;
+
+    case EVEL_DOMAIN_STATE_CHANGE:
+      evel_json_encode_state_change(jbuf, (EVENT_STATE_CHANGE *)event);
+      break;
+
+    case EVEL_DOMAIN_SYSLOG:
+      evel_json_encode_syslog(jbuf, (EVENT_SYSLOG *)event);
+      break;
+
+    case EVEL_DOMAIN_OTHER:
+      evel_json_encode_other(jbuf, (EVENT_OTHER *)event);
+      break;
+
+    case EVEL_DOMAIN_VOICE_QUALITY:
+      evel_json_encode_voice_quality(jbuf, (EVENT_VOICE_QUALITY *)event);
+      break;
+
+    case EVEL_DOMAIN_THRESHOLD_CROSS:
+      evel_json_encode_threshold_cross(jbuf, (EVENT_THRESHOLD_CROSS *)event);
+      break;
+
+    case EVEL_DOMAIN_INTERNAL:
+    default:
+      EVEL_ERROR("Unexpected domain %d", event->event_domain);
+      assert(0);
+  }
+
+  evel_json_close_object(jbuf);
+  evel_json_close_object(jbuf);
+
+  /***************************************************************************/
+  /* Sanity check.                                                           */
+  /***************************************************************************/
+  assert(jbuf->depth == 0);
+
+  EVEL_EXIT();
+
+  return jbuf->offset;
+}
+
+
+/**************************************************************************//**
+ * Initialize an event instance id.
+ *
+ * @param vfield        Pointer to the event vnfname field being initialized.
+ * @param vendor_id     The vendor id to encode in the event instance id.
+ * @param event_id      The event id to encode in the event instance id.
+ *****************************************************************************/
+void evel_init_vendor_field(VENDOR_VNFNAME_FIELD * const vfield,
+                                 const char * const vendor_name)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(vfield != NULL);
+  assert(vendor_name != NULL);
+
+  /***************************************************************************/
+  /* Store the mandatory parts.                                              */
+  /***************************************************************************/
+  vfield->vendorname = strdup(vendor_name);
+  evel_init_option_string(&vfield->vfmodule);
+  evel_init_option_string(&vfield->vnfname);
+
+  /***************************************************************************/
+  /* Initialize the optional parts.                                          */
+  /***************************************************************************/
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Vendor module property of the Vendor.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vfield        Pointer to the Vendor field.
+ * @param module_name   The module name to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_vendor_field_module_set(VENDOR_VNFNAME_FIELD * const vfield,
+                                    const char * const module_name)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(vfield != NULL);
+  assert(module_name != NULL);
+
+  evel_set_option_string(&vfield->vfmodule, module_name, "Module name set");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Vendor module property of the Vendor.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vfield        Pointer to the Vendor field.
+ * @param module_name   The module name to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_vendor_field_vnfname_set(VENDOR_VNFNAME_FIELD * const vfield,
+                                    const char * const vnfname)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(vfield != NULL);
+  assert(vnfname != NULL);
+
+  evel_set_option_string(&vfield->vnfname, vnfname, "Virtual Network Function name set");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free an event instance id.
+ *
+ * @param vfield   Pointer to the event vnfname_field being freed.
+ *****************************************************************************/
+void evel_free_event_vendor_field(VENDOR_VNFNAME_FIELD * const vfield)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(vfield->vendorname != NULL);
+
+  /***************************************************************************/
+  /* Free everything.                                                        */
+  /***************************************************************************/
+  evel_free_option_string(&vfield->vfmodule);
+  evel_free_option_string(&vfield->vnfname);
+  free(vfield->vendorname);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the instance id as a JSON object according to AT&T's schema.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param vfield        Pointer to the ::VENDOR_VNFNAME_FIELD to encode.
+ *****************************************************************************/
+void evel_json_encode_vendor_field(EVEL_JSON_BUFFER * jbuf,
+                                  VENDOR_VNFNAME_FIELD * vfield)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(jbuf->json != NULL);
+  assert(jbuf->max_size > 0);
+  assert(vfield != NULL);
+  assert(vfield->vendorname != NULL);
+
+  evel_json_open_named_object(jbuf, "vendorVnfNameFields");
+
+  /***************************************************************************/
+  /* Mandatory fields.                                                       */
+  /***************************************************************************/
+  evel_enc_kv_string(jbuf, "vendorName", vfield->vendorname);
+  evel_enc_kv_opt_string(jbuf, "vfModuleName", &vfield->vfmodule);
+  evel_enc_kv_opt_string(jbuf, "vnfName", &vfield->vnfname);
+
+  /***************************************************************************/
+  /* Optional fields.                                                        */
+  /***************************************************************************/
+
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event_mgr.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event_mgr.c
new file mode 100644 (file)
index 0000000..a96124a
--- /dev/null
@@ -0,0 +1,1050 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Event Manager
+ *
+ * Simple event manager that is responsible for taking events (Heartbeats,
+ * Faults and Measurements) from the ring-buffer and posting them to the API.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#include <curl/curl.h>
+
+#include "evel.h"
+#include "evel_internal.h"
+#include "ring_buffer.h"
+#include "evel_throttle.h"
+
+/**************************************************************************//**
+ * How long we're prepared to wait for the API service to respond in
+ * seconds.
+ *****************************************************************************/
+static const int EVEL_API_TIMEOUT = 5;
+
+/*****************************************************************************/
+/* Prototypes of locally scoped functions.                                   */
+/*****************************************************************************/
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp);
+static void * event_handler(void *arg);
+static bool evel_handle_response_tokens(const MEMORY_CHUNK * const chunk,
+                                        const jsmntok_t * const json_tokens,
+                                        const int num_tokens,
+                                        MEMORY_CHUNK * const post);
+static bool evel_tokens_match_command_list(const MEMORY_CHUNK * const chunk,
+                                           const jsmntok_t * const json_token,
+                                           const int num_tokens);
+static bool evel_token_equals_string(const MEMORY_CHUNK * const chunk,
+                                     const jsmntok_t * const json_token,
+                                     const char * check_string);
+
+/**************************************************************************//**
+ * Buffers for error strings from libcurl.
+ *****************************************************************************/
+static char curl_err_string[CURL_ERROR_SIZE] = "<NULL>";
+
+/**************************************************************************//**
+ * Handle for the API into libcurl.
+ *****************************************************************************/
+static CURL * curl_handle = NULL;
+
+/**************************************************************************//**
+ * Special headers that we send.
+ *****************************************************************************/
+static struct curl_slist * hdr_chunk = NULL;
+
+/**************************************************************************//**
+ * Message queue for sending events to the API.
+ *****************************************************************************/
+static ring_buffer event_buffer;
+
+/**************************************************************************//**
+ * Single pending priority post, which can be generated as a result of a
+ * response to an event.  Currently only used to respond to a commandList.
+ *****************************************************************************/
+static MEMORY_CHUNK priority_post;
+
+/**************************************************************************//**
+ * The thread which is responsible for handling events off of the ring-buffer
+ * and posting them to the Event Handler API.
+ *****************************************************************************/
+static pthread_t evt_handler_thread;
+
+/**************************************************************************//**
+ * Variable to convey to the event handler thread what the foreground wants it
+ * to do.
+ *****************************************************************************/
+static EVT_HANDLER_STATE evt_handler_state = EVT_HANDLER_UNINITIALIZED;
+
+/**************************************************************************//**
+ * The configured API URL for event and throttling.
+ *****************************************************************************/
+static char * evel_event_api_url;
+static char * evel_throt_api_url;
+
+/**************************************************************************//**
+ * Initialize the event handler.
+ *
+ * Primarily responsible for getting CURL ready for use.
+ *
+ * @param[in] event_api_url
+ *                      The URL where the Vendor Event Listener API is expected
+ *                      to be.
+ * @param[in] throt_api_url
+ *                      The URL where the Throttling API is expected to be.
+ * @param[in] username  The username for the Basic Authentication of requests.
+ * @param[in] password  The password for the Basic Authentication of requests.
+ * @param     verbosity 0 for normal operation, positive values for chattier
+ *                        logs.
+ *****************************************************************************/
+EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url,
+                                        const char * const throt_api_url,
+                                        const char * const username,
+                                        const char * const password,
+                                        int verbosity)
+{
+  int rc = EVEL_SUCCESS;
+  CURLcode curl_rc = CURLE_OK;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(event_api_url != NULL);
+  assert(throt_api_url != NULL);
+  assert(username != NULL);
+  assert(password != NULL);
+
+  /***************************************************************************/
+  /* Store the API URLs.                                                     */
+  /***************************************************************************/
+  evel_event_api_url = strdup(event_api_url);
+  assert(evel_event_api_url != NULL);
+  evel_throt_api_url = strdup(throt_api_url);
+  assert(evel_throt_api_url != NULL);
+
+
+  curl_version_info_data *d = curl_version_info(CURLVERSION_NOW);
+  /* compare with the 24 bit hex number in 8 bit fields */
+  if(d->version_num >= 0x072100) {
+     /* this is libcurl 7.33.0 or later */
+     EVEL_INFO("7.33 or later Curl version %x.",d->version_num);
+  }
+  else {
+     EVEL_INFO("Old Curl version.");
+  }
+  /***************************************************************************/
+  /* Start the CURL library. Note that this initialization is not threadsafe */
+  /* which imposes a constraint that the EVEL library is initialized before  */
+  /* any threads are started.                                                */
+  /***************************************************************************/
+  curl_rc = curl_global_init(CURL_GLOBAL_SSL);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL. Error code=%d", curl_rc);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Get a curl handle which we'll use for all of our output.                */
+  /***************************************************************************/
+  curl_handle = curl_easy_init();
+  if (curl_handle == NULL)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to get libCURL handle");
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Prime the library to give friendly error codes.                         */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle,
+                             CURLOPT_ERRORBUFFER,
+                             curl_err_string);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL to provide friendly errors. "
+                    "Error code=%d", curl_rc);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* If running in verbose mode generate more output.                        */
+  /***************************************************************************/
+  if (verbosity > 0)
+  {
+    curl_rc = curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
+    if (curl_rc != CURLE_OK)
+    {
+      rc = EVEL_CURL_LIBRARY_FAIL;
+      log_error_state("Failed to initialize libCURL to be verbose. "
+                      "Error code=%d", curl_rc);
+      goto exit_label;
+    }
+  }
+
+  /***************************************************************************/
+  /* Set the URL for the API.                                                */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, event_api_url);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL with the API URL. "
+                    "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+  EVEL_INFO("Initializing CURL to send events to: %s", event_api_url);
+
+  /***************************************************************************/
+  /* send all data to this function.                                         */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle,
+                             CURLOPT_WRITEFUNCTION,
+                             evel_write_callback);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL with the write callback. "
+                    "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* some servers don't like requests that are made without a user-agent     */
+  /* field, so we provide one.                                               */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle,
+                             CURLOPT_USERAGENT,
+                             "libcurl-agent/1.0");
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL to upload. "
+                    "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Specify that we are going to POST data.                                 */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle, CURLOPT_POST, 1L);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL to upload. "
+                    "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* we want to use our own read function.                                   */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, read_callback);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL to upload using read "
+                    "function. Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* All of our events are JSON encoded.  We also suppress the               */
+  /* Expect: 100-continue   header that we would otherwise get since it      */
+  /* confuses some servers.                                                  */
+  /*                                                                         */
+  /* @TODO: do AT&T want this behavior?                                      */
+  /***************************************************************************/
+  hdr_chunk = curl_slist_append(hdr_chunk, "Content-type: application/json");
+  hdr_chunk = curl_slist_append(hdr_chunk, "Expect:");
+
+  /***************************************************************************/
+  /* set our custom set of headers.                                         */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, hdr_chunk);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL to use custom headers. "
+                    "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Set the timeout for the operation.                                      */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle,
+                             CURLOPT_TIMEOUT,
+                             EVEL_API_TIMEOUT);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL for API timeout. "
+                    "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Set that we want Basic authentication with username:password Base-64    */
+  /* encoded for the operation.                                              */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL for Basic Authentication. "
+                    "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+  curl_rc = curl_easy_setopt(curl_handle, CURLOPT_USERNAME, username);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL with username. "
+                    "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+  curl_rc = curl_easy_setopt(curl_handle, CURLOPT_PASSWORD, password);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL with password. "
+                    "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Initialize a message ring-buffer to be used between the foreground and  */
+  /* the thread which sends the messages.  This can't fail.                  */
+  /***************************************************************************/
+  ring_buffer_initialize(&event_buffer, EVEL_EVENT_BUFFER_DEPTH);
+
+  /***************************************************************************/
+  /* Initialize the priority post buffer to empty.                           */
+  /***************************************************************************/
+  priority_post.memory = NULL;
+
+exit_label:
+  EVEL_EXIT();
+
+  return(rc);
+}
+
+/**************************************************************************//**
+ * Run the event handler.
+ *
+ * Spawns the thread responsible for handling events and sending them to the
+ * API.
+ *
+ *  @return Status code.
+ *  @retval ::EVEL_SUCCESS if everything OK.
+ *  @retval One of ::EVEL_ERR_CODES if there was a problem.
+ *****************************************************************************/
+EVEL_ERR_CODES event_handler_run()
+{
+  EVEL_ERR_CODES rc = EVEL_SUCCESS;
+  int pthread_rc = 0;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Start the event handler thread.                                         */
+  /***************************************************************************/
+  evt_handler_state = EVT_HANDLER_INACTIVE;
+  pthread_rc = pthread_create(&evt_handler_thread, NULL, event_handler, NULL);
+  if (pthread_rc != 0)
+  {
+    rc = EVEL_PTHREAD_LIBRARY_FAIL;
+    log_error_state("Failed to start event handler thread. "
+                    "Error code=%d", pthread_rc);
+  }
+
+  EVEL_EXIT()
+  return rc;
+}
+
+/**************************************************************************//**
+ * Terminate the event handler.
+ *
+ * Shuts down the event handler thread in as clean a way as possible. Sets the
+ * global exit flag and then signals the thread to interrupt it since it's
+ * most likely waiting on the ring-buffer.
+ *
+ * Having achieved an orderly shutdown of the event handler thread, clean up
+ * the cURL library's resources cleanly.
+ *
+ *  @return Status code.
+ *  @retval ::EVEL_SUCCESS if everything OK.
+ *  @retval One of ::EVEL_ERR_CODES if there was a problem.
+ *****************************************************************************/
+EVEL_ERR_CODES event_handler_terminate()
+{
+  EVEL_ERR_CODES rc = EVEL_SUCCESS;
+
+  EVEL_ENTER();
+  EVENT_INTERNAL *event = NULL;
+
+  /***************************************************************************/
+  /* Make sure that we were initialized before trying to terminate the       */
+  /* event handler thread.                                                   */
+  /***************************************************************************/
+  if (evt_handler_state != EVT_HANDLER_UNINITIALIZED)
+  {
+    /*************************************************************************/
+    /* Make sure that the event handler knows it's time to die.              */
+    /*************************************************************************/
+    event = evel_new_internal_event(EVT_CMD_TERMINATE,"EVELinternal","EVELid");
+    if (event == NULL)
+    {
+      /***********************************************************************/
+      /* We failed to get an event, but we don't bail out - we will just     */
+      /* clean up what we can and continue on our way, since we're exiting   */
+      /* anyway.                                                             */
+      /***********************************************************************/
+      EVEL_ERROR("Failed to get internal event - perform dirty exit instead!");
+    }
+    else
+    {
+      /***********************************************************************/
+      /* Post the event then wait for the Event Handler to exit.  Set the    */
+      /* global command, too, in case the ring-buffer is full.               */
+      /***********************************************************************/
+      EVEL_DEBUG("Sending event to Event Hander to request it to exit.");
+      evt_handler_state = EVT_HANDLER_REQUEST_TERMINATE;
+      evel_post_event((EVENT_HEADER *) event);
+      pthread_join(evt_handler_thread, NULL);
+      EVEL_DEBUG("Event Handler thread has exited.");
+    }
+  }
+  else
+  {
+    EVEL_DEBUG("Event handler was not initialized, so no need to kill it");
+  }
+
+  /***************************************************************************/
+  /* Clean-up the cURL library.                                              */
+  /***************************************************************************/
+  if (curl_handle != NULL)
+  {
+    curl_easy_cleanup(curl_handle);
+    curl_handle = NULL;
+  }
+  if (hdr_chunk != NULL)
+  {
+    curl_slist_free_all(hdr_chunk);
+    hdr_chunk = NULL;
+  }
+
+  /***************************************************************************/
+  /* Free off the stored API URL strings.                                    */
+  /***************************************************************************/
+  if (evel_event_api_url != NULL)
+  {
+    free(evel_event_api_url);
+    evel_event_api_url = NULL;
+  }
+  if (evel_throt_api_url != NULL)
+  {
+    free(evel_throt_api_url);
+    evel_throt_api_url = NULL;
+  }
+
+  EVEL_EXIT();
+  return rc;
+}
+
+/**************************************************************************//**
+ * Post an event.
+ *
+ * @note  So far as the caller is concerned, successfully posting the event
+ * relinquishes all responsibility for the event - the library will take care
+ * of freeing the event in due course.
+
+ * @param event   The event to be posted.
+ *
+ * @returns Status code
+ * @retval  EVEL_SUCCESS On success
+ * @retval  "One of ::EVEL_ERR_CODES" On failure.
+ *****************************************************************************/
+EVEL_ERR_CODES evel_post_event(EVENT_HEADER * event)
+{
+  int rc = EVEL_SUCCESS;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+
+  /***************************************************************************/
+  /* We need to make sure that we are either initializing or running         */
+  /* normally before writing the event into the buffer so that we can        */
+  /* guarantee that the ring-buffer empties  properly on exit.               */
+  /***************************************************************************/
+  if ((evt_handler_state == EVT_HANDLER_ACTIVE) ||
+      (evt_handler_state == EVT_HANDLER_INACTIVE) ||
+      (evt_handler_state == EVT_HANDLER_REQUEST_TERMINATE))
+  {
+    if (ring_buffer_write(&event_buffer, event) == 0)
+    {
+      log_error_state("Failed to write event to buffer - event dropped!");
+      rc = EVEL_EVENT_BUFFER_FULL;
+      evel_free_event(event);
+    }
+  }
+  else
+  {
+    /*************************************************************************/
+    /* System is not in active operation, so reject the event.               */
+    /*************************************************************************/
+    log_error_state("Event Handler system not active - event dropped!");
+    rc = EVEL_EVENT_HANDLER_INACTIVE;
+    evel_free_event(event);
+  }
+
+  EVEL_EXIT();
+  return (rc);
+}
+
+/**************************************************************************//**
+ * Post an event to the Vendor Event Listener API.
+ *
+ * @returns Status code
+ * @retval  EVEL_SUCCESS On success
+ * @retval  "One of ::EVEL_ERR_CODES" On failure.
+ *****************************************************************************/
+static EVEL_ERR_CODES evel_post_api(char * msg, size_t size)
+{
+  int rc = EVEL_SUCCESS;
+  CURLcode curl_rc = CURLE_OK;
+  MEMORY_CHUNK rx_chunk;
+  MEMORY_CHUNK tx_chunk;
+  int http_response_code = 0;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Create the memory chunk to be used for the response to the post.  The   */
+  /* will be realloced.                                                      */
+  /***************************************************************************/
+  rx_chunk.memory = malloc(1);
+  assert(rx_chunk.memory != NULL);
+  rx_chunk.size = 0;
+
+  /***************************************************************************/
+  /* Create the memory chunk to be sent as the body of the post.             */
+  /***************************************************************************/
+  tx_chunk.memory = msg;
+  tx_chunk.size = size;
+  EVEL_DEBUG("Sending chunk of size %d", tx_chunk.size);
+
+  /***************************************************************************/
+  /* Point to the data to be received.                                       */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &rx_chunk);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to initialize libCURL to upload. "
+                    "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+  EVEL_DEBUG("Initialized data to receive");
+
+  /***************************************************************************/
+  /* Pointer to pass to our read function                                    */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle, CURLOPT_READDATA, &tx_chunk);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to set upload data for libCURL to upload. "
+                    "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+  EVEL_DEBUG("Initialized data to send");
+
+  /***************************************************************************/
+  /* Size of the data to transmit.                                           */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle,
+                             CURLOPT_POSTFIELDSIZE,
+                             tx_chunk.size);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to set length of upload data for libCURL to "
+                    "upload.  Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+  EVEL_DEBUG("Initialized length of data to send");
+
+  /***************************************************************************/
+  /* Now run off and do what you've been told!                               */
+  /***************************************************************************/
+  curl_rc = curl_easy_perform(curl_handle);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    log_error_state("Failed to transfer an event to Vendor Event Listener! "
+                    "Error code=%d (%s)", curl_rc, curl_err_string);
+    EVEL_ERROR("Dropped event: %s", msg);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* See what response we got - any 2XX response is good.                    */
+  /***************************************************************************/
+  curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &http_response_code);
+  EVEL_DEBUG("HTTP response code: %d", http_response_code);
+  if ((http_response_code / 100) == 2)
+  {
+    /*************************************************************************/
+    /* If the server responded with data it may be interesting but not a     */
+    /* problem.                                                              */
+    /*************************************************************************/
+    if ((rx_chunk.size > 0) && (rx_chunk.memory != NULL))
+    {
+      EVEL_DEBUG("Server returned data = %d (%s)",
+                 rx_chunk.size,
+                 rx_chunk.memory);
+
+      /***********************************************************************/
+      /* If this is a response to priority post, then we're not interested.  */
+      /***********************************************************************/
+      if (priority_post.memory != NULL)
+      {
+        EVEL_ERROR("Ignoring priority post response");
+      }
+      else
+      {
+        evel_handle_event_response(&rx_chunk, &priority_post);
+      }
+    }
+  }
+  else
+  {
+    EVEL_ERROR("Unexpected HTTP response code: %d with data size %d (%s)",
+                http_response_code,
+                rx_chunk.size,
+                rx_chunk.size > 0 ? rx_chunk.memory : "NONE");
+    EVEL_ERROR("Potentially dropped event: %s", msg);
+  }
+
+exit_label:
+  free(rx_chunk.memory);
+  EVEL_EXIT();
+  return(rc);
+}
+
+/**************************************************************************//**
+ * Callback function to provide data to send.
+ *
+ * Copy data into the supplied buffer, read_callback::ptr, checking size
+ * limits.
+ *
+ * @returns   Number of bytes placed into read_callback::ptr. 0 for EOF.
+ *****************************************************************************/
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+  size_t rtn = 0;
+  size_t bytes_to_write = 0;
+  MEMORY_CHUNK *tx_chunk = (MEMORY_CHUNK *)userp;
+
+  EVEL_ENTER();
+
+  bytes_to_write = min(size*nmemb, tx_chunk->size);
+
+  if (bytes_to_write > 0)
+  {
+    EVEL_DEBUG("Going to try to write %d bytes", bytes_to_write);
+    strncpy((char *)ptr, tx_chunk->memory, bytes_to_write);
+    tx_chunk->memory += bytes_to_write;
+    tx_chunk->size -= bytes_to_write;
+    rtn = bytes_to_write;
+  }
+  else
+  {
+    EVEL_DEBUG("Reached EOF");
+  }
+
+  EVEL_EXIT();
+  return rtn;
+}
+
+/**************************************************************************//**
+ * Callback function to provide returned data.
+ *
+ * Copy data into the supplied buffer, write_callback::ptr, checking size
+ * limits.
+ *
+ * @returns   Number of bytes placed into write_callback::ptr. 0 for EOF.
+ *****************************************************************************/
+size_t evel_write_callback(void *contents,
+                             size_t size,
+                             size_t nmemb,
+                             void *userp)
+{
+  size_t realsize = size * nmemb;
+  MEMORY_CHUNK * rx_chunk = (MEMORY_CHUNK *)userp;
+
+  EVEL_ENTER();
+
+  EVEL_DEBUG("Called with %d chunks of %d size = %d", nmemb, size, realsize);
+  EVEL_DEBUG("rx chunk size is %d", rx_chunk->size);
+
+  rx_chunk->memory = realloc(rx_chunk->memory, rx_chunk->size + realsize + 1);
+  if(rx_chunk->memory == NULL) {
+    /* out of memory! */
+    printf("not enough memory (realloc returned NULL)\n");
+    return 0;
+  }
+
+  memcpy(&(rx_chunk->memory[rx_chunk->size]), contents, realsize);
+  rx_chunk->size += realsize;
+  rx_chunk->memory[rx_chunk->size] = 0;
+
+  EVEL_DEBUG("Rx data: %s", rx_chunk->memory);
+  EVEL_DEBUG("Returning: %d", realsize);
+
+  EVEL_EXIT();
+  return realsize;
+}
+
+/**************************************************************************//**
+ * Event Handler.
+ *
+ * Watch for messages coming on the internal queue and send them to the
+ * listener.
+ *
+ * param[in]  arg  Argument - unused.
+ *****************************************************************************/
+static void * event_handler(void * arg __attribute__ ((unused)))
+{
+  int old_type = 0;
+  EVENT_HEADER * msg = NULL;
+  EVENT_INTERNAL * internal_msg = NULL;
+  int json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  int rc = EVEL_SUCCESS;
+  CURLcode curl_rc;
+
+  EVEL_INFO("Event handler thread started");
+
+  /***************************************************************************/
+  /* Set this thread to be cancellable immediately.                          */
+  /***************************************************************************/
+  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_type);
+
+  /***************************************************************************/
+  /* Set the handler as active, defending against weird situations like      */
+  /* immediately shutting down after initializing the library so the         */
+  /* handler never gets started up properly.                                 */
+  /***************************************************************************/
+  if (evt_handler_state == EVT_HANDLER_INACTIVE)
+  {
+    evt_handler_state = EVT_HANDLER_ACTIVE;
+  }
+  else
+  {
+    EVEL_ERROR("Event Handler State was not INACTIVE at start-up - "
+               "Handler will exit immediately!");
+  }
+
+  while (evt_handler_state == EVT_HANDLER_ACTIVE)
+  {
+    /*************************************************************************/
+    /* Wait for a message to be received.                                    */
+    /*************************************************************************/
+    EVEL_DEBUG("Event handler getting any messages");
+    msg = ring_buffer_read(&event_buffer);
+
+    /*************************************************************************/
+    /* Internal events get special treatment while regular events get posted */
+    /* to the far side.                                                      */
+    /*************************************************************************/
+    if (msg->event_domain != EVEL_DOMAIN_INTERNAL)
+    {
+      EVEL_DEBUG("External event received");
+
+      /***********************************************************************/
+      /* Encode the event in JSON.                                           */
+      /***********************************************************************/
+      json_size = evel_json_encode_event(json_body, EVEL_MAX_JSON_BODY, msg);
+
+      /***********************************************************************/
+      /* Send the JSON across the API.                                       */
+      /***********************************************************************/
+      EVEL_DEBUG("Sending JSON of size %d is: %s", json_size, json_body);
+      rc = evel_post_api(json_body, json_size);
+      if (rc != EVEL_SUCCESS)
+      {
+        EVEL_ERROR("Failed to transfer the data. Error code=%d", rc);
+      }
+    }
+    else
+    {
+      EVEL_DEBUG("Internal event received");
+      internal_msg = (EVENT_INTERNAL *) msg;
+      assert(internal_msg->command == EVT_CMD_TERMINATE);
+      evt_handler_state = EVT_HANDLER_TERMINATING;
+    }
+
+    /*************************************************************************/
+    /* We are responsible for freeing the memory.                            */
+    /*************************************************************************/
+    evel_free_event(msg);
+    msg = NULL;
+
+    /*************************************************************************/
+    /* There may be a single priority post to be sent.                       */
+    /*************************************************************************/
+    if (priority_post.memory != NULL)
+    {
+      EVEL_DEBUG("Priority Post");
+
+      /***********************************************************************/
+      /* Set the URL for the throttling API.                                 */
+      /***********************************************************************/
+      curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, evel_throt_api_url);
+      if (curl_rc != CURLE_OK)
+      {
+        /*********************************************************************/
+        /* This is only likely to happen with CURLE_OUT_OF_MEMORY, in which  */
+        /* case we carry on regardless.                                      */
+        /*********************************************************************/
+        EVEL_ERROR("Failed to set throttling URL. Error code=%d", rc);
+      }
+      else
+      {
+        rc = evel_post_api(priority_post.memory, priority_post.size);
+        if (rc != EVEL_SUCCESS)
+        {
+          EVEL_ERROR("Failed to transfer priority post. Error code=%d", rc);
+        }
+      }
+
+      /***********************************************************************/
+      /* Reinstate the URL for the event API.                                */
+      /***********************************************************************/
+      curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, evel_event_api_url);
+      if (curl_rc != CURLE_OK)
+      {
+        /*********************************************************************/
+        /* This is only likely to happen with CURLE_OUT_OF_MEMORY, in which  */
+        /* case we carry on regardless.                                      */
+        /*********************************************************************/
+        EVEL_ERROR("Failed to reinstate events URL. Error code=%d", rc);
+      }
+
+      /***********************************************************************/
+      /* We are responsible for freeing the memory.                          */
+      /***********************************************************************/
+      free(priority_post.memory);
+      priority_post.memory = NULL;
+    }
+  }
+
+  /***************************************************************************/
+  /* The event handler is now exiting. The ring-buffer could contain events  */
+  /* which have not been processed, so deplete those.  Because we've been    */
+  /* asked to exit we can be confident that the foreground will have stopped */
+  /* sending events in so we know that this process will conclude!           */
+  /***************************************************************************/
+  evt_handler_state = EVT_HANDLER_TERMINATING;
+  while (!ring_buffer_is_empty(&event_buffer))
+  {
+    EVEL_DEBUG("Reading event from buffer");
+    msg = ring_buffer_read(&event_buffer);
+    evel_free_event(msg);
+  }
+  evt_handler_state = EVT_HANDLER_TERMINATED;
+  EVEL_INFO("Event handler thread stopped");
+
+  return (NULL);
+}
+
+/**************************************************************************//**
+ * Handle a JSON response from the listener, contained in a ::MEMORY_CHUNK.
+ *
+ * Tokenize the response, and decode any tokens found.
+ *
+ * @param chunk         The memory chunk containing the response.
+ * @param post          The memory chunk in which to place any resulting POST.
+ *****************************************************************************/
+void evel_handle_event_response(const MEMORY_CHUNK * const chunk,
+                                MEMORY_CHUNK * const post)
+{
+  jsmn_parser json_parser;
+  jsmntok_t json_tokens[EVEL_MAX_RESPONSE_TOKENS];
+  int num_tokens = 0;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(chunk != NULL);
+  assert(priority_post.memory == NULL);
+
+  EVEL_DEBUG("Response size = %d", chunk->size);
+  EVEL_DEBUG("Response = %s", chunk->memory);
+
+  /***************************************************************************/
+  /* Initialize the parser and tokenize the response.                        */
+  /***************************************************************************/
+  jsmn_init(&json_parser);
+  num_tokens = jsmn_parse(&json_parser,
+                          chunk->memory,
+                          chunk->size,
+                          json_tokens,
+                          EVEL_MAX_RESPONSE_TOKENS);
+
+  if (num_tokens < 0)
+  {
+    EVEL_ERROR("Failed to parse JSON response.  "
+               "Error code=%d", num_tokens);
+  }
+  else if (num_tokens == 0)
+  {
+    EVEL_DEBUG("No tokens found in JSON response");
+  }
+  else
+  {
+    EVEL_DEBUG("Decode JSON response tokens");
+    if (!evel_handle_response_tokens(chunk, json_tokens, num_tokens, post))
+    {
+      EVEL_ERROR("Failed to handle JSON response.");
+    }
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Handle a JSON response from the listener, as a list of tokens from JSMN.
+ *
+ * @param chunk         Memory chunk containing the JSON buffer.
+ * @param json_tokens   Array of tokens to handle.
+ * @param num_tokens    The number of tokens to handle.
+ * @param post          The memory chunk in which to place any resulting POST.
+ * @return true if we handled the response, false otherwise.
+ *****************************************************************************/
+bool evel_handle_response_tokens(const MEMORY_CHUNK * const chunk,
+                                 const jsmntok_t * const json_tokens,
+                                 const int num_tokens,
+                                 MEMORY_CHUNK * const post)
+{
+  bool json_ok = false;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(chunk != NULL);
+  assert(json_tokens != NULL);
+  assert(num_tokens < EVEL_MAX_RESPONSE_TOKENS);
+
+  /***************************************************************************/
+  /* Peek at the tokens to decide what the response it, then call the        */
+  /* appropriate handler to handle it.  There is only one handler at this    */
+  /* point.                                                                  */
+  /***************************************************************************/
+  if (evel_tokens_match_command_list(chunk, json_tokens, num_tokens))
+  {
+    json_ok = evel_handle_command_list(chunk, json_tokens, num_tokens, post);
+  }
+
+  EVEL_EXIT();
+
+  return json_ok;
+}
+
+/**************************************************************************//**
+ * Determine whether a list of tokens looks like a "commandList" response.
+ *
+ * @param chunk         Memory chunk containing the JSON buffer.
+ * @param json_tokens   Token to check.
+ * @param num_tokens    The number of tokens to handle.
+ * @return true if the tokens look like a "commandList" match, or false.
+ *****************************************************************************/
+bool evel_tokens_match_command_list(const MEMORY_CHUNK * const chunk,
+                                    const jsmntok_t * const json_tokens,
+                                    const int num_tokens)
+{
+  bool result = false;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Make some checks on the basic layout of the commandList.                */
+  /***************************************************************************/
+  if ((num_tokens > 3) &&
+      (json_tokens[0].type == JSMN_OBJECT) &&
+      (json_tokens[1].type == JSMN_STRING) &&
+      (json_tokens[2].type == JSMN_ARRAY) &&
+      (evel_token_equals_string(chunk, &json_tokens[1], "commandList")))
+  {
+    result = true;
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Check that a string token matches a given input string.
+ *
+ * @param chunk         Memory chunk containing the JSON buffer.
+ * @param json_token    Token to check.
+ * @param check_string  String to check it against.
+ * @return true if the strings match, or false.
+ *****************************************************************************/
+bool evel_token_equals_string(const MEMORY_CHUNK * const chunk,
+                              const jsmntok_t * json_token,
+                              const char * check_string)
+{
+  bool result = false;
+
+  EVEL_ENTER();
+
+  const int token_length = json_token->end - json_token->start;
+  const char * const token_string = chunk->memory + json_token->start;
+
+  if (token_length == (int)strlen(check_string))
+  {
+    result = (strncmp(token_string, check_string, token_length) == 0);
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_fault.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_fault.c
new file mode 100644 (file)
index 0000000..c211f60
--- /dev/null
@@ -0,0 +1,367 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to the Fault.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "evel.h"
+#include "evel_internal.h"
+#include "evel_throttle.h"
+
+/**************************************************************************//**
+ * Create a new fault event.
+ *
+ * @note    The mandatory fields on the Fault must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Fault has immutable properties.
+ * @param event_name  Unique Event Name confirming Domain AsdcModel Description
+ * @param event_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
+ * @param   condition   The condition indicated by the Fault.
+ * @param   specific_problem  The specific problem triggering the fault.
+ * @param   priority    The priority of the event.
+ * @param   severity    The severity of the Fault.
+ * @param   ev_source_type    Source of Alarm event
+ * @param   version     fault version
+ * @param   status      status of Virtual Function
+ * @returns pointer to the newly manufactured ::EVENT_FAULT.  If the event is
+ *          not used (i.e. posted) it must be released using ::evel_free_fault.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_FAULT * evel_new_fault(const char * ev_name,
+                            const char * ev_id,
+                            const char * const condition,
+                             const char * const specific_problem,
+                            EVEL_EVENT_PRIORITIES priority,
+                             EVEL_SEVERITIES severity,
+                             EVEL_SOURCE_TYPES ev_source_type,
+                            EVEL_VF_STATUSES status)
+{
+  EVENT_FAULT * fault = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(condition != NULL);
+  assert(specific_problem != NULL);
+  assert(priority < EVEL_MAX_PRIORITIES);
+  assert(severity < EVEL_MAX_SEVERITIES);
+
+  /***************************************************************************/
+  /* Allocate the fault.                                                     */
+  /***************************************************************************/
+  fault = malloc(sizeof(EVENT_FAULT));
+  if (fault == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(fault, 0, sizeof(EVENT_FAULT));
+  EVEL_DEBUG("New fault is at %lp", fault);
+
+  /***************************************************************************/
+  /* Initialize the header & the fault fields.  Optional string values are   */
+  /* uninitialized (NULL).                                                   */
+  /***************************************************************************/
+  evel_init_header_nameid(&fault->header,ev_name,ev_id);
+  fault->header.event_domain = EVEL_DOMAIN_FAULT;
+  fault->header.priority = priority;
+  fault->major_version = EVEL_FAULT_MAJOR_VERSION;
+  fault->minor_version = EVEL_FAULT_MINOR_VERSION;
+  fault->event_severity = severity;
+  fault->event_source_type = ev_source_type;
+  fault->vf_status = status;
+  fault->alarm_condition = strdup(condition);
+  fault->specific_problem = strdup(specific_problem);
+  evel_init_option_string(&fault->category);
+  evel_init_option_string(&fault->alarm_interface_a);
+  dlist_initialize(&fault->additional_info);
+
+exit_label:
+  EVEL_EXIT();
+  return fault;
+}
+
+/**************************************************************************//**
+ * Add an additional value name/value pair to the Fault.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param fault     Pointer to the fault.
+ * @param name      ASCIIZ string with the attribute's name.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ * @param value     ASCIIZ string with the attribute's value.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ *****************************************************************************/
+void evel_fault_addl_info_add(EVENT_FAULT * fault, char * name, char * value)
+{
+  FAULT_ADDL_INFO * addl_info = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(fault != NULL);
+  assert(fault->header.event_domain == EVEL_DOMAIN_FAULT);
+  assert(name != NULL);
+  assert(value != NULL);
+
+  EVEL_DEBUG("Adding name=%s value=%s", name, value);
+  addl_info = malloc(sizeof(FAULT_ADDL_INFO));
+  assert(addl_info != NULL);
+  memset(addl_info, 0, sizeof(FAULT_ADDL_INFO));
+  addl_info->name = strdup(name);
+  addl_info->value = strdup(value);
+  assert(addl_info->name != NULL);
+  assert(addl_info->value != NULL);
+
+  dlist_push_last(&fault->additional_info, addl_info);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Fault Category property of the Fault.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param fault      Pointer to the fault.
+ * @param category   Category : license, link, routing, security, signaling.
+ *                      ASCIIZ string. The caller
+ *                   does not need to preserve the value once the function
+ *                   returns.
+ *****************************************************************************/
+void evel_fault_category_set(EVENT_FAULT * fault,
+                              const char * const category)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(fault != NULL);
+  assert(fault->header.event_domain == EVEL_DOMAIN_FAULT);
+  assert(category != NULL);
+
+  evel_set_option_string(&fault->category,
+                         category,
+                         "Fault Category set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Alarm Interface A property of the Fault.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param fault      Pointer to the fault.
+ * @param interface  The Alarm Interface A to be set. ASCIIZ string. The caller
+ *                   does not need to preserve the value once the function
+ *                   returns.
+ *****************************************************************************/
+void evel_fault_interface_set(EVENT_FAULT * fault,
+                              const char * const interface)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(fault != NULL);
+  assert(fault->header.event_domain == EVEL_DOMAIN_FAULT);
+  assert(interface != NULL);
+
+  evel_set_option_string(&fault->alarm_interface_a,
+                         interface,
+                         "Alarm Interface A");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Event Type property of the Fault.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param fault      Pointer to the fault.
+ * @param type       The Event Type to be set. ASCIIZ string. The caller
+ *                   does not need to preserve the value once the function
+ *                   returns.
+ *****************************************************************************/
+void evel_fault_type_set(EVENT_FAULT * fault, const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and call evel_header_type_set.                      */
+  /***************************************************************************/
+  assert(fault != NULL);
+  assert(fault->header.event_domain == EVEL_DOMAIN_FAULT);
+  evel_header_type_set(&fault->header, type);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the fault in JSON according to AT&T's schema for the fault type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_fault(EVEL_JSON_BUFFER * jbuf,
+                            EVENT_FAULT * event)
+{
+  FAULT_ADDL_INFO * addl_info = NULL;
+  DLIST_ITEM * addl_info_item = NULL;
+  char * fault_severity;
+  char * fault_source_type;
+  char * fault_vf_status;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_FAULT);
+
+  fault_severity = evel_severity(event->event_severity);
+  fault_source_type = evel_source_type(event->event_source_type);
+  fault_vf_status = evel_vf_status(event->vf_status);
+
+  evel_json_encode_header(jbuf, &event->header);
+  evel_json_open_named_object(jbuf, "faultFields");
+
+  /***************************************************************************/
+  /* Mandatory fields.                                                       */
+  /***************************************************************************/
+  evel_enc_kv_string(jbuf, "alarmCondition", event->alarm_condition);
+  evel_enc_kv_opt_string(jbuf, "eventCategory", &event->category);
+  evel_enc_kv_string(jbuf, "eventSeverity", fault_severity);
+  evel_enc_kv_string(jbuf, "eventSourceType", fault_source_type);
+  evel_enc_kv_string(jbuf, "specificProblem", event->specific_problem);
+  evel_enc_kv_string(jbuf, "vfStatus", fault_vf_status);
+  evel_enc_version(
+    jbuf, "faultFieldsVersion", event->major_version, event->minor_version);
+
+  /***************************************************************************/
+  /* Optional fields.                                                        */
+  /***************************************************************************/
+
+  /***************************************************************************/
+  /* Checkpoint, so that we can wind back if all fields are suppressed.      */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "alarmAdditionalInformation"))
+  {
+    bool item_added = false;
+
+    addl_info_item = dlist_get_first(&event->additional_info);
+    while (addl_info_item != NULL)
+    {
+      addl_info = (FAULT_ADDL_INFO*) addl_info_item->item;
+      assert(addl_info != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "alarmAdditionalInformation",
+                                          addl_info->name))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "name", addl_info->name);
+        evel_enc_kv_string(jbuf, "value", addl_info->value);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      addl_info_item = dlist_get_next(addl_info_item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+  evel_enc_kv_opt_string(jbuf, "alarmInterfaceA", &event->alarm_interface_a);
+
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free a Fault.
+ *
+ * Free off the Fault supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the Fault itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_fault(EVENT_FAULT * event)
+{
+  FAULT_ADDL_INFO * addl_info = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+  /* events as we do on the public API.                                      */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_FAULT);
+
+  /***************************************************************************/
+  /* Free all internal strings then the header itself.                       */
+  /***************************************************************************/
+  addl_info = dlist_pop_last(&event->additional_info);
+  while (addl_info != NULL)
+  {
+    EVEL_DEBUG("Freeing Additional Info (%s, %s)",
+               addl_info->name,
+               addl_info->value);
+    free(addl_info->name);
+    free(addl_info->value);
+    free(addl_info);
+    addl_info = dlist_pop_last(&event->additional_info);
+  }
+  free(event->alarm_condition);
+  free(event->specific_problem);
+  evel_free_option_string(&event->category);
+  evel_free_option_string(&event->alarm_interface_a);
+  evel_free_header(&event->header);
+
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_heartbeat_fields.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_heartbeat_fields.c
new file mode 100644 (file)
index 0000000..872af1f
--- /dev/null
@@ -0,0 +1,269 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to Heartbeat fields.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "evel.h"
+#include "evel_throttle.h"
+
+/**************************************************************************//**
+ * Create a new Heartbeat fields event.
+ *
+ * @note    The mandatory fields on the Heartbeat fields must be supplied to
+ *          this factory function and are immutable once set.  Optional fields
+ *          have explicit setter functions, but again values may only be set
+ *          once so that the event has immutable properties.
+ * @param event_name  Unique Event Name confirming Domain AsdcModel Description
+ * @param event_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
+ * @param vendor_id     The vendor id to encode in the event instance id.
+ * @param event_id      The vendor event id to encode in the event instance id.
+ * @returns pointer to the newly manufactured ::EVENT_HEARTBEAT_FIELD.  If the event
+ *          is not used (i.e. posted) it must be released using
+ *          ::evel_free_hrtbt_field.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_HEARTBEAT_FIELD * evel_new_heartbeat_field(int interval,const char* ev_name, const char *ev_id)
+{
+  EVENT_HEARTBEAT_FIELD * event = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(interval > 0);
+
+  /***************************************************************************/
+  /* Allocate the Heartbeat fields event.                                           */
+  /***************************************************************************/
+  event = malloc(sizeof(EVENT_HEARTBEAT_FIELD));
+  if (event == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(event, 0, sizeof(EVENT_HEARTBEAT_FIELD));
+  EVEL_DEBUG("New Heartbeat fields event is at %lp", event);
+
+  /***************************************************************************/
+  /* Initialize the header & the Heartbeat fields fields.                           */
+  /***************************************************************************/
+  evel_init_header_nameid(&event->header,ev_name,ev_id);
+  event->header.event_domain = EVEL_DOMAIN_HEARTBEAT_FIELD;
+  event->major_version = EVEL_HEARTBEAT_FIELD_MAJOR_VERSION;
+  event->minor_version = EVEL_HEARTBEAT_FIELD_MINOR_VERSION;
+
+  event->heartbeat_interval = interval;
+  dlist_initialize(&event->additional_info);
+
+exit_label:
+
+  EVEL_EXIT();
+  return event;
+}
+
+/**************************************************************************//**
+ * Add a name/value pair to the Heartbeat fields, under the additionalFields array.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param event     Pointer to the Heartbeat fields event.
+ * @param name      ASCIIZ string with the field's name.  The caller does not
+ *                  need to preserve the value once the function returns.
+ * @param value     ASCIIZ string with the field's value.  The caller does not
+ *                  need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_hrtbt_field_addl_field_add(EVENT_HEARTBEAT_FIELD * const event,
+                                 const char * const name,
+                                 const char * const value)
+{
+  OTHER_FIELD * nv_pair = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_HEARTBEAT_FIELD);
+  assert(name != NULL);
+  assert(value != NULL);
+
+  EVEL_DEBUG("Adding name=%s value=%s", name, value);
+  nv_pair = malloc(sizeof(OTHER_FIELD));
+  assert(nv_pair != NULL);
+  nv_pair->name = strdup(name);
+  nv_pair->value = strdup(value);
+  assert(nv_pair->name != NULL);
+  assert(nv_pair->value != NULL);
+
+  dlist_push_last(&event->additional_info, nv_pair);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Interval property of the Heartbeat fields event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Heartbeat fields event.
+ * @param product_id    The vendor product id to be set. ASCIIZ string. The
+ *                      caller does not need to preserve the value once the
+ *                      function returns.
+ *****************************************************************************/
+void evel_hrtbt_interval_set(EVENT_HEARTBEAT_FIELD * const event,
+                                 const int interval)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and call evel_set_option_string.                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_HEARTBEAT_FIELD);
+  assert(interval > 0);
+
+  event->heartbeat_interval = interval;
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Encode the Heartbeat fields in JSON according to AT&T's schema for the
+ * event type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_hrtbt_field(EVEL_JSON_BUFFER * const jbuf,
+                                EVENT_HEARTBEAT_FIELD * const event)
+{
+  OTHER_FIELD * nv_pair = NULL;
+  DLIST_ITEM * dlist_item = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_HEARTBEAT_FIELD);
+
+  evel_json_encode_header(jbuf, &event->header);
+  evel_json_open_named_object(jbuf, "heartbeatField");
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  evel_enc_version(jbuf, "heartbeatFieldsVersion", event->major_version,event->minor_version);
+  evel_enc_kv_int(jbuf, "heartbeatInterval", event->heartbeat_interval);
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+
+  /***************************************************************************/
+  /* Checkpoint, so that we can wind back if all fields are suppressed.      */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "additionalFields"))
+  {
+    bool added = false;
+
+    dlist_item = dlist_get_first(&event->additional_info);
+    while (dlist_item != NULL)
+    {
+      nv_pair = (OTHER_FIELD *) dlist_item->item;
+      assert(nv_pair != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "additionalFields",
+                                          nv_pair->name))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "name", nv_pair->name);
+        evel_enc_kv_string(jbuf, "value", nv_pair->value);
+        evel_json_close_object(jbuf);
+        added = true;
+      }
+      dlist_item = dlist_get_next(dlist_item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free a Heartbeat fields event.
+ *
+ * Free off the event supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the event itself, since that may be part of a larger
+ * structure.
+ *****************************************************************************/
+void evel_free_hrtbt_field(EVENT_HEARTBEAT_FIELD * const event)
+{
+  OTHER_FIELD * nv_pair = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_HEARTBEAT_FIELD);
+
+  /***************************************************************************/
+  /* Free all internal strings then the header itself.                       */
+  /***************************************************************************/
+  nv_pair = dlist_pop_last(&event->additional_info);
+  while (nv_pair != NULL)
+  {
+    EVEL_DEBUG("Freeing Other Field (%s, %s)", nv_pair->name, nv_pair->value);
+    free(nv_pair->name);
+    free(nv_pair->value);
+    free(nv_pair);
+    nv_pair = dlist_pop_last(&event->additional_info);
+  }
+  evel_free_header(&event->header);
+
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal.h b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal.h
new file mode 100644 (file)
index 0000000..46f71af
--- /dev/null
@@ -0,0 +1,858 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * EVEL internal definitions.
+ *
+ * These are internal definitions which need to be shared between modules
+ * within the library but are not intended for external consumption.
+ *
+ ****************************************************************************/
+
+#ifndef EVEL_INTERNAL_INCLUDED
+#define EVEL_INTERNAL_INCLUDED
+
+#include "evel.h"
+
+/*****************************************************************************/
+/* Define some type-safe min/max macros.                                     */
+/*****************************************************************************/
+#define max(a,b) \
+   ({ __typeof__ (a) _a = (a); \
+       __typeof__ (b) _b = (b); \
+     _a > _b ? _a : _b; })
+
+#define min(a,b) \
+   ({ __typeof__ (a) _a = (a); \
+       __typeof__ (b) _b = (b); \
+     _a < _b ? _a : _b; })
+
+
+/**************************************************************************//**
+ * Compile-time assertion.
+ *****************************************************************************/
+#define EVEL_CT_ASSERT(X) switch (0) {case 0: case (X):;}
+
+/**************************************************************************//**
+ * The Functional Role of the equipment represented by this VNF.
+ *****************************************************************************/
+extern char * functional_role;
+
+/**************************************************************************//**
+ * The type of equipment represented by this VNF.
+ *****************************************************************************/
+extern EVEL_SOURCE_TYPES event_source_type;
+
+/**************************************************************************//**
+ * A chunk of memory used in the cURL functions.
+ *****************************************************************************/
+typedef struct memory_chunk {
+  char * memory;
+  size_t size;
+} MEMORY_CHUNK;
+
+/**************************************************************************//**
+ * Global commands that may be sent to the Event Handler thread.
+ *****************************************************************************/
+typedef enum {
+  EVT_CMD_TERMINATE,
+  EVT_CMD_MAX_COMMANDS
+} EVT_HANDLER_COMMAND;
+
+/**************************************************************************//**
+ * State of the Event Handler thread.
+ *****************************************************************************/
+typedef enum {
+  EVT_HANDLER_UNINITIALIZED,      /** The library cannot handle events.      */
+  EVT_HANDLER_INACTIVE,           /** The event handler thread not started.  */
+  EVT_HANDLER_ACTIVE,             /** The event handler thread is started.   */
+  EVT_HANDLER_REQUEST_TERMINATE,  /** Initial stages of shutdown.            */
+  EVT_HANDLER_TERMINATING,        /** The ring-buffer is being depleted.     */
+  EVT_HANDLER_TERMINATED,         /** The library is exited.                 */
+  EVT_HANDLER_MAX_STATES          /** Maximum number of valid states.        */
+} EVT_HANDLER_STATE;
+
+/**************************************************************************//**
+ * Internal event.
+ * Pseudo-event used for routing internal commands.
+ *****************************************************************************/
+typedef struct event_internal {
+  EVENT_HEADER header;
+  EVT_HANDLER_COMMAND command;
+} EVENT_INTERNAL;
+
+/**************************************************************************//**
+ * Suppressed NV pairs list entry.
+ * JSON equivalent field: suppressedNvPairs
+ *****************************************************************************/
+typedef struct evel_suppressed_nv_pairs {
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /* JSON equivalent field: nvPairFieldName                                  */
+  /***************************************************************************/
+  char * nv_pair_field_name;
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /* JSON equivalent field: suppressedNvPairNames                            */
+  /* Type of each list entry: char *                                         */
+  /***************************************************************************/
+  DLIST suppressed_nv_pair_names;
+
+  /***************************************************************************/
+  /* Hash table containing suppressed_nv_pair_names as keys.                 */
+  /***************************************************************************/
+  struct hsearch_data * hash_nv_pair_names;
+
+} EVEL_SUPPRESSED_NV_PAIRS;
+
+/**************************************************************************//**
+ * Event Throttling Specification for a domain which is in a throttled state.
+ * JSON equivalent object: eventThrottlingState
+ *****************************************************************************/
+typedef struct evel_throttle_spec {
+
+  /***************************************************************************/
+  /* List of field names to be suppressed.                                   */
+  /* JSON equivalent field: suppressedFieldNames                             */
+  /* Type of each list entry: char *                                         */
+  /***************************************************************************/
+  DLIST suppressed_field_names;
+
+  /***************************************************************************/
+  /* List of name-value pairs to be suppressed.                              */
+  /* JSON equivalent field: suppressedNvPairsList                            */
+  /* Type of each list entry: EVEL_SUPPRESSED_NV_PAIRS *                     */
+  /***************************************************************************/
+  DLIST suppressed_nv_pairs_list;
+
+  /***************************************************************************/
+  /* Hash table containing suppressed_nv_pair_names as keys.                 */
+  /***************************************************************************/
+  struct hsearch_data * hash_field_names;
+
+  /***************************************************************************/
+  /* Hash table containing nv_pair_field_name as keys, and                   */
+  /* suppressed_nv_pairs_list as values.                                     */
+  /***************************************************************************/
+  struct hsearch_data * hash_nv_pairs_list;
+
+} EVEL_THROTTLE_SPEC;
+
+/*****************************************************************************/
+/* RFC2822 format string for strftime.                                       */
+/*****************************************************************************/
+#define EVEL_RFC2822_STRFTIME_FORMAT "%a, %d %b %Y %T %z"
+
+/*****************************************************************************/
+/* EVEL_JSON_BUFFER depth at which we throttle fields.                       */
+/*****************************************************************************/
+#define EVEL_THROTTLE_FIELD_DEPTH 3
+
+/**************************************************************************//**
+ * Initialize the event handler.
+ *
+ * Primarily responsible for getting cURL ready for use.
+ *
+ * @param[in] event_api_url
+ *                      The URL where the Vendor Event Listener API is expected
+ *                      to be.
+ * @param[in] throt_api_url
+ *                      The URL where the Throttling API is expected to be.
+ * @param[in] username  The username for the Basic Authentication of requests.
+ * @param[in] password  The password for the Basic Authentication of requests.
+ * @param     verbosity 0 for normal operation, positive values for chattier
+ *                        logs.
+ *****************************************************************************/
+EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url,
+                                        const char * const throt_api_url,
+                                        const char * const username,
+                                        const char * const password,
+                                        int verbosity);
+
+/**************************************************************************//**
+ * Terminate the event handler.
+ *
+ * Shuts down the event handler thread in as clean a way as possible. Sets the
+ * global exit flag and then signals the thread to interrupt it since it's
+ * most likely waiting on the ring-buffer.
+ *
+ * Having achieved an orderly shutdown of the event handler thread, clean up
+ * the cURL library's resources cleanly.
+ *
+ *  @return Status code.
+ *  @retval ::EVEL_SUCCESS if everything OK.
+ *  @retval One of ::EVEL_ERR_CODES if there was a problem.
+ *****************************************************************************/
+EVEL_ERR_CODES event_handler_terminate();
+
+/**************************************************************************//**
+ * Run the event handler.
+ *
+ * Spawns the thread responsible for handling events and sending them to the
+ * API.
+ *
+ *  @return Status code.
+ *  @retval ::EVEL_SUCCESS if everything OK.
+ *  @retval One of ::EVEL_ERR_CODES if there was a problem.
+ *****************************************************************************/
+EVEL_ERR_CODES event_handler_run();
+
+/**************************************************************************//**
+ * Create a new internal event.
+ *
+ * @note    The mandatory fields on the Fault must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Fault has immutable properties.
+ * @param   command   The condition indicated by the event.
+ * @returns pointer to the newly manufactured ::EVENT_INTERNAL.  If the event
+ *          is not used (i.e. posted) it must be released using
+ *          ::evel_free_event.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_INTERNAL * evel_new_internal_event(EVT_HANDLER_COMMAND command,const char* ev_name, const char *ev_id);
+
+/**************************************************************************//**
+ * Free an internal event.
+ *
+ * Free off the event supplied.  Will free all the contained* allocated memory.
+ *
+ * @note It does not free the internal event itself, since that may be part of
+ * a larger structure.
+ *****************************************************************************/
+void evel_free_internal_event(EVENT_INTERNAL * event);
+
+/*****************************************************************************/
+/* Structure to hold JSON buffer and associated tracking, as it is written.  */
+/*****************************************************************************/
+typedef struct evel_json_buffer
+{
+  char * json;
+  int offset;
+  int max_size;
+
+  /***************************************************************************/
+  /* The working throttle specification, which can be NULL.                  */
+  /***************************************************************************/
+  EVEL_THROTTLE_SPEC * throttle_spec;
+
+  /***************************************************************************/
+  /* Current object/list nesting depth.                                      */
+  /***************************************************************************/
+  int depth;
+
+  /***************************************************************************/
+  /* The checkpoint.                                                         */
+  /***************************************************************************/
+  int checkpoint;
+
+} EVEL_JSON_BUFFER;
+
+/**************************************************************************//**
+ * Encode the event as a JSON event object according to AT&T's schema.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_header(EVEL_JSON_BUFFER * jbuf,
+                             EVENT_HEADER * event);
+
+/**************************************************************************//**
+ * Encode the fault in JSON according to AT&T's schema for the fault type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_fault(EVEL_JSON_BUFFER * jbuf,
+                            EVENT_FAULT * event);
+
+/**************************************************************************//**
+ * Encode the measurement as a JSON measurement.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_measurement(EVEL_JSON_BUFFER * jbuf,
+                                  EVENT_MEASUREMENT * event);
+
+/**************************************************************************//**
+ * Encode the Mobile Flow in JSON according to AT&T's schema for the event
+ * type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_mobile_flow(EVEL_JSON_BUFFER * jbuf,
+                                  EVENT_MOBILE_FLOW * event);
+
+/**************************************************************************//**
+ * Encode the report as a JSON report.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_report(EVEL_JSON_BUFFER * jbuf,
+                             EVENT_REPORT * event);
+
+/**************************************************************************//**
+ * Encode the Heartbeat fields in JSON according to AT&T's schema for the
+ * event type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_hrtbt_field(EVEL_JSON_BUFFER * const jbuf,
+                                EVENT_HEARTBEAT_FIELD * const event);
+
+/**************************************************************************//**
+ * Encode the Signaling in JSON according to AT&T's schema for the event type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_signaling(EVEL_JSON_BUFFER * const jbuf,
+                                EVENT_SIGNALING * const event);
+
+/**************************************************************************//**
+ * Encode the state change as a JSON state change.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param state_change  Pointer to the ::EVENT_STATE_CHANGE to encode.
+ *****************************************************************************/
+void evel_json_encode_state_change(EVEL_JSON_BUFFER * jbuf,
+                                   EVENT_STATE_CHANGE * state_change);
+
+/**************************************************************************//**
+ * Encode the Syslog in JSON according to AT&T's schema for the event type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_syslog(EVEL_JSON_BUFFER * jbuf,
+                             EVENT_SYSLOG * event);
+
+/**************************************************************************//**
+ * Encode the Other in JSON according to AT&T's schema for the event type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_other(EVEL_JSON_BUFFER * jbuf,
+                            EVENT_OTHER * event);
+
+/**************************************************************************//**
+ * Set the next event_sequence to use.
+ *
+ * @param sequence      The next sequence number to use.
+ *****************************************************************************/
+void evel_set_next_event_sequence(const int sequence);
+
+/**************************************************************************//**
+ * Handle a JSON response from the listener, contained in a ::MEMORY_CHUNK.
+ *
+ * Tokenize the response, and decode any tokens found.
+ *
+ * @param chunk         The memory chunk containing the response.
+ * @param post          The memory chunk in which to place any resulting POST.
+ *****************************************************************************/
+void evel_handle_event_response(const MEMORY_CHUNK * const chunk,
+                                MEMORY_CHUNK * const post);
+
+/**************************************************************************//**
+ * Initialize a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to initialise.
+ * @param json          Pointer to the underlying working buffer to use.
+ * @param max_size      Size of storage available in the JSON buffer.
+ * @param throttle_spec Pointer to throttle specification. Can be NULL.
+ *****************************************************************************/
+void evel_json_buffer_init(EVEL_JSON_BUFFER * jbuf,
+                           char * const json,
+                           const int max_size,
+                           EVEL_THROTTLE_SPEC * throttle_spec);
+
+/**************************************************************************//**
+ * Encode a string key and string value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param option        Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_string(EVEL_JSON_BUFFER * jbuf,
+                            const char * const key,
+                            const EVEL_OPTION_STRING * const option);
+
+/**************************************************************************//**
+ * Encode a string key and string value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param value         Pointer to the corresponding value to encode.
+ *****************************************************************************/
+void evel_enc_kv_string(EVEL_JSON_BUFFER * jbuf,
+                        const char * const key,
+                        const char * const value);
+
+/**************************************************************************//**
+ * Encode a string key and integer value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param option        Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_int(EVEL_JSON_BUFFER * jbuf,
+                         const char * const key,
+                         const EVEL_OPTION_INT * const option);
+
+/**************************************************************************//**
+ * Encode a string key and integer value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param value         The corresponding value to encode.
+ *****************************************************************************/
+void evel_enc_kv_int(EVEL_JSON_BUFFER * jbuf,
+                     const char * const key,
+                     const int value);
+
+/**************************************************************************//**
+ * Encode a string key and double value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param option        Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_double(EVEL_JSON_BUFFER * jbuf,
+                            const char * const key,
+                            const EVEL_OPTION_DOUBLE * const option);
+
+/**************************************************************************//**
+ * Encode a string key and double value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param value         The corresponding value to encode.
+ *****************************************************************************/
+void evel_enc_kv_double(EVEL_JSON_BUFFER * jbuf,
+                        const char * const key,
+                        const double value);
+
+/**************************************************************************//**
+ * Encode a string key and unsigned long long value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param option        Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_ull(EVEL_JSON_BUFFER * jbuf,
+                         const char * const key,
+                         const EVEL_OPTION_ULL * const option);
+
+/**************************************************************************//**
+ * Encode a string key and unsigned long long value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param value         The corresponding value to encode.
+ *****************************************************************************/
+void evel_enc_kv_ull(EVEL_JSON_BUFFER * jbuf,
+                     const char * const key,
+                     const unsigned long long value);
+
+/**************************************************************************//**
+ * Encode a string key and time value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param option        Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_time(EVEL_JSON_BUFFER * jbuf,
+                          const char * const key,
+                          const EVEL_OPTION_TIME * const option);
+
+/**************************************************************************//**
+ * Encode a string key and time value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param time          Pointer to the time to encode.
+ *****************************************************************************/
+void evel_enc_kv_time(EVEL_JSON_BUFFER * jbuf,
+                      const char * const key,
+                      const time_t * time);
+
+/**************************************************************************//**
+ * Encode a key and version.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param major_version The major version to encode.
+ * @param minor_version The minor version to encode.
+ *****************************************************************************/
+void evel_enc_version(EVEL_JSON_BUFFER * jbuf,
+                      const char * const key,
+                      const int major_version,
+                      const int minor_version);
+
+/**************************************************************************//**
+ * Add the key and opening bracket of an optional named list to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @return true if the list was opened, false if it was suppressed.
+ *****************************************************************************/
+bool evel_json_open_opt_named_list(EVEL_JSON_BUFFER * jbuf,
+                                   const char * const key);
+
+/**************************************************************************//**
+ * Add the key and opening bracket of a named list to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ *****************************************************************************/
+void evel_json_open_named_list(EVEL_JSON_BUFFER * jbuf,
+                               const char * const key);
+
+/**************************************************************************//**
+ * Add the closing bracket of a list to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_close_list(EVEL_JSON_BUFFER * jbuf);
+
+/**************************************************************************//**
+ * Encode a list item with format and param list to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param format        Format string in standard printf format.
+ * @param ...           Variable parameters for format string.
+ *****************************************************************************/
+void evel_enc_list_item(EVEL_JSON_BUFFER * jbuf,
+                        const char * const format,
+                        ...);
+
+/**************************************************************************//**
+ * Add the opening bracket of an optional named object to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ *****************************************************************************/
+bool evel_json_open_opt_named_object(EVEL_JSON_BUFFER * jbuf,
+                                     const char * const key);
+
+/**************************************************************************//**
+ * Add the opening bracket of an object to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @return true if the object was opened, false if it was suppressed.
+ *****************************************************************************/
+void evel_json_open_named_object(EVEL_JSON_BUFFER * jbuf,
+                                 const char * const key);
+
+/**************************************************************************//**
+ * Add the opening bracket of an object to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_open_object(EVEL_JSON_BUFFER * jbuf);
+
+/**************************************************************************//**
+ * Add the closing bracket of an object to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_close_object(EVEL_JSON_BUFFER * jbuf);
+
+/**************************************************************************//**
+ * Add a checkpoint - a stake in the ground to which we can rewind.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_checkpoint(EVEL_JSON_BUFFER * jbuf);
+
+/**************************************************************************//**
+ * Rewind to the latest checkoint.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_rewind(EVEL_JSON_BUFFER * jbuf);
+
+/**************************************************************************//**
+ * Free the underlying resources of an ::EVEL_OPTION_STRING.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_STRING.
+ *****************************************************************************/
+void evel_free_option_string(EVEL_OPTION_STRING * const option);
+
+/**************************************************************************//**
+ * Initialize an ::EVEL_OPTION_STRING to a not-set state.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_STRING.
+ *****************************************************************************/
+void evel_init_option_string(EVEL_OPTION_STRING * const option);
+
+/**************************************************************************//**
+ * Set the value of an ::EVEL_OPTION_STRING.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_STRING.
+ * @param value         The value to set.
+ * @param description   Description to be used in logging.
+ *****************************************************************************/
+void evel_set_option_string(EVEL_OPTION_STRING * const option,
+                            const char * const value,
+                            const char * const description);
+
+/**************************************************************************//**
+ * Force the value of an ::EVEL_OPTION_STRING.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_STRING.
+ * @param value         The value to set.
+ *****************************************************************************/
+void evel_force_option_string(EVEL_OPTION_STRING * const option,
+                              const char * const value);
+
+/**************************************************************************//**
+ * Initialize an ::EVEL_OPTION_INT to a not-set state.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INT.
+ *****************************************************************************/
+void evel_init_option_int(EVEL_OPTION_INT * const option);
+
+/**************************************************************************//**
+ * Force the value of an ::EVEL_OPTION_INT.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INT.
+ * @param value         The value to set.
+ *****************************************************************************/
+void evel_force_option_int(EVEL_OPTION_INT * const option,
+                           const int value);
+
+/**************************************************************************//**
+ * Set the value of an ::EVEL_OPTION_INT.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INT.
+ * @param value         The value to set.
+ * @param description   Description to be used in logging.
+ *****************************************************************************/
+void evel_set_option_int(EVEL_OPTION_INT * const option,
+                         const int value,
+                         const char * const description);
+
+/**************************************************************************//**
+ * Initialize an ::EVEL_OPTION_DOUBLE to a not-set state.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_DOUBLE.
+ *****************************************************************************/
+void evel_init_option_double(EVEL_OPTION_DOUBLE * const option);
+
+/**************************************************************************//**
+ * Force the value of an ::EVEL_OPTION_DOUBLE.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_DOUBLE.
+ * @param value         The value to set.
+ *****************************************************************************/
+void evel_force_option_double(EVEL_OPTION_DOUBLE * const option,
+                              const double value);
+
+/**************************************************************************//**
+ * Set the value of an ::EVEL_OPTION_DOUBLE.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_DOUBLE.
+ * @param value         The value to set.
+ * @param description   Description to be used in logging.
+ *****************************************************************************/
+void evel_set_option_double(EVEL_OPTION_DOUBLE * const option,
+                            const double value,
+                            const char * const description);
+
+/**************************************************************************//**
+ * Initialize an ::EVEL_OPTION_ULL to a not-set state.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_ULL.
+ *****************************************************************************/
+void evel_init_option_ull(EVEL_OPTION_ULL * const option);
+
+/**************************************************************************//**
+ * Force the value of an ::EVEL_OPTION_ULL.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_ULL.
+ * @param value         The value to set.
+ *****************************************************************************/
+void evel_force_option_ull(EVEL_OPTION_ULL * const option,
+                           const unsigned long long value);
+
+/**************************************************************************//**
+ * Set the value of an ::EVEL_OPTION_ULL.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_ULL.
+ * @param value         The value to set.
+ * @param description   Description to be used in logging.
+ *****************************************************************************/
+void evel_set_option_ull(EVEL_OPTION_ULL * const option,
+                         const unsigned long long value,
+                         const char * const description);
+
+/**************************************************************************//**
+ * Initialize an ::EVEL_OPTION_TIME to a not-set state.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_TIME.
+ *****************************************************************************/
+void evel_init_option_time(EVEL_OPTION_TIME * const option);
+
+/**************************************************************************//**
+ * Force the value of an ::EVEL_OPTION_TIME.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_TIME.
+ * @param value         The value to set.
+ *****************************************************************************/
+void evel_force_option_time(EVEL_OPTION_TIME * const option,
+                            const time_t value);
+
+/**************************************************************************//**
+ * Set the value of an ::EVEL_OPTION_TIME.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_TIME.
+ * @param value         The value to set.
+ * @param description   Description to be used in logging.
+ *****************************************************************************/
+void evel_set_option_time(EVEL_OPTION_TIME * const option,
+                          const time_t value,
+                          const char * const description);
+
+/**************************************************************************//**
+ * Map an ::EVEL_COUNTER_CRITICALITIES enum value to the equivalent string.
+ *
+ * @param criticality   The criticality to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_criticality(const EVEL_COUNTER_CRITICALITIES criticality);
+
+/**************************************************************************//**
+ * Map an ::EVEL_SEVERITIES enum value to the equivalent string.
+ *
+ * @param severity      The severity to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_severity(const EVEL_SEVERITIES severity);
+
+/**************************************************************************//**
+ * Map an ::EVEL_ALERT_ACTIONS enum value to the equivalent string.
+ *
+ * @param alert_action  The alert_action to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_alert_action(const EVEL_ALERT_ACTIONS alert_action);
+
+/**************************************************************************//**
+ * Map an ::EVEL_ALERT_TYPES enum value to the equivalent string.
+ *
+ * @param alert_type    The alert_type to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_alert_type(const EVEL_ALERT_TYPES alert_type);
+
+/**************************************************************************//**
+ * Map an ::EVEL_EVENT_DOMAINS enum value to the equivalent string.
+ *
+ * @param domain        The domain to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_event_domain(const EVEL_EVENT_DOMAINS domain);
+
+/**************************************************************************//**
+ * Map an ::EVEL_EVENT_PRIORITIES enum value to the equivalent string.
+ *
+ * @param priority      The priority to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_event_priority(const EVEL_EVENT_PRIORITIES priority);
+
+/**************************************************************************//**
+ * Map an ::EVEL_SOURCE_TYPES enum value to the equivalent string.
+ *
+ * @param source_type   The source type to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_source_type(const EVEL_SOURCE_TYPES source_type);
+
+/**************************************************************************//**
+ * Map an ::EVEL_VF_STATUSES enum value to the equivalent string.
+ *
+ * @param vf_status     The vf_status to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_vf_status(const EVEL_VF_STATUSES vf_status);
+
+/**************************************************************************//**
+ * Convert a ::EVEL_ENTITY_STATE to it's string form for JSON encoding.
+ *
+ * @param state         The entity state to encode.
+ *
+ * @returns the corresponding string
+ *****************************************************************************/
+char * evel_entity_state(const EVEL_ENTITY_STATE state);
+
+/**************************************************************************//**
+ * Convert a ::EVEL_SERVICE_ENDPOINT_DESC to string form for JSON encoding.
+ *
+ * @param endpoint_desc endpoint description to encode.
+ *
+ * @returns the corresponding string
+ *****************************************************************************/
+char * evel_service_endpoint_desc(const EVEL_ENTITY_STATE endpoint_desc);
+
+
+/**************************************************************************//**
+ * Initialize an ::EVEL_OPTION_INTHEADER_FIELDS to a not-set state.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INTHEADER_FIELDS.
+ *****************************************************************************/
+void evel_init_option_intheader(EVEL_OPTION_INTHEADER_FIELDS * const option);
+/**************************************************************************//**
+ * Force the value of an ::EVEL_OPTION_INTHEADER_FIELDS.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INTHEADER_FIELDS.
+ * @param value         The value to set.
+ *****************************************************************************/
+void evel_force_option_intheader(EVEL_OPTION_INTHEADER_FIELDS * const option,
+                           const void* value);
+/**************************************************************************//**
+ * Set the value of an ::EVEL_OPTION_INTHEADER_FIELDS.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INTHEADER_FIELDS.
+ * @param value         The value to set.
+ * @param description   Description to be used in logging.
+ *****************************************************************************/
+void evel_set_option_intheader(EVEL_OPTION_INTHEADER_FIELDS * const option,
+                         const void * value,
+                         const char * const description);
+/**************************************************************************//**
+ * Free the underlying resources of an ::EVEL_OPTION_INTHEADER_FIELDS.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INTHEADER_FIELDS.
+ *****************************************************************************/
+void evel_free_option_intheader(EVEL_OPTION_INTHEADER_FIELDS * const option);
+
+#endif
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal_event.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal_event.c
new file mode 100644 (file)
index 0000000..cb56c88
--- /dev/null
@@ -0,0 +1,113 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to the internal events.
+ *
+ * Internal events are never expected to be sent to the JSON API but comply
+ * with interfaces for regular event types.  The primary use-case is to enable
+ * the foreground processing to communicate with the background event handling
+ * processing in an orderly fashion.  At present the only use is to initiate an
+ * orderly shutdown of the Event Handler thread.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "evel.h"
+#include "evel_internal.h"
+
+
+/**************************************************************************//**
+ * Create a new internal event.
+ *
+ * @note    The mandatory fields on the Fault must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Fault has immutable properties.
+ * @param   command   The condition indicated by the event.
+ * @param event_name  Unique Event Name confirming Domain AsdcModel Description
+ * @param event_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
+ * @returns pointer to the newly manufactured ::EVENT_INTERNAL.  If the event
+ *          is not used (i.e. posted) it must be released using
+ *          ::evel_free_event.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_INTERNAL * evel_new_internal_event(EVT_HANDLER_COMMAND command,const char* ev_name, const char *ev_id)
+{
+  EVENT_INTERNAL * event = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(command < EVT_CMD_MAX_COMMANDS);
+
+  /***************************************************************************/
+  /* Allocate the fault.                                                     */
+  /***************************************************************************/
+  event = malloc(sizeof(EVENT_INTERNAL));
+  if (event == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(event, 0, sizeof(EVENT_INTERNAL));
+  EVEL_DEBUG("New internal event is at %lp", event);
+
+  /***************************************************************************/
+  /* Initialize the header & the event fields.                               */
+  /***************************************************************************/
+  evel_init_header_nameid(&event->header,ev_name,ev_id);
+  event->header.event_domain = EVEL_DOMAIN_INTERNAL;
+  event->command = command;
+
+exit_label:
+  EVEL_EXIT();
+  return event;
+}
+
+/**************************************************************************//**
+ * Free an internal event.
+ *
+ * Free off the event supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the internal event itself, since that may be part of
+ * a larger structure.
+ *****************************************************************************/
+void evel_free_internal_event(EVENT_INTERNAL * event)
+{
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+  /* events as we do on the public API.                                      */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_INTERNAL);
+
+  /***************************************************************************/
+  /* Free the header itself.                                                 */
+  /***************************************************************************/
+  evel_free_header(&event->header);
+
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_json_buffer.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_json_buffer.c
new file mode 100644 (file)
index 0000000..b6026e2
--- /dev/null
@@ -0,0 +1,870 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Source module relating to internal EVEL_JSON_BUFFER manipulation functions.
+ *
+ ****************************************************************************/
+
+#include <assert.h>
+#include <string.h>
+
+#include "evel_throttle.h"
+
+/*****************************************************************************/
+/* Local prototypes.                                                         */
+/*****************************************************************************/
+static char * evel_json_kv_comma(EVEL_JSON_BUFFER * jbuf);
+
+/**************************************************************************//**
+ * Initialize a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to initialise.
+ * @param json          Pointer to the underlying working buffer to use.
+ * @param max_size      Size of storage available in the JSON buffer.
+ * @param throttle_spec Pointer to throttle specification. Can be NULL.
+ *****************************************************************************/
+void evel_json_buffer_init(EVEL_JSON_BUFFER * jbuf,
+                           char * const json,
+                           const int max_size,
+                           EVEL_THROTTLE_SPEC * throttle_spec)
+{
+  EVEL_ENTER();
+
+  assert(jbuf != NULL);
+  assert(json != NULL);
+  jbuf->json = json;
+  jbuf->max_size = max_size;
+  jbuf->offset = 0;
+  jbuf->throttle_spec = throttle_spec;
+  jbuf->depth = 0;
+  jbuf->checkpoint = -1;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode an integer value to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param value         The integer to add to it.
+ *****************************************************************************/
+void evel_enc_int(EVEL_JSON_BUFFER * jbuf,
+                  const int value)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "%d", value);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a string key and string value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param option        Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_string(EVEL_JSON_BUFFER * jbuf,
+                            const char * const key,
+                            const EVEL_OPTION_STRING * const option)
+{
+  bool added = false;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  if (option->is_set)
+  {
+    if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+        (jbuf->throttle_spec != NULL) &&
+        evel_throttle_suppress_field(jbuf->throttle_spec, key))
+    {
+      EVEL_INFO("Suppressed: %s, %s", key, option->value);
+    }
+    else
+    {
+      EVEL_DEBUG("Encoded: %s, %s", key, option->value);
+      evel_enc_kv_string(jbuf, key, option->value);
+      added = true;
+    }
+  }
+
+  EVEL_EXIT();
+
+  return added;
+}
+
+/**************************************************************************//**
+ * Encode a string key and string value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param value         Pointer to the corresponding value to encode.
+ *****************************************************************************/
+void evel_enc_kv_string(EVEL_JSON_BUFFER * jbuf,
+                        const char * const key,
+                        const char * const value)
+{
+  int index;
+  int length;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(key != NULL);
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "%s\"%s\": \"",
+                           evel_json_kv_comma(jbuf),
+                           key);
+
+  /***************************************************************************/
+  /* We need to escape quotation marks and backslashes in the value.         */
+  /***************************************************************************/
+  length = strlen(value);
+
+  for (index = 0; index < length; index++)
+  {
+    /*************************************************************************/
+    /* Drop out if no more space.                                            */
+    /*************************************************************************/
+    if (jbuf->max_size - jbuf->offset < 2)
+    {
+      break;
+    }
+
+    /*************************************************************************/
+    /* Add an escape character if necessary, then write the character        */
+    /* itself.                                                               */
+    /*************************************************************************/
+    if ((value[index] == '\"') || (value[index] == '\\'))
+    {
+      jbuf->json[jbuf->offset] = '\\';
+      jbuf->offset++;
+    }
+
+    jbuf->json[jbuf->offset] = value[index];
+    jbuf->offset++;
+  }
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "\"");
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Encode a string key and integer value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param option        Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_int(EVEL_JSON_BUFFER * jbuf,
+                         const char * const key,
+                         const EVEL_OPTION_INT * const option)
+{
+  bool added = false;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  if (option->is_set)
+  {
+    if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+        (jbuf->throttle_spec != NULL) &&
+        evel_throttle_suppress_field(jbuf->throttle_spec, key))
+    {
+      EVEL_INFO("Suppressed: %s, %d", key, option->value);
+    }
+    else
+    {
+      EVEL_DEBUG("Encoded: %s, %d", key, option->value);
+      evel_enc_kv_int(jbuf, key, option->value);
+      added = true;
+    }
+  }
+
+  EVEL_EXIT();
+
+  return added;
+}
+
+/**************************************************************************//**
+ * Encode a string key and integer value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param value         The corresponding value to encode.
+ *****************************************************************************/
+void evel_enc_kv_int(EVEL_JSON_BUFFER * jbuf,
+                     const char * const key,
+                     const int value)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(key != NULL);
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "%s\"%s\": %d",
+                           evel_json_kv_comma(jbuf),
+                           key,
+                           value);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a string key and json object value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param value         The corresponding json string to encode.
+ *****************************************************************************/
+void evel_enc_kv_object(EVEL_JSON_BUFFER * jbuf,
+                     const char * const key,
+                     const char * value)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(key != NULL);
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "%s\"%s\": %s",
+                           evel_json_kv_comma(jbuf),
+                           key,
+                           value);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a string key and double value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param option        Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_double(EVEL_JSON_BUFFER * jbuf,
+                            const char * const key,
+                            const EVEL_OPTION_DOUBLE * const option)
+{
+  bool added = false;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  if (option->is_set)
+  {
+    if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+        (jbuf->throttle_spec != NULL) &&
+        evel_throttle_suppress_field(jbuf->throttle_spec, key))
+    {
+      EVEL_INFO("Suppressed: %s, %1f", key, option->value);
+    }
+    else
+    {
+      EVEL_DEBUG("Encoded: %s, %1f", key, option->value);
+      evel_enc_kv_double(jbuf, key, option->value);
+      added = true;
+    }
+  }
+
+  EVEL_EXIT();
+
+  return added;
+}
+
+/**************************************************************************//**
+ * Encode a string key and double value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param value         The corresponding value to encode.
+ *****************************************************************************/
+void evel_enc_kv_double(EVEL_JSON_BUFFER * jbuf,
+                        const char * const key,
+                        const double value)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(key != NULL);
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "%s\"%s\": %1f",
+                           evel_json_kv_comma(jbuf),
+                           key,
+                           value);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a string key and unsigned long long value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param option        Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_ull(EVEL_JSON_BUFFER * jbuf,
+                         const char * const key,
+                         const EVEL_OPTION_ULL * const option)
+{
+  bool added = false;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  if (option->is_set)
+  {
+    if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+        (jbuf->throttle_spec != NULL) &&
+        evel_throttle_suppress_field(jbuf->throttle_spec, key))
+    {
+      EVEL_INFO("Suppressed: %s, %1lu", key, option->value);
+    }
+    else
+    {
+      EVEL_DEBUG("Encoded: %s, %1lu", key, option->value);
+      evel_enc_kv_ull(jbuf, key, option->value);
+      added = true;
+    }
+  }
+
+  EVEL_EXIT();
+
+  return added;
+}
+
+/**************************************************************************//**
+ * Encode a string key and unsigned long long value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param value         The corresponding value to encode.
+ *****************************************************************************/
+void evel_enc_kv_ull(EVEL_JSON_BUFFER * jbuf,
+                     const char * const key,
+                     const unsigned long long value)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(key != NULL);
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "%s\"%s\": %llu",
+                           evel_json_kv_comma(jbuf),
+                           key,
+                           value);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a string key and time value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param option        Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_time(EVEL_JSON_BUFFER * jbuf,
+                          const char * const key,
+                          const EVEL_OPTION_TIME * const option)
+{
+  bool added = false;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  if (option->is_set)
+  {
+    if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+        (jbuf->throttle_spec != NULL) &&
+        evel_throttle_suppress_field(jbuf->throttle_spec, key))
+    {
+      EVEL_INFO("Suppressed time: %s", key);
+    }
+    else
+    {
+      EVEL_DEBUG("Encoded time: %s", key);
+      evel_enc_kv_time(jbuf, key, &option->value);
+      added = true;
+    }
+  }
+
+  EVEL_EXIT();
+
+  return added;
+}
+
+/**************************************************************************//**
+ * Encode a string key and time value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param time          Pointer to the time to encode.
+ *****************************************************************************/
+void evel_enc_kv_time(EVEL_JSON_BUFFER * jbuf,
+                      const char * const key,
+                      const time_t * time)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(key != NULL);
+  assert(time != NULL);
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "%s\"%s\": \"",
+                           evel_json_kv_comma(jbuf),
+                           key);
+  jbuf->offset += strftime(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           EVEL_RFC2822_STRFTIME_FORMAT,
+                           localtime(time));
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "\"");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a key and version.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @param major_version The major version to encode.
+ * @param minor_version The minor version to encode.
+ *****************************************************************************/
+void evel_enc_version(EVEL_JSON_BUFFER * jbuf,
+                      const char * const key,
+                      const int major_version,
+                      const int minor_version)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(key != NULL);
+
+  evel_enc_kv_int(jbuf, key, major_version);
+  if (minor_version != 0)
+  {
+    jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                             jbuf->max_size - jbuf->offset,
+                             ".%d",
+                             minor_version);
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add the key and opening bracket of an optional named list to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @return true if the list was opened, false if it was suppressed.
+ *****************************************************************************/
+bool evel_json_open_opt_named_list(EVEL_JSON_BUFFER * jbuf,
+                                   const char * const key)
+{
+  bool opened = false;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(key != NULL);
+
+  if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+      (jbuf->throttle_spec != NULL) &&
+      evel_throttle_suppress_field(jbuf->throttle_spec, key))
+  {
+    EVEL_INFO("Suppressed: %s", key);
+    opened = false;
+  }
+  else
+  {
+    evel_json_open_named_list(jbuf, key);
+    opened = true;
+  }
+
+  EVEL_EXIT();
+
+  return opened;
+}
+
+/**************************************************************************//**
+ * Add the key and opening bracket of a named list to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ *****************************************************************************/
+void evel_json_open_named_list(EVEL_JSON_BUFFER * jbuf,
+                               const char * const key)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(key != NULL);
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "%s\"%s\": [",
+                           evel_json_kv_comma(jbuf),
+                           key);
+  jbuf->depth++;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add the closing bracket of a list to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_close_list(EVEL_JSON_BUFFER * jbuf)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "]");
+  jbuf->depth--;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a list item with format and param list to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param format        Format string in standard printf format.
+ * @param ...           Variable parameters for format string.
+ *****************************************************************************/
+void evel_enc_list_item(EVEL_JSON_BUFFER * jbuf,
+                        const char * const format,
+                        ...)
+{
+  va_list largs;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(format != NULL);
+
+  /***************************************************************************/
+  /* Add a comma unless we're at the start of the list.                      */
+  /***************************************************************************/
+  if (jbuf->json[jbuf->offset - 1] != '[')
+  {
+    jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                             jbuf->max_size - jbuf->offset,
+                             ", ");
+  }
+
+  va_start(largs, format);
+  jbuf->offset += vsnprintf(jbuf->json + jbuf->offset,
+                            jbuf->max_size - jbuf->offset,
+                            format,
+                            largs);
+  va_end(largs);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add the opening bracket of an optional named object to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ *****************************************************************************/
+bool evel_json_open_opt_named_object(EVEL_JSON_BUFFER * jbuf,
+                                     const char * const key)
+{
+  bool opened = false;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(key != NULL);
+
+  if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+      (jbuf->throttle_spec != NULL) &&
+      evel_throttle_suppress_field(jbuf->throttle_spec, key))
+  {
+    EVEL_INFO("Suppressed: %s", key);
+    opened = false;
+  }
+  else
+  {
+    evel_json_open_named_object(jbuf, key);
+    opened = true;
+  }
+
+  EVEL_EXIT();
+
+  return opened;
+}
+
+/**************************************************************************//**
+ * Add the opening bracket of an object to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key           Pointer to the key to encode.
+ * @return true if the object was opened, false if it was suppressed.
+ *****************************************************************************/
+void evel_json_open_named_object(EVEL_JSON_BUFFER * jbuf,
+                                 const char * const key)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(key != NULL);
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "%s\"%s\": {",
+                           evel_json_kv_comma(jbuf),
+                           key);
+  jbuf->depth++;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add the opening bracket of an object to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_open_object(EVEL_JSON_BUFFER * jbuf)
+{
+  char * comma;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+
+  if ((jbuf->offset != 0) && (jbuf->json[jbuf->offset-1] == '}'))
+  {
+    comma = ", ";
+  }
+  else
+  {
+    comma = "";
+  }
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "%s{",
+                           comma);
+  jbuf->depth++;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add the closing bracket of an object to a JSON buffer.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_close_object(EVEL_JSON_BUFFER * jbuf)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+
+  jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+                           jbuf->max_size - jbuf->offset,
+                           "}");
+  jbuf->depth--;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Determine whether to add a comma when adding a key-value pair.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @returns A string containing the comma if it is required.
+ *****************************************************************************/
+char * evel_json_kv_comma(EVEL_JSON_BUFFER * jbuf)
+{
+  char * result;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+
+  if ((jbuf->offset == 0) ||
+      (jbuf->json[jbuf->offset-1] == '{') ||
+      (jbuf->json[jbuf->offset-1] == '['))
+  {
+    result = "";
+  }
+  else
+  {
+    result = ", ";
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Add a checkpoint - a stake in the ground to which we can rewind.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_checkpoint(EVEL_JSON_BUFFER * jbuf)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+
+  /***************************************************************************/
+  /* Store the current offset.                                               */
+  /***************************************************************************/
+  jbuf->checkpoint = jbuf->offset;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Rewind to the latest checkoint.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_rewind(EVEL_JSON_BUFFER * jbuf)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(jbuf->checkpoint >= 0);
+  assert(jbuf->checkpoint <= jbuf->offset);
+
+  /***************************************************************************/
+  /* Reinstate the offset from the last checkpoint.                          */
+  /***************************************************************************/
+  jbuf->offset = jbuf->checkpoint;
+  jbuf->checkpoint = -1;
+
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_jsonobject.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_jsonobject.c
new file mode 100644 (file)
index 0000000..caf1a1e
--- /dev/null
@@ -0,0 +1,446 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to json_object.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "jsmn.h"
+#include "evel.h"
+#include "evel_internal.h"
+
+/**************************************************************************//**
+ * Create a new json object.
+ *
+ * @note    The mandatory fields on the Other must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Other has immutable properties.
+ * @param name       name of the object.
+ * @returns pointer to the newly manufactured ::EVEL_JSON_OBJECT.
+ *          not used (i.e. posted) it must be released using ::evel_free_jsonobject.
+ * @retval  NULL  Failed to create the json object.
+ *****************************************************************************/
+EVEL_JSON_OBJECT * evel_new_jsonobject(const char *const name)
+{
+  EVEL_JSON_OBJECT *jobj = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(name != NULL);
+
+  /***************************************************************************/
+  /* Allocate the json object.                                                     */
+  /***************************************************************************/
+  jobj = malloc(sizeof(EVEL_JSON_OBJECT));
+  if (jobj == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(jobj, 0, sizeof(EVEL_JSON_OBJECT));
+  EVEL_DEBUG("New json object is at %lp", jobj);
+
+  /***************************************************************************/
+  /* Initialize the fields.  Optional string values are   */
+  /* uninitialized (NULL).                                                   */
+  /***************************************************************************/
+  jobj->object_name = strdup(name);
+  evel_init_option_string(&jobj->objectschema);
+  evel_init_option_string(&jobj->objectschemaurl);
+  evel_init_option_string(&jobj->nfsubscribedobjname);
+  evel_init_option_string(&jobj->nfsubscriptionid);
+  dlist_initialize(&jobj->jsonobjectinstances);
+
+exit_label:
+  EVEL_EXIT();
+  return jobj;
+}
+
+
+/**************************************************************************//**
+ * Create a new json object instance.
+ *
+ * @note    The mandatory fields on the Other must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Other has immutable properties.
+ * @param   yourjson       json string.
+ * @returns pointer to the newly manufactured ::EVEL_JSON_OBJECT_INSTANCE.
+ *          not used (i.e. posted) it must be released using ::evel_free_jsonobjectinstance.
+ * @retval  NULL  Failed to create the json object instance.
+ *****************************************************************************/
+EVEL_JSON_OBJECT_INSTANCE * evel_new_jsonobjinstance(const char *const yourjson)
+{
+  EVEL_JSON_OBJECT_INSTANCE *jobjinst = NULL;
+  jsmntok_t *key;
+  int resultCode;
+  jsmn_parser p;
+  jsmntok_t tokens[MAX_JSON_TOKENS]; // a number >= total number of tokens
+  int len=0;
+
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(yourjson != NULL);
+  len = strlen(yourjson)+1;
+  assert(len > 0);
+
+  /***************************************************************************/
+  /*  Validate JSON for json object
+  /***************************************************************************/
+  jsmn_init(&p);
+  resultCode = jsmn_parse(&p, yourjson, len, tokens, sizeof(tokens)/sizeof(tokens[0]));
+  if( resultCode < 0 ){
+    log_error_state("Failed to parse json for object");
+    goto exit_label;
+  }
+
+  if (resultCode < 1 || tokens[0].type != JSMN_OBJECT) {
+    log_error_state("Error json object expected");
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Allocate the json object.                                                     */
+  /***************************************************************************/
+  jobjinst = malloc(sizeof(EVEL_JSON_OBJECT_INSTANCE));
+  if (jobjinst == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(jobjinst, 0, sizeof(EVEL_JSON_OBJECT_INSTANCE));
+
+  /***************************************************************************/
+  /* Initialize the fields.  Optional key values are   */
+  /* uninitialized (NULL).                                                   */
+  /***************************************************************************/
+  jobjinst->jsonstring = strdup(yourjson);
+  dlist_initialize(&jobjinst->object_keys);
+
+exit_label:
+  EVEL_EXIT();
+  return jobjinst;
+}
+
+
+/**************************************************************************//**
+ * Create a new internal key.
+ *
+ * @note    The mandatory fields on the Other must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Other has immutable properties.
+ * @param   keyname       name of the key.
+ * @returns pointer to the newly manufactured ::EVEL_INTERNAL_KEY.
+ *          not used (i.e. posted) it must be released using ::evel_free_internal_key.
+ * @retval  NULL  Failed to create the internal key.
+ *****************************************************************************/
+EVEL_INTERNAL_KEY * evel_new_internal_key(char *keyname)
+{
+  EVEL_INTERNAL_KEY *keyinst = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(keyname != NULL);
+
+  /***************************************************************************/
+  /* Allocate the key object.                                                     */
+  /***************************************************************************/
+  keyinst = malloc(sizeof(EVEL_INTERNAL_KEY));
+  if (keyinst == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(keyinst, 0, sizeof(EVEL_INTERNAL_KEY));
+  keyinst->keyname = strdup(keyname);
+
+  /***************************************************************************/
+  /* Optional string values are  uninitialized (NULL).  */
+  /***************************************************************************/
+  evel_init_option_int(&keyinst->keyorder);
+  evel_init_option_string(&keyinst->keyvalue);
+
+exit_label:
+  EVEL_EXIT();
+  return keyinst;
+}
+
+/**************************************************************************//**
+ * Set the keyorder  of the internal key instance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param int keyorder
+ *****************************************************************************/
+void evel_internal_key_keyorder_set(EVEL_INTERNAL_KEY * pinst, const int keyorder)
+{
+  assert (pinst != NULL);
+  evel_set_option_int(&pinst->keyorder,keyorder,"Key order");
+}
+
+/**************************************************************************//**
+ * Set the keyvalue  of the internal key instance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param string keyvalue
+ *****************************************************************************/
+void evel_internal_key_keyvalue_set(EVEL_INTERNAL_KEY * pinst, const char * const keyval)
+{
+  assert (pinst != NULL);
+  evel_set_option_string(&pinst->keyvalue,keyval,"Key Value");
+}
+
+/**************************************************************************//**
+ * Set the string values of json object
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param string object schema
+ *****************************************************************************/
+void evel_jsonobject_objectschema_set(EVEL_JSON_OBJECT * pinst, const char * const objectschema)
+{
+  assert (pinst != NULL);
+  evel_set_option_string(&pinst->objectschema,objectschema,"Object Schema");
+}
+
+/**************************************************************************//**
+ * Set the string values of json object
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param string object schema url
+ *****************************************************************************/
+void evel_jsonobject_objectschemaurl_set(EVEL_JSON_OBJECT * pinst, const char * const objectschemaurl)
+{
+  assert (pinst != NULL);
+  evel_set_option_string(&pinst->objectschemaurl,objectschemaurl,"Object Schema URL");
+}
+
+/**************************************************************************//**
+ * Set the string values of json object
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param string  NF Subscribed object name
+ *****************************************************************************/
+void evel_jsonobject_nfsubscribedobjname_set(EVEL_JSON_OBJECT * pinst, const char * const nfsubscribedobjname)
+{
+  assert (pinst != NULL);
+  evel_set_option_string(&pinst->nfsubscribedobjname,nfsubscribedobjname,"NF Subscribed Object Name");
+}
+
+/**************************************************************************//**
+ * Set the string values of json object
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param string  NF Subscription Id
+ *****************************************************************************/
+void evel_jsonobject_nfsubscriptionid_set(EVEL_JSON_OBJECT * pinst, const char * const nfsubscriptionid)
+{
+  assert (pinst != NULL);
+  evel_set_option_string(&pinst->nfsubscriptionid,nfsubscriptionid,"NF Subscription Id");
+}
+
+/**************************************************************************//**
+ * Set the Epoch time of the json object instance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param unsigned long long epoch time
+ *****************************************************************************/
+void evel_epoch_microsec_set(EVEL_JSON_OBJECT_INSTANCE * pinst, const unsigned long long epmicrosec)
+{
+  assert(epmicrosec != 0 );
+  pinst->objinst_epoch_microsec = epmicrosec;
+}
+
+/**************************************************************************//**
+ * Add a json object instance to jsonObject list.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param pobj         Pointer to the Other.
+ * @param jinst        Pointer to HashTable
+ *****************************************************************************/
+void evel_jsonobject_add_jsoninstance(EVEL_JSON_OBJECT * pobj, EVEL_JSON_OBJECT_INSTANCE *jinst)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(pobj != NULL);
+  assert(jinst != NULL);
+
+  EVEL_DEBUG("Adding json object instance");
+
+  dlist_push_last(&pobj->jsonobjectinstances, jinst);
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Add a json object to jsonObject list.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param other     Pointer to the Other.
+ * @param jsonobj   Pointer to json object
+ *****************************************************************************/
+void evel_jsonobjinst_add_objectkey(EVEL_JSON_OBJECT_INSTANCE * jsoninst, EVEL_INTERNAL_KEY *keyp)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jsoninst != NULL);
+  assert(keyp != NULL);
+
+  EVEL_DEBUG("Adding jsonObject instance");
+
+  dlist_push_last(&jsoninst->object_keys, keyp);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free an internal key.
+ *
+ * Free off the internal key supplied.  Will free all the contained allocated memory.
+ *
+ *****************************************************************************/
+void evel_free_internal_key(EVEL_INTERNAL_KEY * keyp)
+{
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+  /* events as we do on the public API.                                      */
+  /***************************************************************************/
+  assert(keyp != NULL);
+
+  free(keyp->keyname);
+  evel_free_option_string(&keyp->keyvalue);
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Free an json object instance.
+ *
+ * Free off the json object instance supplied.
+ *  Will free all the contained allocated memory.
+ *
+ *****************************************************************************/
+void evel_free_jsonobjinst(EVEL_JSON_OBJECT_INSTANCE * objinst)
+{
+  EVEL_INTERNAL_KEY *other_field = NULL;
+
+  EVEL_ENTER();
+  assert(objinst != NULL);
+  assert(objinst->jsonstring != NULL);
+
+  free(objinst->jsonstring);
+
+  /***************************************************************************/
+  /* Free all internal internal keys
+  /***************************************************************************/
+  other_field = dlist_pop_last(&objinst->object_keys);
+  while (other_field != NULL)
+  {
+    EVEL_DEBUG("Freeing Object Instance Field (%s)",
+               other_field->keyname);
+    evel_free_internal_key(other_field);
+    other_field = dlist_pop_last(&objinst->object_keys);
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free an json object.
+ *
+ * Free off the json object instance supplied.
+ *  Will free all the contained allocated memory.
+ *
+ *****************************************************************************/
+void evel_free_jsonobject(EVEL_JSON_OBJECT * jsobj)
+{
+  EVEL_JSON_OBJECT_INSTANCE *other_field = NULL;
+
+  EVEL_ENTER();
+  assert(jsobj != NULL);
+
+  free(jsobj->object_name);
+  evel_free_option_string(&jsobj->objectschema);
+  evel_free_option_string(&jsobj->objectschemaurl);
+  evel_free_option_string(&jsobj->nfsubscribedobjname);
+  evel_free_option_string(&jsobj->nfsubscriptionid);
+
+  /***************************************************************************/
+  /* Free all internal strings then the header itself.                       */
+  /***************************************************************************/
+  other_field = dlist_pop_last(&jsobj->jsonobjectinstances);
+  while (other_field != NULL)
+  {
+    EVEL_DEBUG("Freeing Object Instance Field (%s)",
+               other_field->jsonstring);
+    evel_free_jsonobjinst(other_field);
+    other_field = dlist_pop_last(&jsobj->jsonobjectinstances);
+  }
+
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_logging.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_logging.c
new file mode 100644 (file)
index 0000000..5a44f07
--- /dev/null
@@ -0,0 +1,167 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * Wrapper for event logging built on syslog.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <syslog.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include <curl/curl.h>
+
+#include "evel.h"
+
+
+/*****************************************************************************/
+/* Debug settings.  Logging is done through macros so these need to be       */
+/* externally visible.                                                       */
+/*****************************************************************************/
+EVEL_LOG_LEVELS debug_level = EVEL_LOG_DEBUG;
+//static char *syslog_ident = "evel";
+int debug_indent = 0;
+
+/*****************************************************************************/
+/* Buffers for error strings from this library.                              */
+/*****************************************************************************/
+static char evel_err_string[EVEL_MAX_ERROR_STRING_LEN] = "<NULL>";
+
+
+/**************************************************************************//**
+ * Initialize logging
+ *
+ * @param[in] level  The debugging level - one of ::EVEL_LOG_LEVELS.
+ * @param[in] ident  The identifier for our logs.
+ *****************************************************************************/
+void log_initialize(EVEL_LOG_LEVELS level, const char * ident)
+{
+  assert(level < EVEL_LOG_MAX);
+  assert(ident != NULL);
+
+  debug_level = level;
+  openlog(ident, LOG_PID, LOG_USER);
+}
+
+/**************************************************************************//**
+ * Descriptive text for library errors.
+ *
+ * Return a text error string that relates to the last failure.  May be
+ * "<null>" but will never be NULL.
+ *
+ * @returns   Text error string.
+ *
+ * @note      Must not be freed!
+ *****************************************************************************/
+const char * evel_error_string(void)
+{
+  return(evel_err_string);
+}
+
+/***************************************************************************//*
+ * Store the formatted string into the static error string and log the error.
+ *
+ * @param format  Error string in standard printf format.
+ * @param ...     Variable parameters to be substituted into the format string.
+ *****************************************************************************/
+void log_error_state(char * format, ...)
+{
+  va_list largs;
+
+  assert(format != NULL);
+  va_start(largs, format);
+  vsnprintf(evel_err_string, EVEL_MAX_ERROR_STRING_LEN, format, largs);
+  va_end(largs);
+  EVEL_ERROR("%s", evel_err_string);
+}
+
+
+/**************************************************************************//**
+ *  Generate a debug log.
+ *
+ *  Provides an interface to syslog with formatting of the nesting level
+ *  so that it's easier to see function entry/exit.
+ *
+ *  @param[in]  level   The debug level - see ::EVEL_LOG_LEVELS.
+ *  @param[in]  format  The output formatting in printf style.
+ *  @param[in]  ...     Variable arguments as specified in the format string.
+ *****************************************************************************/
+void log_debug(EVEL_LOG_LEVELS level, char * format, ...)
+{
+  va_list largs;
+  int priority;
+  char indent_fmt[1024];
+  char *syslog_fmt = NULL;
+
+  /***************************************************************************/
+  /* Test assumptions.                                                       */
+  /***************************************************************************/
+  assert(format != NULL);
+  assert(level <= EVEL_LOG_MAX);
+
+  if (level >= debug_level)
+  {
+    if ((debug_level == EVEL_LOG_INFO) || (debug_indent == 0))
+    {
+      /***********************************************************************/
+      /* Just use the format as is.                                          */
+      /***********************************************************************/
+      syslog_fmt = format;
+    }
+    else
+    {
+      /***********************************************************************/
+      /* Combine the format with a preceding number of indent markers.       */
+      /***********************************************************************/
+      sprintf(indent_fmt, "%.*s%s",
+              debug_indent,
+              INDENT_SEPARATORS,
+              format);
+      syslog_fmt = indent_fmt;
+    }
+
+    /*************************************************************************/
+    /* Work out the syslog priority value.                                   */
+    /*************************************************************************/
+    switch (level)
+    {
+    case EVEL_LOG_ERROR:
+      priority = LOG_ERR;
+      break;
+
+    case EVEL_LOG_INFO:
+      priority = LOG_INFO;
+      break;
+
+    case EVEL_LOG_DEBUG:
+    case EVEL_LOG_SPAMMY:
+    default:
+      priority = LOG_DEBUG;
+      break;
+    }
+
+    /*************************************************************************/
+    /* Write the log to the file next, which requires the var args list.     */
+    /*************************************************************************/
+    va_start(largs, format);
+    vsyslog(priority, syslog_fmt, largs);
+    va_end(largs);
+  }
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_mobile_flow.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_mobile_flow.c
new file mode 100644 (file)
index 0000000..5085d6a
--- /dev/null
@@ -0,0 +1,2122 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to the Mobile Flow.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "evel.h"
+#include "evel_internal.h"
+
+/*****************************************************************************/
+/* Array of strings to use when encoding TCP flags.                          */
+/*****************************************************************************/
+static char * evel_tcp_flag_strings[EVEL_MAX_TCP_FLAGS] = {
+  "NS",
+  "CWR",
+  "ECE",
+  "URG",
+  "ACK",
+  "PSH",
+  "RST",
+  "SYN",
+  "FIN"
+};
+
+/*****************************************************************************/
+/* Array of strings to use when encoding QCI COS.                            */
+/*****************************************************************************/
+static char * evel_qci_cos_strings[EVEL_MAX_QCI_COS_TYPES] = {
+  "conversational",
+  "streaming",
+  "interactive",
+  "background",
+  "1",
+  "2",
+  "3",
+  "4",
+  "65",
+  "66",
+  "5",
+  "6",
+  "7",
+  "8",
+  "9",
+  "69",
+  "70"
+};
+
+/*****************************************************************************/
+/* Local prototypes                                                          */
+/*****************************************************************************/
+void evel_json_encode_mobile_flow_gtp_flow_metrics(
+                                        EVEL_JSON_BUFFER * jbuf,
+                                        MOBILE_GTP_PER_FLOW_METRICS * metrics);
+
+/**************************************************************************//**
+ * Create a new Mobile Flow event.
+ *
+ * @note    The mandatory fields on the Mobile Flow must be supplied to this
+ *          factory function and are immutable once set.  Optional fields have
+ *          explicit setter functions, but again values may only be set once so
+ *          that the Mobile Flow has immutable properties.
+ * @param event_name  Unique Event Name confirming Domain AsdcModel Description
+ * @param event_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
+ * @param   flow_direction              Flow direction.
+ * @param   gtp_per_flow_metrics        GTP per-flow metrics.
+ * @param   ip_protocol_type            IP protocol type.
+ * @param   ip_version                  IP protocol version.
+ * @param   other_endpoint_ip_address   IP address of the other endpoint.
+ * @param   other_endpoint_port         IP port of the other endpoint.
+ * @param   reporting_endpoint_ip_addr  IP address of the reporting endpoint.
+ * @param   reporting_endpoint_port     IP port of the reporting endpoint.
+ * @returns pointer to the newly manufactured ::EVENT_MOBILE_FLOW.  If the
+ *          event is not used (i.e. posted) it must be released using
+ *          ::evel_free_mobile_flow.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_MOBILE_FLOW * evel_new_mobile_flow(const char* ev_name, const char *ev_id,
+                            const char * const flow_direction,
+                            MOBILE_GTP_PER_FLOW_METRICS * gtp_per_flow_metrics,
+                            const char * const ip_protocol_type,
+                            const char * const ip_version,
+                            const char * const other_endpoint_ip_address,
+                            int other_endpoint_port,
+                            const char * const reporting_endpoint_ip_addr,
+                            int reporting_endpoint_port)
+{
+  EVENT_MOBILE_FLOW * mobile_flow = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(flow_direction != NULL);
+  assert(gtp_per_flow_metrics != NULL);
+  assert(ip_protocol_type != NULL);
+  assert(ip_version != NULL);
+  assert(other_endpoint_ip_address != NULL);
+  assert(other_endpoint_port > 0);
+  assert(reporting_endpoint_ip_addr != NULL);
+  assert(reporting_endpoint_port > 0);
+
+  /***************************************************************************/
+  /* Allocate the Mobile Flow.                                               */
+  /***************************************************************************/
+  mobile_flow = malloc(sizeof(EVENT_MOBILE_FLOW));
+  if (mobile_flow == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(mobile_flow, 0, sizeof(EVENT_MOBILE_FLOW));
+  EVEL_DEBUG("New Mobile Flow is at %lp", mobile_flow);
+
+  /***************************************************************************/
+  /* Initialize the header & the Mobile Flow fields.  Optional string values */
+  /* are uninitialized (NULL).                                               */
+  /***************************************************************************/
+  evel_init_header_nameid(&mobile_flow->header,ev_name,ev_id);
+  mobile_flow->header.event_domain = EVEL_DOMAIN_MOBILE_FLOW;
+  mobile_flow->major_version = EVEL_MOBILE_FLOW_MAJOR_VERSION;
+  mobile_flow->minor_version = EVEL_MOBILE_FLOW_MINOR_VERSION;
+  mobile_flow->flow_direction = strdup(flow_direction);
+  mobile_flow->gtp_per_flow_metrics = gtp_per_flow_metrics;
+  mobile_flow->ip_protocol_type = strdup(ip_protocol_type);
+  mobile_flow->ip_version = strdup(ip_version);
+  mobile_flow->other_endpoint_ip_address = strdup(other_endpoint_ip_address);
+  mobile_flow->other_endpoint_port = other_endpoint_port;
+  mobile_flow->reporting_endpoint_ip_addr = strdup(reporting_endpoint_ip_addr);
+  mobile_flow->reporting_endpoint_port = reporting_endpoint_port;
+  evel_init_option_string(&mobile_flow->application_type);
+  evel_init_option_string(&mobile_flow->app_protocol_type);
+  evel_init_option_string(&mobile_flow->app_protocol_version);
+  evel_init_option_string(&mobile_flow->cid);
+  evel_init_option_string(&mobile_flow->connection_type);
+  evel_init_option_string(&mobile_flow->ecgi);
+  evel_init_option_string(&mobile_flow->gtp_protocol_type);
+  evel_init_option_string(&mobile_flow->gtp_version);
+  evel_init_option_string(&mobile_flow->http_header);
+  evel_init_option_string(&mobile_flow->imei);
+  evel_init_option_string(&mobile_flow->imsi);
+  evel_init_option_string(&mobile_flow->lac);
+  evel_init_option_string(&mobile_flow->mcc);
+  evel_init_option_string(&mobile_flow->mnc);
+  evel_init_option_string(&mobile_flow->msisdn);
+  evel_init_option_string(&mobile_flow->other_functional_role);
+  evel_init_option_string(&mobile_flow->rac);
+  evel_init_option_string(&mobile_flow->radio_access_technology);
+  evel_init_option_string(&mobile_flow->sac);
+  evel_init_option_int(&mobile_flow->sampling_algorithm);
+  evel_init_option_string(&mobile_flow->tac);
+  evel_init_option_string(&mobile_flow->tunnel_id);
+  evel_init_option_string(&mobile_flow->vlan_id);
+  dlist_initialize(&mobile_flow->additional_info);
+
+exit_label:
+  EVEL_EXIT();
+  return mobile_flow;
+}
+
+/**************************************************************************//**
+ * Add an additional value name/value pair to the Mobile flow.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param fault     Pointer to the Mobile flow.
+ * @param name      ASCIIZ string with the attribute's name.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ * @param value     ASCIIZ string with the attribute's value.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ *****************************************************************************/
+void evel_mobile_flow_addl_field_add(EVENT_MOBILE_FLOW * const event, char * name, char * value)
+{
+  OTHER_FIELD * nv_pair = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(name != NULL);
+  assert(value != NULL);
+
+  EVEL_DEBUG("Adding name=%s value=%s", name, value);
+  nv_pair = malloc(sizeof(OTHER_FIELD));
+  assert(nv_pair != NULL);
+  nv_pair->name = strdup(name);
+  nv_pair->value = strdup(value);
+  assert(nv_pair->name != NULL);
+  assert(nv_pair->value != NULL);
+
+  dlist_push_last(&event->additional_info, nv_pair);
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Set the Event Type property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param type        The Event Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_mobile_flow_type_set(EVENT_MOBILE_FLOW * mobile_flow,
+                               const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and call evel_header_type_set.                      */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  evel_header_type_set(&mobile_flow->header, type);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Application Type property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param type        The Application Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_mobile_flow_app_type_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                   const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(type != NULL);
+
+  evel_set_option_string(&mobile_flow->application_type,
+                         type,
+                         "Application Type");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Application Protocol Type property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param type        The Application Protocol Type to be set. ASCIIZ string.
+ *                    The caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_flow_app_prot_type_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                        const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(type != NULL);
+
+  evel_set_option_string(&mobile_flow->app_protocol_type,
+                         type,
+                         "Application Protocol Type");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Application Protocol Version property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param version     The Application Protocol Version to be set. ASCIIZ
+ *                    string.  The caller does not need to preserve the value
+ *                    once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_app_prot_ver_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                       const char * const version)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(version != NULL);
+
+  evel_set_option_string(&mobile_flow->app_protocol_version,
+                         version,
+                         "Application Protocol Version");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the CID property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param cid         The CID to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_cid_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const cid)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(cid != NULL);
+
+  evel_set_option_string(&mobile_flow->cid,
+                         cid,
+                         "CID");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Connection Type property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param type        The Connection Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_mobile_flow_con_type_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                   const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(type != NULL);
+
+  evel_set_option_string(&mobile_flow->connection_type,
+                         type,
+                         "Connection Type");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the ECGI property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param ecgi        The ECGI to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_ecgi_set(EVENT_MOBILE_FLOW * mobile_flow,
+                               const char * const ecgi)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(ecgi != NULL);
+
+  evel_set_option_string(&mobile_flow->ecgi,
+                         ecgi,
+                         "ECGI");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the GTP Protocol Type property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param type        The GTP Protocol Type to be set. ASCIIZ string.  The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_flow_gtp_prot_type_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                        const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(type != NULL);
+
+  evel_set_option_string(&mobile_flow->gtp_protocol_type,
+                         type,
+                         "GTP Protocol Type");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the GTP Protocol Version property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param version     The GTP Protocol Version to be set. ASCIIZ string.  The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_flow_gtp_prot_ver_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                       const char * const version)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(version != NULL);
+
+  evel_set_option_string(&mobile_flow->gtp_version,
+                         version,
+                         "GTP Protocol Version");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the HTTP Header property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param header      The HTTP header to be set. ASCIIZ string. The caller does
+ *                    not need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_http_header_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                      const char * const header)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(header != NULL);
+
+  evel_set_option_string(&mobile_flow->http_header,
+                         header,
+                         "HTTP Header");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the IMEI property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param imei        The IMEI to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_imei_set(EVENT_MOBILE_FLOW * mobile_flow,
+                               const char * const imei)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(imei != NULL);
+
+  evel_set_option_string(&mobile_flow->imei,
+                         imei,
+                         "IMEI");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the IMSI property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param imsi        The IMSI to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_imsi_set(EVENT_MOBILE_FLOW * mobile_flow,
+                               const char * const imsi)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(imsi != NULL);
+
+  evel_set_option_string(&mobile_flow->imsi,
+                         imsi,
+                         "IMSI");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the LAC property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param lac         The LAC to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_lac_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const lac)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(lac != NULL);
+
+  evel_set_option_string(&mobile_flow->lac,
+                         lac,
+                         "LAC");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the MCC property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param mcc         The MCC to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_mcc_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const mcc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(mcc != NULL);
+
+  evel_set_option_string(&mobile_flow->mcc,
+                         mcc,
+                         "MCC");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the MNC property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param mnc         The MNC to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_mnc_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const mnc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(mnc != NULL);
+
+  evel_set_option_string(&mobile_flow->mnc,
+                         mnc,
+                         "MNC");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the MSISDN property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param msisdn      The MSISDN to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_msisdn_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                 const char * const msisdn)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(msisdn != NULL);
+
+  evel_set_option_string(&mobile_flow->msisdn,
+                         msisdn,
+                         "MSISDN");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Other Functional Role property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param role        The Other Functional Role to be set. ASCIIZ string. The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_flow_other_func_role_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                          const char * const role)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(role != NULL);
+
+  evel_set_option_string(&mobile_flow->other_functional_role,
+                         role,
+                         "Other Functional Role");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the RAC property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param rac         The RAC to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_rac_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const rac)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(rac != NULL);
+
+  evel_set_option_string(&mobile_flow->rac,
+                         rac,
+                         "RAC");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Radio Access Technology property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param tech        The Radio Access Technology to be set. ASCIIZ string. The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_flow_radio_acc_tech_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                         const char * const tech)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(tech != NULL);
+
+  evel_set_option_string(&mobile_flow->radio_access_technology,
+                         tech,
+                         "Radio Access Technology");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the SAC property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param sac         The SAC to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_sac_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const sac)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(sac != NULL);
+
+  evel_set_option_string(&mobile_flow->sac,
+                         sac,
+                         "SAC");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Sampling Algorithm property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param algorithm   The Sampling Algorithm to be set.
+ *****************************************************************************/
+void evel_mobile_flow_samp_alg_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                   int algorithm)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(algorithm >= 0);
+
+  evel_set_option_int(&mobile_flow->sampling_algorithm,
+                      algorithm,
+                      "Sampling Algorithm");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the TAC property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param tac         The TAC to be set. ASCIIZ string.  The caller does not
+ *                    need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_tac_set(EVENT_MOBILE_FLOW * mobile_flow,
+                              const char * const tac)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(tac != NULL);
+
+  evel_set_option_string(&mobile_flow->tac,
+                         tac,
+                         "TAC");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Tunnel ID property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param tunnel_id   The Tunnel ID to be set. ASCIIZ string.  The caller does
+ *                    not need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_tunnel_id_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                    const char * const tunnel_id)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(tunnel_id != NULL);
+
+  evel_set_option_string(&mobile_flow->tunnel_id,
+                         tunnel_id,
+                         "Tunnel ID");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the VLAN ID property of the Mobile Flow.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mobile_flow Pointer to the Mobile Flow.
+ * @param vlan_id     The VLAN ID to be set. ASCIIZ string.  The caller does
+ *                    not need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_mobile_flow_vlan_id_set(EVENT_MOBILE_FLOW * mobile_flow,
+                                  const char * const vlan_id)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(mobile_flow != NULL);
+  assert(mobile_flow->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+  assert(vlan_id != NULL);
+
+  evel_set_option_string(&mobile_flow->vlan_id,
+                         vlan_id,
+                         "VLAN ID");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the Mobile Flow in JSON according to AT&T's schema for the event
+ * type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_mobile_flow(EVEL_JSON_BUFFER * jbuf,
+                                  EVENT_MOBILE_FLOW * event)
+{
+  OTHER_FIELD * nv_pair = NULL;
+  DLIST_ITEM * dlist_item = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+
+  evel_json_encode_header(jbuf, &event->header);
+  evel_json_open_named_object(jbuf, "mobileFlowFields");
+
+
+  /***************************************************************************/
+  /* Checkpoint, so that we can wind back if all fields are suppressed.      */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "additionalFields"))
+  {
+    bool added = false;
+
+    dlist_item = dlist_get_first(&event->additional_info);
+    while (dlist_item != NULL)
+    {
+      nv_pair = (OTHER_FIELD *) dlist_item->item;
+      assert(nv_pair != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "additionalFields",
+                                          nv_pair->name))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "name", nv_pair->name);
+        evel_enc_kv_string(jbuf, "value", nv_pair->value);
+        evel_json_close_object(jbuf);
+        added = true;
+      }
+      dlist_item = dlist_get_next(dlist_item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+
+  /***************************************************************************/
+  /* Mandatory parameters.                                                   */
+  /***************************************************************************/
+  evel_enc_kv_string(jbuf, "flowDirection", event->flow_direction);
+  evel_json_encode_mobile_flow_gtp_flow_metrics(
+    jbuf, event->gtp_per_flow_metrics);
+  evel_enc_kv_string(jbuf, "ipProtocolType", event->ip_protocol_type);
+  evel_enc_kv_string(jbuf, "ipVersion", event->ip_version);
+  evel_enc_kv_string(
+    jbuf, "otherEndpointIpAddress", event->other_endpoint_ip_address);
+  evel_enc_kv_int(jbuf, "otherEndpointPort", event->other_endpoint_port);
+  evel_enc_kv_string(
+    jbuf, "reportingEndpointIpAddr", event->reporting_endpoint_ip_addr);
+  evel_enc_kv_int(
+    jbuf, "reportingEndpointPort", event->reporting_endpoint_port);
+
+  /***************************************************************************/
+  /* Optional parameters.                                                    */
+  /***************************************************************************/
+  evel_enc_kv_opt_string(jbuf, "applicationType", &event->application_type);
+  evel_enc_kv_opt_string(jbuf, "appProtocolType", &event->app_protocol_type);
+  evel_enc_kv_opt_string(
+    jbuf, "appProtocolVersion", &event->app_protocol_version);
+  evel_enc_kv_opt_string(jbuf, "cid", &event->cid);
+  evel_enc_kv_opt_string(jbuf, "connectionType", &event->connection_type);
+  evel_enc_kv_opt_string(jbuf, "ecgi", &event->ecgi);
+  evel_enc_kv_opt_string(jbuf, "gtpProtocolType", &event->gtp_protocol_type);
+  evel_enc_kv_opt_string(jbuf, "gtpVersion", &event->gtp_version);
+  evel_enc_kv_opt_string(jbuf, "httpHeader", &event->http_header);
+  evel_enc_kv_opt_string(jbuf, "imei", &event->imei);
+  evel_enc_kv_opt_string(jbuf, "imsi", &event->imsi);
+  evel_enc_kv_opt_string(jbuf, "lac", &event->lac);
+  evel_enc_kv_opt_string(jbuf, "mcc", &event->mcc);
+  evel_enc_kv_opt_string(jbuf, "mnc", &event->mnc);
+  evel_enc_kv_opt_string(jbuf, "msisdn", &event->msisdn);
+  evel_enc_kv_opt_string(
+    jbuf, "otherFunctionalRole", &event->other_functional_role);
+  evel_enc_kv_opt_string(jbuf, "rac", &event->rac);
+  evel_enc_kv_opt_string(
+    jbuf, "radioAccessTechnology", &event->radio_access_technology);
+  evel_enc_kv_opt_string(jbuf, "sac", &event->sac);
+  evel_enc_kv_opt_int(jbuf, "samplingAlgorithm", &event->sampling_algorithm);
+  evel_enc_kv_opt_string(jbuf, "tac", &event->tac);
+  evel_enc_kv_opt_string(jbuf, "tunnelId", &event->tunnel_id);
+  evel_enc_kv_opt_string(jbuf, "vlanId", &event->vlan_id);
+  evel_enc_version(jbuf,
+                   "mobileFlowFieldsVersion",
+                   event->major_version,
+                   event->minor_version);
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free a Mobile Flow.
+ *
+ * Free off the Mobile Flow supplied.  Will free all the contained allocated
+ * memory.
+ *
+ * @note It does not free the Mobile Flow itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_mobile_flow(EVENT_MOBILE_FLOW * event)
+{
+  OTHER_FIELD * nv_pair = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+  /* events as we do on the public API.                                      */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_MOBILE_FLOW);
+
+  /***************************************************************************/
+  /* Free all internal strings then the header itself.                       */
+  /***************************************************************************/
+  free(event->flow_direction);
+
+  evel_free_mobile_gtp_flow_metrics(event->gtp_per_flow_metrics);
+  free(event->gtp_per_flow_metrics);
+  free(event->ip_protocol_type);
+  free(event->ip_version);
+  free(event->other_endpoint_ip_address);
+  free(event->reporting_endpoint_ip_addr);
+  evel_free_option_string(&event->application_type);
+  evel_free_option_string(&event->app_protocol_type);
+  evel_free_option_string(&event->app_protocol_version);
+  evel_free_option_string(&event->cid);
+  evel_free_option_string(&event->connection_type);
+  evel_free_option_string(&event->ecgi);
+  evel_free_option_string(&event->gtp_protocol_type);
+  evel_free_option_string(&event->gtp_version);
+  evel_free_option_string(&event->http_header);
+  evel_free_option_string(&event->imei);
+  evel_free_option_string(&event->imsi);
+  evel_free_option_string(&event->lac);
+  evel_free_option_string(&event->mcc);
+  evel_free_option_string(&event->mnc);
+  evel_free_option_string(&event->msisdn);
+  evel_free_option_string(&event->other_functional_role);
+  evel_free_option_string(&event->rac);
+  evel_free_option_string(&event->radio_access_technology);
+  evel_free_option_string(&event->sac);
+  evel_free_option_string(&event->tac);
+  evel_free_option_string(&event->tunnel_id);
+  evel_free_option_string(&event->vlan_id);
+
+  /***************************************************************************/
+  /* Free all internal strings then the header itself.                       */
+  /***************************************************************************/
+  nv_pair = dlist_pop_last(&event->additional_info);
+  while (nv_pair != NULL)
+  {
+    EVEL_DEBUG("Freeing Other Field (%s, %s)", nv_pair->name, nv_pair->value);
+    free(nv_pair->name);
+    free(nv_pair->value);
+    free(nv_pair);
+    nv_pair = dlist_pop_last(&event->additional_info);
+  }
+
+  evel_free_header(&event->header);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Create a new Mobile GTP Per Flow Metrics.
+ *
+ * @note    The mandatory fields on the Mobile GTP Per Flow Metrics must be
+ *          supplied to this factory function and are immutable once set.
+ *          Optional fields have explicit setter functions, but again values
+ *          may only be set once so that the Mobile GTP Per Flow Metrics has
+ *          immutable properties.
+ *
+ * @param   avg_bit_error_rate          Average bit error rate.
+ * @param   avg_packet_delay_variation  Average delay or jitter in ms.
+ * @param   avg_packet_latency          Average delivery latency.
+ * @param   avg_receive_throughput      Average receive throughput.
+ * @param   avg_transmit_throughput     Average transmit throughput.
+ * @param   flow_activation_epoch       Time the connection is activated.
+ * @param   flow_activation_microsec    Microseconds for the start of the flow
+ *                                      connection.
+ * @param   flow_deactivation_epoch     Time for the end of the connection.
+ * @param   flow_deactivation_microsec  Microseconds for the end of the flow
+ *                                      connection.
+ * @param   flow_deactivation_time      Transmission time of the first packet.
+ * @param   flow_status                 Connection status.
+ * @param   max_packet_delay_variation  Maximum packet delay or jitter in ms.
+ * @param   num_activation_failures     Number of failed activation requests.
+ * @param   num_bit_errors              Number of errored bits.
+ * @param   num_bytes_received          Number of bytes received.
+ * @param   num_bytes_transmitted       Number of bytes transmitted.
+ * @param   num_dropped_packets         Number of received packets dropped.
+ * @param   num_l7_bytes_received       Number of tunneled Layer 7 bytes
+ *                                      received.
+ * @param   num_l7_bytes_transmitted    Number of tunneled Layer 7 bytes
+ *                                      transmitted.
+ * @param   num_lost_packets            Number of lost packets.
+ * @param   num_out_of_order_packets    Number of out-of-order packets.
+ * @param   num_packet_errors           Number of errored packets.
+ * @param   num_packets_received_excl_retrans  Number of packets received,
+ *                                             excluding retransmits.
+ * @param   num_packets_received_incl_retrans  Number of packets received.
+ * @param   num_packets_transmitted_incl_retrans  Number of packets
+ *                                                transmitted.
+ * @param   num_retries                 Number of packet retries.
+ * @param   num_timeouts                Number of packet timeouts.
+ * @param   num_tunneled_l7_bytes_received  Number of tunneled Layer 7 bytes
+ *                                          received, excluding retransmits.
+ * @param   round_trip_time             Round trip time.
+ * @param   time_to_first_byte          Time in ms between connection
+ *                                      activation and first byte received.
+ *
+ * @returns pointer to the newly manufactured ::MOBILE_GTP_PER_FLOW_METRICS.
+ *          If the structure is not used it must be released using
+ *          ::evel_free_mobile_gtp_flow_metrics.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+MOBILE_GTP_PER_FLOW_METRICS * evel_new_mobile_gtp_flow_metrics(
+                                      double avg_bit_error_rate,
+                                      double avg_packet_delay_variation,
+                                      int avg_packet_latency,
+                                      int avg_receive_throughput,
+                                      int avg_transmit_throughput,
+                                      int flow_activation_epoch,
+                                      int flow_activation_microsec,
+                                      int flow_deactivation_epoch,
+                                      int flow_deactivation_microsec,
+                                      time_t flow_deactivation_time,
+                                      const char * const flow_status,
+                                      int max_packet_delay_variation,
+                                      int num_activation_failures,
+                                      int num_bit_errors,
+                                      int num_bytes_received,
+                                      int num_bytes_transmitted,
+                                      int num_dropped_packets,
+                                      int num_l7_bytes_received,
+                                      int num_l7_bytes_transmitted,
+                                      int num_lost_packets,
+                                      int num_out_of_order_packets,
+                                      int num_packet_errors,
+                                      int num_packets_received_excl_retrans,
+                                      int num_packets_received_incl_retrans,
+                                      int num_packets_transmitted_incl_retrans,
+                                      int num_retries,
+                                      int num_timeouts,
+                                      int num_tunneled_l7_bytes_received,
+                                      int round_trip_time,
+                                      int time_to_first_byte)
+{
+  MOBILE_GTP_PER_FLOW_METRICS * metrics = NULL;
+  int ii;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(avg_bit_error_rate >= 0.0);
+  assert(avg_packet_delay_variation >= 0.0);
+  assert(avg_packet_latency >= 0);
+  assert(avg_receive_throughput >= 0);
+  assert(avg_transmit_throughput >= 0);
+  assert(flow_activation_epoch > 0);
+  assert(flow_activation_microsec >= 0);
+  assert(flow_deactivation_epoch > 0);
+  assert(flow_deactivation_microsec >= 0);
+  assert(flow_status != NULL);
+  assert(max_packet_delay_variation >= 0);
+  assert(num_activation_failures >= 0);
+  assert(num_bit_errors >= 0);
+  assert(num_bytes_received >= 0);
+  assert(num_bytes_transmitted >= 0);
+  assert(num_dropped_packets >= 0);
+  assert(num_l7_bytes_received >= 0);
+  assert(num_l7_bytes_transmitted >= 0);
+  assert(num_lost_packets >= 0);
+  assert(num_out_of_order_packets >= 0);
+  assert(num_packet_errors >= 0);
+  assert(num_packets_received_excl_retrans >= 0);
+  assert(num_packets_received_incl_retrans >= 0);
+  assert(num_packets_transmitted_incl_retrans >= 0);
+  assert(num_retries >= 0);
+  assert(num_timeouts >= 0);
+  assert(num_tunneled_l7_bytes_received >= 0);
+  assert(round_trip_time >= 0);
+  assert(time_to_first_byte >= 0);
+
+  /***************************************************************************/
+  /* Allocate the Mobile Flow GTP Per Flow Metrics.                          */
+  /***************************************************************************/
+  metrics = malloc(sizeof(MOBILE_GTP_PER_FLOW_METRICS));
+  if (metrics == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(metrics, 0, sizeof(MOBILE_GTP_PER_FLOW_METRICS));
+  EVEL_DEBUG("New Mobile Flow GTP Per Flow Metrics is at %lp", metrics);
+
+  /***************************************************************************/
+  /* Initialize the Mobile Flow GTP Per Flow Metrics fields.  Optional       */
+  /* string values are uninitialized (NULL).                                 */
+  /***************************************************************************/
+  metrics->avg_bit_error_rate = avg_bit_error_rate;
+  metrics->avg_packet_delay_variation = avg_packet_delay_variation;
+  metrics->avg_packet_latency = avg_packet_latency;
+  metrics->avg_receive_throughput = avg_receive_throughput;
+  metrics->avg_transmit_throughput = avg_transmit_throughput;
+  metrics->flow_activation_epoch = flow_activation_epoch;
+  metrics->flow_activation_microsec = flow_activation_microsec;
+  metrics->flow_deactivation_epoch = flow_deactivation_epoch;
+  metrics->flow_deactivation_microsec = flow_deactivation_microsec;
+  metrics->flow_deactivation_time = flow_deactivation_time;
+  metrics->flow_status = strdup(flow_status);
+  metrics->max_packet_delay_variation = max_packet_delay_variation;
+  metrics->num_activation_failures = num_activation_failures;
+  metrics->num_bit_errors = num_bit_errors;
+  metrics->num_bytes_received = num_bytes_received;
+  metrics->num_bytes_transmitted = num_bytes_transmitted;
+  metrics->num_dropped_packets = num_dropped_packets;
+  metrics->num_l7_bytes_received = num_l7_bytes_received;
+  metrics->num_l7_bytes_transmitted = num_l7_bytes_transmitted;
+  metrics->num_lost_packets = num_lost_packets;
+  metrics->num_out_of_order_packets = num_out_of_order_packets;
+  metrics->num_packet_errors = num_packet_errors;
+  metrics->num_packets_received_excl_retrans =
+                                             num_packets_received_excl_retrans;
+  metrics->num_packets_received_incl_retrans =
+                                             num_packets_received_incl_retrans;
+  metrics->num_packets_transmitted_incl_retrans =
+                                          num_packets_transmitted_incl_retrans;
+  metrics->num_retries = num_retries;
+  metrics->num_timeouts = num_timeouts;
+  metrics->num_tunneled_l7_bytes_received = num_tunneled_l7_bytes_received;
+  metrics->round_trip_time = round_trip_time;
+  metrics->time_to_first_byte = time_to_first_byte;
+  for (ii = 0; ii < EVEL_TOS_SUPPORTED; ii++)
+  {
+    evel_init_option_int(&metrics->ip_tos_counts[ii]);
+  }
+  for (ii = 0; ii < EVEL_MAX_TCP_FLAGS; ii++)
+  {
+    evel_init_option_int(&metrics->tcp_flag_counts[ii]);
+  }
+  for (ii = 0; ii < EVEL_MAX_QCI_COS_TYPES; ii++)
+  {
+    evel_init_option_int(&metrics->qci_cos_counts[ii]);
+  }
+  evel_init_option_int(&metrics->dur_connection_failed_status);
+  evel_init_option_int(&metrics->dur_tunnel_failed_status);
+  evel_init_option_string(&metrics->flow_activated_by);
+  evel_init_option_time(&metrics->flow_activation_time);
+  evel_init_option_string(&metrics->flow_deactivated_by);
+  evel_init_option_string(&metrics->gtp_connection_status);
+  evel_init_option_string(&metrics->gtp_tunnel_status);
+  evel_init_option_int(&metrics->large_packet_rtt);
+  evel_init_option_double(&metrics->large_packet_threshold);
+  evel_init_option_int(&metrics->max_receive_bit_rate);
+  evel_init_option_int(&metrics->max_transmit_bit_rate);
+  evel_init_option_int(&metrics->num_gtp_echo_failures);
+  evel_init_option_int(&metrics->num_gtp_tunnel_errors);
+  evel_init_option_int(&metrics->num_http_errors);
+
+exit_label:
+  EVEL_EXIT();
+  return metrics;
+}
+
+/**************************************************************************//**
+ * Set the Duration of Connection Failed Status property of the Mobile GTP Per
+ * Flow Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param duration    The Duration of Connection Failed Status to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_dur_con_fail_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int duration)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(duration >= 0);
+
+  evel_set_option_int(&metrics->dur_connection_failed_status,
+                      duration,
+                      "Duration of Connection Failed Status");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Duration of Tunnel Failed Status property of the Mobile GTP Per Flow
+ * Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param duration    The Duration of Tunnel Failed Status to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_dur_tun_fail_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int duration)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(duration >= 0);
+
+  evel_set_option_int(&metrics->dur_tunnel_failed_status,
+                      duration,
+                      "Duration of Tunnel Failed Status");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Activated By property of the Mobile GTP Per Flow metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param act_by      The Activated By to be set.  ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_act_by_set(MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                        const char * const act_by)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(act_by != NULL);
+
+  evel_set_option_string(&metrics->flow_activated_by,
+                         act_by,
+                         "Activated By");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Activation Time property of the Mobile GTP Per Flow metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param act_time    The Activation Time to be set.  ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_act_time_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         time_t act_time)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(act_time > 0);
+
+  evel_set_option_time(&metrics->flow_activation_time,
+                       act_time,
+                       "Activation Time");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Deactivated By property of the Mobile GTP Per Flow metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param deact_by    The Deactivated By to be set.  ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_deact_by_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         const char * const deact_by)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(deact_by != NULL);
+
+  evel_set_option_string(&metrics->flow_deactivated_by,
+                         deact_by,
+                         "Deactivated By");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the GTP Connection Status property of the Mobile GTP Per Flow metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param status      The GTP Connection Status to be set.  ASCIIZ string. The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_con_status_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         const char * const status)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(status != NULL);
+
+  evel_set_option_string(&metrics->gtp_connection_status,
+                         status,
+                         "GTP Connection Status");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the GTP Tunnel Status property of the Mobile GTP Per Flow metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param status      The GTP Tunnel Status to be set.  ASCIIZ string. The
+ *                    caller does not need to preserve the value once the
+ *                    function returns.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_tun_status_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         const char * const status)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(status != NULL);
+
+  evel_set_option_string(&metrics->gtp_tunnel_status,
+                         status,
+                         "GTP Tunnel Status");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set an IP Type-of-Service count property of the Mobile GTP Per Flow metrics.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param index       The index of the IP Type-of-Service.
+ * @param count       The count.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_iptos_set(MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                       int index,
+                                       int count)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(index >= 0);
+  assert(index < EVEL_TOS_SUPPORTED);
+  assert(count >= 0);
+  assert(count <= 255);
+
+  EVEL_DEBUG("IP Type-of-Service %d", index);
+  evel_set_option_int(&metrics->ip_tos_counts[index],
+                      count,
+                      "IP Type-of-Service");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Large Packet Round-Trip Time property of the Mobile GTP Per Flow
+ * Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param rtt         The Large Packet Round-Trip Time to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_large_pkt_rtt_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int rtt)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(rtt >= 0);
+
+  evel_set_option_int(&metrics->large_packet_rtt,
+                      rtt,
+                      "Large Packet Round-Trip Time");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Large Packet Threshold property of the Mobile GTP Per Flow Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param threshold   The Large Packet Threshold to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_large_pkt_thresh_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         double threshold)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(threshold >= 0.0);
+
+  evel_set_option_double(&metrics->large_packet_threshold,
+                         threshold,
+                         "Large Packet Threshold");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Max Receive Bit Rate property of the Mobile GTP Per Flow Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param rate        The Max Receive Bit Rate to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_max_rcv_bit_rate_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int rate)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(rate >= 0);
+
+  evel_set_option_int(&metrics->max_receive_bit_rate,
+                      rate,
+                      "Max Receive Bit Rate");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Max Transmit Bit Rate property of the Mobile GTP Per Flow Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param rate        The Max Transmit Bit Rate to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_max_trx_bit_rate_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int rate)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(rate >= 0);
+
+  evel_set_option_int(&metrics->max_transmit_bit_rate,
+                      rate,
+                      "Max Transmit Bit Rate");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Number of GTP Echo Failures property of the Mobile GTP Per Flow
+ * Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param num         The Number of GTP Echo Failures to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_num_echo_fail_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int num)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(num >= 0);
+
+  evel_set_option_int(&metrics->num_gtp_echo_failures,
+                      num,
+                      "Number of GTP Echo Failures");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Number of GTP Tunnel Errors property of the Mobile GTP Per Flow
+ * Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param num         The Number of GTP Tunnel Errors to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_num_tun_fail_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int num)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(num >= 0);
+
+  evel_set_option_int(&metrics->num_gtp_tunnel_errors,
+                      num,
+                      "Number of GTP Tunnel Errors");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Number of HTTP Errors property of the Mobile GTP Per Flow Metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.
+ * @param num         The Number of HTTP Errors to be set.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_num_http_errors_set(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         int num)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(num >= 0);
+
+  evel_set_option_int(&metrics->num_http_errors,
+                      num,
+                      "Number of HTTP Errors");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add a TCP flag count to the metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics       Pointer to the Mobile GTP Per Flow Metrics.
+ * @param tcp_flag      The TCP flag to be updated.
+ * @param count         The associated flag count, which must be nonzero.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_tcp_flag_count_add(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         const EVEL_TCP_FLAGS tcp_flag,
+                                         const int count)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(tcp_flag >= 0);
+  assert(tcp_flag < EVEL_MAX_TCP_FLAGS);
+  assert(count >= 0);
+
+  EVEL_DEBUG("TCP Flag: %d", tcp_flag);
+  evel_set_option_int(&metrics->tcp_flag_counts[tcp_flag],
+                      count,
+                      "TCP flag");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add a QCI COS count to the metrics.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param metrics       Pointer to the Mobile GTP Per Flow Metrics.
+ * @param qci_cos       The QCI COS count to be updated.
+ * @param count         The associated QCI COS count.
+ *****************************************************************************/
+void evel_mobile_gtp_metrics_qci_cos_count_add(
+                                         MOBILE_GTP_PER_FLOW_METRICS * metrics,
+                                         const EVEL_QCI_COS_TYPES qci_cos,
+                                         const int count)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+  assert(qci_cos >= 0);
+  assert(qci_cos < EVEL_MAX_QCI_COS_TYPES);
+  assert(count >= 0);
+
+  EVEL_DEBUG("QCI COS: %d", qci_cos);
+  evel_set_option_int(&metrics->qci_cos_counts[qci_cos],
+                      count,
+                      "QCI COS");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the Mobile Flow GTP Per Flow Metrics as a JSON object.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param metrics       Pointer to the ::EVENT_MOBILE_FLOW to encode.
+ * @returns Number of bytes actually written.
+ *****************************************************************************/
+void evel_json_encode_mobile_flow_gtp_flow_metrics(
+                                        EVEL_JSON_BUFFER * jbuf,
+                                        MOBILE_GTP_PER_FLOW_METRICS * metrics)
+{
+  int index;
+  bool found_ip_tos;
+  bool found_tcp_flag;
+  bool found_qci_cos;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(metrics != NULL);
+
+  evel_json_open_named_object(jbuf, "gtpPerFlowMetrics");
+
+  /***************************************************************************/
+  /* Mandatory parameters.                                                   */
+  /***************************************************************************/
+  evel_enc_kv_double(jbuf, "avgBitErrorRate", metrics->avg_bit_error_rate);
+  evel_enc_kv_double(
+    jbuf, "avgPacketDelayVariation", metrics->avg_packet_delay_variation);
+  evel_enc_kv_int(jbuf, "avgPacketLatency", metrics->avg_packet_latency);
+  evel_enc_kv_int(
+    jbuf, "avgReceiveThroughput", metrics->avg_receive_throughput);
+  evel_enc_kv_int(
+    jbuf, "avgTransmitThroughput", metrics->avg_transmit_throughput);
+  evel_enc_kv_int(jbuf, "flowActivationEpoch", metrics->flow_activation_epoch);
+  evel_enc_kv_int(
+    jbuf, "flowActivationMicrosec", metrics->flow_activation_microsec);
+  evel_enc_kv_int(
+    jbuf, "flowDeactivationEpoch", metrics->flow_deactivation_epoch);
+  evel_enc_kv_int(
+    jbuf, "flowDeactivationMicrosec", metrics->flow_deactivation_microsec);
+  evel_enc_kv_time(
+    jbuf, "flowDeactivationTime", &metrics->flow_deactivation_time);
+  evel_enc_kv_string(jbuf, "flowStatus", metrics->flow_status);
+  evel_enc_kv_int(
+    jbuf, "maxPacketDelayVariation", metrics->max_packet_delay_variation);
+  evel_enc_kv_int(
+    jbuf, "numActivationFailures", metrics->num_activation_failures);
+  evel_enc_kv_int(jbuf, "numBitErrors", metrics->num_bit_errors);
+  evel_enc_kv_int(jbuf, "numBytesReceived", metrics->num_bytes_received);
+  evel_enc_kv_int(jbuf, "numBytesTransmitted", metrics->num_bytes_transmitted);
+  evel_enc_kv_int(jbuf, "numDroppedPackets", metrics->num_dropped_packets);
+  evel_enc_kv_int(jbuf, "numL7BytesReceived", metrics->num_l7_bytes_received);
+  evel_enc_kv_int(
+    jbuf, "numL7BytesTransmitted", metrics->num_l7_bytes_transmitted);
+  evel_enc_kv_int(jbuf, "numLostPackets", metrics->num_lost_packets);
+  evel_enc_kv_int(
+    jbuf, "numOutOfOrderPackets", metrics->num_out_of_order_packets);
+  evel_enc_kv_int(jbuf, "numPacketErrors", metrics->num_packet_errors);
+  evel_enc_kv_int(jbuf,
+                  "numPacketsReceivedExclRetrans",
+                  metrics->num_packets_received_excl_retrans);
+  evel_enc_kv_int(jbuf,
+                  "numPacketsReceivedInclRetrans",
+                  metrics->num_packets_received_incl_retrans);
+  evel_enc_kv_int(jbuf,
+                  "numPacketsTransmittedInclRetrans",
+                  metrics->num_packets_transmitted_incl_retrans);
+  evel_enc_kv_int(jbuf, "numRetries", metrics->num_retries);
+  evel_enc_kv_int(jbuf, "numTimeouts", metrics->num_timeouts);
+  evel_enc_kv_int(jbuf,
+                  "numTunneledL7BytesReceived",
+                  metrics->num_tunneled_l7_bytes_received);
+  evel_enc_kv_int(jbuf, "roundTripTime", metrics->round_trip_time);
+  evel_enc_kv_int(jbuf, "timeToFirstByte", metrics->time_to_first_byte);
+
+  /***************************************************************************/
+  /* Optional parameters.                                                    */
+  /***************************************************************************/
+  found_ip_tos = false;
+  for (index = 0; index < EVEL_TOS_SUPPORTED; index++)
+  {
+    if (metrics->ip_tos_counts[index].is_set)
+    {
+      found_ip_tos = true;
+      break;
+    }
+  }
+
+  if (found_ip_tos)
+  {
+    evel_json_open_named_list(jbuf, "ipTosCountList");
+    for (index = 0; index < EVEL_TOS_SUPPORTED; index++)
+    {
+      if (metrics->ip_tos_counts[index].is_set)
+      {
+        evel_enc_list_item(jbuf,
+                           "[\"%d\", %d]",
+                           index,
+                           metrics->ip_tos_counts[index].value);
+      }
+    }
+    evel_json_close_list(jbuf);
+  }
+
+  if (found_ip_tos)
+  {
+    evel_json_open_named_list(jbuf, "ipTosList");
+    for (index = 0; index < EVEL_TOS_SUPPORTED; index++)
+    {
+      if (metrics->ip_tos_counts[index].is_set)
+      {
+        evel_enc_list_item(jbuf, "\"%d\"", index);
+      }
+    }
+    evel_json_close_list(jbuf);
+  }
+
+  /***************************************************************************/
+  /* Make some compile-time assertions about EVEL_TCP_FLAGS.  If you update  */
+  /* these, make sure you update evel_tcp_flag_strings to match the enum.    */
+  /***************************************************************************/
+  EVEL_CT_ASSERT(EVEL_TCP_NS == 0);
+  EVEL_CT_ASSERT(EVEL_TCP_CWR == 1);
+  EVEL_CT_ASSERT(EVEL_TCP_ECE == 2);
+  EVEL_CT_ASSERT(EVEL_TCP_URG == 3);
+  EVEL_CT_ASSERT(EVEL_TCP_ACK == 4);
+  EVEL_CT_ASSERT(EVEL_TCP_PSH == 5);
+  EVEL_CT_ASSERT(EVEL_TCP_RST == 6);
+  EVEL_CT_ASSERT(EVEL_TCP_SYN == 7);
+  EVEL_CT_ASSERT(EVEL_TCP_FIN == 8);
+  EVEL_CT_ASSERT(EVEL_MAX_TCP_FLAGS == 9);
+
+  found_tcp_flag = false;
+  for (index = 0; index < EVEL_MAX_TCP_FLAGS; index++)
+  {
+    if (metrics->tcp_flag_counts[index].is_set)
+    {
+      found_tcp_flag = true;
+      break;
+    }
+  }
+
+  if (found_tcp_flag)
+  {
+    evel_json_open_named_list(jbuf, "tcpFlagList");
+    for (index = 0; index < EVEL_MAX_TCP_FLAGS; index++)
+    {
+      if (metrics->tcp_flag_counts[index].is_set)
+      {
+        evel_enc_list_item(jbuf,
+                           "\"%s\"",
+                           evel_tcp_flag_strings[index]);
+      }
+    }
+    evel_json_close_list(jbuf);
+  }
+
+  if (found_tcp_flag)
+  {
+    evel_json_open_named_list(jbuf, "tcpFlagCountList");
+    for (index = 0; index < EVEL_MAX_TCP_FLAGS; index++)
+    {
+      if (metrics->tcp_flag_counts[index].is_set)
+      {
+        evel_enc_list_item(jbuf,
+                           "[\"%s\", %d]",
+                           evel_tcp_flag_strings[index],
+                           metrics->tcp_flag_counts[index].value);
+      }
+    }
+    evel_json_close_list(jbuf);
+  }
+
+  /***************************************************************************/
+  /* Make some compile-time assertions about EVEL_QCI_COS_TYPES.  If you     */
+  /* update these, make sure you update evel_qci_cos_strings to match the    */
+  /* enum.                                                                   */
+  /***************************************************************************/
+  EVEL_CT_ASSERT(EVEL_QCI_COS_UMTS_CONVERSATIONAL ==0);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_UMTS_STREAMING == 1);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_UMTS_INTERACTIVE == 2);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_UMTS_BACKGROUND == 3);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_1 == 4);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_2 == 5);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_3 == 6);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_4 == 7);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_65 == 8);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_66 == 9);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_5 == 10);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_6 == 11);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_7 == 12);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_8 == 13);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_9 == 14);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_69 == 15);
+  EVEL_CT_ASSERT(EVEL_QCI_COS_LTE_70 == 16);
+  EVEL_CT_ASSERT(EVEL_MAX_QCI_COS_TYPES == 17);
+
+  found_qci_cos = false;
+  for (index = 0; index < EVEL_MAX_QCI_COS_TYPES; index++)
+  {
+    if (metrics->qci_cos_counts[index].is_set)
+    {
+      found_qci_cos = true;
+      break;
+    }
+  }
+
+  if (found_qci_cos)
+  {
+    evel_json_open_named_list(jbuf, "mobileQciCosList");
+    for (index = 0; index < EVEL_MAX_QCI_COS_TYPES; index++)
+    {
+      if (metrics->qci_cos_counts[index].is_set)
+      {
+        evel_enc_list_item(jbuf,
+                           "\"%s\"",
+                           evel_qci_cos_strings[index]);
+      }
+    }
+    evel_json_close_list(jbuf);
+  }
+
+  if (found_qci_cos)
+  {
+    evel_json_open_named_list(jbuf, "mobileQciCosCountList");
+    for (index = 0; index < EVEL_MAX_QCI_COS_TYPES; index++)
+    {
+      if (metrics->qci_cos_counts[index].is_set)
+      {
+        evel_enc_list_item(jbuf,
+                           "[\"%s\", %d]",
+                           evel_qci_cos_strings[index],
+                           metrics->qci_cos_counts[index].value);
+      }
+    }
+    evel_json_close_list(jbuf);
+  }
+
+  evel_enc_kv_opt_int(
+    jbuf, "durConnectionFailedStatus", &metrics->dur_connection_failed_status);
+  evel_enc_kv_opt_int(
+    jbuf, "durTunnelFailedStatus", &metrics->dur_tunnel_failed_status);
+  evel_enc_kv_opt_string(jbuf, "flowActivatedBy", &metrics->flow_activated_by);
+  evel_enc_kv_opt_time(
+    jbuf, "flowActivationTime", &metrics->flow_activation_time);
+  evel_enc_kv_opt_string(
+    jbuf, "flowDeactivatedBy", &metrics->flow_deactivated_by);
+  evel_enc_kv_opt_string(
+    jbuf, "gtpConnectionStatus", &metrics->gtp_connection_status);
+  evel_enc_kv_opt_string(jbuf, "gtpTunnelStatus", &metrics->gtp_tunnel_status);
+  evel_enc_kv_opt_int(jbuf, "largePacketRtt", &metrics->large_packet_rtt);
+  evel_enc_kv_opt_double(
+    jbuf, "largePacketThreshold", &metrics->large_packet_threshold);
+  evel_enc_kv_opt_int(
+    jbuf, "maxReceiveBitRate", &metrics->max_receive_bit_rate);
+  evel_enc_kv_opt_int(
+    jbuf, "maxTransmitBitRate", &metrics->max_transmit_bit_rate);
+  evel_enc_kv_opt_int(
+    jbuf, "numGtpEchoFailures", &metrics->num_gtp_echo_failures);
+  evel_enc_kv_opt_int(
+    jbuf, "numGtpTunnelErrors", &metrics->num_gtp_tunnel_errors);
+  evel_enc_kv_opt_int(jbuf, "numHttpErrors", &metrics->num_http_errors);
+
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free a Mobile GTP Per Flow Metrics.
+ *
+ * Free off the Mobile GTP Per Flow Metrics supplied.  Will free all the
+ * contained allocated memory.
+ *
+ * @note It does not free the Mobile GTP Per Flow Metrics itself, since that
+ * may be part of a larger structure.
+ *****************************************************************************/
+void evel_free_mobile_gtp_flow_metrics(MOBILE_GTP_PER_FLOW_METRICS * metrics)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(metrics != NULL);
+
+  /***************************************************************************/
+  /* Free all internal strings.                                              */
+  /***************************************************************************/
+  free(metrics->flow_status);
+
+  evel_free_option_string(&metrics->flow_activated_by);
+  evel_free_option_string(&metrics->flow_deactivated_by);
+  evel_free_option_string(&metrics->gtp_connection_status);
+  evel_free_option_string(&metrics->gtp_tunnel_status);
+
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_option.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_option.c
new file mode 100644 (file)
index 0000000..7d53e8f
--- /dev/null
@@ -0,0 +1,526 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * Source module relating to EVEL_OPTION_ types.
+ *
+ ****************************************************************************/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "evel_internal.h"
+
+/**************************************************************************//**
+ * Free the underlying resources of an ::EVEL_OPTION_STRING.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_STRING.
+ *****************************************************************************/
+void evel_free_option_string(EVEL_OPTION_STRING * const option)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  if (option->is_set)
+  {
+    free(option->value);
+    option->value = NULL;
+    option->is_set = EVEL_FALSE;
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Initialize an ::EVEL_OPTION_STRING to a not-set state.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_STRING.
+ *****************************************************************************/
+void evel_init_option_string(EVEL_OPTION_STRING * const option)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  option->value = NULL;
+  option->is_set = EVEL_FALSE;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the value of an ::EVEL_OPTION_STRING.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_STRING.
+ * @param value         The value to set.
+ * @param description   Description to be used in logging.
+ *****************************************************************************/
+void evel_set_option_string(EVEL_OPTION_STRING * const option,
+                            const char * const value,
+                            const char * const description)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+  assert(value != NULL);
+  assert(description != NULL);
+
+  if (option->is_set)
+  {
+    EVEL_ERROR("Ignoring attempt to update %s to %s. %s already set to %s",
+               description, value, description, option->value);
+  }
+  else
+  {
+    EVEL_DEBUG("Setting %s to %s", description, value);
+    option->value = strdup(value);
+    option->is_set = EVEL_TRUE;
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Force the value of an ::EVEL_OPTION_STRING.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_STRING.
+ * @param value         The value to set.
+ *****************************************************************************/
+void evel_force_option_string(EVEL_OPTION_STRING * const option,
+                              const char * const value)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+  assert(option->is_set == EVEL_FALSE);
+  assert(option->value == NULL);
+
+  option->value = strdup(value);
+  option->is_set = EVEL_TRUE;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Initialize an ::EVEL_OPTION_INT to a not-set state.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INT.
+ *****************************************************************************/
+void evel_init_option_int(EVEL_OPTION_INT * const option)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  option->value = 0;
+  option->is_set = EVEL_FALSE;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Force the value of an ::EVEL_OPTION_INT.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INT.
+ * @param value         The value to set.
+ *****************************************************************************/
+void evel_force_option_int(EVEL_OPTION_INT * const option,
+                           const int value)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  option->value = value;
+  option->is_set = EVEL_TRUE;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the value of an ::EVEL_OPTION_INT.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INT.
+ * @param value         The value to set.
+ * @param description   Description to be used in logging.
+ *****************************************************************************/
+void evel_set_option_int(EVEL_OPTION_INT * const option,
+                         const int value,
+                         const char * const description)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+  assert(description != NULL);
+
+  if (option->is_set)
+  {
+    EVEL_ERROR("Ignoring attempt to update %s to %d. %s already set to %d",
+               description, value, description, option->value);
+  }
+  else
+  {
+    EVEL_DEBUG("Setting %s to %d", description, value);
+    option->value = value;
+    option->is_set = EVEL_TRUE;
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Initialize an ::EVEL_OPTION_DOUBLE to a not-set state.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_DOUBLE.
+ *****************************************************************************/
+void evel_init_option_double(EVEL_OPTION_DOUBLE * const option)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  option->value = 0.0;
+  option->is_set = EVEL_FALSE;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Force the value of an ::EVEL_OPTION_DOUBLE.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_DOUBLE.
+ * @param value         The value to set.
+ *****************************************************************************/
+void evel_force_option_double(EVEL_OPTION_DOUBLE * const option,
+                              const double value)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  option->value = value;
+  option->is_set = EVEL_TRUE;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the value of an ::EVEL_OPTION_DOUBLE.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_DOUBLE.
+ * @param value         The value to set.
+ * @param description   Description to be used in logging.
+ *****************************************************************************/
+void evel_set_option_double(EVEL_OPTION_DOUBLE * const option,
+                            const double value,
+                            const char * const description)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+  assert(description != NULL);
+
+  if (option->is_set)
+  {
+    EVEL_ERROR("Ignoring attempt to update %s to %lf. %s already set to %lf",
+               description, value, description, option->value);
+  }
+  else
+  {
+    EVEL_DEBUG("Setting %s to %lf", description, value);
+    option->value = value;
+    option->is_set = EVEL_TRUE;
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Initialize an ::EVEL_OPTION_ULL to a not-set state.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_ULL.
+ *****************************************************************************/
+void evel_init_option_ull(EVEL_OPTION_ULL * const option)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+  option->value = 0;
+  option->is_set = EVEL_FALSE;
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Force the value of an ::EVEL_OPTION_ULL.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_ULL.
+ * @param value         The value to set.
+ *****************************************************************************/
+void evel_force_option_ull(EVEL_OPTION_ULL * const option,
+                           const unsigned long long value)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  option->value = value;
+  option->is_set = EVEL_TRUE;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the value of an ::EVEL_OPTION_ULL.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_ULL.
+ * @param value         The value to set.
+ * @param description   Description to be used in logging.
+ *****************************************************************************/
+void evel_set_option_ull(EVEL_OPTION_ULL * const option,
+                         const unsigned long long value,
+                         const char * const description)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+  assert(description != NULL);
+
+  if (option->is_set)
+  {
+    EVEL_ERROR("Ignoring attempt to update %s to %llu. %s already set to %llu",
+               description, value, description, option->value);
+  }
+  else
+  {
+    EVEL_DEBUG("Setting %s to %llu", description, value);
+    option->value = value;
+    option->is_set = EVEL_TRUE;
+  }
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Initialize an ::EVEL_OPTION_INTHEADER_FIELDS to a not-set state.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INTHEADER_FIELDS.
+ *****************************************************************************/
+void evel_init_option_intheader(EVEL_OPTION_INTHEADER_FIELDS * const option)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+  option->object = NULL;
+  option->is_set = EVEL_FALSE;
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Force the value of an ::EVEL_OPTION_INTHEADER_FIELDS.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INTHEADER_FIELDS.
+ * @param value         The value to set.
+ *****************************************************************************/
+void evel_force_option_intheader(EVEL_OPTION_INTHEADER_FIELDS * const option,
+                           const void* value)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  option->object = value;
+  option->is_set = EVEL_TRUE;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the value of an ::EVEL_OPTION_INTHEADER_FIELDS.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INTHEADER_FIELDS.
+ * @param value         The value to set.
+ * @param description   Description to be used in logging.
+ *****************************************************************************/
+void evel_set_option_intheader(EVEL_OPTION_INTHEADER_FIELDS * const option,
+                         const void * value,
+                         const char * const description)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+  assert(description != NULL);
+
+  if (option->is_set)
+  {
+    EVEL_ERROR("Ignoring attempt to update %s to %llu. %s already set to %llu",
+               description, value, description, option->object);
+  }
+  else
+  {
+    EVEL_DEBUG("Setting %s to %llu", description, value);
+    option->object = value;
+    option->is_set = EVEL_TRUE;
+  }
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free the underlying resources of an ::EVEL_OPTION_INTHEADER_FIELDS.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_INTHEADER_FIELDS.
+ *****************************************************************************/
+void evel_free_option_intheader(EVEL_OPTION_INTHEADER_FIELDS * const option)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  if (option->is_set)
+  {
+    free(option->object);
+    option->object = NULL;
+    option->is_set = EVEL_FALSE;
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Initialize an ::EVEL_OPTION_TIME to a not-set state.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_TIME.
+ *****************************************************************************/
+void evel_init_option_time(EVEL_OPTION_TIME * const option)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+  option->value = 0;
+  option->is_set = EVEL_FALSE;
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Force the value of an ::EVEL_OPTION_TIME.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_TIME.
+ * @param value         The value to set.
+ *****************************************************************************/
+void evel_force_option_time(EVEL_OPTION_TIME * const option,
+                            const time_t value)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+
+  option->value = value;
+  option->is_set = EVEL_TRUE;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the value of an ::EVEL_OPTION_TIME.
+ *
+ * @param option        Pointer to the ::EVEL_OPTION_TIME.
+ * @param value         The value to set.
+ * @param description   Description to be used in logging.
+ *****************************************************************************/
+void evel_set_option_time(EVEL_OPTION_TIME * const option,
+                          const time_t value,
+                          const char * const description)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(option != NULL);
+  assert(description != NULL);
+
+  if (option->is_set)
+  {
+    EVEL_ERROR("Ignoring attempt to update %s to %d. %s already set to %d",
+               description, value, description, option->value);
+  }
+  else
+  {
+    EVEL_DEBUG("Setting %s to %d", description, value);
+    option->value = value;
+    option->is_set = EVEL_TRUE;
+  }
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_other.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_other.c
new file mode 100644 (file)
index 0000000..c7a227b
--- /dev/null
@@ -0,0 +1,492 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to Other.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "evel.h"
+#include "evel_internal.h"
+
+/**************************************************************************//**
+ * Create a new Other event.
+ *
+ * @note    The mandatory fields on the Other must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Other has immutable properties.
+ * @returns pointer to the newly manufactured ::EVENT_OTHER.  If the event is
+ *          not used (i.e. posted) it must be released using ::evel_free_other.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_OTHER * evel_new_other(const char *ev_name, const char *ev_id)
+{
+  EVENT_OTHER * other = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+
+  /***************************************************************************/
+  /* Allocate the Other.                                                     */
+  /***************************************************************************/
+  other = malloc(sizeof(EVENT_OTHER));
+  if (other == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(other, 0, sizeof(EVENT_OTHER));
+  EVEL_DEBUG("New Other is at %lp", other);
+
+  /***************************************************************************/
+  /* Initialize the header & the Other fields.  Optional string values are   */
+  /* uninitialized (NULL).                                                   */
+  /***************************************************************************/
+  evel_init_header_nameid(&other->header,ev_name,ev_id);
+  other->header.event_domain = EVEL_DOMAIN_OTHER;
+  other->major_version = EVEL_OTHER_EVENT_MAJOR_VERSION;
+  other->minor_version = EVEL_OTHER_EVENT_MINOR_VERSION;
+
+  other->namedarrays = NULL;
+  dlist_initialize(&other->jsonobjects);
+  dlist_initialize(&other->namedvalues);
+
+exit_label:
+  EVEL_EXIT();
+  return other;
+}
+
+/**************************************************************************//**
+ * Set the Event Type property of the Other.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param other       Pointer to the Other.
+ * @param type        The Event Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_other_type_set(EVENT_OTHER * other,
+                         const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and call evel_header_type_set.                      */
+  /***************************************************************************/
+  assert(other != NULL);
+  assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
+  evel_header_type_set(&other->header, type);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add a json object to jsonObject list.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param other         Pointer to the Other.
+ * @param size          size of hashtable
+ *****************************************************************************/
+void evel_other_field_set_namedarraysize(EVENT_OTHER * other, const int size)
+{
+  OTHER_FIELD * other_field = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(other != NULL);
+  assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
+  assert(other->namedarrays == NULL);
+  assert(size > 0);
+
+  EVEL_DEBUG("Adding Named array");
+
+  other->namedarrays =  ht_create(size);
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Add a json object to jsonObject list.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param other         Pointer to the Other.
+ * @param size          size of hashtable
+ *****************************************************************************/
+void evel_other_field_add_namedarray(EVENT_OTHER * other, const char *hashname,  char * name, char *value)
+{
+  OTHER_FIELD * other_field = NULL;
+  DLIST *list = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(other != NULL);
+  assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
+  assert(other->namedarrays != NULL);
+
+  EVEL_DEBUG("Adding values to Named array");
+      
+  EVEL_DEBUG("Adding name=%s value=%s", name, value);
+  other_field = malloc(sizeof(OTHER_FIELD));
+  assert(other_field != NULL);
+  memset(other_field, 0, sizeof(OTHER_FIELD));
+  other_field->name = strdup(name);
+  other_field->value = strdup(value);
+  assert(other_field->name != NULL);
+  assert(other_field->value != NULL);
+
+
+  list = ht_get(other->namedarrays, hashname);
+  if( list == NULL )
+  {
+     DLIST * nlist = malloc(sizeof(DLIST));
+     dlist_initialize(nlist);
+     dlist_push_last(nlist, other_field);
+     ht_set(other->namedarrays, hashname, nlist);
+     EVEL_DEBUG("Created to new table table");
+  }
+  else
+  {
+     dlist_push_last(list, other_field);
+     EVEL_DEBUG("Adding to existing table");
+  }
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Add a json object to jsonObject list.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param other     Pointer to the Other.
+ * @param jsonobj   Pointer to json object
+ *****************************************************************************/
+void evel_other_field_add_jsonobj(EVENT_OTHER * other, EVEL_JSON_OBJECT *jsonobj)
+{
+  OTHER_FIELD * other_field = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(other != NULL);
+  assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
+  assert(jsonobj != NULL);
+
+  EVEL_DEBUG("Adding jsonObject");
+
+  dlist_push_last(&other->jsonobjects, jsonobj);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add a field name/value pair to the Other.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param other     Pointer to the Other.
+ * @param name      ASCIIZ string with the field's name.  The caller does not
+ *                  need to preserve the value once the function returns.
+ * @param value     ASCIIZ string with the field's value.  The caller does not
+ *                  need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_other_field_add(EVENT_OTHER * other, char * name, char * value)
+{
+  OTHER_FIELD * other_field = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(other != NULL);
+  assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
+  assert(name != NULL);
+  assert(value != NULL);
+
+  EVEL_DEBUG("Adding name=%s value=%s", name, value);
+  other_field = malloc(sizeof(OTHER_FIELD));
+  assert(other_field != NULL);
+  memset(other_field, 0, sizeof(OTHER_FIELD));
+  other_field->name = strdup(name);
+  other_field->value = strdup(value);
+  assert(other_field->name != NULL);
+  assert(other_field->value != NULL);
+
+  dlist_push_last(&other->namedvalues, other_field);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the Other in JSON according to AT&T's schema for the event type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_other(EVEL_JSON_BUFFER * jbuf,
+                            EVENT_OTHER * event)
+{
+  OTHER_FIELD * other_field = NULL;
+  EVEL_JSON_OBJECT * jsonobjp = NULL;
+  DLIST_ITEM * other_field_item = NULL;
+  EVEL_JSON_OBJECT_INSTANCE * jsonobjinst = NULL;
+  DLIST_ITEM * jsobj_field_item = NULL;
+  EVEL_INTERNAL_KEY * keyinst = NULL;
+  DLIST_ITEM * keyinst_field_item = NULL;
+  HASHTABLE_T *ht = NULL;
+  int i;
+  bool itm_added = false;
+  DLIST *itm_list = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_OTHER);
+
+  evel_json_encode_header(jbuf, &event->header);
+  evel_json_open_named_object(jbuf, "otherFields");
+
+// iterate through hashtable and print DLIST for each entry
+
+   ht = event->namedarrays;
+   if( ht != NULL )
+   {
+     if( ht->size > 0)
+     {
+        for( i = 0; i < ht->size; i++ ) {
+             if( ht->table[i] != NULL)
+            {
+               itm_added = true;
+            }
+        }
+        if( itm_added == true)
+        {
+
+  if (evel_json_open_opt_named_list(jbuf, "hashOfNameValuePairArrays"))
+  {
+       for( i = 0; i < ht->size; i++ ) {
+             if( ht->table[i] != NULL)
+            {
+               itm_list = ht->table[i];
+
+  if(evel_json_open_opt_named_list(jbuf, ht->table[i]->key))
+  {
+    other_field_item = dlist_get_first(&itm_list);
+    while (other_field_item != NULL)
+    {
+     other_field = (OTHER_FIELD *) other_field_item->item;
+     if(other_field != NULL){
+       evel_json_open_object(jbuf);
+       evel_enc_kv_string(jbuf, "name", other_field->name);
+       evel_enc_kv_string(jbuf, "value", other_field->value);
+       evel_json_close_object(jbuf);
+       other_field_item = dlist_get_next(other_field_item);
+     }
+    }
+    evel_json_close_list(jbuf);
+  }
+
+            }
+       }
+
+       evel_json_close_list(jbuf);
+  }
+
+
+        }
+     }
+   }
+
+  evel_json_checkpoint(jbuf);
+  if(evel_json_open_opt_named_list(jbuf, "jsonObjects"))
+  {
+  bool item_added = false;
+  other_field_item = dlist_get_first(&event->jsonobjects);
+  while (other_field_item != NULL)
+  {
+    jsonobjp = (EVEL_JSON_OBJECT *) other_field_item->item;
+    if(jsonobjp != NULL);
+    {
+     evel_json_open_object(jbuf);
+
+       if( evel_json_open_opt_named_list(jbuf, "objectInstances"))
+       {
+       bool item_added2 = false;
+        jsobj_field_item = dlist_get_first(&jsonobjp->jsonobjectinstances);
+       while (jsobj_field_item != NULL)
+       {
+          jsonobjinst = (EVEL_JSON_OBJECT_INSTANCE *) jsobj_field_item->item;
+          if( jsonobjinst != NULL )
+          {
+              evel_json_open_object(jbuf);
+              evel_enc_kv_object(jbuf, "objectInstance", jsonobjinst->jsonstring);
+              evel_enc_kv_ull(jbuf, "objectInstanceEpochMicrosec", jsonobjinst->objinst_epoch_microsec);
+  //evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "objectKeys"))
+  {
+    bool item_added3 = false;
+
+    keyinst_field_item = dlist_get_first(&jsonobjinst->object_keys);
+    while (keyinst_field_item != NULL)
+    {
+      keyinst = (EVEL_INTERNAL_KEY *)keyinst_field_item->item;
+      if(keyinst != NULL)
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "keyName", keyinst->keyname);
+        evel_enc_kv_opt_int(jbuf, "keyOrder", &keyinst->keyorder);
+        evel_enc_kv_opt_string(jbuf, "keyValue", &keyinst->keyvalue);
+        evel_json_close_object(jbuf);
+       item_added3 = false;
+      }
+      keyinst_field_item = dlist_get_next(keyinst_field_item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    //if (!item_added3)
+    //{
+    //  evel_json_rewind(jbuf);
+    //}
+  }
+              evel_json_close_object(jbuf);
+           }
+           item_added2 = true;
+            jsobj_field_item = dlist_get_next(jsobj_field_item);
+       }
+        evel_json_close_list(jbuf);
+       if( !item_added2 )
+       {
+         evel_json_rewind(jbuf);
+       }
+       }
+
+    evel_enc_kv_string(jbuf, "objectName", jsonobjp->object_name);
+    evel_enc_kv_opt_string(jbuf, "objectSchema", &jsonobjp->objectschema);
+    evel_enc_kv_opt_string(jbuf, "objectSchemaUrl", &jsonobjp->objectschemaurl);
+    evel_enc_kv_opt_string(jbuf, "nfSubscribedObjectName", &jsonobjp->nfsubscribedobjname);
+    evel_enc_kv_opt_string(jbuf, "nfSubscriptionId", &jsonobjp->nfsubscriptionid);
+    evel_json_close_object(jbuf);
+    item_added = true;
+  }
+  other_field_item = dlist_get_next(other_field_item);
+  }
+  evel_json_close_list(jbuf);
+
+  if (!item_added)
+  {
+     evel_json_rewind(jbuf);
+  }
+
+  }
+
+  if( evel_json_open_opt_named_list(jbuf, "nameValuePairs"))
+  {
+  other_field_item = dlist_get_first(&event->namedvalues);
+  while (other_field_item != NULL)
+  {
+    other_field = (OTHER_FIELD *) other_field_item->item;
+    assert(other_field != NULL);
+
+    evel_json_open_object(jbuf);
+    evel_enc_kv_string(jbuf, "name", other_field->name);
+    evel_enc_kv_string(jbuf, "value", other_field->value);
+    evel_json_close_object(jbuf);
+    other_field_item = dlist_get_next(other_field_item);
+  }
+  }
+  evel_json_close_list(jbuf);
+
+  evel_enc_version(jbuf, "otherFieldsVersion", event->major_version,event->minor_version);
+
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free an Other.
+ *
+ * Free off the Other supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the Other itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_other(EVENT_OTHER * event)
+{
+  OTHER_FIELD * other_field = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+  /* events as we do on the public API.                                      */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_OTHER);
+
+  /***************************************************************************/
+  /* Free all internal strings then the header itself.                       */
+  /***************************************************************************/
+  other_field = dlist_pop_last(&event->namedvalues);
+  while (other_field != NULL)
+  {
+    EVEL_DEBUG("Freeing Other Field (%s, %s)",
+               other_field->name,
+               other_field->value);
+    free(other_field->name);
+    free(other_field->value);
+    free(other_field);
+    other_field = dlist_pop_last(&event->namedvalues);
+  }
+  evel_free_header(&event->header);
+
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_reporting_measurement.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_reporting_measurement.c
new file mode 100644 (file)
index 0000000..36c34da
--- /dev/null
@@ -0,0 +1,437 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to the Measurement for VF
+ * Reporting event.
+ *
+ * @note  This is an experimental event tytpe and does not form part of the
+ *        currently approved AT&T event schema.  It is intended to allow a
+ *        less-onerous event reporting mechanism because it avoids having to
+ *        return all the platform statistics which are mandatory in the
+ *        **measurementsForVfScaling** event.
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "evel.h"
+#include "evel_internal.h"
+#include "evel_throttle.h"
+
+/**************************************************************************//**
+ * Create a new Report event.
+ *
+ * @note    The mandatory fields on the Report must be supplied to this
+ *          factory function and are immutable once set.  Optional fields have
+ *          explicit setter functions, but again values may only be set once so
+ *          that the Report has immutable properties.
+ *
+ * @param   measurement_interval
+ * @param event_name    Unique Event Name
+ * @param event_id    A universal identifier of the event for analysis etc
+ * @returns pointer to the newly manufactured ::EVENT_REPORT.  If the event is
+ *          not used (i.e. posted) it must be released using ::evel_free_event.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_REPORT * evel_new_report(double measurement_interval,const char *ev_name, const char *ev_id)
+{
+  EVENT_REPORT * report = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(measurement_interval >= 0.0);
+
+  /***************************************************************************/
+  /* Allocate the report.                                                    */
+  /***************************************************************************/
+  report = malloc(sizeof(EVENT_REPORT));
+  if (report == NULL)
+  {
+    log_error_state("Out of memory for Report");
+    goto exit_label;
+  }
+  memset(report, 0, sizeof(EVENT_REPORT));
+  EVEL_DEBUG("New report is at %lp", report);
+
+  /***************************************************************************/
+  /* Initialize the header & the report fields.                              */
+  /***************************************************************************/
+  evel_init_header_nameid(&report->header,ev_name,ev_id);
+  report->header.event_domain = EVEL_DOMAIN_REPORT;
+  report->measurement_interval = measurement_interval;
+
+  dlist_initialize(&report->feature_usage);
+  dlist_initialize(&report->measurement_groups);
+  report->major_version = EVEL_REPORT_MAJOR_VERSION;
+  report->minor_version = EVEL_REPORT_MINOR_VERSION;
+
+exit_label:
+  EVEL_EXIT();
+  return report;
+}
+
+/**************************************************************************//**
+ * Set the Event Type property of the Report.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param report Pointer to the Report.
+ * @param type        The Event Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_report_type_set(EVENT_REPORT * report,
+                          const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and call evel_header_type_set.                      */
+  /***************************************************************************/
+  assert(report != NULL);
+  assert(report->header.event_domain == EVEL_DOMAIN_REPORT);
+  evel_header_type_set(&report->header, type);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add a Feature usage value name/value pair to the Report.
+ *
+ * The name is null delimited ASCII string.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param report          Pointer to the report.
+ * @param feature         ASCIIZ string with the feature's name.
+ * @param utilization     Utilization of the feature.
+ *****************************************************************************/
+void evel_report_feature_use_add(EVENT_REPORT * report,
+                                 char * feature,
+                                 int utilization)
+{
+  MEASUREMENT_FEATURE_USE * feature_use = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(report != NULL);
+  assert(report->header.event_domain == EVEL_DOMAIN_REPORT);
+  assert(feature != NULL);
+  assert(utilization >= 0);
+
+  /***************************************************************************/
+  /* Allocate a container for the value and push onto the list.              */
+  /***************************************************************************/
+  EVEL_DEBUG("Adding Feature=%s Use=%d", feature, utilization);
+  feature_use = malloc(sizeof(MEASUREMENT_FEATURE_USE));
+  assert(feature_use != NULL);
+  memset(feature_use, 0, sizeof(MEASUREMENT_FEATURE_USE));
+  feature_use->feature_id = strdup(feature);
+  assert(feature_use->feature_id != NULL);
+  feature_use->feature_utilization = utilization;
+
+  dlist_push_last(&report->feature_usage, feature_use);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add a Additional Measurement value name/value pair to the Report.
+ *
+ * The name is null delimited ASCII string.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param report   Pointer to the report.
+ * @param group    ASCIIZ string with the measurement group's name.
+ * @param name     ASCIIZ string containing the measurement's name.
+ * @param value    ASCIIZ string containing the measurement's value.
+ *****************************************************************************/
+void evel_report_custom_measurement_add(EVENT_REPORT * report,
+                                        const char * const group,
+                                        const char * const name,
+                                        const char * const value)
+{
+  MEASUREMENT_GROUP * measurement_group = NULL;
+  CUSTOM_MEASUREMENT * measurement = NULL;
+  DLIST_ITEM * item = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(report != NULL);
+  assert(report->header.event_domain == EVEL_DOMAIN_REPORT);
+  assert(group != NULL);
+  assert(name != NULL);
+  assert(value != NULL);
+
+  /***************************************************************************/
+  /* Allocate a container for the name/value pair.                           */
+  /***************************************************************************/
+  EVEL_DEBUG("Adding Measurement Group=%s Name=%s Value=%s",
+              group, name, value);
+  measurement = malloc(sizeof(CUSTOM_MEASUREMENT));
+  assert(measurement != NULL);
+  memset(measurement, 0, sizeof(CUSTOM_MEASUREMENT));
+  measurement->name = strdup(name);
+  assert(measurement->name != NULL);
+  measurement->value = strdup(value);
+  assert(measurement->value != NULL);
+
+  /***************************************************************************/
+  /* See if we have that group already.                                      */
+  /***************************************************************************/
+  item = dlist_get_first(&report->measurement_groups);
+  while (item != NULL)
+  {
+    measurement_group = (MEASUREMENT_GROUP *) item->item;
+    assert(measurement_group != NULL);
+
+    EVEL_DEBUG("Got measurement group %s", measurement_group->name);
+    if (strcmp(group, measurement_group->name) == 0)
+    {
+      EVEL_DEBUG("Found existing Measurement Group");
+      break;
+    }
+    item = dlist_get_next(item);
+  }
+
+  /***************************************************************************/
+  /* If we didn't have the group already, create it.                         */
+  /***************************************************************************/
+  if (item == NULL)
+  {
+    EVEL_DEBUG("Creating new Measurement Group");
+    measurement_group = malloc(sizeof(MEASUREMENT_GROUP));
+    assert(measurement_group != NULL);
+    memset(measurement_group, 0, sizeof(MEASUREMENT_GROUP));
+    measurement_group->name = strdup(group);
+    assert(measurement_group->name != NULL);
+    dlist_initialize(&measurement_group->measurements);
+    dlist_push_last(&report->measurement_groups, measurement_group);
+  }
+
+  /***************************************************************************/
+  /* If we didn't have the group already, create it.                         */
+  /***************************************************************************/
+  dlist_push_last(&measurement_group->measurements, measurement);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the report as a JSON report.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_report(EVEL_JSON_BUFFER * jbuf,
+                             EVENT_REPORT * event)
+{
+  MEASUREMENT_FEATURE_USE * feature_use = NULL;
+  MEASUREMENT_GROUP * measurement_group = NULL;
+  CUSTOM_MEASUREMENT * custom_measurement = NULL;
+  DLIST_ITEM * item = NULL;
+  DLIST_ITEM * nested_item = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_REPORT);
+
+  evel_json_encode_header(jbuf, &event->header);
+  evel_json_open_named_object(jbuf, "measurementsForVfReportingFields");
+  evel_enc_kv_double(jbuf, "measurementInterval", event->measurement_interval);
+
+  /***************************************************************************/
+  /* Feature Utilization list.                                               */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "featureUsageArray"))
+  {
+    bool item_added = false;
+
+    item = dlist_get_first(&event->feature_usage);
+    while (item != NULL)
+    {
+      feature_use = (MEASUREMENT_FEATURE_USE*) item->item;
+      assert(feature_use != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "featureUsageArray",
+                                          feature_use->feature_id))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "featureIdentifier", feature_use->feature_id);
+        evel_enc_kv_int(
+          jbuf, "featureUtilization", feature_use->feature_utilization);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      item = dlist_get_next(item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+  /***************************************************************************/
+  /* Additional Measurement Groups list.                                     */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "additionalMeasurements"))
+  {
+    bool item_added = false;
+
+    item = dlist_get_first(&event->measurement_groups);
+    while (item != NULL)
+    {
+      measurement_group = (MEASUREMENT_GROUP *) item->item;
+      assert(measurement_group != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "additionalMeasurements",
+                                          measurement_group->name))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "name", measurement_group->name);
+        evel_json_open_named_list(jbuf, "measurements");
+
+        /*********************************************************************/
+        /* Measurements list.                                                */
+        /*********************************************************************/
+        nested_item = dlist_get_first(&measurement_group->measurements);
+        while (nested_item != NULL)
+        {
+          custom_measurement = (CUSTOM_MEASUREMENT *) nested_item->item;
+          assert(custom_measurement != NULL);
+
+          evel_json_open_object(jbuf);
+          evel_enc_kv_string(jbuf, "name", custom_measurement->name);
+          evel_enc_kv_string(jbuf, "value", custom_measurement->value);
+          evel_json_close_object(jbuf);
+          nested_item = dlist_get_next(nested_item);
+        }
+        evel_json_close_list(jbuf);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      item = dlist_get_next(item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+  /***************************************************************************/
+  /* Although optional, we always generate the version.  Note that this      */
+  /* closes the object, too.                                                 */
+  /***************************************************************************/
+  evel_enc_version(jbuf,
+                   "measurementFieldsVersion",
+                   event->major_version,
+                   event->minor_version);
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free a Report.
+ *
+ * Free off the Report supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the Report itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_report(EVENT_REPORT * event)
+{
+  MEASUREMENT_FEATURE_USE * feature_use = NULL;
+  MEASUREMENT_GROUP * measurement_group = NULL;
+  CUSTOM_MEASUREMENT * custom_measurement = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+  /* events as we do on the public API.                                      */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_REPORT);
+
+  /***************************************************************************/
+  /* Free all internal strings then the header itself.                       */
+  /***************************************************************************/
+  feature_use = dlist_pop_last(&event->feature_usage);
+  while (feature_use != NULL)
+  {
+    EVEL_DEBUG("Freeing Feature use Info (%s)", feature_use->feature_id);
+    free(feature_use->feature_id);
+    free(feature_use);
+    feature_use = dlist_pop_last(&event->feature_usage);
+  }
+  measurement_group = dlist_pop_last(&event->measurement_groups);
+  while (measurement_group != NULL)
+  {
+    EVEL_DEBUG("Freeing Measurement Group (%s)", measurement_group->name);
+
+    custom_measurement = dlist_pop_last(&measurement_group->measurements);
+    while (custom_measurement != NULL)
+    {
+      EVEL_DEBUG("Freeing mesaurement (%s)", custom_measurement->name);
+
+      free(custom_measurement->name);
+      free(custom_measurement->value);
+      free(custom_measurement);
+      custom_measurement = dlist_pop_last(&measurement_group->measurements);
+    }
+
+    free(measurement_group->name);
+    free(measurement_group);
+    measurement_group = dlist_pop_last(&event->measurement_groups);
+  }
+
+  evel_free_header(&event->header);
+
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_scaling_measurement.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_scaling_measurement.c
new file mode 100644 (file)
index 0000000..b3e73c9
--- /dev/null
@@ -0,0 +1,3716 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to the Measurement.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "evel.h"
+#include "evel_internal.h"
+#include "evel_throttle.h"
+
+/**************************************************************************//**
+ * Create a new Measurement event.
+ *
+ * @note    The mandatory fields on the Measurement must be supplied to this
+ *          factory function and are immutable once set.  Optional fields have
+ *          explicit setter functions, but again values may only be set once so
+ *          that the Measurement has immutable properties.
+ *
+ * @param   measurement_interval
+ * @param event_name  Unique Event Name confirming Domain AsdcModel Description
+ * @param event_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
+ *
+ * @returns pointer to the newly manufactured ::EVENT_MEASUREMENT.  If the
+ *          event is not used (i.e. posted) it must be released using
+ *          ::evel_free_event.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_MEASUREMENT * evel_new_measurement(double measurement_interval, const char* ev_name, const char *ev_id)
+{
+  EVENT_MEASUREMENT * measurement = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(measurement_interval >= 0.0);
+
+  /***************************************************************************/
+  /* Allocate the measurement.                                               */
+  /***************************************************************************/
+  measurement = malloc(sizeof(EVENT_MEASUREMENT));
+  if (measurement == NULL)
+  {
+    log_error_state("Out of memory for Measurement");
+    goto exit_label;
+  }
+  memset(measurement, 0, sizeof(EVENT_MEASUREMENT));
+  EVEL_DEBUG("New measurement is at %lp", measurement);
+
+  /***************************************************************************/
+  /* Initialize the header & the measurement fields.                         */
+  /***************************************************************************/
+  evel_init_header_nameid(&measurement->header,ev_name,ev_id);
+  measurement->header.event_domain = EVEL_DOMAIN_MEASUREMENT;
+  measurement->measurement_interval = measurement_interval;
+  dlist_initialize(&measurement->additional_info);
+  dlist_initialize(&measurement->additional_measurements);
+  dlist_initialize(&measurement->additional_objects);
+  dlist_initialize(&measurement->cpu_usage);
+  dlist_initialize(&measurement->disk_usage);
+  dlist_initialize(&measurement->mem_usage);
+  dlist_initialize(&measurement->filesystem_usage);
+  dlist_initialize(&measurement->latency_distribution);
+  dlist_initialize(&measurement->vnic_usage);
+  dlist_initialize(&measurement->codec_usage);
+  dlist_initialize(&measurement->feature_usage);
+  evel_init_option_double(&measurement->mean_request_latency);
+  evel_init_option_int(&measurement->vnfc_scaling_metric);
+  evel_init_option_int(&measurement->concurrent_sessions);
+  evel_init_option_int(&measurement->configured_entities);
+  evel_init_option_int(&measurement->media_ports_in_use);
+  evel_init_option_int(&measurement->request_rate);
+  measurement->major_version = EVEL_MEASUREMENT_MAJOR_VERSION;
+  measurement->minor_version = EVEL_MEASUREMENT_MINOR_VERSION;
+
+exit_label:
+  EVEL_EXIT();
+  return measurement;
+}
+
+/**************************************************************************//**
+ * Set the Event Type property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement Pointer to the Measurement.
+ * @param type        The Event Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_measurement_type_set(EVENT_MEASUREMENT * measurement,
+                               const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and call evel_header_type_set.                      */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  evel_header_type_set(&measurement->header, type);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add an additional value name/value pair to the Measurement.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement     Pointer to the measurement.
+ * @param name      ASCIIZ string with the attribute's name.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ * @param value     ASCIIZ string with the attribute's value.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ *****************************************************************************/
+void evel_measurement_addl_info_add(EVENT_MEASUREMENT * measurement, char * name, char * value)
+{
+  OTHER_FIELD * addl_info = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(name != NULL);
+  assert(value != NULL);
+  
+  EVEL_DEBUG("Adding name=%s value=%s", name, value);
+  addl_info = malloc(sizeof(OTHER_FIELD));
+  assert(addl_info != NULL);
+  memset(addl_info, 0, sizeof(OTHER_FIELD));
+  addl_info->name = strdup(name);
+  addl_info->value = strdup(value);
+  assert(addl_info->name != NULL);
+  assert(addl_info->value != NULL);
+
+  dlist_push_last(&measurement->additional_info, addl_info);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Concurrent Sessions property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement         Pointer to the Measurement.
+ * @param concurrent_sessions The Concurrent Sessions to be set.
+ *****************************************************************************/
+void evel_measurement_conc_sess_set(EVENT_MEASUREMENT * measurement,
+                                    int concurrent_sessions)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(concurrent_sessions >= 0);
+
+  evel_set_option_int(&measurement->concurrent_sessions,
+                      concurrent_sessions,
+                      "Concurrent Sessions");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Configured Entities property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement         Pointer to the Measurement.
+ * @param configured_entities The Configured Entities to be set.
+ *****************************************************************************/
+void evel_measurement_cfg_ents_set(EVENT_MEASUREMENT * measurement,
+                                   int configured_entities)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(configured_entities >= 0);
+
+  evel_set_option_int(&measurement->configured_entities,
+                      configured_entities,
+                      "Configured Entities");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add an additional set of Errors to the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement       Pointer to the measurement.
+ * @param receive_discards  The number of receive discards.
+ * @param receive_errors    The number of receive errors.
+ * @param transmit_discards The number of transmit discards.
+ * @param transmit_errors   The number of transmit errors.
+ *****************************************************************************/
+void evel_measurement_errors_set(EVENT_MEASUREMENT * measurement,
+                                 int receive_discards,
+                                 int receive_errors,
+                                 int transmit_discards,
+                                 int transmit_errors)
+{
+  MEASUREMENT_ERRORS * errors = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                      */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(receive_discards >= 0);
+  assert(receive_errors >= 0);
+  assert(transmit_discards >= 0);
+  assert(transmit_errors >= 0);
+
+  if (measurement->errors == NULL)
+  {
+    EVEL_DEBUG("Adding Errors: %d, %d; %d, %d",
+               receive_discards,
+               receive_errors,
+               transmit_discards,
+               transmit_errors);
+    errors = malloc(sizeof(MEASUREMENT_ERRORS));
+    assert(errors != NULL);
+    memset(errors, 0, sizeof(MEASUREMENT_ERRORS));
+    errors->receive_discards = receive_discards;
+    errors->receive_errors = receive_errors;
+    errors->transmit_discards = transmit_discards;
+    errors->transmit_errors = transmit_errors;
+    measurement->errors = errors;
+  }
+  else
+  {
+    errors = measurement->errors;
+    EVEL_DEBUG("Ignoring attempt to add Errors: %d, %d; %d, %d\n"
+               "Errors already set: %d, %d; %d, %d",
+               receive_discards,
+               receive_errors,
+               transmit_discards,
+               transmit_errors,
+               errors->receive_discards,
+               errors->receive_errors,
+               errors->transmit_discards,
+               errors->transmit_errors);
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Mean Request Latency property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement          Pointer to the Measurement.
+ * @param mean_request_latency The Mean Request Latency to be set.
+ *****************************************************************************/
+void evel_measurement_mean_req_lat_set(EVENT_MEASUREMENT * measurement,
+                                       double mean_request_latency)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(mean_request_latency >= 0.0);
+
+  evel_set_option_double(&measurement->mean_request_latency,
+                         mean_request_latency,
+                         "Mean Request Latency");
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Set the Request Rate property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement  Pointer to the Measurement.
+ * @param request_rate The Request Rate to be set.
+ *****************************************************************************/
+void evel_measurement_request_rate_set(EVENT_MEASUREMENT * measurement,
+                                       int request_rate)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(request_rate >= 0);
+
+  evel_set_option_int(&measurement->request_rate,
+                      request_rate,
+                      "Request Rate");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add an additional CPU usage value name/value pair to the Measurement.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement   Pointer to the measurement.
+ * @param id            ASCIIZ string with the CPU's identifier.
+ * @param usage         CPU utilization.
+ *****************************************************************************/
+MEASUREMENT_CPU_USE *evel_measurement_new_cpu_use_add(EVENT_MEASUREMENT * measurement,
+                                 char * id, double usage)
+{
+  MEASUREMENT_CPU_USE * cpu_use = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(id != NULL);
+  assert(usage >= 0.0);
+
+  /***************************************************************************/
+  /* Allocate a container for the value and push onto the list.              */
+  /***************************************************************************/
+  EVEL_DEBUG("Adding id=%s usage=%lf", id, usage);
+  cpu_use = malloc(sizeof(MEASUREMENT_CPU_USE));
+  assert(cpu_use != NULL);
+  memset(cpu_use, 0, sizeof(MEASUREMENT_CPU_USE));
+  cpu_use->id    = strdup(id);
+  cpu_use->usage = usage;
+  evel_init_option_double(&cpu_use->idle);
+  evel_init_option_double(&cpu_use->intrpt);
+  evel_init_option_double(&cpu_use->nice);
+  evel_init_option_double(&cpu_use->softirq);
+  evel_init_option_double(&cpu_use->steal);
+  evel_init_option_double(&cpu_use->sys);
+  evel_init_option_double(&cpu_use->user);
+  evel_init_option_double(&cpu_use->wait);
+
+  dlist_push_last(&measurement->cpu_usage, cpu_use);
+
+  EVEL_EXIT();
+  return cpu_use;
+}
+
+/**************************************************************************//**
+ * Set the CPU Idle value in measurement interval
+ *   percentage of CPU time spent in the idle task
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_idle_set(MEASUREMENT_CPU_USE *const cpu_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&cpu_use->idle, val, "CPU idle time");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the percentage of time spent servicing interrupts
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_interrupt_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&cpu_use->intrpt, val, "CPU interrupt value");
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Set the percentage of time spent running user space processes that have been niced
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_nice_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&cpu_use->nice, val, "CPU nice value");
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Set the percentage of time spent handling soft irq interrupts
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_softirq_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&cpu_use->softirq, val, "CPU Soft IRQ value");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the percentage of time spent in involuntary wait
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_steal_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&cpu_use->steal, val, "CPU involuntary wait");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the percentage of time spent on system tasks running the kernel
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_system_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&cpu_use->sys, val, "CPU System load");
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Set the percentage of time spent running un-niced user space processes
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_usageuser_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&cpu_use->user, val, "CPU User load value");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the percentage of CPU time spent waiting for I/O operations to complete
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param cpu_use      Pointer to the CPU Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_cpu_use_wait_set(MEASUREMENT_CPU_USE * const cpu_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&cpu_use->wait, val, "CPU Wait IO value");
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Add an additional Memory usage value name/value pair to the Measurement.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement   Pointer to the measurement.
+ * @param id            ASCIIZ string with the Memory identifier.
+ * @param vmidentifier  ASCIIZ string with the VM's identifier.
+ * @param membuffsz     Memory Size.
+ *
+ * @return  Returns pointer to memory use structure in measurements
+ *****************************************************************************/
+MEASUREMENT_MEM_USE * evel_measurement_new_mem_use_add(EVENT_MEASUREMENT * measurement,
+                                 char * id,  char *vmidentifier,  double membuffsz)
+{
+  MEASUREMENT_MEM_USE * mem_use = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(id != NULL);
+  assert(membuffsz >= 0.0);
+
+  /***************************************************************************/
+  /* Allocate a container for the value and push onto the list.              */
+  /***************************************************************************/
+  EVEL_DEBUG("Adding id=%s buffer size=%lf", id, membuffsz);
+  mem_use = malloc(sizeof(MEASUREMENT_MEM_USE));
+  assert(mem_use != NULL);
+  memset(mem_use, 0, sizeof(MEASUREMENT_MEM_USE));
+  mem_use->id    = strdup(id);
+  mem_use->vmid  = strdup(vmidentifier);
+  mem_use->membuffsz = membuffsz;
+  evel_init_option_double(&mem_use->memcache);
+  evel_init_option_double(&mem_use->memconfig);
+  evel_init_option_double(&mem_use->memfree);
+  evel_init_option_double(&mem_use->slabrecl);
+  evel_init_option_double(&mem_use->slabunrecl);
+  evel_init_option_double(&mem_use->memused);
+
+  assert(mem_use->id != NULL);
+
+  dlist_push_last(&measurement->mem_usage, mem_use);
+
+  EVEL_EXIT();
+  return mem_use;
+}
+
+/**************************************************************************//**
+ * Set kilobytes of memory used for cache
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mem_use      Pointer to the Memory Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_mem_use_memcache_set(MEASUREMENT_MEM_USE * const mem_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&mem_use->memcache, val, "Memory cache value");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set kilobytes of memory configured in the virtual machine on which the VNFC reporting
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mem_use      Pointer to the Memory Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_mem_use_memconfig_set(MEASUREMENT_MEM_USE * const mem_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&mem_use->memconfig, val, "Memory configured value");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set kilobytes of physical RAM left unused by the system
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mem_use      Pointer to the Memory Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_mem_use_memfree_set(MEASUREMENT_MEM_USE * const mem_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&mem_use->memfree, val, "Memory freely available value");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the part of the slab that can be reclaimed such as caches measured in kilobytes
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mem_use      Pointer to the Memory Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_mem_use_slab_reclaimed_set(MEASUREMENT_MEM_USE * const mem_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&mem_use->slabrecl, val, "Memory reclaimable slab set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the part of the slab that cannot be reclaimed such as caches measured in kilobytes
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mem_use      Pointer to the Memory Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_mem_use_slab_unreclaimable_set(MEASUREMENT_MEM_USE * const mem_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&mem_use->slabunrecl, val, "Memory unreclaimable slab set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the total memory minus the sum of free, buffered, cached and slab memory in kilobytes
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param mem_use      Pointer to the Memory Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_mem_use_usedup_set(MEASUREMENT_MEM_USE * const mem_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&mem_use->memused, val, "Memory usedup total set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add an additional Disk usage value name/value pair to the Measurement.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement   Pointer to the measurement.
+ * @param id            ASCIIZ string with the CPU's identifier.
+ * @param usage         Disk utilization.
+ *****************************************************************************/
+MEASUREMENT_DISK_USE * evel_measurement_new_disk_use_add(EVENT_MEASUREMENT * measurement, char * id)
+{
+  MEASUREMENT_DISK_USE * disk_use = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(id != NULL);
+
+  /***************************************************************************/
+  /* Allocate a container for the value and push onto the list.              */
+  /***************************************************************************/
+  EVEL_DEBUG("Adding id=%s disk usage", id);
+  disk_use = malloc(sizeof(MEASUREMENT_DISK_USE));
+  assert(disk_use != NULL);
+  memset(disk_use, 0, sizeof(MEASUREMENT_DISK_USE));
+  disk_use->id    = strdup(id);
+  assert(disk_use->id != NULL);
+  dlist_push_last(&measurement->disk_usage, disk_use);
+
+  evel_init_option_double(&disk_use->iotimeavg );
+  evel_init_option_double(&disk_use->iotimelast );
+  evel_init_option_double(&disk_use->iotimemax );
+  evel_init_option_double(&disk_use->iotimemin );
+  evel_init_option_double(&disk_use->mergereadavg );
+  evel_init_option_double(&disk_use->mergereadlast );
+  evel_init_option_double(&disk_use->mergereadmax );
+  evel_init_option_double(&disk_use->mergereadmin );
+  evel_init_option_double(&disk_use->mergewriteavg );
+  evel_init_option_double(&disk_use->mergewritelast );
+  evel_init_option_double(&disk_use->mergewritemax );
+  evel_init_option_double(&disk_use->mergewritemin );
+  evel_init_option_double(&disk_use->octetsreadavg );
+  evel_init_option_double(&disk_use->octetsreadlast );
+  evel_init_option_double(&disk_use->octetsreadmax );
+  evel_init_option_double(&disk_use->octetsreadmin );
+  evel_init_option_double(&disk_use->octetswriteavg );
+  evel_init_option_double(&disk_use->octetswritelast );
+  evel_init_option_double(&disk_use->octetswritemax );
+  evel_init_option_double(&disk_use->octetswritemin );
+  evel_init_option_double(&disk_use->opsreadavg );
+  evel_init_option_double(&disk_use->opsreadlast );
+  evel_init_option_double(&disk_use->opsreadmax );
+  evel_init_option_double(&disk_use->opsreadmin );
+  evel_init_option_double(&disk_use->opswriteavg );
+  evel_init_option_double(&disk_use->opswritelast );
+  evel_init_option_double(&disk_use->opswritemax );
+  evel_init_option_double(&disk_use->opswritemin );
+  evel_init_option_double(&disk_use->pendingopsavg );
+  evel_init_option_double(&disk_use->pendingopslast );
+  evel_init_option_double(&disk_use->pendingopsmax );
+  evel_init_option_double(&disk_use->pendingopsmin );
+  evel_init_option_double(&disk_use->timereadavg );
+  evel_init_option_double(&disk_use->timereadlast );
+  evel_init_option_double(&disk_use->timereadmax );
+  evel_init_option_double(&disk_use->timereadmin );
+  evel_init_option_double(&disk_use->timewriteavg );
+  evel_init_option_double(&disk_use->timewritelast );
+  evel_init_option_double(&disk_use->timewritemax );
+  evel_init_option_double(&disk_use->timewritemin );
+
+  EVEL_EXIT();
+  return disk_use;
+}
+
+/**************************************************************************//**
+ * Set milliseconds spent doing input/output operations over 1 sec; treat
+ * this metric as a device load percentage where 1000ms  matches 100% load;
+ * provide the average over the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_iotimeavg_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val) 
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->iotimeavg, val, "Disk ioload set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set milliseconds spent doing input/output operations over 1 sec; treat
+ * this metric as a device load percentage where 1000ms  matches 100% load;
+ * provide the last value within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_iotimelast_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->iotimelast, val, "Disk ioloadlast set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set milliseconds spent doing input/output operations over 1 sec; treat
+ * this metric as a device load percentage where 1000ms  matches 100% load;
+ * provide the maximum value within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_iotimemax_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->iotimemax, val, "Disk ioloadmax set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set milliseconds spent doing input/output operations over 1 sec; treat
+ * this metric as a device load percentage where 1000ms  matches 100% load;
+ * provide the minimum value within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_iotimemin_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->iotimemin, val, "Disk ioloadmin set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set number of logical read operations that were merged into physical read
+ * operations, e.g., two logical reads were served by one physical disk access;
+ * provide the average measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_mergereadavg_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->mergereadavg, val, "Disk Merged read average set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of logical read operations that were merged into physical read
+ * operations, e.g., two logical reads were served by one physical disk access;
+ * provide the last measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_mergereadlast_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->mergereadlast, val, "Disk mergedload last set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of logical read operations that were merged into physical read
+ * operations, e.g., two logical reads were served by one physical disk access;
+ * provide the maximum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_mergereadmax_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->mergereadmax, val, "Disk merged loadmax set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set number of logical read operations that were merged into physical read
+ * operations, e.g., two logical reads were served by one physical disk access;
+ * provide the minimum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_mergereadmin_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->mergereadmin, val, "Disk merged loadmin set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of logical write operations that were merged into physical read
+ * operations, e.g., two logical writes were served by one physical disk access;
+ * provide the last measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_mergewritelast_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->mergewritelast, val, "Disk merged writelast set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of logical write operations that were merged into physical read
+ * operations, e.g., two logical writes were served by one physical disk access;
+ * provide the maximum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_mergewritemax_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->mergewritemax, val, "Disk writemax set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of logical write operations that were merged into physical read
+ * operations, e.g., two logical writes were served by one physical disk access;
+ * provide the maximum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_mergewritemin_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->mergewritemin, val, "Disk writemin set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set number of octets per second read from a disk or partition;
+ * provide the average measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_octetsreadavg_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->octetsreadavg, val, "Octets readavg set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set number of octets per second read from a disk or partition;
+ * provide the last measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_octetsreadlast_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->octetsreadlast, val, "Octets readlast set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set number of octets per second read from a disk or partition;
+ * provide the maximum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_octetsreadmax_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->octetsreadmax, val, "Octets readmax set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of octets per second read from a disk or partition;
+ * provide the minimum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_octetsreadmin_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->octetsreadmin, val, "Octets readmin set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of octets per second written to a disk or partition;
+ * provide the average measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_octetswriteavg_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->octetswriteavg, val, "Octets writeavg set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of octets per second written to a disk or partition;
+ * provide the last measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_octetswritelast_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->octetswritelast, val, "Octets writelast set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of octets per second written to a disk or partition;
+ * provide the maximum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_octetswritemax_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->octetswritemax, val, "Octets writemax set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of octets per second written to a disk or partition;
+ * provide the minimum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_octetswritemin_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->octetswritemin, val, "Octets writemin set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set number of read operations per second issued to the disk;
+ * provide the average measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_opsreadavg_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->opsreadavg, val, "Disk read operation average set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of read operations per second issued to the disk;
+ * provide the last measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_opsreadlast_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->opsreadlast, val, "Disk read operation last set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of read operations per second issued to the disk;
+ * provide the maximum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_opsreadmax_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->opsreadmax, val, "Disk read operation maximum set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of read operations per second issued to the disk;
+ * provide the minimum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_opsreadmin_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->opsreadmin, val, "Disk read operation minimum set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of write operations per second issued to the disk;
+ * provide the average measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_opswriteavg_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->opswriteavg, val, "Disk write operation average set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of write operations per second issued to the disk;
+ * provide the last measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_opswritelast_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->opswritelast, val, "Disk write operation last set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set number of write operations per second issued to the disk;
+ * provide the maximum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_opswritemax_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->opswritemax, val, "Disk write operation maximum set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set number of write operations per second issued to the disk;
+ * provide the average measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_opswritemin_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->opswritemin, val, "Disk write operation minimum set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set queue size of pending I/O operations per second;
+ * provide the average measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_pendingopsavg_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->pendingopsavg, val, "Disk pending operation average set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set queue size of pending I/O operations per second;
+ * provide the last measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_pendingopslast_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->pendingopslast, val, "Disk pending operation last set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set queue size of pending I/O operations per second;
+ * provide the maximum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_pendingopsmax_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->pendingopsmax, val, "Disk pending operation maximum set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set queue size of pending I/O operations per second;
+ * provide the minimum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_pendingopsmin_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->pendingopsmin, val, "Disk pending operation min set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set milliseconds a read operation took to complete;
+ * provide the average measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_timereadavg_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->timereadavg, val, "Disk read time average set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set milliseconds a read operation took to complete;
+ * provide the last measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_timereadlast_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->timereadlast, val, "Disk read time last set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set milliseconds a read operation took to complete;
+ * provide the maximum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_timereadmax_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->timereadmax, val, "Disk read time maximum set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set milliseconds a read operation took to complete;
+ * provide the minimum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_timereadmin_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->timereadmin, val, "Disk read time minimum set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set milliseconds a write operation took to complete;
+ * provide the average measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_timewriteavg_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->timewriteavg, val, "Disk write time average set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set milliseconds a write operation took to complete;
+ * provide the last measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_timewritelast_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->timewritelast, val, "Disk write time last set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set milliseconds a write operation took to complete;
+ * provide the maximum measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_timewritemax_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->timewritemax, val, "Disk write time max set");
+  EVEL_EXIT();
+}
+/**************************************************************************//**
+ * Set milliseconds a write operation took to complete;
+ * provide the average measurement within the measurement interval
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param disk_use     Pointer to the Disk Use.
+ * @param val          double
+ *****************************************************************************/
+void evel_measurement_disk_use_timewritemin_set(MEASUREMENT_DISK_USE * const disk_use,
+                                    const double val)
+{
+  EVEL_ENTER();
+  evel_set_option_double(&disk_use->timewritemin, val, "Disk write time min set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add an additional File System usage value name/value pair to the
+ * Measurement.
+ *
+ * The filesystem_name is null delimited ASCII string.  The library takes a
+ * copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement     Pointer to the measurement.
+ * @param filesystem_name   ASCIIZ string with the file-system's UUID.
+ * @param block_configured  Block storage configured.
+ * @param block_used        Block storage in use.
+ * @param block_iops        Block storage IOPS.
+ * @param ephemeral_configured  Ephemeral storage configured.
+ * @param ephemeral_used        Ephemeral storage in use.
+ * @param ephemeral_iops        Ephemeral storage IOPS.
+ *****************************************************************************/
+void evel_measurement_fsys_use_add(EVENT_MEASUREMENT * measurement,
+                                   char * filesystem_name,
+                                   double block_configured,
+                                   double block_used,
+                                   double block_iops,
+                                   double ephemeral_configured,
+                                   double ephemeral_used,
+                                   double ephemeral_iops)
+{
+  MEASUREMENT_FSYS_USE * fsys_use = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(filesystem_name != NULL);
+  assert(block_configured >= 0.0);
+  assert(block_used >= 0.0);
+  assert(block_iops >= 0.0);
+  assert(ephemeral_configured >= 0.0);
+  assert(ephemeral_used >= 0.0);
+  assert(ephemeral_iops >= 0.0);
+
+  /***************************************************************************/
+  /* Allocate a container for the value and push onto the list.              */
+  /***************************************************************************/
+  EVEL_DEBUG("Adding filesystem_name=%s", filesystem_name);
+  fsys_use = malloc(sizeof(MEASUREMENT_FSYS_USE));
+  assert(fsys_use != NULL);
+  memset(fsys_use, 0, sizeof(MEASUREMENT_FSYS_USE));
+  fsys_use->filesystem_name = strdup(filesystem_name);
+  fsys_use->block_configured = block_configured;
+  fsys_use->block_used = block_used;
+  fsys_use->block_iops = block_iops;
+  fsys_use->ephemeral_configured = ephemeral_configured;
+  fsys_use->ephemeral_used = ephemeral_used;
+  fsys_use->ephemeral_iops = ephemeral_iops;
+
+  dlist_push_last(&measurement->filesystem_usage, fsys_use);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add a Feature usage value name/value pair to the Measurement.
+ *
+ * The name is null delimited ASCII string.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement     Pointer to the measurement.
+ * @param feature         ASCIIZ string with the feature's name.
+ * @param utilization     Utilization of the feature.
+ *****************************************************************************/
+void evel_measurement_feature_use_add(EVENT_MEASUREMENT * measurement,
+                                      char * feature,
+                                      int utilization)
+{
+  MEASUREMENT_FEATURE_USE * feature_use = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(feature != NULL);
+  assert(utilization >= 0);
+
+  /***************************************************************************/
+  /* Allocate a container for the value and push onto the list.              */
+  /***************************************************************************/
+  EVEL_DEBUG("Adding Feature=%s Use=%d", feature, utilization);
+  feature_use = malloc(sizeof(MEASUREMENT_FEATURE_USE));
+  assert(feature_use != NULL);
+  memset(feature_use, 0, sizeof(MEASUREMENT_FEATURE_USE));
+  feature_use->feature_id = strdup(feature);
+  assert(feature_use->feature_id != NULL);
+  feature_use->feature_utilization = utilization;
+
+  dlist_push_last(&measurement->feature_usage, feature_use);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add a Additional Measurement value name/value pair to the Report.
+ *
+ * The name is null delimited ASCII string.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement   Pointer to the Measaurement.
+ * @param group    ASCIIZ string with the measurement group's name.
+ * @param name     ASCIIZ string containing the measurement's name.
+ * @param value    ASCIIZ string containing the measurement's value.
+ *****************************************************************************/
+void evel_measurement_custom_measurement_add(EVENT_MEASUREMENT * measurement,
+                                             const char * const group,
+                                             const char * const name,
+                                             const char * const value)
+{
+  MEASUREMENT_GROUP * measurement_group = NULL;
+  CUSTOM_MEASUREMENT * custom_measurement = NULL;
+  DLIST_ITEM * item = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(group != NULL);
+  assert(name != NULL);
+  assert(value != NULL);
+
+  /***************************************************************************/
+  /* Allocate a container for the name/value pair.                           */
+  /***************************************************************************/
+  EVEL_DEBUG("Adding Measurement Group=%s Name=%s Value=%s",
+              group, name, value);
+  custom_measurement = malloc(sizeof(CUSTOM_MEASUREMENT));
+  assert(custom_measurement != NULL);
+  memset(custom_measurement, 0, sizeof(CUSTOM_MEASUREMENT));
+  custom_measurement->name = strdup(name);
+  assert(custom_measurement->name != NULL);
+  custom_measurement->value = strdup(value);
+  assert(custom_measurement->value != NULL);
+
+  /***************************************************************************/
+  /* See if we have that group already.                                      */
+  /***************************************************************************/
+  item = dlist_get_first(&measurement->additional_measurements);
+  while (item != NULL)
+  {
+    measurement_group = (MEASUREMENT_GROUP *) item->item;
+    assert(measurement_group != NULL);
+
+    EVEL_DEBUG("Got measurement group %s", measurement_group->name);
+    if (strcmp(group, measurement_group->name) == 0)
+    {
+      EVEL_DEBUG("Found existing Measurement Group");
+      break;
+    }
+    item = dlist_get_next(item);
+  }
+
+  /***************************************************************************/
+  /* If we didn't have the group already, create it.                         */
+  /***************************************************************************/
+  if (item == NULL)
+  {
+    EVEL_DEBUG("Creating new Measurement Group");
+    measurement_group = malloc(sizeof(MEASUREMENT_GROUP));
+    assert(measurement_group != NULL);
+    memset(measurement_group, 0, sizeof(MEASUREMENT_GROUP));
+    measurement_group->name = strdup(group);
+    assert(measurement_group->name != NULL);
+    dlist_initialize(&measurement_group->measurements);
+    dlist_push_last(&measurement->additional_measurements, measurement_group);
+  }
+
+  /***************************************************************************/
+  /* If we didn't have the group already, create it.                         */
+  /***************************************************************************/
+  dlist_push_last(&measurement_group->measurements, custom_measurement);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add a Codec usage value name/value pair to the Measurement.
+ *
+ * The name is null delimited ASCII string.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param measurement     Pointer to the measurement.
+ * @param codec           ASCIIZ string with the codec's name.
+ * @param utilization     Number of codecs in use.
+ *****************************************************************************/
+void evel_measurement_codec_use_add(EVENT_MEASUREMENT * measurement,
+                                    char * codec,
+                                    int utilization)
+{
+  MEASUREMENT_CODEC_USE * codec_use = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(codec != NULL);
+  assert(utilization >= 0.0);
+
+  /***************************************************************************/
+  /* Allocate a container for the value and push onto the list.              */
+  /***************************************************************************/
+  EVEL_DEBUG("Adding Codec=%s Use=%d", codec, utilization);
+  codec_use = malloc(sizeof(MEASUREMENT_CODEC_USE));
+  assert(codec_use != NULL);
+  memset(codec_use, 0, sizeof(MEASUREMENT_CODEC_USE));
+  codec_use->codec_id = strdup(codec);
+  assert(codec_use->codec_id != NULL);
+  codec_use->number_in_use = utilization;
+
+  dlist_push_last(&measurement->codec_usage, codec_use);
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Set the Media Ports in Use property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement         Pointer to the measurement.
+ * @param media_ports_in_use  The media port usage to set.
+ *****************************************************************************/
+void evel_measurement_media_port_use_set(EVENT_MEASUREMENT * measurement,
+                                         int media_ports_in_use)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(media_ports_in_use >= 0);
+
+  evel_set_option_int(&measurement->media_ports_in_use,
+                      media_ports_in_use,
+                      "Media Ports In Use");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the VNFC Scaling Metric property of the Measurement.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param measurement     Pointer to the measurement.
+ * @param scaling_metric  The scaling metric to set.
+ *****************************************************************************/
+void evel_measurement_vnfc_scaling_metric_set(EVENT_MEASUREMENT * measurement,
+                                              int scaling_metric)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(scaling_metric >= 0.0);
+
+  evel_set_option_int(&measurement->vnfc_scaling_metric,
+                         scaling_metric,
+                         "VNFC Scaling Metric");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Create a new Latency Bucket to be added to a Measurement event.
+ *
+ * @note    The mandatory fields on the ::MEASUREMENT_LATENCY_BUCKET must be
+ *          supplied to this factory function and are immutable once set.
+ *          Optional fields have explicit setter functions, but again values
+ *          may only be set once so that the ::MEASUREMENT_LATENCY_BUCKET has
+ *          immutable properties.
+ *
+ * @param count         Count of events in this bucket.
+ *
+ * @returns pointer to the newly manufactured ::MEASUREMENT_LATENCY_BUCKET.
+ *          If the structure is not used it must be released using free.
+ * @retval  NULL  Failed to create the Latency Bucket.
+ *****************************************************************************/
+MEASUREMENT_LATENCY_BUCKET * evel_new_meas_latency_bucket(const int count)
+{
+  MEASUREMENT_LATENCY_BUCKET * bucket;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(count >= 0);
+
+  /***************************************************************************/
+  /* Allocate, then set Mandatory Parameters.                                */
+  /***************************************************************************/
+  EVEL_DEBUG("Creating bucket, count = %d", count);
+  bucket = malloc(sizeof(MEASUREMENT_LATENCY_BUCKET));
+  assert(bucket != NULL);
+
+  /***************************************************************************/
+  /* Set Mandatory Parameters.                                               */
+  /***************************************************************************/
+  bucket->count = count;
+
+  /***************************************************************************/
+  /* Initialize Optional Parameters.                                         */
+  /***************************************************************************/
+  evel_init_option_double(&bucket->high_end);
+  evel_init_option_double(&bucket->low_end);
+
+  EVEL_EXIT();
+
+  return bucket;
+}
+
+/**************************************************************************//**
+ * Set the High End property of the Measurement Latency Bucket.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param bucket        Pointer to the Measurement Latency Bucket.
+ * @param high_end      High end of the bucket's range.
+ *****************************************************************************/
+void evel_meas_latency_bucket_high_end_set(
+                                     MEASUREMENT_LATENCY_BUCKET * const bucket,
+                                     const double high_end)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(high_end >= 0.0);
+  evel_set_option_double(&bucket->high_end, high_end, "High End");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Low End property of the Measurement Latency Bucket.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param bucket        Pointer to the Measurement Latency Bucket.
+ * @param low_end       Low end of the bucket's range.
+ *****************************************************************************/
+void evel_meas_latency_bucket_low_end_set(
+                                     MEASUREMENT_LATENCY_BUCKET * const bucket,
+                                     const double low_end)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(low_end >= 0.0);
+  evel_set_option_double(&bucket->low_end, low_end, "Low End");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add an additional Measurement Latency Bucket to the specified event.
+ *
+ * @param measurement   Pointer to the Measurement event.
+ * @param bucket        Pointer to the Measurement Latency Bucket to add.
+ *****************************************************************************/
+void evel_meas_latency_bucket_add(EVENT_MEASUREMENT * const measurement,
+                                  MEASUREMENT_LATENCY_BUCKET * const bucket)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(bucket != NULL);
+  dlist_push_last(&measurement->latency_distribution, bucket);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add an additional Latency Distribution bucket to the Measurement.
+ *
+ * This function implements the previous API, purely for convenience.
+ *
+ * @param measurement   Pointer to the measurement.
+ * @param low_end       Low end of the bucket's range.
+ * @param high_end      High end of the bucket's range.
+ * @param count         Count of events in this bucket.
+ *****************************************************************************/
+void evel_measurement_latency_add(EVENT_MEASUREMENT * const measurement,
+                                  const double low_end,
+                                  const double high_end,
+                                  const int count)
+{
+  MEASUREMENT_LATENCY_BUCKET * bucket = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Trust the assertions in the underlying methods.                         */
+  /***************************************************************************/
+  bucket = evel_new_meas_latency_bucket(count);
+  evel_meas_latency_bucket_low_end_set(bucket, low_end);
+  evel_meas_latency_bucket_high_end_set(bucket, high_end);
+  evel_meas_latency_bucket_add(measurement, bucket);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Create a new vNIC Use to be added to a Measurement event.
+ *
+ * @note    The mandatory fields on the ::MEASUREMENT_VNIC_PERFORMANCE must be supplied
+ *          to this factory function and are immutable once set. Optional
+ *          fields have explicit setter functions, but again values may only be
+ *          set once so that the ::MEASUREMENT_VNIC_PERFORMANCE has immutable
+ *          properties.
+ *
+ * @param vnic_id               ASCIIZ string with the vNIC's ID.
+ * @param val_suspect           True or false confidence in data.
+ *
+ * @returns pointer to the newly manufactured ::MEASUREMENT_VNIC_PERFORMANCE.
+ *          If the structure is not used it must be released using
+ *          ::evel_measurement_free_vnic_performance.
+ * @retval  NULL  Failed to create the vNIC Use.
+ *****************************************************************************/
+MEASUREMENT_VNIC_PERFORMANCE * evel_measurement_new_vnic_performance(char * const vnic_id,
+                                                     char * const val_suspect)
+{
+  MEASUREMENT_VNIC_PERFORMANCE * vnic_performance;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(vnic_id != NULL);
+  assert(!strcmp(val_suspect,"true") || !strcmp(val_suspect,"false"));
+
+  /***************************************************************************/
+  /* Allocate, then set Mandatory Parameters.                                */
+  /***************************************************************************/
+  EVEL_DEBUG("Adding VNIC ID=%s", vnic_id);
+  vnic_performance = malloc(sizeof(MEASUREMENT_VNIC_PERFORMANCE));
+  assert(vnic_performance != NULL);
+  vnic_performance->vnic_id = strdup(vnic_id);
+  vnic_performance->valuesaresuspect = strdup(val_suspect);
+
+  /***************************************************************************/
+  /* Initialize Optional Parameters.                                         */
+  /***************************************************************************/
+  evel_init_option_double(&vnic_performance-> recvd_bcast_packets_acc);
+  evel_init_option_double(&vnic_performance-> recvd_bcast_packets_delta);
+  evel_init_option_double(&vnic_performance-> recvd_discarded_packets_acc);
+  evel_init_option_double(&vnic_performance-> recvd_discarded_packets_delta);
+  evel_init_option_double(&vnic_performance-> recvd_error_packets_acc);
+  evel_init_option_double(&vnic_performance-> recvd_error_packets_delta);
+  evel_init_option_double(&vnic_performance-> recvd_mcast_packets_acc);
+  evel_init_option_double(&vnic_performance-> recvd_mcast_packets_delta);
+  evel_init_option_double(&vnic_performance-> recvd_octets_acc);
+  evel_init_option_double(&vnic_performance-> recvd_octets_delta);
+  evel_init_option_double(&vnic_performance-> recvd_total_packets_acc);
+  evel_init_option_double(&vnic_performance-> recvd_total_packets_delta);
+  evel_init_option_double(&vnic_performance-> recvd_ucast_packets_acc);
+  evel_init_option_double(&vnic_performance-> recvd_ucast_packets_delta);
+  evel_init_option_double(&vnic_performance-> tx_bcast_packets_acc);
+  evel_init_option_double(&vnic_performance-> tx_bcast_packets_delta);
+  evel_init_option_double(&vnic_performance-> tx_discarded_packets_acc);
+  evel_init_option_double(&vnic_performance-> tx_discarded_packets_delta);
+  evel_init_option_double(&vnic_performance-> tx_error_packets_acc);
+  evel_init_option_double(&vnic_performance-> tx_error_packets_delta);
+  evel_init_option_double(&vnic_performance-> tx_mcast_packets_acc);
+  evel_init_option_double(&vnic_performance-> tx_mcast_packets_delta);
+  evel_init_option_double(&vnic_performance-> tx_octets_acc);
+  evel_init_option_double(&vnic_performance-> tx_octets_delta);
+  evel_init_option_double(&vnic_performance-> tx_total_packets_acc);
+  evel_init_option_double(&vnic_performance-> tx_total_packets_delta);
+  evel_init_option_double(&vnic_performance-> tx_ucast_packets_acc);
+  evel_init_option_double(&vnic_performance-> tx_ucast_packets_delta);
+
+  EVEL_EXIT();
+
+  return vnic_performance;
+}
+
+/**************************************************************************//**
+ * Free a vNIC Use.
+ *
+ * Free off the ::MEASUREMENT_VNIC_PERFORMANCE supplied.  Will free all the contained
+ * allocated memory.
+ *
+ * @note It does not free the vNIC Use itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_measurement_free_vnic_performance(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(vnic_performance != NULL);
+  assert(vnic_performance->vnic_id != NULL);
+  assert(vnic_performance->valuesaresuspect != NULL);
+
+  /***************************************************************************/
+  /* Free the duplicated string.                                             */
+  /***************************************************************************/
+  free(vnic_performance->vnic_id);
+  free(vnic_performance->valuesaresuspect);
+  vnic_performance->vnic_id = NULL;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Accumulated Broadcast Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_bcast_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_bcast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_bcast_packets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_bcast_packets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_bcast_packets_acc,
+                      recvd_bcast_packets_acc,
+                      "Broadcast Packets accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Broadcast Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_bcast_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_bcast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_bcast_packets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_bcast_packets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_bcast_packets_delta,
+                      recvd_bcast_packets_delta,
+                      "Delta Broadcast Packets recieved");
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Set the Discarded Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_discard_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_discard_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_discard_packets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_discard_packets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_discarded_packets_acc,
+                      recvd_discard_packets_acc,
+                      "Discarded Packets accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Discarded Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_discard_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_discard_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_discard_packets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_discard_packets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_discarded_packets_delta,
+                      recvd_discard_packets_delta,
+                      "Delta Discarded Packets recieved");
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Set the Error Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_error_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_error_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_error_packets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_error_packets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_error_packets_acc,
+                      recvd_error_packets_acc,
+                      "Error Packets received accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Error Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_error_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_error_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_error_packets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_error_packets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_error_packets_delta,
+                      recvd_error_packets_delta,
+                      "Delta Error Packets recieved");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Accumulated Multicast Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_mcast_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_mcast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_mcast_packets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_mcast_packets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_mcast_packets_acc,
+                      recvd_mcast_packets_acc,
+                      "Multicast Packets accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Multicast Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_mcast_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_mcast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_mcast_packets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_mcast_packets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_mcast_packets_delta,
+                      recvd_mcast_packets_delta,
+                      "Delta Multicast Packets recieved");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Accumulated Octets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_octets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_octets_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_octets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_octets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_octets_acc,
+                      recvd_octets_acc,
+                      "Octets received accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Octets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_octets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_octets_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_octets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_octets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_octets_delta,
+                      recvd_octets_delta,
+                      "Delta Octets recieved");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Accumulated Total Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_total_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_total_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_total_packets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_total_packets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_total_packets_acc,
+                      recvd_total_packets_acc,
+                      "Total Packets accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Total Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_total_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_total_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_total_packets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_total_packets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_total_packets_delta,
+                      recvd_total_packets_delta,
+                      "Delta Total Packets recieved");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Accumulated Unicast Packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_ucast_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_rx_ucast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_ucast_packets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_ucast_packets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_ucast_packets_acc,
+                      recvd_ucast_packets_acc,
+                      "Unicast Packets received accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Unicast packets Received in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param recvd_ucast_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_rx_ucast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double recvd_ucast_packets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(recvd_ucast_packets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->recvd_ucast_packets_delta,
+                      recvd_ucast_packets_delta,
+                      "Delta Unicast packets recieved");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Transmitted Broadcast Packets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_bcast_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_bcast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_bcast_packets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_bcast_packets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_bcast_packets_acc,
+                      tx_bcast_packets_acc,
+                      "Transmitted Broadcast Packets accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Broadcast packets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_bcast_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_bcast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_bcast_packets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_bcast_packets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_bcast_packets_delta,
+                      tx_bcast_packets_delta,
+                      "Delta Transmitted Broadcast packets ");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Transmitted Discarded Packets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_discarded_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_discarded_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_discarded_packets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_discarded_packets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_discarded_packets_acc,
+                      tx_discarded_packets_acc,
+                      "Transmitted Discarded Packets accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Discarded packets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_discarded_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_discarded_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_discarded_packets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_discarded_packets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_discarded_packets_delta,
+                      tx_discarded_packets_delta,
+                      "Delta Transmitted Discarded packets ");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Transmitted Errored Packets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_error_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_error_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_error_packets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_error_packets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_error_packets_acc,
+                      tx_error_packets_acc,
+                      "Transmitted Error Packets accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Errored packets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_error_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_error_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_error_packets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_error_packets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_error_packets_delta,
+                      tx_error_packets_delta,
+                      "Delta Transmitted Error packets ");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Transmitted Multicast Packets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_mcast_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_mcast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_mcast_packets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_mcast_packets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_mcast_packets_acc,
+                      tx_mcast_packets_acc,
+                      "Transmitted Multicast Packets accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Multicast packets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_mcast_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_mcast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_mcast_packets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_mcast_packets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_mcast_packets_delta,
+                      tx_mcast_packets_delta,
+                      "Delta Transmitted Multicast packets ");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Transmitted Octets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_octets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_octets_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_octets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_octets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_octets_acc,
+                      tx_octets_acc,
+                      "Transmitted Octets accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Octets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_octets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_octets_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_octets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_octets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_octets_delta,
+                      tx_octets_delta,
+                      "Delta Transmitted Octets ");
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Set the Transmitted Total Packets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_total_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_total_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_total_packets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_total_packets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_total_packets_acc,
+                      tx_total_packets_acc,
+                      "Transmitted Total Packets accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Total Packets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_total_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_total_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_total_packets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_total_packets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_total_packets_delta,
+                      tx_total_packets_delta,
+                      "Delta Transmitted Total Packets ");
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Set the Transmitted Unicast Packets in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_ucast_packets_acc
+ *****************************************************************************/
+void evel_vnic_performance_tx_ucast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_ucast_packets_acc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_ucast_packets_acc >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_ucast_packets_acc,
+                      tx_ucast_packets_acc,
+                      "Transmitted Unicast Packets accumulated");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Delta Octets Transmitted in measurement interval
+ * property of the vNIC performance.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param vnic_performance      Pointer to the vNIC Use.
+ * @param tx_ucast_packets_delta
+ *****************************************************************************/
+void evel_vnic_performance_tx_ucast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance,
+                                    const double tx_ucast_packets_delta)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(tx_ucast_packets_delta >= 0.0);
+
+  evel_set_option_double(&vnic_performance->tx_ucast_packets_delta,
+                      tx_ucast_packets_delta,
+                      "Delta Transmitted Unicast Packets ");
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Add an additional vNIC Use to the specified Measurement event.
+ *
+ * @param measurement   Pointer to the measurement.
+ * @param vnic_performance      Pointer to the vNIC Use to add.
+ *****************************************************************************/
+void evel_meas_vnic_performance_add(EVENT_MEASUREMENT * const measurement,
+                            MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(measurement != NULL);
+  assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+  assert(vnic_performance != NULL);
+
+  dlist_push_last(&measurement->vnic_usage, vnic_performance);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add an additional vNIC usage record Measurement.
+ *
+ * This function implements the previous API, purely for convenience.
+ *
+ * The ID is null delimited ASCII string.  The library takes a copy so the
+ * caller does not have to preserve values after the function returns.
+ *
+ * @param measurement           Pointer to the measurement.
+ * @param vnic_id               ASCIIZ string with the vNIC's ID.
+ * @param valset                true or false confidence level
+ * @param recvd_bcast_packets_acc         Recieved broadcast packets
+ * @param recvd_bcast_packets_delta       Received delta broadcast packets
+ * @param recvd_discarded_packets_acc     Recieved discarded packets
+ * @param recvd_discarded_packets_delta   Received discarded delta packets
+ * @param recvd_error_packets_acc         Received error packets
+ * @param recvd_error_packets_delta,      Received delta error packets
+ * @param recvd_mcast_packets_acc         Received multicast packets
+ * @param recvd_mcast_packets_delta       Received delta multicast packets
+ * @param recvd_octets_acc                Received octets
+ * @param recvd_octets_delta              Received delta octets
+ * @param recvd_total_packets_acc         Received total packets
+ * @param recvd_total_packets_delta       Received delta total packets
+ * @param recvd_ucast_packets_acc         Received Unicast packets
+ * @param recvd_ucast_packets_delta       Received delta unicast packets
+ * @param tx_bcast_packets_acc            Transmitted broadcast packets
+ * @param tx_bcast_packets_delta          Transmitted delta broadcast packets
+ * @param tx_discarded_packets_acc        Transmitted packets discarded
+ * @param tx_discarded_packets_delta      Transmitted delta discarded packets
+ * @param tx_error_packets_acc            Transmitted error packets
+ * @param tx_error_packets_delta          Transmitted delta error packets
+ * @param tx_mcast_packets_acc            Transmitted multicast packets accumulated
+ * @param tx_mcast_packets_delta          Transmitted delta multicast packets
+ * @param tx_octets_acc                   Transmitted octets
+ * @param tx_octets_delta                 Transmitted delta octets
+ * @param tx_total_packets_acc            Transmitted total packets
+ * @param tx_total_packets_delta          Transmitted delta total packets
+ * @param tx_ucast_packets_acc            Transmitted Unicast packets
+ * @param tx_ucast_packets_delta          Transmitted delta Unicast packets
+ *****************************************************************************/
+void evel_measurement_vnic_performance_add(EVENT_MEASUREMENT * const measurement,
+                               char * const vnic_id,
+                               char * valset,
+                               double recvd_bcast_packets_acc,
+                               double recvd_bcast_packets_delta,
+                               double recvd_discarded_packets_acc,
+                               double recvd_discarded_packets_delta,
+                               double recvd_error_packets_acc,
+                               double recvd_error_packets_delta,
+                               double recvd_mcast_packets_acc,
+                               double recvd_mcast_packets_delta,
+                               double recvd_octets_acc,
+                               double recvd_octets_delta,
+                               double recvd_total_packets_acc,
+                               double recvd_total_packets_delta,
+                               double recvd_ucast_packets_acc,
+                               double recvd_ucast_packets_delta,
+                               double tx_bcast_packets_acc,
+                               double tx_bcast_packets_delta,
+                               double tx_discarded_packets_acc,
+                               double tx_discarded_packets_delta,
+                               double tx_error_packets_acc,
+                               double tx_error_packets_delta,
+                               double tx_mcast_packets_acc,
+                               double tx_mcast_packets_delta,
+                               double tx_octets_acc,
+                               double tx_octets_delta,
+                               double tx_total_packets_acc,
+                               double tx_total_packets_delta,
+                               double tx_ucast_packets_acc,
+                               double tx_ucast_packets_delta)
+{
+  MEASUREMENT_VNIC_PERFORMANCE * vnic_performance = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Trust the assertions in the underlying methods.                         */
+  /***************************************************************************/
+  vnic_performance = evel_measurement_new_vnic_performance(vnic_id, valset);
+                                           
+  evel_vnic_performance_rx_bcast_pkt_acc_set(vnic_performance, recvd_bcast_packets_acc);
+  evel_vnic_performance_rx_bcast_pkt_delta_set(vnic_performance, recvd_bcast_packets_delta);
+  evel_vnic_performance_rx_discard_pkt_acc_set(vnic_performance, recvd_discarded_packets_acc);
+  evel_vnic_performance_rx_discard_pkt_delta_set(vnic_performance, recvd_discarded_packets_delta);
+  evel_vnic_performance_rx_error_pkt_acc_set(vnic_performance, recvd_error_packets_acc);
+  evel_vnic_performance_rx_error_pkt_delta_set(vnic_performance, recvd_error_packets_delta);
+  evel_vnic_performance_rx_mcast_pkt_acc_set(vnic_performance, recvd_mcast_packets_acc);
+  evel_vnic_performance_rx_mcast_pkt_delta_set(vnic_performance, recvd_mcast_packets_delta);
+  evel_vnic_performance_rx_octets_acc_set(vnic_performance, recvd_octets_acc);
+  evel_vnic_performance_rx_octets_delta_set(vnic_performance, recvd_octets_delta);
+  evel_vnic_performance_rx_total_pkt_acc_set(vnic_performance, recvd_total_packets_acc);
+  evel_vnic_performance_rx_total_pkt_delta_set(vnic_performance, recvd_total_packets_delta);
+  evel_vnic_performance_rx_ucast_pkt_acc_set(vnic_performance, recvd_ucast_packets_acc);
+  evel_vnic_performance_rx_ucast_pkt_delta_set(vnic_performance, recvd_ucast_packets_delta);
+  evel_vnic_performance_tx_bcast_pkt_acc_set(vnic_performance, tx_bcast_packets_acc);
+  evel_vnic_performance_tx_bcast_pkt_delta_set(vnic_performance, tx_bcast_packets_delta);
+  evel_vnic_performance_tx_discarded_pkt_acc_set(vnic_performance, tx_discarded_packets_acc);
+  evel_vnic_performance_tx_discarded_pkt_delta_set(vnic_performance, tx_discarded_packets_delta);
+  evel_vnic_performance_tx_error_pkt_acc_set(vnic_performance, tx_error_packets_acc);
+  evel_vnic_performance_tx_error_pkt_delta_set(vnic_performance, tx_error_packets_delta);
+  evel_vnic_performance_tx_mcast_pkt_acc_set(vnic_performance, tx_mcast_packets_acc);
+  evel_vnic_performance_tx_mcast_pkt_delta_set(vnic_performance, tx_mcast_packets_delta);
+  evel_vnic_performance_tx_octets_acc_set(vnic_performance, tx_octets_acc);
+  evel_vnic_performance_tx_octets_delta_set(vnic_performance, tx_octets_delta);
+  evel_vnic_performance_tx_total_pkt_acc_set(vnic_performance, tx_total_packets_acc);
+  evel_vnic_performance_tx_total_pkt_delta_set(vnic_performance, tx_total_packets_delta);
+  evel_vnic_performance_tx_ucast_pkt_acc_set(vnic_performance, tx_ucast_packets_acc);
+  evel_vnic_performance_tx_ucast_pkt_delta_set(vnic_performance, tx_ucast_packets_delta);
+  evel_meas_vnic_performance_add(measurement, vnic_performance);
+}
+
+/**************************************************************************//**
+ * Encode the measurement as a JSON measurement.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_measurement(EVEL_JSON_BUFFER * jbuf,
+                                  EVENT_MEASUREMENT * event)
+{
+  MEASUREMENT_CPU_USE * cpu_use = NULL;
+  MEASUREMENT_MEM_USE * mem_use = NULL;
+  MEASUREMENT_DISK_USE * disk_use = NULL;
+  MEASUREMENT_FSYS_USE * fsys_use = NULL;
+  MEASUREMENT_LATENCY_BUCKET * bucket = NULL;
+  MEASUREMENT_VNIC_PERFORMANCE * vnic_performance = NULL;
+  MEASUREMENT_ERRORS * errors = NULL;
+  MEASUREMENT_FEATURE_USE * feature_use = NULL;
+  MEASUREMENT_CODEC_USE * codec_use = NULL;
+  MEASUREMENT_GROUP * measurement_group = NULL;
+  CUSTOM_MEASUREMENT * custom_measurement = NULL;
+  DLIST_ITEM * item = NULL;
+  DLIST_ITEM * nested_item = NULL;
+  DLIST_ITEM * addl_info_item = NULL;
+  OTHER_FIELD *addl_info = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+
+  evel_json_encode_header(jbuf, &event->header);
+  evel_json_open_named_object(jbuf, "measurementsForVfScalingFields");
+
+  /***************************************************************************/
+  /* Mandatory fields.                                                       */
+  /***************************************************************************/
+  evel_enc_kv_int(jbuf, "measurementInterval", event->measurement_interval);
+
+  /***************************************************************************/
+  /* Optional fields.                                                        */
+  /***************************************************************************/
+  // additional fields
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "additionalFields"))
+  {
+    bool item_added = false;
+
+    addl_info_item = dlist_get_first(&event->additional_info);
+    while (addl_info_item != NULL)
+    {
+      addl_info = (OTHER_FIELD*) addl_info_item->item;
+      assert(addl_info != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "additionalFields",
+                                          addl_info->name))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "name", addl_info->name);
+        evel_enc_kv_string(jbuf, "value", addl_info->value);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      addl_info_item = dlist_get_next(addl_info_item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+  // TBD additional json objects
+  evel_enc_kv_opt_int(jbuf, "concurrentSessions", &event->concurrent_sessions);
+  evel_enc_kv_opt_int(jbuf, "configuredEntities", &event->configured_entities);
+
+  /***************************************************************************/
+  /* CPU Use list.                                                           */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "cpuUsageArray"))
+  {
+    bool item_added = false;
+
+    item = dlist_get_first(&event->cpu_usage);
+    while (item != NULL)
+    {
+      cpu_use = (MEASUREMENT_CPU_USE*) item->item;
+      assert(cpu_use != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "cpuUsageArray",
+                                          cpu_use->id))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "cpuIdentifier", cpu_use->id);
+        evel_enc_kv_opt_double(jbuf, "cpuIdle", &cpu_use->idle);
+        evel_enc_kv_opt_double(jbuf, "cpuUsageInterrupt", &cpu_use->intrpt);
+        evel_enc_kv_opt_double(jbuf, "cpuUsageNice", &cpu_use->nice);
+        evel_enc_kv_opt_double(jbuf, "cpuUsageSoftIrq", &cpu_use->softirq);
+        evel_enc_kv_opt_double(jbuf, "cpuUsageSteal", &cpu_use->steal);
+        evel_enc_kv_opt_double(jbuf, "cpuUsageSystem", &cpu_use->sys);
+        evel_enc_kv_opt_double(jbuf, "cpuUsageUser", &cpu_use->user);
+        evel_enc_kv_opt_double(jbuf, "cpuWait", &cpu_use->wait);
+        evel_enc_kv_double(jbuf, "percentUsage",cpu_use->usage);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      item = dlist_get_next(item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+
+  /***************************************************************************/
+  /* Disk Use list.                                                           */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "diskUsageArray"))
+  {
+    bool item_added = false;
+
+    item = dlist_get_first(&event->disk_usage);
+    while (item != NULL)
+    {
+      disk_use = (MEASUREMENT_DISK_USE*) item->item;
+      assert(disk_use != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "diskUsageArray",
+                                          disk_use->id))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "diskIdentifier", disk_use->id);
+        evel_enc_kv_opt_double(jbuf, "diskIoTimeAvg", &disk_use->iotimeavg);
+        evel_enc_kv_opt_double(jbuf, "diskIoTimeLast", &disk_use->iotimelast);
+        evel_enc_kv_opt_double(jbuf, "diskIoTimeMax", &disk_use->iotimemax);
+        evel_enc_kv_opt_double(jbuf, "diskIoTimeMin", &disk_use->iotimemin);
+        evel_enc_kv_opt_double(jbuf, "diskMergedReadAvg", &disk_use->mergereadavg);
+        evel_enc_kv_opt_double(jbuf, "diskMergedReadLast", &disk_use->mergereadlast);
+        evel_enc_kv_opt_double(jbuf, "diskMergedReadMax", &disk_use->mergereadmax);
+        evel_enc_kv_opt_double(jbuf, "diskMergedReadMin", &disk_use->mergereadmin);
+        evel_enc_kv_opt_double(jbuf, "diskMergedWriteAvg", &disk_use->mergewriteavg);
+        evel_enc_kv_opt_double(jbuf, "diskMergedWriteLast", &disk_use->mergewritelast);
+        evel_enc_kv_opt_double(jbuf, "diskMergedWriteMax", &disk_use->mergewritemax);
+        evel_enc_kv_opt_double(jbuf, "diskMergedWriteMin", &disk_use->mergewritemin);
+        evel_enc_kv_opt_double(jbuf, "diskOctetsReadAvg", &disk_use->octetsreadavg);
+        evel_enc_kv_opt_double(jbuf, "diskOctetsReadLast", &disk_use->octetsreadlast);
+        evel_enc_kv_opt_double(jbuf, "diskOctetsReadMax", &disk_use->octetsreadmax);
+        evel_enc_kv_opt_double(jbuf, "diskOctetsReadMin", &disk_use->octetsreadmin);
+        evel_enc_kv_opt_double(jbuf, "diskOctetsWriteAvg", &disk_use->octetswriteavg);
+        evel_enc_kv_opt_double(jbuf, "diskOctetsWriteLast", &disk_use->octetswritelast);
+        evel_enc_kv_opt_double(jbuf, "diskOctetsWriteMax", &disk_use->octetswritemax);
+        evel_enc_kv_opt_double(jbuf, "diskOctetsWriteMin", &disk_use->octetswritemin);
+        evel_enc_kv_opt_double(jbuf, "diskOpsReadAvg", &disk_use->opsreadavg);
+        evel_enc_kv_opt_double(jbuf, "diskOpsReadLast", &disk_use->opsreadlast);
+        evel_enc_kv_opt_double(jbuf, "diskOpsReadMax", &disk_use->opsreadmax);
+        evel_enc_kv_opt_double(jbuf, "diskOpsReadMin", &disk_use->opsreadmin);
+        evel_enc_kv_opt_double(jbuf, "diskOpsWriteAvg", &disk_use->opswriteavg);
+        evel_enc_kv_opt_double(jbuf, "diskOpsWriteLast", &disk_use->opswritelast);
+        evel_enc_kv_opt_double(jbuf, "diskOpsWriteMax", &disk_use->opswritemax);
+        evel_enc_kv_opt_double(jbuf, "diskOpsWriteMin", &disk_use->opswritemin);
+        evel_enc_kv_opt_double(jbuf, "diskPendingOperationsAvg", &disk_use->pendingopsavg);
+        evel_enc_kv_opt_double(jbuf, "diskPendingOperationsLast", &disk_use->pendingopslast);
+        evel_enc_kv_opt_double(jbuf, "diskPendingOperationsMax", &disk_use->pendingopsmax);
+        evel_enc_kv_opt_double(jbuf, "diskPendingOperationsMin", &disk_use->pendingopsmin);
+        evel_enc_kv_opt_double(jbuf, "diskTimeReadAvg", &disk_use->timereadavg);
+        evel_enc_kv_opt_double(jbuf, "diskTimeReadLast", &disk_use->timereadlast);
+        evel_enc_kv_opt_double(jbuf, "diskTimeReadMax", &disk_use->timereadmax);
+        evel_enc_kv_opt_double(jbuf, "diskTimeReadMin", &disk_use->timereadmin);
+        evel_enc_kv_opt_double(jbuf, "diskTimeWriteAvg", &disk_use->timewriteavg);
+        evel_enc_kv_opt_double(jbuf, "diskTimeWriteLast", &disk_use->timewritelast);
+        evel_enc_kv_opt_double(jbuf, "diskTimeWriteMax", &disk_use->timewritemax);
+        evel_enc_kv_opt_double(jbuf, "diskTimeWriteMin", &disk_use->timewritemin);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      item = dlist_get_next(item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+  /***************************************************************************/
+  /* Filesystem Usage list.                                                  */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "filesystemUsageArray"))
+  {
+    bool item_added = false;
+
+    item = dlist_get_first(&event->filesystem_usage);
+    while (item != NULL)
+    {
+      fsys_use = (MEASUREMENT_FSYS_USE *) item->item;
+      assert(fsys_use != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "filesystemUsageArray",
+                                          fsys_use->filesystem_name))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "filesystemName", fsys_use->filesystem_name);
+        evel_enc_kv_double(
+          jbuf, "blockConfigured", fsys_use->block_configured);
+        evel_enc_kv_double(jbuf, "blockIops", fsys_use->block_iops);
+        evel_enc_kv_double(jbuf, "blockUsed", fsys_use->block_used);
+        evel_enc_kv_double(
+          jbuf, "ephemeralConfigured", fsys_use->ephemeral_configured);
+        evel_enc_kv_double(jbuf, "ephemeralIops", fsys_use->ephemeral_iops);
+        evel_enc_kv_double(jbuf, "ephemeralUsed", fsys_use->ephemeral_used);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      item = dlist_get_next(item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+  /***************************************************************************/
+  /* Latency distribution.                                                   */
+  /***************************************************************************/
+  item = dlist_get_first(&event->latency_distribution);
+  if ((item != NULL) &&
+      evel_json_open_opt_named_list(jbuf, "latencyDistribution"))
+  {
+    while (item != NULL)
+    {
+      bucket = (MEASUREMENT_LATENCY_BUCKET*) item->item;
+      assert(bucket != NULL);
+
+      evel_json_open_object(jbuf);
+      evel_enc_kv_opt_double(
+        jbuf, "lowEndOfLatencyBucket", &bucket->low_end);
+      evel_enc_kv_opt_double(
+        jbuf, "highEndOfLatencyBucket", &bucket->high_end);
+      evel_enc_kv_int(jbuf, "countsInTheBucket", bucket->count);
+      evel_json_close_object(jbuf);
+      item = dlist_get_next(item);
+    }
+    evel_json_close_list(jbuf);
+  }
+
+  evel_enc_kv_opt_double(
+    jbuf, "meanRequestLatency", &event->mean_request_latency);
+  evel_enc_kv_opt_int(jbuf, "requestRate", &event->request_rate);
+
+  /***************************************************************************/
+  /* vNIC Usage TBD Performance array                          */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "vNicUsageArray"))
+  {
+    bool item_added = false;
+
+    item = dlist_get_first(&event->vnic_usage);
+    while (item != NULL)
+    {
+      vnic_performance = (MEASUREMENT_VNIC_PERFORMANCE *) item->item;
+      assert(vnic_performance != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "vNicPerformanceArray",
+                                          vnic_performance->vnic_id))
+      {
+        evel_json_open_object(jbuf);
+
+        /*********************************************************************/
+        /* Optional fields.                                                  */
+        /*********************************************************************/
+        evel_enc_kv_opt_double( jbuf,
+                "receivedBroadcastPacketsAccumulated", &vnic_performance->recvd_bcast_packets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedBroadcastPacketsDelta", &vnic_performance->recvd_bcast_packets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedDiscardedPacketsAccumulated", &vnic_performance->recvd_discarded_packets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedDiscardedPacketsDelta", &vnic_performance->recvd_discarded_packets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedErrorPacketsAccumulated", &vnic_performance->recvd_error_packets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedErrorPacketsDelta", &vnic_performance->recvd_error_packets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedMulticastPacketsAccumulated", &vnic_performance->recvd_mcast_packets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedMulticastPacketsDelta", &vnic_performance->recvd_mcast_packets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedOctetsAccumulated", &vnic_performance->recvd_octets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedOctetsDelta", &vnic_performance->recvd_octets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedTotalPacketsAccumulated", &vnic_performance->recvd_total_packets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedTotalPacketsDelta", &vnic_performance->recvd_total_packets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedUnicastPacketsAccumulated", &vnic_performance->recvd_ucast_packets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "receivedUnicastPacketsDelta", &vnic_performance->recvd_ucast_packets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedBroadcastPacketsAccumulated", &vnic_performance->tx_bcast_packets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedBroadcastPacketsDelta", &vnic_performance->tx_bcast_packets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedDiscardedPacketsAccumulated", &vnic_performance->tx_discarded_packets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedDiscardedPacketsDelta", &vnic_performance->tx_discarded_packets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedErrorPacketsAccumulated", &vnic_performance->tx_error_packets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedErrorPacketsDelta", &vnic_performance->tx_error_packets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedMulticastPacketsAccumulated", &vnic_performance->tx_mcast_packets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedMulticastPacketsDelta", &vnic_performance->tx_mcast_packets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedOctetsAccumulated", &vnic_performance->tx_octets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedOctetsDelta", &vnic_performance->tx_octets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedTotalPacketsAccumulated", &vnic_performance->tx_total_packets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedTotalPacketsDelta", &vnic_performance->tx_total_packets_delta);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedUnicastPacketsAccumulated", &vnic_performance->tx_ucast_packets_acc);
+        evel_enc_kv_opt_double( jbuf,
+                "transmittedUnicastPacketsDelta", &vnic_performance->tx_ucast_packets_delta);
+
+        /*********************************************************************/
+        /* Mandatory fields.                                                 */
+        /*********************************************************************/
+        evel_enc_kv_string(jbuf, "valuesAreSuspect", vnic_performance->valuesaresuspect);
+        evel_enc_kv_string(jbuf, "vNicIdentifier", vnic_performance->vnic_id);
+
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      item = dlist_get_next(item);
+    }
+
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+
+  /***************************************************************************/
+  /* Memory Use list.                                                           */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "memoryUsageArray"))
+  {
+    bool item_added = false;
+
+    item = dlist_get_first(&event->mem_usage);
+    while (item != NULL)
+    {
+      mem_use = (MEASUREMENT_MEM_USE*) item->item;
+      assert(mem_use != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "memoryUsageArray",
+                                          mem_use->id))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_double(jbuf, "memoryBuffered", mem_use->membuffsz);
+        evel_enc_kv_opt_double(jbuf, "memoryCached", &mem_use->memcache);
+        evel_enc_kv_opt_double(jbuf, "memoryConfigured", &mem_use->memconfig);
+        evel_enc_kv_opt_double(jbuf, "memoryFree", &mem_use->memfree);
+        evel_enc_kv_opt_double(jbuf, "memorySlabRecl", &mem_use->slabrecl);
+        evel_enc_kv_opt_double(jbuf, "memorySlabUnrecl", &mem_use->slabunrecl);
+        evel_enc_kv_opt_double(jbuf, "memoryUsed", &mem_use->memused);
+        evel_enc_kv_string(jbuf, "vmIdentifier", mem_use->id);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      item = dlist_get_next(item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+
+  evel_enc_kv_opt_int(
+    jbuf, "numberOfMediaPortsInUse", &event->media_ports_in_use);
+  evel_enc_kv_opt_int(
+    jbuf, "vnfcScalingMetric", &event->vnfc_scaling_metric);
+
+  /***************************************************************************/
+  /* Errors list.                                                            */
+  /***************************************************************************/
+  if ((event->errors != NULL) &&
+      evel_json_open_opt_named_object(jbuf, "errors"))
+  {
+    errors = event->errors;
+    evel_enc_kv_int(jbuf, "receiveDiscards", errors->receive_discards);
+    evel_enc_kv_int(jbuf, "receiveErrors", errors->receive_errors);
+    evel_enc_kv_int(jbuf, "transmitDiscards", errors->transmit_discards);
+    evel_enc_kv_int(jbuf, "transmitErrors", errors->transmit_errors);
+    evel_json_close_object(jbuf);
+  }
+
+  /***************************************************************************/
+  /* Feature Utilization list.                                               */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "featureUsageArray"))
+  {
+    bool item_added = false;
+
+    item = dlist_get_first(&event->feature_usage);
+    while (item != NULL)
+    {
+      feature_use = (MEASUREMENT_FEATURE_USE*) item->item;
+      assert(feature_use != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "featureUsageArray",
+                                          feature_use->feature_id))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "featureIdentifier", feature_use->feature_id);
+        evel_enc_kv_int(
+          jbuf, "featureUtilization", feature_use->feature_utilization);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      item = dlist_get_next(item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+  /***************************************************************************/
+  /* Codec Utilization list.                                                 */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "codecUsageArray"))
+  {
+    bool item_added = false;
+
+    item = dlist_get_first(&event->codec_usage);
+    while (item != NULL)
+    {
+      codec_use = (MEASUREMENT_CODEC_USE*) item->item;
+      assert(codec_use != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "codecUsageArray",
+                                          codec_use->codec_id))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "codecIdentifier", codec_use->codec_id);
+        evel_enc_kv_int(jbuf, "numberInUse", codec_use->number_in_use);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      item = dlist_get_next(item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+  /***************************************************************************/
+  /* Additional Measurement Groups list.                                     */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "additionalMeasurements"))
+  {
+    bool item_added = false;
+
+    item = dlist_get_first(&event->additional_measurements);
+    while (item != NULL)
+    {
+      measurement_group = (MEASUREMENT_GROUP *) item->item;
+      assert(measurement_group != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "additionalMeasurements",
+                                          measurement_group->name))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "name", measurement_group->name);
+        evel_json_open_opt_named_list(jbuf, "measurements");
+
+        /*********************************************************************/
+        /* Measurements list.                                                */
+        /*********************************************************************/
+        nested_item = dlist_get_first(&measurement_group->measurements);
+        while (nested_item != NULL)
+        {
+          custom_measurement = (CUSTOM_MEASUREMENT *) nested_item->item;
+          assert(custom_measurement != NULL);
+
+          evel_json_open_object(jbuf);
+          evel_enc_kv_string(jbuf, "name", custom_measurement->name);
+          evel_enc_kv_string(jbuf, "value", custom_measurement->value);
+          evel_json_close_object(jbuf);
+          nested_item = dlist_get_next(nested_item);
+        }
+        evel_json_close_list(jbuf);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      item = dlist_get_next(item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+  /***************************************************************************/
+  /* Although optional, we always generate the version.  Note that this      */
+  /* closes the object, too.                                                 */
+  /***************************************************************************/
+  evel_enc_version(jbuf,
+                   "measurementsForVfScalingVersion",
+                   event->major_version,
+                   event->minor_version);
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free a Measurement.
+ *
+ * Free off the Measurement supplied.  Will free all the contained allocated
+ * memory.
+ *
+ * @note It does not free the Measurement itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_measurement(EVENT_MEASUREMENT * event)
+{
+  MEASUREMENT_CPU_USE * cpu_use = NULL;
+  MEASUREMENT_DISK_USE * disk_use = NULL;
+  MEASUREMENT_FSYS_USE * fsys_use = NULL;
+  MEASUREMENT_LATENCY_BUCKET * bucket = NULL;
+  MEASUREMENT_MEM_USE * mem_use = NULL;
+  MEASUREMENT_VNIC_PERFORMANCE * vnic_performance = NULL;
+  MEASUREMENT_FEATURE_USE * feature_use = NULL;
+  MEASUREMENT_CODEC_USE * codec_use = NULL;
+  MEASUREMENT_GROUP * measurement_group = NULL;
+  CUSTOM_MEASUREMENT * measurement = NULL;
+  OTHER_FIELD *addl_info = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+  /* events as we do on the public API.                                      */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
+
+  /***************************************************************************/
+  /* Free all internal strings then the header itself.                       */
+  /***************************************************************************/
+  addl_info = dlist_pop_last(&event->additional_info);
+  while (addl_info != NULL)
+  {
+    EVEL_DEBUG("Freeing Additional Info (%s, %s)",
+               addl_info->name,
+               addl_info->value);
+    free(addl_info->name);
+    free(addl_info->value);
+    free(addl_info);
+    addl_info = dlist_pop_last(&event->additional_info);
+  }
+
+
+
+  cpu_use = dlist_pop_last(&event->cpu_usage);
+  while (cpu_use != NULL)
+  {
+    EVEL_DEBUG("Freeing CPU use Info (%s)", cpu_use->id);
+    free(cpu_use->id);
+    free(cpu_use);
+    cpu_use = dlist_pop_last(&event->cpu_usage);
+  }
+  disk_use = dlist_pop_last(&event->disk_usage);
+  while (disk_use != NULL)
+  {
+    EVEL_DEBUG("Freeing Disk use Info (%s)", disk_use->id);
+    free(disk_use->id);
+    free(disk_use);
+    disk_use = dlist_pop_last(&event->disk_usage);
+  }
+  mem_use = dlist_pop_last(&event->mem_usage);
+  while (mem_use != NULL)
+  {
+    EVEL_DEBUG("Freeing Memory use Info (%s)", mem_use->id);
+    free(mem_use->id);
+    free(mem_use->vmid);
+    free(mem_use);
+    mem_use = dlist_pop_last(&event->mem_usage);
+  }
+
+  fsys_use = dlist_pop_last(&event->filesystem_usage);
+  while (fsys_use != NULL)
+  {
+    EVEL_DEBUG("Freeing Filesystem Use info (%s)", fsys_use->filesystem_name);
+    free(fsys_use->filesystem_name);
+    free(fsys_use);
+    fsys_use = dlist_pop_last(&event->filesystem_usage);
+  }
+
+  bucket = dlist_pop_last(&event->latency_distribution);
+  while (bucket != NULL)
+  {
+    EVEL_DEBUG("Freeing Latency Bucket");
+    free(bucket);
+    bucket = dlist_pop_last(&event->latency_distribution);
+  }
+
+  vnic_performance = dlist_pop_last(&event->vnic_usage);
+  while (vnic_performance != NULL)
+  {
+    EVEL_DEBUG("Freeing vNIC performance Info (%s)", vnic_performance->vnic_id);
+    evel_measurement_free_vnic_performance(vnic_performance);
+    free(vnic_performance);
+    vnic_performance = dlist_pop_last(&event->vnic_usage);
+  }
+
+  codec_use = dlist_pop_last(&event->codec_usage);
+  while (codec_use != NULL)
+  {
+    EVEL_DEBUG("Freeing Codec use Info (%s)", codec_use->codec_id);
+    free(codec_use->codec_id);
+    free(codec_use);
+    codec_use = dlist_pop_last(&event->codec_usage);
+  }
+
+  if (event->errors != NULL)
+  {
+    EVEL_DEBUG("Freeing Errors");
+    free(event->errors);
+  }
+
+  feature_use = dlist_pop_last(&event->feature_usage);
+  while (feature_use != NULL)
+  {
+    EVEL_DEBUG("Freeing Feature use Info (%s)", feature_use->feature_id);
+    free(feature_use->feature_id);
+    free(feature_use);
+    feature_use = dlist_pop_last(&event->feature_usage);
+  }
+
+  measurement_group = dlist_pop_last(&event->additional_measurements);
+  while (measurement_group != NULL)
+  {
+    EVEL_DEBUG("Freeing Measurement Group (%s)", measurement_group->name);
+
+    measurement = dlist_pop_last(&measurement_group->measurements);
+    while (measurement != NULL)
+    {
+      EVEL_DEBUG("Freeing Measurement (%s)", measurement->name);
+      free(measurement->name);
+      free(measurement->value);
+      free(measurement);
+      measurement = dlist_pop_last(&measurement_group->measurements);
+    }
+    free(measurement_group->name);
+    free(measurement_group);
+    measurement_group = dlist_pop_last(&event->additional_measurements);
+  }
+
+  evel_free_header(&event->header);
+
+  EVEL_EXIT();
+}
+
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_sipsignaling.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_sipsignaling.c
new file mode 100644 (file)
index 0000000..45f5348
--- /dev/null
@@ -0,0 +1,574 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to Signaling.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "evel_throttle.h"
+
+/**************************************************************************//**
+ * Create a new Signaling event.
+ *
+ * @note    The mandatory fields on the Signaling must be supplied to
+ *          this factory function and are immutable once set.  Optional fields
+ *          have explicit setter functions, but again values may only be set
+ *          once so that the event has immutable properties.
+ * @param event_name  Unique Event Name confirming Domain AsdcModel Description
+ * @param event_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
+ * @param vendor_name   The vendor id to encode in the event vnf field.
+ * @param module        The module to encode in the event.
+ * @param vnfname       The Virtual network function to encode in the event.
+ * @returns pointer to the newly manufactured ::EVENT_SIGNALING.  If the event
+ *          is not used (i.e. posted) it must be released using
+ *          ::evel_free_signaling.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_SIGNALING * evel_new_signaling(const char* ev_name, const char *ev_id,
+                                    const char * const vendor_name,
+                                     const char * const correlator,
+                                     const char * const local_ip_address,
+                                     const char * const local_port,
+                                     const char * const remote_ip_address,
+                                     const char * const remote_port)
+{
+  EVENT_SIGNALING * event = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(vendor_name != NULL);
+
+  /***************************************************************************/
+  /* Allocate the Signaling event.                                           */
+  /***************************************************************************/
+  event = malloc(sizeof(EVENT_SIGNALING));
+  if (event == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(event, 0, sizeof(EVENT_SIGNALING));
+  EVEL_DEBUG("New Signaling event is at %lp", event);
+
+  /***************************************************************************/
+  /* Initialize the header & the Signaling fields.                           */
+  /***************************************************************************/
+  evel_init_header_nameid(&event->header,ev_name,ev_id);
+  event->header.event_domain = EVEL_DOMAIN_SIPSIGNALING;
+  event->major_version = EVEL_SIGNALING_MAJOR_VERSION;
+  event->minor_version = EVEL_SIGNALING_MINOR_VERSION;
+  evel_init_vendor_field(&event->vnfname_field, vendor_name);
+  evel_set_option_string(&event->correlator,correlator,"Init correlator");
+  evel_set_option_string(&event->local_ip_address,local_ip_address,"Init correlator");
+  evel_set_option_string(&event->local_port,local_port,"Init local port");
+  evel_set_option_string(&event->remote_ip_address,remote_ip_address,"Init remote ip");
+  evel_set_option_string(&event->remote_port,remote_port,"Init remote port");
+  evel_init_option_string(&event->compressed_sip);
+  evel_init_option_string(&event->summary_sip);
+  dlist_initialize(&event->additional_info);
+
+exit_label:
+
+  EVEL_EXIT();
+  return event;
+}
+
+/**************************************************************************//**
+ * Add an additional value name/value pair to the SIP signaling.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param event     Pointer to the fault.
+ * @param name      ASCIIZ string with the attribute's name.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ * @param value     ASCIIZ string with the attribute's value.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ *****************************************************************************/
+void evel_signaling_addl_info_add(EVENT_SIGNALING * event, char * name, char * value)
+{
+  FAULT_ADDL_INFO * addl_info = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+  assert(name != NULL);
+  assert(value != NULL);
+
+  EVEL_DEBUG("Adding name=%s value=%s", name, value);
+  addl_info = malloc(sizeof(SIGNALING_ADDL_FIELD));
+  assert(addl_info != NULL);
+  memset(addl_info, 0, sizeof(SIGNALING_ADDL_FIELD));
+  addl_info->name = strdup(name);
+  addl_info->value = strdup(value);
+  assert(addl_info->name != NULL);
+  assert(addl_info->value != NULL);
+
+  dlist_push_last(&event->additional_info, addl_info);
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Set the Event Type property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param type          The Event Type to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_type_set(EVENT_SIGNALING * const event,
+                             const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and call evel_header_type_set.                      */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+  evel_header_type_set(&event->header, type);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Local Ip Address property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param local_ip_address
+ *                      The Local Ip Address to be set. ASCIIZ string. The
+ *                      caller does not need to preserve the value once the
+ *                      function returns.
+ *****************************************************************************/
+void evel_signaling_local_ip_address_set(EVENT_SIGNALING * const event,
+                                         const char * const local_ip_address)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+  assert(local_ip_address != NULL);
+
+  evel_set_option_string(&event->local_ip_address,
+                         local_ip_address,
+                         "Local Ip Address");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Local Port property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param local_port    The Local Port to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_local_port_set(EVENT_SIGNALING * const event,
+                                   const char * const local_port)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+  assert(local_port != NULL);
+
+  evel_set_option_string(&event->local_port,
+                         local_port,
+                         "Local Port");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Remote Ip Address property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param remote_ip_address
+ *                      The Remote Ip Address to be set. ASCIIZ string. The
+ *                      caller does not need to preserve the value once the
+ *                      function returns.
+ *****************************************************************************/
+void evel_signaling_remote_ip_address_set(EVENT_SIGNALING * const event,
+                                          const char * const remote_ip_address)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+  assert(remote_ip_address != NULL);
+
+  evel_set_option_string(&event->remote_ip_address,
+                         remote_ip_address,
+                         "Remote Ip Address");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Remote Port property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param remote_port   The Remote Port to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_remote_port_set(EVENT_SIGNALING * const event,
+                                    const char * const remote_port)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+  assert(remote_port != NULL);
+
+  evel_set_option_string(&event->remote_port,
+                         remote_port,
+                         "Remote Port");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Vendor module property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param modulename    The module name to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_vnfmodule_name_set(EVENT_SIGNALING * const event,
+                                    const char * const module_name)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+  assert(module_name != NULL);
+
+  evel_vendor_field_module_set(&event->vnfname_field, module_name);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Vendor module property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param vnfname       The Virtual Network function to be set. ASCIIZ string.
+ *                      The caller does not need to preserve the value once
+ *                     the function returns.
+ *****************************************************************************/
+void evel_signaling_vnfname_set(EVENT_SIGNALING * const event,
+                                    const char * const vnfname)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+  assert(vnfname != NULL);
+
+  evel_vendor_field_vnfname_set(&event->vnfname_field, vnfname);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Compressed SIP property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param compressed_sip
+ *                      The Compressed SIP to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_compressed_sip_set(EVENT_SIGNALING * const event,
+                                       const char * const compressed_sip)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+  assert(compressed_sip != NULL);
+
+  evel_set_option_string(&event->compressed_sip,
+                         compressed_sip,
+                         "Compressed SIP");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Summary SIP property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param summary_sip   The Summary SIP to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_summary_sip_set(EVENT_SIGNALING * const event,
+                                    const char * const summary_sip)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+  assert(summary_sip != NULL);
+
+  evel_set_option_string(&event->summary_sip,
+                         summary_sip,
+                         "Summary SIP");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Correlator property of the Signaling event.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param event         Pointer to the Signaling event.
+ * @param correlator    The correlator to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_signaling_correlator_set(EVENT_SIGNALING * const event,
+                                   const char * const correlator)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and call evel_header_type_set.                      */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+  evel_set_option_string(&event->correlator,
+                         correlator,
+                         "Correlator");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the Signaling in JSON according to AT&T's schema for the
+ * event type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_signaling(EVEL_JSON_BUFFER * const jbuf,
+                                EVENT_SIGNALING * const event)
+{
+  SIGNALING_ADDL_FIELD * addl_info = NULL;
+  DLIST_ITEM * addl_info_item = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+
+  evel_json_encode_header(jbuf, &event->header);
+  evel_json_open_named_object(jbuf, "signalingFields");
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  evel_enc_kv_opt_string(jbuf, "compressedSip", &event->compressed_sip);
+  evel_enc_kv_opt_string(jbuf, "correlator", &event->correlator);
+  evel_enc_kv_opt_string(jbuf, "localIpAddress", &event->local_ip_address);
+  evel_enc_kv_opt_string(jbuf, "localPort", &event->local_port);
+  evel_enc_kv_opt_string(jbuf, "remoteIpAddress", &event->remote_ip_address);
+  evel_enc_kv_opt_string(jbuf, "remotePort", &event->remote_port);
+  evel_enc_version(jbuf, "signalingFieldsVersion", event->major_version,event->minor_version);
+  evel_enc_kv_opt_string(jbuf, "summarySip", &event->summary_sip);
+  evel_json_encode_vendor_field(jbuf, &event->vnfname_field);
+
+
+  /***************************************************************************/
+  /* Checkpoint, so that we can wind back if all fields are suppressed.      */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "additionalInformation"))
+  {
+    bool item_added = false;
+
+    addl_info_item = dlist_get_first(&event->additional_info);
+    while (addl_info_item != NULL)
+    { 
+      addl_info = (SIGNALING_ADDL_FIELD*) addl_info_item->item;
+      assert(addl_info != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "additionalInformation",
+                                          addl_info->name))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "name", addl_info->name);
+        evel_enc_kv_string(jbuf, "value", addl_info->value);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      addl_info_item = dlist_get_next(addl_info_item);
+    }
+    evel_json_close_list(jbuf);
+    
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free a Signaling event.
+ *
+ * Free off the event supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the event itself, since that may be part of a larger
+ * structure.
+ *****************************************************************************/
+void evel_free_signaling(EVENT_SIGNALING * const event)
+{
+  SIGNALING_ADDL_FIELD * addl_info = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+  /* events as we do on the public API.                                      */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SIPSIGNALING);
+
+ /***************************************************************************/
+  /* Free all internal strings then the header itself.                       */
+  /***************************************************************************/
+  addl_info = dlist_pop_last(&event->additional_info);
+  while (addl_info != NULL)
+  {
+    EVEL_DEBUG("Freeing Additional Info (%s, %s)",
+               addl_info->name,
+               addl_info->value);
+    free(addl_info->name);
+    free(addl_info->value);
+    free(addl_info);
+    addl_info = dlist_pop_last(&event->additional_info);
+  }
+
+  evel_free_event_vendor_field(&event->vnfname_field);
+  evel_free_option_string(&event->correlator);
+  evel_free_option_string(&event->local_ip_address);
+  evel_free_option_string(&event->local_port);
+  evel_free_option_string(&event->remote_ip_address);
+  evel_free_option_string(&event->remote_port);
+  evel_free_option_string(&event->compressed_sip);
+  evel_free_option_string(&event->summary_sip);
+  evel_free_header(&event->header);
+
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_state_change.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_state_change.c
new file mode 100644 (file)
index 0000000..8915afa
--- /dev/null
@@ -0,0 +1,286 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to the State Change.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "evel_throttle.h"
+
+/**************************************************************************//**
+ * Create a new State Change event.
+ *
+ * @note    The mandatory fields on the State Change must be supplied to this
+ *          factory function and are immutable once set.  Optional fields have
+ *          explicit setter functions, but again values may only be set once
+ *          so that the State Change has immutable properties.
+ *
+ * @param event_name  Unique Event Name confirming Domain AsdcModel Description
+ * @param event_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
+ * @param new_state     The new state of the reporting entity.
+ * @param old_state     The old state of the reporting entity.
+ * @param interface     The card or port name of the reporting entity.
+ *
+ * @returns pointer to the newly manufactured ::EVENT_STATE_CHANGE.  If the
+ *          event is not used it must be released using
+ *          ::evel_free_state_change
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_STATE_CHANGE * evel_new_state_change(const char* ev_name,
+                                           const char *ev_id,
+                                          const EVEL_ENTITY_STATE new_state,
+                                           const EVEL_ENTITY_STATE old_state,
+                                           const char * const interface)
+{
+  EVENT_STATE_CHANGE * state_change = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(new_state < EVEL_MAX_ENTITY_STATES);
+  assert(old_state < EVEL_MAX_ENTITY_STATES);
+  assert(interface != NULL);
+
+  /***************************************************************************/
+  /* Allocate the State Change.                                              */
+  /***************************************************************************/
+  state_change = malloc(sizeof(EVENT_STATE_CHANGE));
+  if (state_change == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(state_change, 0, sizeof(EVENT_STATE_CHANGE));
+  EVEL_DEBUG("New State Change is at %lp", state_change);
+
+  /***************************************************************************/
+  /* Initialize the header & the State Change fields.  Optional string       */
+  /* values are uninitialized (NULL).                                        */
+  /***************************************************************************/
+  evel_init_header_nameid(&state_change->header,ev_name,ev_id);
+  state_change->header.event_domain = EVEL_DOMAIN_STATE_CHANGE;
+  state_change->major_version = EVEL_STATE_CHANGE_MAJOR_VERSION;
+  state_change->minor_version = EVEL_STATE_CHANGE_MINOR_VERSION;
+  state_change->new_state = new_state;
+  state_change->old_state = old_state;
+  state_change->state_interface = strdup(interface);
+  dlist_initialize(&state_change->additional_fields);
+
+exit_label:
+  EVEL_EXIT();
+  return state_change;
+}
+
+/**************************************************************************//**
+ * Free a State Change.
+ *
+ * Free off the State Change supplied.  Will free all the contained allocated
+ * memory.
+ *
+ * @note It does not free the State Change itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_state_change(EVENT_STATE_CHANGE * const state_change)
+{
+  STATE_CHANGE_ADDL_FIELD * addl_field = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+  /* events as we do on the public API.                                      */
+  /***************************************************************************/
+  assert(state_change != NULL);
+  assert(state_change->header.event_domain == EVEL_DOMAIN_STATE_CHANGE);
+
+  /***************************************************************************/
+  /* Free all internal strings then the header itself.                       */
+  /***************************************************************************/
+  addl_field = dlist_pop_last(&state_change->additional_fields);
+  while (addl_field != NULL)
+  {
+    EVEL_DEBUG("Freeing Additional Field (%s, %s)",
+               addl_field->name,
+               addl_field->value);
+    free(addl_field->name);
+    free(addl_field->value);
+    free(addl_field);
+    addl_field = dlist_pop_last(&state_change->additional_fields);
+  }
+  free(state_change->state_interface);
+  evel_free_header(&state_change->header);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Event Type property of the State Change.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param state_change  Pointer to the ::EVENT_STATE_CHANGE.
+ * @param type          The Event Type to be set. ASCIIZ string. The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_state_change_type_set(EVENT_STATE_CHANGE * const state_change,
+                                const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and call evel_header_type_set.                      */
+  /***************************************************************************/
+  assert(state_change != NULL);
+  assert(state_change->header.event_domain == EVEL_DOMAIN_STATE_CHANGE);
+  evel_header_type_set(&state_change->header, type);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add an additional field name/value pair to the State Change.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param state_change  Pointer to the ::EVENT_STATE_CHANGE.
+ * @param name          ASCIIZ string with the attribute's name.  The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ * @param value         ASCIIZ string with the attribute's value.  The caller
+ *                      does not need to preserve the value once the function
+ *                      returns.
+ *****************************************************************************/
+void evel_state_change_addl_field_add(EVENT_STATE_CHANGE * const state_change,
+                                      const char * const name,
+                                      const char * const value)
+{
+  STATE_CHANGE_ADDL_FIELD * addl_field = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(state_change != NULL);
+  assert(state_change->header.event_domain == EVEL_DOMAIN_STATE_CHANGE);
+  assert(name != NULL);
+  assert(value != NULL);
+
+  EVEL_DEBUG("Adding name=%s value=%s", name, value);
+  addl_field = malloc(sizeof(STATE_CHANGE_ADDL_FIELD));
+  assert(addl_field != NULL);
+  memset(addl_field, 0, sizeof(STATE_CHANGE_ADDL_FIELD));
+  addl_field->name = strdup(name);
+  addl_field->value = strdup(value);
+  assert(addl_field->name != NULL);
+  assert(addl_field->value != NULL);
+
+  dlist_push_last(&state_change->additional_fields, addl_field);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the state change as a JSON state change.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param state_change  Pointer to the ::EVENT_STATE_CHANGE to encode.
+ *****************************************************************************/
+void evel_json_encode_state_change(EVEL_JSON_BUFFER * jbuf,
+                                   EVENT_STATE_CHANGE * state_change)
+{
+  STATE_CHANGE_ADDL_FIELD * addl_field = NULL;
+  DLIST_ITEM * addl_field_item = NULL;
+  char * new_state;
+  char * old_state;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(state_change != NULL);
+  assert(state_change->header.event_domain == EVEL_DOMAIN_STATE_CHANGE);
+
+  new_state = evel_entity_state(state_change->new_state);
+  old_state = evel_entity_state(state_change->old_state);
+
+  evel_json_encode_header(jbuf, &state_change->header);
+  evel_json_open_named_object(jbuf, "stateChangeFields");
+
+  /***************************************************************************/
+  /* Mandatory fields.                                                       */
+  /***************************************************************************/
+  evel_enc_kv_string(jbuf, "newState", new_state);
+  evel_enc_kv_string(jbuf, "oldState", old_state);
+  evel_enc_kv_string(jbuf, "stateInterface", state_change->state_interface);
+
+  /***************************************************************************/
+  /* Optional fields.                                                        */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "additionalFields"))
+  {
+    bool item_added = false;
+
+    addl_field_item = dlist_get_first(&state_change->additional_fields);
+    while (addl_field_item != NULL)
+    {
+      addl_field = (STATE_CHANGE_ADDL_FIELD *) addl_field_item->item;
+      assert(addl_field != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "additionalFields",
+                                          addl_field->name))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "name", addl_field->name);
+        evel_enc_kv_string(jbuf, "value", addl_field->value);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      addl_field_item = dlist_get_next(addl_field_item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+  evel_enc_version(jbuf,
+                   "stateChangeFieldsVersion",
+                   state_change->major_version,state_change->minor_version);
+
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_strings.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_strings.c
new file mode 100644 (file)
index 0000000..96db59b
--- /dev/null
@@ -0,0 +1,473 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions to convert common enum types to strings.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "evel_internal.h"
+
+/**************************************************************************//**
+ * Map an ::EVEL_COUNTER_CRITICALITIES enum value to the equivalent string.
+ *
+ * @param criticality   The criticality to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_criticality(const EVEL_COUNTER_CRITICALITIES criticality)
+{
+  char * result;
+
+  EVEL_ENTER();
+
+  switch (criticality)
+  {
+    case EVEL_COUNTER_CRITICALITY_CRIT:
+      result = "CRIT";
+      break;
+
+    case EVEL_COUNTER_CRITICALITY_MAJ:
+      result = "MAJ";
+      break;
+
+    default:
+      EVEL_ERROR("Unexpected counter criticality %d", criticality);
+      assert(0);
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Map an ::EVEL_SEVERITIES enum value to the equivalent string.
+ *
+ * @param severity      The severity to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_severity(const EVEL_SEVERITIES severity)
+{
+  char * result;
+
+  EVEL_ENTER();
+
+  switch (severity)
+  {
+    case EVEL_SEVERITY_CRITICAL:
+      result = "CRITICAL";
+      break;
+
+    case EVEL_SEVERITY_MAJOR:
+      result = "MAJOR";
+      break;
+
+    case EVEL_SEVERITY_MINOR:
+      result = "MINOR";
+      break;
+
+    case EVEL_SEVERITY_WARNING:
+      result = "WARNING";
+      break;
+
+    case EVEL_SEVERITY_NORMAL:
+      result = "NORMAL";
+      break;
+
+    default:
+      EVEL_ERROR("Unexpected event severity %d", severity);
+      assert(0);
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Map an ::EVEL_ALERT_ACTIONS enum value to the equivalent string.
+ *
+ * @param alert_action  The alert_action to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_alert_action(const EVEL_ALERT_ACTIONS alert_action)
+{
+  char * result;
+
+  EVEL_ENTER();
+
+  switch (alert_action)
+  {
+    case EVEL_ALERT_ACTION_CLEAR:
+      result = "CLEAR";
+      break;
+
+    case EVEL_ALERT_ACTION_CONT:
+      result = "CONT";
+      break;
+
+    case EVEL_ALERT_ACTION_SET:
+      result = "SET";
+      break;
+
+    default:
+      EVEL_ERROR("Unexpected alert action %d", alert_action);
+      assert(0);
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Map an ::EVEL_ALERT_TYPES enum value to the equivalent string.
+ *
+ * @param alert_type    The alert_type to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_alert_type(const EVEL_ALERT_TYPES alert_type)
+{
+  char * result;
+
+  EVEL_ENTER();
+
+  switch (alert_type)
+  {
+    case EVEL_ALERT_TYPE_CARD:
+      result = "CARD-ANOMALY";
+      break;
+
+    case EVEL_ALERT_TYPE_ELEMENT:
+      result = "ELEMENT-ANOMALY";
+      break;
+
+    case EVEL_ALERT_TYPE_INTERFACE:
+      result = "INTERFACE-ANOMALY";
+      break;
+
+    case EVEL_ALERT_TYPE_SERVICE:
+      result = "SERVICE-ANOMALY";
+      break;
+
+    default:
+      EVEL_ERROR("Unexpected alert type %d", alert_type);
+      assert(0);
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Map an ::EVEL_EVENT_DOMAINS enum value to the equivalent string.
+ *
+ * @param domain        The domain to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_event_domain(const EVEL_EVENT_DOMAINS domain)
+{
+  char * result;
+
+  EVEL_ENTER();
+
+  switch (domain)
+  {
+    case EVEL_DOMAIN_HEARTBEAT:
+      result = "heartbeat";
+      break;
+
+    case EVEL_DOMAIN_FAULT:
+      result = "fault";
+      break;
+
+    case EVEL_DOMAIN_MEASUREMENT:
+      result = "measurementsForVfScaling";
+      break;
+
+    case EVEL_DOMAIN_REPORT:
+      result = "measurementsForVfReporting";
+      break;
+
+    case EVEL_DOMAIN_MOBILE_FLOW:
+      result = "mobileFlow";
+      break;
+
+    case EVEL_DOMAIN_HEARTBEAT_FIELD:
+      result = "heartbeat";
+      break;
+
+    case EVEL_DOMAIN_SIPSIGNALING:
+      result = "sipSignaling";
+      break;
+
+    case EVEL_DOMAIN_STATE_CHANGE:
+      result = "stateChange";
+      break;
+
+    case EVEL_DOMAIN_SYSLOG:
+      result = "syslog";
+      break;
+
+    case EVEL_DOMAIN_OTHER:
+      result = "other";
+      break;
+
+    case EVEL_DOMAIN_VOICE_QUALITY:
+      result = "voiceQuality";
+      break;
+
+    case EVEL_DOMAIN_THRESHOLD_CROSS:
+      result = "thresholdCrossingAlert";
+      break;
+
+    default:
+      result = NULL;
+      EVEL_ERROR("Unexpected domain %d", domain);
+      assert(0);
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Map an ::EVEL_EVENT_PRIORITIES enum value to the equivalent string.
+ *
+ * @param priority      The priority to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_event_priority(const EVEL_EVENT_PRIORITIES priority)
+{
+  char * result;
+
+  EVEL_ENTER();
+
+  switch (priority)
+  {
+    case EVEL_PRIORITY_HIGH:
+      result = "High";
+      break;
+
+    case EVEL_PRIORITY_MEDIUM:
+      result = "Medium";
+      break;
+
+    case EVEL_PRIORITY_NORMAL:
+      result = "Normal";
+      break;
+
+    case EVEL_PRIORITY_LOW:
+      result = "Low";
+      break;
+
+    default:
+      result = NULL;
+      EVEL_ERROR("Unexpected priority %d", priority);
+      assert(0);
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Map an ::EVEL_SOURCE_TYPES enum value to the equivalent string.
+ *
+ * @param source_type   The source type to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_source_type(const EVEL_SOURCE_TYPES source_type)
+{
+  char * result;
+
+  EVEL_ENTER();
+
+  switch (source_type)
+  {
+    case EVEL_SOURCE_OTHER:
+      result = "other";
+      break;
+
+    case EVEL_SOURCE_ROUTER:
+      result = "router";
+      break;
+
+    case EVEL_SOURCE_SWITCH:
+      result = "switch";
+      break;
+
+    case EVEL_SOURCE_HOST:
+      result = "host";
+      break;
+
+    case EVEL_SOURCE_CARD:
+      result = "card";
+      break;
+
+    case EVEL_SOURCE_PORT:
+      result = "port";
+      break;
+
+    case EVEL_SOURCE_SLOT_THRESHOLD:
+      result = "slotThreshold";
+      break;
+
+    case EVEL_SOURCE_PORT_THRESHOLD:
+      result = "portThreshold";
+      break;
+
+    case EVEL_SOURCE_VIRTUAL_MACHINE:
+      result = "virtualMachine";
+      break;
+
+    case EVEL_SOURCE_VIRTUAL_NETWORK_FUNCTION:
+      result = "virtualNetworkFunction";
+      break;
+
+    default:
+      result = NULL;
+      EVEL_ERROR("Unexpected Event Source Type %d", (int) source_type);
+      assert(0);
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Map an ::EVEL_VF_STATUSES enum value to the equivalent string.
+ *
+ * @param vf_status     The vf_status to convert.
+ * @returns The equivalent string.
+ *****************************************************************************/
+char * evel_vf_status(const EVEL_VF_STATUSES vf_status)
+{
+  char * result;
+
+  EVEL_ENTER();
+
+  switch (vf_status)
+  {
+    case EVEL_VF_STATUS_ACTIVE:
+      result = "Active";
+      break;
+
+    case EVEL_VF_STATUS_IDLE:
+      result = "Idle";
+      break;
+
+    case EVEL_VF_STATUS_PREP_TERMINATE:
+      result = "Preparing to terminate";
+      break;
+
+    case EVEL_VF_STATUS_READY_TERMINATE:
+      result = "Ready to terminate";
+      break;
+
+    case EVEL_VF_STATUS_REQ_TERMINATE:
+      result = "Requesting termination";
+      break;
+
+    default:
+      result = NULL;
+      EVEL_ERROR("Unexpected VF Status %d", vf_status);
+      assert(0);
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Convert a ::EVEL_ENTITY_STATE to it's string form for JSON encoding.
+ *
+ * @param state         The entity state to encode.
+ *
+ * @returns the corresponding string
+ *****************************************************************************/
+char * evel_entity_state(const EVEL_ENTITY_STATE state)
+{
+  char * result;
+
+  EVEL_ENTER();
+
+  switch (state)
+  {
+    case EVEL_ENTITY_STATE_IN_SERVICE:
+      result = "inService";
+      break;
+
+    case EVEL_ENTITY_STATE_MAINTENANCE:
+      result = "maintenance";
+      break;
+
+    case EVEL_ENTITY_STATE_OUT_OF_SERVICE:
+      result = "outOfService";
+      break;
+
+    default:
+      EVEL_ERROR("Unexpected entity state %d", state);
+      assert(0);
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Convert a ::EVEL_SERVICE_ENDPOINT_DESC to string form for JSON encoding.
+ *
+ * @param endpoint_desc endpoint description to encode.
+ *
+ * @returns the corresponding string
+ *****************************************************************************/
+char * evel_service_endpoint_desc(const EVEL_ENTITY_STATE endpoint_desc)
+{
+  char * result;
+
+  EVEL_ENTER();
+
+  switch (endpoint_desc)
+  {
+    case EVEL_SERVICE_ENDPOINT_CALLEE:
+      result = "Callee";
+      break;
+
+    case EVEL_SERVICE_ENDPOINT_CALLER:
+      result = "Caller";
+      break;
+
+    default:
+      EVEL_ERROR("Unexpected endpoint description %d", endpoint_desc);
+      assert(0);
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_syslog.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_syslog.c
new file mode 100644 (file)
index 0000000..85b0ec9
--- /dev/null
@@ -0,0 +1,505 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to the Syslog.
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "evel_throttle.h"
+
+/**************************************************************************//**
+ * Create a new Syslog event.
+ *
+ * @note    The mandatory fields on the Syslog must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          Syslog has immutable properties.
+ * @param event_name  Unique Event Name confirming Domain AsdcModel Description
+ * @param event_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
+ * @param   event_source_type  The type of Syslog event source.
+ * @param   syslog_msg         The Syslog event message.
+ * @param   syslog_tag         The messgaeId identifying the type of message.
+ * @returns pointer to the newly manufactured ::EVENT_SYSLOG.  If the event is
+ *          not used (i.e. posted) it must be released using
+ *          ::evel_free_syslog.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_SYSLOG * evel_new_syslog(const char* ev_name, const char *ev_id,
+                              EVEL_SOURCE_TYPES event_source_type,
+                               const char * const syslog_msg,
+                               const char * const syslog_tag)
+{
+  EVENT_SYSLOG * syslog = NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event_source_type < EVEL_MAX_SOURCE_TYPES);
+  assert(syslog_msg != NULL);
+  assert(syslog_tag != NULL);
+
+  /***************************************************************************/
+  /* Allocate the Syslog.                                                    */
+  /***************************************************************************/
+  syslog = malloc(sizeof(EVENT_SYSLOG));
+  if (syslog == NULL)
+  {
+    log_error_state("Out of memory");
+    goto exit_label;
+  }
+  memset(syslog, 0, sizeof(EVENT_SYSLOG));
+  EVEL_DEBUG("New Syslog is at %lp", syslog);
+
+  /***************************************************************************/
+  /* Initialize the header & the Syslog fields.  Optional string values are  */
+  /* uninitialized (NULL).                                                   */
+  /***************************************************************************/
+  evel_init_header_nameid(&syslog->header,ev_name,ev_id);
+  syslog->header.event_domain = EVEL_DOMAIN_SYSLOG;
+  syslog->major_version = EVEL_SYSLOG_MAJOR_VERSION;
+  syslog->minor_version = EVEL_SYSLOG_MINOR_VERSION;
+  syslog->event_source_type = event_source_type;
+  syslog->syslog_msg = strdup(syslog_msg);
+  syslog->syslog_tag = strdup(syslog_tag);
+  evel_init_option_int(&syslog->syslog_facility);
+  evel_init_option_int(&syslog->syslog_proc_id);
+  evel_init_option_int(&syslog->syslog_ver);
+  evel_init_option_string(&syslog->additional_filters);
+  evel_init_option_string(&syslog->event_source_host);
+  evel_init_option_string(&syslog->syslog_proc);
+  evel_init_option_string(&syslog->syslog_s_data);
+  evel_init_option_string(&syslog->syslog_sdid);
+  evel_init_option_string(&syslog->syslog_severity);
+
+exit_label:
+  EVEL_EXIT();
+  return syslog;
+}
+
+/**************************************************************************//**
+ * Set the Event Type property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog      Pointer to the syslog.
+ * @param type        The Event Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_syslog_type_set(EVENT_SYSLOG * syslog,
+                          const char * const type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and call evel_header_type_set.                      */
+  /***************************************************************************/
+  assert(syslog != NULL);
+  assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
+  evel_header_type_set(&syslog->header, type);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add an additional value name/value pair to the Syslog.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param syslog    Pointer to the syslog.
+ * @param name      ASCIIZ string with the attribute's name.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ * @param value     ASCIIZ string with the attribute's value.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ *****************************************************************************/
+void evel_syslog_addl_filter_set(EVENT_SYSLOG * syslog,
+                                char * filter)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(syslog != NULL);
+  assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
+  assert(filter != NULL);
+
+  evel_set_option_string(&syslog->additional_filters,
+                         filter,
+                         "Syslog filter string");
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Event Source Host property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog     Pointer to the Syslog.
+ * @param host       The Event Source Host to be set. ASCIIZ string. The caller
+ *                   does not need to preserve the value once the function
+ *                   returns.
+ *****************************************************************************/
+void evel_syslog_event_source_host_set(EVENT_SYSLOG * syslog,
+                                       const char * const host)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(syslog != NULL);
+  assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
+  assert(host != NULL);
+
+  evel_set_option_string(&syslog->event_source_host,
+                         host,
+                         "Event Source Host");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Facility property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog      Pointer to the Syslog.
+ * @param facility    The Syslog Facility to be set.  ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_syslog_facility_set(EVENT_SYSLOG * syslog,
+                              EVEL_SYSLOG_FACILITIES facility)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(syslog != NULL);
+  assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
+  assert(facility < EVEL_MAX_SYSLOG_FACILITIES);
+
+  evel_set_option_int(&syslog->syslog_facility,
+                      facility,
+                      "Facility");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Process property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog     Pointer to the Syslog.
+ * @param proc       The Process to be set. ASCIIZ string. The caller does not
+ *                   need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_syslog_proc_set(EVENT_SYSLOG * syslog, const char * const proc)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(syslog != NULL);
+  assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
+  assert(proc != NULL);
+
+  evel_set_option_string(&syslog->syslog_proc, proc, "Process");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Process ID property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog     Pointer to the Syslog.
+ * @param proc_id    The Process ID to be set. ASCIIZ string. The caller does
+ *                   not need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_syslog_proc_id_set(EVENT_SYSLOG * syslog, int proc_id)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(syslog != NULL);
+  assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
+  assert(proc_id > 0);
+
+  evel_set_option_int(&syslog->syslog_proc_id,
+                      proc_id,
+                      "Process ID");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Version property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog     Pointer to the Syslog.
+ * @param version    The Version to be set. ASCIIZ string. The caller does not
+ *                   need to preserve the value once the function returns.
+ *****************************************************************************/
+void evel_syslog_version_set(EVENT_SYSLOG * syslog, int version)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(syslog != NULL);
+  assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
+  assert(version >= 0);
+
+  evel_set_option_int(&syslog->syslog_ver,
+                      version,
+                      "Version");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Structured Data property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog     Pointer to the Syslog.
+ * @param s_data     The Structured Data to be set. ASCIIZ string. The caller
+ *                   does not need to preserve the value once the function
+ *                   returns.
+ *****************************************************************************/
+void evel_syslog_s_data_set(EVENT_SYSLOG * syslog, const char * const s_data)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(syslog != NULL);
+  assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
+  assert(s_data != NULL);
+
+  evel_set_option_string(&syslog->syslog_s_data,
+                         s_data,
+                         "Structured Data");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Structured SDID property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog     Pointer to the Syslog.
+ * @param sdid     The Structured Data to be set. ASCIIZ string. name@number
+ *                 Caller does not need to preserve the value once the function
+ *                   returns.
+ *****************************************************************************/
+void evel_syslog_sdid_set(EVENT_SYSLOG * syslog, const char * const sdid)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(syslog != NULL);
+  assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
+  assert(sdid != NULL);
+
+  evel_set_option_string(&syslog->syslog_sdid,
+                         sdid,
+                         "SdId set");
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Structured Severity property of the Syslog.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param syslog     Pointer to the Syslog.
+ * @param sdid     The Structured Data to be set. ASCIIZ string. 
+ *                 Caller does not need to preserve the value once the function
+ *                   returns.
+ *****************************************************************************/
+void evel_syslog_severity_set(EVENT_SYSLOG * syslog, const char * const severty)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(syslog != NULL);
+  assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
+  assert(severty != NULL);
+
+  if( !strcmp(severty,"Alert") || !strcmp(severty,"Critical") || !strcmp(severty,"Debug") ||
+      !strcmp(severty,"Emergency") || !strcmp(severty,"Error") || !strcmp(severty,"Info") ||
+      !strcmp(severty,"Notice") || !strcmp(severty,"Warning") )
+  {
+     evel_set_option_string(&syslog->syslog_severity,
+                         severty,
+                         "Severity set");
+  }
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the Syslog in JSON according to AT&T's schema for the event type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_syslog(EVEL_JSON_BUFFER * jbuf,
+                             EVENT_SYSLOG * event)
+{
+  char * event_source_type;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SYSLOG);
+
+  event_source_type = evel_source_type(event->event_source_type);
+
+  evel_json_encode_header(jbuf, &event->header);
+  evel_json_open_named_object(jbuf, "syslogFields");
+
+  evel_enc_kv_opt_string(jbuf, "additionalFields", &event->additional_filters);
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  evel_enc_kv_string(jbuf, "eventSourceType", event_source_type);
+  evel_enc_kv_string(jbuf, "syslogMsg", event->syslog_msg);
+  evel_enc_kv_string(jbuf, "syslogTag", event->syslog_tag);
+  evel_enc_version(
+    jbuf, "syslogFieldsVersion", event->major_version, event->minor_version);
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  evel_enc_kv_opt_string(jbuf, "eventSourceHost", &event->event_source_host);
+  evel_enc_kv_opt_int(jbuf, "syslogFacility", &event->syslog_facility);
+  evel_enc_kv_opt_int(jbuf, "syslogPri", &event->syslog_priority);
+  evel_enc_kv_opt_string(jbuf, "syslogProc", &event->syslog_proc);
+  evel_enc_kv_opt_int(jbuf, "syslogProcId", &event->syslog_proc_id);
+  evel_enc_kv_opt_string(jbuf, "syslogSData", &event->syslog_s_data);
+  evel_enc_kv_opt_string(jbuf, "syslogSdId", &event->syslog_sdid);
+  evel_enc_kv_opt_string(jbuf, "syslogSev", &event->syslog_severity);
+  evel_enc_kv_opt_int(jbuf, "syslogVer", &event->syslog_ver);
+  evel_json_close_object(jbuf);
+
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_KERNEL == 0);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_USER == 1);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_MAIL == 2);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_SYSTEM_DAEMON == 3);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_SECURITY_AUTH == 4);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_INTERNAL == 5);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LINE_PRINTER == 6);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_NETWORK_NEWS == 7);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_UUCP == 8);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_CLOCK_DAEMON == 9);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_SECURITY_AUTH2 == 10);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_FTP_DAEMON == 11);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_NTP == 12);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOG_AUDIT == 13);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOG_ALERT == 14);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_CLOCK_DAEMON2 == 15);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL0 == 16);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL1 == 17);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL2 == 18);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL3 == 19);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL4 == 20);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL5 == 21);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL6 == 22);
+  EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL7 == 23);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free a Syslog.
+ *
+ * Free off the Syslog supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the Syslog itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_syslog(EVENT_SYSLOG * event)
+{
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+  /* events as we do on the public API.                                      */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_SYSLOG);
+
+  /***************************************************************************/
+  /* Free all internal strings then the header itself.                       */
+  /***************************************************************************/
+
+  evel_free_option_string(&event->additional_filters);
+  evel_free_option_string(&event->event_source_host);
+  free(event->syslog_msg);
+  evel_free_option_string(&event->syslog_proc);
+  evel_free_option_string(&event->syslog_s_data);
+  evel_free_option_string(&event->syslog_sdid);
+  evel_free_option_string(&event->syslog_severity);
+  free(event->syslog_tag);
+  evel_free_header(&event->header);
+
+  EVEL_EXIT();
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_threshold_cross.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_threshold_cross.c
new file mode 100644 (file)
index 0000000..f4fa620
--- /dev/null
@@ -0,0 +1,531 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to the Threshold Cross Alerts.
+ *
+ *****************************************************************************/
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include "evel.h"      
+#include "evel_internal.h"     
+#include "evel_throttle.h"     
+
+
+/**************************************************************************//**
+ * Create a new Threshold Crossing Alert event.
+ *
+ * @note    The mandatory fields on the TCA must be supplied to this factory
+ *          function and are immutable once set.  Optional fields have explicit
+ *          setter functions, but again values may only be set once so that the
+ *          TCA has immutable properties.
+ *
+ * @param event_name  Unique Event Name confirming Domain AsdcVnfModel Description
+ * @param event_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
+ * @param char* tcriticality   Performance Counter Criticality MAJ MIN,
+ * @param char* tname          Performance Counter Threshold name
+ * @param char* tthresholdCrossed  Counter Threshold crossed value
+ * @param char* tvalue             Counter actual value
+ * @param EVEL_EVENT_ACTION talertAction   Alert set continue or clear
+ * @param char*  talertDescription
+ * @param EVEL_ALERT_TYPE     talertType    Kind of anamoly
+ * @param unsigned long long  tcollectionTimestamp time at which alert was collected
+ * @param EVEL_SEVERITIES     teventSeverity  Severity of Alert
+ * @param unsigned long long  teventStartTimestamp Time when this alert started
+ *
+ * @returns pointer to the newly manufactured ::EVENT_THRESHOLD_CROSS.  If the
+ *          event is not used it must be released using
+ *          ::evel_free_threshold_cross
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_THRESHOLD_CROSS * evel_new_threshold_cross(const char * ev_name, const char * ev_id,
+                          char *  tcriticality,
+                           char *  tname,
+                           char *  tthresholdCrossed,
+                           char *  tvalue,
+                           EVEL_EVENT_ACTION  talertAction,
+                           char *             talertDescription, 
+                           EVEL_ALERT_TYPE    talertType,
+                           unsigned long long  tcollectionTimestamp, 
+                           EVEL_SEVERITIES     teventSeverity,
+                           unsigned long long  teventStartTimestamp )
+{
+        EVENT_THRESHOLD_CROSS * event = NULL;
+        EVEL_ENTER();
+
+       assert( tcriticality!= NULL );
+       assert( tname!= NULL );
+       assert( tthresholdCrossed != NULL );
+       assert( tvalue!= NULL );
+       assert( talertDescription != NULL );
+               
+
+       /***************************************************************************/
+       /* Allocate the Threshold crossing event.                                  */
+       /***************************************************************************/
+       event = malloc(sizeof(EVENT_THRESHOLD_CROSS));
+       if (event == NULL)
+       {
+           log_error_state("Out of memory");
+           goto exit_label;
+       }
+       memset(event, 0, sizeof(EVENT_THRESHOLD_CROSS));
+       EVEL_DEBUG("New Threshold Cross event is at %lp", event);
+
+  /***************************************************************************/
+  /* Initialize the header & the threshold crossing fields.                  */
+  /***************************************************************************/
+  evel_init_header_nameid(&event->header,ev_name,ev_id);
+  event->header.event_domain = EVEL_DOMAIN_THRESHOLD_CROSS;
+  event->major_version = EVEL_THRESHOLD_CROSS_MAJOR_VERSION;
+  event->minor_version = EVEL_THRESHOLD_CROSS_MINOR_VERSION;
+
+
+  event->additionalParameters.criticality = strdup(tcriticality);
+  event->additionalParameters.name = strdup(tname);
+  event->additionalParameters.thresholdCrossed = strdup(tthresholdCrossed);
+  event->additionalParameters.value = strdup(tvalue);
+  event->alertAction      =  talertAction;
+  event->alertDescription =  strdup(talertDescription); 
+  event->alertType        =  talertType;
+  event->collectionTimestamp =   tcollectionTimestamp; 
+  event->eventSeverity       =   teventSeverity;
+  event->eventStartTimestamp =   teventStartTimestamp;
+
+  evel_init_option_string(&event->alertValue);
+  evel_init_option_string(&event->dataCollector);
+  evel_init_option_string(&event->elementType);
+  evel_init_option_string(&event->interfaceName);
+  evel_init_option_string(&event->networkService);
+  evel_init_option_string(&event->possibleRootCause);
+  dlist_initialize(&event->additional_info);
+  dlist_initialize(&event->alertidList);
+
+exit_label:
+
+  EVEL_EXIT();
+  return event;
+
+}
+
+
+/**************************************************************************//**
+ * Set the Event Type property of the TC Alert.
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param type        The Event Type to be set. ASCIIZ string. The caller
+ *                    does not need to preserve the value once the function
+ *                    returns.
+ *****************************************************************************/
+void evel_threshold_cross_type_set(EVENT_THRESHOLD_CROSS * const event,char *  type)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions and call evel_header_type_set.                      */
+  /***************************************************************************/
+  assert(type!=NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
+  evel_header_type_set(&event->header, type);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add an optional additional alertid value to Alert.
+ *
+ *****************************************************************************/
+void evel_threshold_cross_alertid_add(EVENT_THRESHOLD_CROSS * const event,char *  alertid)
+{
+  char *alid=NULL;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
+  assert(alertid != NULL);
+
+  EVEL_DEBUG("Adding AlertId=%s", alertid);
+  alid = strdup(alertid);
+  assert(alid != NULL);
+
+  dlist_push_last(&event->alertidList, alid);
+
+  EVEL_EXIT();
+}
+       
+/**************************************************************************//**
+ * Add an optional additional value name/value pair to the Alert.
+ *
+ * The name and value are NULL delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ * @param name      ASCIIZ string with the attribute's name.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ * @param value     ASCIIZ string with the attribute's value.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ *****************************************************************************/
+void evel_threshold_cross_addl_info_add(EVENT_THRESHOLD_CROSS * const event, const char *  name, const char *  value)
+{
+  OTHER_FIELD * nv_pair = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
+  assert(name != NULL);
+  assert(value != NULL);
+
+  EVEL_DEBUG("Adding name=%s value=%s", name, value);
+  nv_pair = malloc(sizeof(OTHER_FIELD));
+  assert(nv_pair != NULL);
+  nv_pair->name = strdup(name);
+  nv_pair->value = strdup(value);
+  assert(nv_pair->name != NULL);
+  assert(nv_pair->value != NULL);
+
+  dlist_push_last(&event->additional_info, nv_pair);
+
+  EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Free a Signaling event.
+ *
+ * Free off the event supplied.  Will free all the contained allocated memory.
+ *
+ * @note It does not free the event itself, since that may be part of a larger
+ * structure.
+ *****************************************************************************/
+void evel_free_threshold_cross(EVENT_THRESHOLD_CROSS * const event)
+{
+  OTHER_FIELD * addl_info = NULL;
+  char *ptr;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+  /* events as we do on the API.                                      */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
+
+  /***************************************************************************/
+  /* Free all internal strings then the header itself.                       */
+  /***************************************************************************/
+  addl_info = dlist_pop_last(&event->additional_info);
+  while (addl_info != NULL)
+  {
+    EVEL_DEBUG("Freeing Additional Info (%s, %s)",
+               addl_info->name,
+               addl_info->value);
+    free(addl_info->name);
+    free(addl_info->value);
+    free(addl_info);
+    addl_info = dlist_pop_last(&event->additional_info);
+  }
+  ptr = dlist_pop_last(&event->alertidList);
+  while (ptr != NULL)
+  {
+    free(ptr);
+    ptr = dlist_pop_last(&event->alertidList);
+  }
+
+  free(event->additionalParameters.criticality);
+  free(event->additionalParameters.name);
+  free(event->additionalParameters.thresholdCrossed);
+  free(event->additionalParameters.value);
+  free(event->alertDescription); 
+
+  evel_free_option_string(&event->alertValue);
+  evel_free_option_string(&event->dataCollector);
+  evel_free_option_string(&event->elementType);
+  evel_free_option_string(&event->interfaceName);
+  evel_free_option_string(&event->networkService);
+  evel_free_option_string(&event->possibleRootCause);
+  evel_free_header(&event->header);
+
+  EVEL_EXIT();
+}
+
+  /**************************************************************************//**
+   * Set the TCA probable Root cause.
+   *
+   * @param sheader     Possible root cause to Threshold
+   *****************************************************************************/
+  void evel_threshold_cross_possible_rootcause_set(EVENT_THRESHOLD_CROSS * const event, char *  sheader)
+  {
+    EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check preconditions.                                                    */
+    /***************************************************************************/
+    assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
+    assert(sheader != NULL);
+
+    evel_set_option_string(&event->possibleRootCause,
+                         sheader,
+                         "Rootcause value");
+
+    EVEL_EXIT();
+  }
+    
+  /**************************************************************************//**
+   * Set the TCA networking cause.
+   *
+   * @param sheader     Possible networking service value to Threshold
+   *****************************************************************************/
+  void evel_threshold_cross_networkservice_set(EVENT_THRESHOLD_CROSS * const event, char *  sheader)
+  {
+           EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check preconditions.                                                    */
+    /***************************************************************************/
+    assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
+    assert(sheader != NULL);
+
+    evel_set_option_string(&event->networkService,
+                         sheader,
+                         "Networking service value");
+
+           EVEL_EXIT();
+  }
+    
+  /**************************************************************************//**
+   * Set the TCA Interface name.
+   *
+   * @param sheader     Interface name to threshold
+   *****************************************************************************/
+  void evel_threshold_cross_interfacename_set(EVENT_THRESHOLD_CROSS * const event,char *  sheader)
+  {
+           EVEL_ENTER();
+
+           /***************************************************************************/
+           /* Check preconditions.                                                    */
+           /***************************************************************************/
+            assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
+           assert(sheader != NULL);
+
+           evel_set_option_string(&event->interfaceName,
+                                  sheader,
+                                  "TCA Interface name");
+           EVEL_EXIT();
+  }
+    
+  /**************************************************************************//**
+   * Set the TCA Data element type.
+   *
+   * @param sheader     element type of Threshold
+   *****************************************************************************/
+  void evel_threshold_cross_data_elementtype_set(EVENT_THRESHOLD_CROSS * const event,char *  sheader)
+  {
+           EVEL_ENTER();
+
+           /***************************************************************************/
+           /* Check preconditions.                                                    */
+           /***************************************************************************/
+            assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
+           assert(sheader != NULL);
+
+           evel_set_option_string(&event->elementType,
+                                  sheader,
+                                  "TCA Element type value");
+           EVEL_EXIT();
+  }
+
+  /**************************************************************************//**
+   * Set the TCA Data collector value.
+   *
+   * @param sheader     Data collector value
+   *****************************************************************************/
+  void evel_threshold_cross_data_collector_set(EVENT_THRESHOLD_CROSS * const event,char *  sheader)
+  {
+           EVEL_ENTER();
+
+           /***************************************************************************/
+           /* Check preconditions.                                                    */
+           /***************************************************************************/
+            assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
+           assert(sheader != NULL);
+
+           evel_set_option_string(&event->dataCollector,
+                                  sheader,
+                                  "Datacollector value");
+           EVEL_EXIT();
+  }
+    
+    
+    
+  /**************************************************************************//**
+   * Set the TCA alert value.
+   *
+   * @param sheader     Possible alert value
+   *****************************************************************************/
+  void evel_threshold_cross_alertvalue_set(EVENT_THRESHOLD_CROSS * const event,char *  sheader)
+  {
+           EVEL_ENTER();
+
+           /***************************************************************************/
+           /* Check preconditions.                                                    */
+           /***************************************************************************/
+            assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
+           assert(sheader != NULL);
+
+           evel_set_option_string(&event->alertValue,
+                                  sheader,
+                                  "Alert value");
+           EVEL_EXIT();
+  }
+
+/**************************************************************************//**
+ * Encode the Mobile Flow GTP Per Flow Metrics as a JSON object.
+ *
+ * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
+ * @param metrics       Pointer to the ::EVENT_MOBILE_FLOW to encode.
+ * @returns Number of bytes actually written.
+ *****************************************************************************/
+void evel_json_encode_perf_counter( EVEL_JSON_BUFFER * jbuf, PERF_COUNTER *pcounter)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(jbuf != NULL);
+  assert(pcounter != NULL);
+
+  evel_json_open_named_object(jbuf, "additionalParameters");
+
+  /***************************************************************************/
+  /* Mandatory parameters.                                                   */
+  /***************************************************************************/
+  evel_enc_kv_string(jbuf, "criticality", pcounter->criticality);
+  evel_enc_kv_string(jbuf, "name", pcounter->name);
+  evel_enc_kv_string(jbuf, "thresholdCrossed", pcounter->name);
+  evel_enc_kv_string(jbuf, "value", pcounter->value);
+
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the Signaling in JSON according to AT&T's schema for the
+ * event type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_threshold_cross(EVEL_JSON_BUFFER * const jbuf,
+                                EVENT_THRESHOLD_CROSS * const event)
+{
+  OTHER_FIELD * nv_pair = NULL;
+  DLIST_ITEM * dlist_item = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
+
+  evel_json_encode_header(jbuf, &event->header);
+  evel_json_open_named_object(jbuf, "thresholdCrossingAlert");
+
+  /***************************************************************************/
+  /* Mandatory fields                                                        */
+  /***************************************************************************/
+  evel_json_encode_perf_counter(jbuf, &event->additionalParameters);
+  evel_enc_kv_int(jbuf, "alertAction", event->alertAction);
+  evel_enc_kv_string(jbuf, "alertDescription", event->alertDescription);
+  evel_enc_kv_int(jbuf, "alertType", event->alertType);
+  evel_enc_kv_ull(
+    jbuf, "collectionTimestamp", event->collectionTimestamp);
+  evel_enc_kv_int(jbuf, "eventSeverity", event->eventSeverity);
+  evel_enc_kv_ull(
+    jbuf, "eventStartTimestamp", event->eventStartTimestamp);
+
+  /***************************************************************************/
+  /* Optional fields                                                         */
+  /***************************************************************************/
+  evel_enc_kv_opt_string(jbuf, "alertValue", &event->alertValue);
+  evel_enc_kv_opt_string(jbuf, "dataCollector", &event->dataCollector);
+  evel_enc_kv_opt_string(jbuf, "elementType", &event->elementType);
+  evel_enc_kv_opt_string(jbuf, "interfaceName", &event->interfaceName);
+  evel_enc_kv_opt_string(jbuf, "networkService", &event->networkService);
+  evel_enc_kv_opt_string(jbuf, "possibleRootCause", &event->possibleRootCause);
+
+  /***************************************************************************/
+  /* Checkpoint, so that we can wind back if all fields are suppressed.      */
+  /***************************************************************************/
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "additionalFields"))
+  {
+    bool added = false;
+
+    dlist_item = dlist_get_first(&event->additional_info);
+    while (dlist_item != NULL)
+    {
+      nv_pair = (OTHER_FIELD *) dlist_item->item;
+      assert(nv_pair != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "additionalFields",
+                                          nv_pair->name))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "name", nv_pair->name);
+        evel_enc_kv_string(jbuf, "value", nv_pair->value);
+        evel_json_close_object(jbuf);
+        added = true;
+      }
+      dlist_item = dlist_get_next(dlist_item);
+    }
+    evel_json_close_list(jbuf);
+
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+  evel_enc_version(jbuf,
+                   "thresholdCrossingFieldsVersion",
+                   event->major_version,
+                   event->minor_version);
+
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
+
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_throttle.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_throttle.c
new file mode 100644 (file)
index 0000000..6327741
--- /dev/null
@@ -0,0 +1,2103 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Event Manager
+ *
+ * Simple event manager that is responsible for taking events (Heartbeats,
+ * Faults and Measurements) from the ring-buffer and posting them to the API.
+ *
+ ****************************************************************************/
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <pthread.h>
+#include <search.h>
+
+#include "evel_throttle.h"
+
+/*****************************************************************************/
+/* The Event Throttling State for all domains, indexed by                    */
+/* ::EVEL_EVENT_DOMAINS, corresponding to JSON eventDomain.                  */
+/*                                                                           */
+/* A given domain is in a throttled state if ::evel_throttle_spec is         */
+/* non-NULL.                                                                 */
+/*****************************************************************************/
+static EVEL_THROTTLE_SPEC * evel_throttle_spec[EVEL_MAX_DOMAINS];
+
+/*****************************************************************************/
+/* The current measurement interval.  Default: MEASUREMENT_INTERVAL_UKNOWN.  */
+/* Must be protected by evel_measurement_interval_mutex.                     */
+/*****************************************************************************/
+static int evel_measurement_interval;
+
+/*****************************************************************************/
+/* Mutex protecting evel_measurement_interval from contention between an     */
+/* EVEL client reading it, and the EVEL event handler updating it.           */
+/*****************************************************************************/
+static pthread_mutex_t evel_measurement_interval_mutex;
+
+/*****************************************************************************/
+/* Flag stating that we have received a "provideThrottlingState" command.    */
+/* Set during JSON processing and cleared on sending the throttling state.   */
+/*****************************************************************************/
+static bool evel_provide_throttling_state;
+
+/*****************************************************************************/
+/* Holder for the "commandType" value during JSON processing.                */
+/*****************************************************************************/
+static char * evel_command_type_value;
+
+/*****************************************************************************/
+/* Holder for the "measurementInterval" value during JSON processing.        */
+/*****************************************************************************/
+static char * evel_measurement_interval_value;
+
+/*****************************************************************************/
+/* Holder for the "eventDomain" value during JSON processing.                */
+/*****************************************************************************/
+static char * evel_throttle_spec_domain_value;
+
+/*****************************************************************************/
+/* Decoded version of ::evel_throttle_spec_domain_value.                     */
+/*****************************************************************************/
+static EVEL_EVENT_DOMAINS evel_throttle_spec_domain;
+
+/*****************************************************************************/
+/* During JSON processing of a single throttling specification, we collect   */
+/* parameters in this working ::EVEL_THROTTLE_SPEC                           */
+/*****************************************************************************/
+static EVEL_THROTTLE_SPEC * evel_temp_throttle;
+
+/*****************************************************************************/
+/* State tracking our progress through the command list                      */
+/*****************************************************************************/
+EVEL_JSON_COMMAND_STATE evel_json_command_state;
+
+/*****************************************************************************/
+/* Debug strings for ::EVEL_JSON_COMMAND_STATE.                              */
+/*****************************************************************************/
+static const char * const evel_jcs_strings[EVEL_JCS_MAX] = {
+  "EVEL_JCS_START",
+  "EVEL_JCS_COMMAND_LIST",
+  "EVEL_JCS_COMMAND_LIST_ENTRY",
+  "EVEL_JCS_COMMAND",
+  "EVEL_JCS_SPEC",
+  "EVEL_JCS_FIELD_NAMES",
+  "EVEL_JCS_PAIRS_LIST",
+  "EVEL_JCS_PAIRS_LIST_ENTRY",
+  "EVEL_JCS_NV_PAIR_NAMES"
+};
+
+/*****************************************************************************/
+/* Debug strings for JSON token type.                                        */
+/*****************************************************************************/
+#define JSON_TOKEN_TYPES                (JSMN_PRIMITIVE + 1)
+static const char * const evel_json_token_strings[JSON_TOKEN_TYPES] = {
+  "JSMN_UNDEFINED",
+  "JSMN_OBJECT",
+  "JSMN_ARRAY",
+  "JSMN_STRING",
+  "JSMN_PRIMITIVE"
+};
+
+/*****************************************************************************/
+/* Debug strings for JSON domains.                                           */
+/*****************************************************************************/
+static const char * evel_domain_strings[EVEL_MAX_DOMAINS] = {
+  "internal",
+  "heartbeat",
+  "fault",
+  "measurementsForVfScaling",
+  "mobileFlow",
+  "report",
+  "serviceEvents",
+  "signaling",
+  "stateChange",
+  "syslog",
+  "other"
+  "voiceQuality",
+  "maxDomain"
+};
+
+/*****************************************************************************/
+/* Local prototypes.                                                         */
+/*****************************************************************************/
+static void evel_throttle_finalize(EVEL_THROTTLE_SPEC * throttle_spec);
+static struct hsearch_data * evel_throttle_hash_create(DLIST * hash_keys);
+static void evel_throttle_free(EVEL_THROTTLE_SPEC * throttle_spec);
+static void evel_throttle_free_nv_pair(EVEL_SUPPRESSED_NV_PAIRS * nv_pairs);
+static void evel_init_json_stack(EVEL_JSON_STACK * json_stack,
+                                 const MEMORY_CHUNK * const chunk);
+static bool evel_stack_push(EVEL_JSON_STACK * const json_stack,
+                            const int num_required,
+                            const EVEL_JSON_STATE new_state);
+static void evel_stack_pop(EVEL_JSON_STACK * const json_stack);
+static void evel_stack_cleanup(EVEL_JSON_STACK * const json_stack);
+static char * evel_stack_strdup(const MEMORY_CHUNK * const chunk,
+                                const jsmntok_t * const token);
+static void evel_stack_store_key(EVEL_JSON_STACK * const json_stack,
+                                 const jsmntok_t * const token);
+static void evel_stack_store_value(EVEL_JSON_STACK * const json_stack,
+                                   const jsmntok_t * const token);
+static void evel_stack_store_item(EVEL_JSON_STACK * const json_stack,
+                                  const jsmntok_t * const token);
+static void evel_set_command_state(const EVEL_JSON_COMMAND_STATE new_state);
+static void evel_debug_token(const MEMORY_CHUNK * const chunk,
+                             const jsmntok_t * const token);
+static void evel_command_list_response(MEMORY_CHUNK * const post);
+static int evel_json_encode_throttle(char * const json, const int max_size);
+static int evel_json_encode_throttle_spec(char * const json,
+                                          const int max_size,
+                                          const EVEL_EVENT_DOMAINS domain);
+static int evel_json_encode_nv_pairs(char * const json,
+                                     const int max_size,
+                                     EVEL_SUPPRESSED_NV_PAIRS * nv_pairs);
+static void evel_close_command();
+static void evel_open_command();
+static void evel_set_throttling_spec();
+static void evel_set_measurement_interval();
+static void evel_open_throttle_spec();
+static void evel_close_throttle_spec();
+static EVEL_EVENT_DOMAINS evel_decode_domain(char * domain_value);
+static void evel_open_nv_pairs_list_entry();
+static void evel_close_nv_pairs_list_entry();
+static void evel_store_nv_pair_field_name(char * const value);
+static void evel_store_nv_pair_name(char * const item);
+static void evel_store_suppressed_field_name(char * const item);
+static EVEL_SUPPRESSED_NV_PAIRS * evel_get_last_nv_pairs();
+
+/**************************************************************************//**
+ * Return the current measurement interval provided by the Event Listener.
+ *
+ * @returns The current measurement interval
+ * @retval  EVEL_MEASUREMENT_INTERVAL_UKNOWN (0) - interval has not been
+ *          specified
+ *****************************************************************************/
+int evel_get_measurement_interval()
+{
+  int result;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Lock, read, unlock.                                                     */
+  /***************************************************************************/
+  pthread_mutex_lock(&evel_measurement_interval_mutex);
+  result = evel_measurement_interval;
+  pthread_mutex_unlock(&evel_measurement_interval_mutex);
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Return the ::EVEL_THROTTLE_SPEC for a given domain.
+ *
+ * @param domain        The domain for which to return state.
+ *****************************************************************************/
+EVEL_THROTTLE_SPEC * evel_get_throttle_spec(EVEL_EVENT_DOMAINS domain)
+{
+  EVEL_THROTTLE_SPEC * result;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(domain < EVEL_MAX_DOMAINS);
+
+  result = evel_throttle_spec[domain];
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Determine whether a field_name should be suppressed.
+ *
+ * @param throttle_spec Throttle specification for the domain being encoded.
+ * @param field_name    The field name to encoded or suppress.
+ * @return true if the field_name should be suppressed, false otherwise.
+ *****************************************************************************/
+bool evel_throttle_suppress_field(EVEL_THROTTLE_SPEC * throttle_spec,
+                                  const char * const field_name)
+{
+  bool suppress = false;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(field_name != NULL);
+
+  /***************************************************************************/
+  /* If the throttle spec and hash table exist, query the field_names table. */
+  /***************************************************************************/
+  if ((throttle_spec != NULL) && (throttle_spec->hash_field_names != NULL))
+  {
+    ENTRY hash_query;
+    ENTRY * hash_result;
+    hash_query.key = (char * const) field_name;
+    suppress = (hsearch_r(hash_query,
+                          FIND,
+                          &hash_result,
+                          throttle_spec->hash_field_names) != 0);
+  }
+
+  EVEL_EXIT();
+
+  return suppress;
+}
+
+/**************************************************************************//**
+ * Determine whether a name-value pair should be allowed (not suppressed).
+ *
+ * @param throttle_spec Throttle specification for the domain being encoded.
+ * @param field_name    The field name holding the name-value pairs.
+ * @param name          The name of the name-value pair to encoded or suppress.
+ * @return true if the name-value pair should be suppressed, false otherwise.
+ *****************************************************************************/
+bool evel_throttle_suppress_nv_pair(EVEL_THROTTLE_SPEC * throttle_spec,
+                                    const char * const field_name,
+                                    const char * const name)
+{
+  EVEL_SUPPRESSED_NV_PAIRS * nv_pairs;
+  bool hit = false;
+  bool suppress = false;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(field_name != NULL);
+  assert(name != NULL);
+
+  /***************************************************************************/
+  /* If the throttle spec and hash table exist, query the nv_pairs table.    */
+  /***************************************************************************/
+  if ((throttle_spec != NULL) && (throttle_spec->hash_nv_pairs_list != NULL))
+  {
+    ENTRY hash_query;
+    ENTRY * hash_result;
+    hash_query.key = (char * const) field_name;
+    hit = (hsearch_r(hash_query,
+                     FIND,
+                     &hash_result,
+                     throttle_spec->hash_nv_pairs_list) != 0);
+    if (hit)
+    {
+      nv_pairs = hash_result->data;
+    }
+  }
+
+  /***************************************************************************/
+  /* If we got a hit, and the nv_pairs and hash table exist, query the       */
+  /* nv_pairs table.                                                         */
+  /***************************************************************************/
+  if (hit && (nv_pairs != NULL) && (nv_pairs->hash_nv_pair_names != NULL))
+  {
+    ENTRY hash_query;
+    ENTRY * hash_result;
+    hash_query.key = (char * const) name;
+    suppress = (hsearch_r(hash_query,
+                          FIND,
+                          &hash_result,
+                          nv_pairs->hash_nv_pair_names) != 0);
+  }
+
+  EVEL_EXIT();
+
+  return suppress;
+}
+
+/**************************************************************************//**
+ * Initialize event throttling to the default state.
+ *
+ * Called from ::evel_initialize.
+ *****************************************************************************/
+void evel_throttle_initialize()
+{
+  int pthread_rc;
+  int ii;
+
+  EVEL_ENTER();
+
+  for (ii = 0; ii < EVEL_MAX_DOMAINS; ii++)
+  {
+    evel_throttle_spec[ii] = NULL;
+  }
+
+  pthread_rc = pthread_mutex_init(&evel_measurement_interval_mutex, NULL);
+  assert(pthread_rc == 0);
+
+  evel_measurement_interval = EVEL_MEASUREMENT_INTERVAL_UKNOWN;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Clean up event throttling.
+ *
+ * Called from ::evel_terminate.
+ *****************************************************************************/
+void evel_throttle_terminate()
+{
+  int pthread_rc;
+  int ii;
+
+  EVEL_ENTER();
+
+  for (ii = 0; ii < EVEL_MAX_DOMAINS; ii++)
+  {
+    if (evel_throttle_spec[ii] != NULL)
+    {
+      evel_throttle_free(evel_throttle_spec[ii]);
+      evel_throttle_spec[ii] = NULL;
+    }
+  }
+
+  pthread_rc = pthread_mutex_destroy(&evel_measurement_interval_mutex);
+  assert(pthread_rc == 0);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Finalize a single ::EVEL_THROTTLE_SPEC.
+ *
+ * Now that the specification is collected, build hash tables to simplify the
+ * throttling itself.
+ *
+ * @param throttle_spec The ::EVEL_THROTTLE_SPEC to finalize.
+ *****************************************************************************/
+void evel_throttle_finalize(EVEL_THROTTLE_SPEC * throttle_spec)
+{
+  int nv_pairs_count;
+  DLIST_ITEM * dlist_item;
+  ENTRY * add_result;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(throttle_spec != NULL);
+
+  /***************************************************************************/
+  /* Populate the hash table for suppressed field names.                     */
+  /***************************************************************************/
+  throttle_spec->hash_field_names =
+             evel_throttle_hash_create(&throttle_spec->suppressed_field_names);
+
+  /***************************************************************************/
+  /* Create the hash table for suppressed nv pairs.                          */
+  /***************************************************************************/
+  nv_pairs_count = dlist_count(&throttle_spec->suppressed_nv_pairs_list);
+  if (nv_pairs_count > 0)
+  {
+    throttle_spec->hash_nv_pairs_list = calloc(1, sizeof(struct hsearch_data));
+    assert(throttle_spec->hash_nv_pairs_list != NULL);
+
+    /*************************************************************************/
+    /* Provide plenty of space in the table - see hcreate_r notes.           */
+    /*************************************************************************/
+    if (hcreate_r(nv_pairs_count * 2, throttle_spec->hash_nv_pairs_list) == 0)
+    {
+      EVEL_ERROR("Failed to create hash table");
+      free(throttle_spec->hash_nv_pairs_list);
+      throttle_spec->hash_nv_pairs_list = NULL;
+    }
+  }
+
+  /***************************************************************************/
+  /* Populate the hash tables under suppressed field names.                  */
+  /***************************************************************************/
+  dlist_item = dlist_get_first(&throttle_spec->suppressed_nv_pairs_list);
+  while (dlist_item != NULL)
+  {
+    EVEL_SUPPRESSED_NV_PAIRS * nv_pairs = dlist_item->item;
+    ENTRY hash_add;
+
+    /*************************************************************************/
+    /* Set the key to the string, and the item to the nv_pairs.              */
+    /*************************************************************************/
+    assert(nv_pairs != NULL);
+    hash_add.key = nv_pairs->nv_pair_field_name;
+    hash_add.data = nv_pairs;
+    hsearch_r(hash_add, ENTER, &add_result, throttle_spec->hash_nv_pairs_list);
+
+    /*************************************************************************/
+    /* Create the nv_pair_names hash since we're in here.                    */
+    /*************************************************************************/
+    nv_pairs->hash_nv_pair_names =
+      evel_throttle_hash_create(&nv_pairs->suppressed_nv_pair_names);
+
+    dlist_item = dlist_get_next(dlist_item);
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Create and populate a hash table from a DLIST of keys.
+ *
+ * @param hash_keys     Pointer to a DLIST of hash table keys.
+ * @return Pointer to the created hash-table, or NULL on failure.
+ *****************************************************************************/
+struct hsearch_data * evel_throttle_hash_create(DLIST * hash_keys)
+{
+  int key_count;
+  struct hsearch_data * hash_table;
+  ENTRY * add_result;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(hash_keys != NULL);
+
+  /***************************************************************************/
+  /* Count the keys and if there are any, populate the hash table with them. */
+  /***************************************************************************/
+  key_count = dlist_count(hash_keys);
+  if (key_count > 0)
+  {
+    EVEL_DEBUG("Populating table for %d keys", key_count);
+
+    hash_table = calloc(1, sizeof(struct hsearch_data));
+    assert(hash_table != NULL);
+
+    /*************************************************************************/
+    /* We need to leave plenty of space in the table - see hcreate_r notes.  */
+    /*************************************************************************/
+    if (hcreate_r(key_count * 2, hash_table) != 0)
+    {
+      DLIST_ITEM * dlist_item;
+      dlist_item = dlist_get_first(hash_keys);
+      while (dlist_item != NULL)
+      {
+        assert(dlist_item->item != NULL);
+
+        /*********************************************************************/
+        /* Set the key and data to the item, which is a string in this case. */
+        /*********************************************************************/
+        ENTRY hash_add;
+        hash_add.key = dlist_item->item;
+        hash_add.data = dlist_item->item;
+        hsearch_r(hash_add, ENTER, &add_result, hash_table);
+        dlist_item = dlist_get_next(dlist_item);
+      }
+    }
+    else
+    {
+      EVEL_ERROR("Failed to create hash table");
+      free(hash_table);
+      hash_table = NULL;
+    }
+  }
+  else
+  {
+    hash_table = NULL;
+  }
+
+  EVEL_EXIT();
+
+  return hash_table;
+}
+
+/**************************************************************************//**
+ * Free resources associated with a single ::EVEL_THROTTLE_SPEC.
+ *
+ * @param throttle_spec The ::EVEL_THROTTLE_SPEC to free.
+ *****************************************************************************/
+void evel_throttle_free(EVEL_THROTTLE_SPEC * throttle_spec)
+{
+  char * field_name;
+  EVEL_SUPPRESSED_NV_PAIRS * nv_pairs;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(throttle_spec != NULL);
+
+  /***************************************************************************/
+  /* Free any hash tables.                                                   */
+  /***************************************************************************/
+  if (throttle_spec->hash_field_names != NULL)
+  {
+    hdestroy_r(throttle_spec->hash_field_names);
+    free(throttle_spec->hash_field_names);
+  }
+  if (throttle_spec->hash_nv_pairs_list != NULL)
+  {
+    hdestroy_r(throttle_spec->hash_nv_pairs_list);
+    free(throttle_spec->hash_nv_pairs_list);
+  }
+
+  /***************************************************************************/
+  /* Iterate through the linked lists, freeing memory.                       */
+  /***************************************************************************/
+  field_name = dlist_pop_last(&throttle_spec->suppressed_field_names);
+  while (field_name != NULL)
+  {
+    free(field_name);
+    field_name = dlist_pop_last(&throttle_spec->suppressed_field_names);
+  }
+
+  nv_pairs = dlist_pop_last(&throttle_spec->suppressed_nv_pairs_list);
+  while (nv_pairs != NULL)
+  {
+    evel_throttle_free_nv_pair(nv_pairs);
+    nv_pairs = dlist_pop_last(&throttle_spec->suppressed_nv_pairs_list);
+  }
+
+  free(throttle_spec);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free resources associated with a single ::EVEL_SUPPRESSED_NV_PAIR.
+ *
+ * @param nv_pair       The ::EVEL_SUPPRESSED_NV_PAIR to free.
+ *****************************************************************************/
+void evel_throttle_free_nv_pair(EVEL_SUPPRESSED_NV_PAIRS * nv_pairs)
+{
+  char * suppressed_name;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(nv_pairs != NULL);
+
+  /***************************************************************************/
+  /* Free any hash tables.                                                   */
+  /***************************************************************************/
+  if (nv_pairs->hash_nv_pair_names != NULL)
+  {
+    hdestroy_r(nv_pairs->hash_nv_pair_names);
+    free(nv_pairs->hash_nv_pair_names);
+  }
+
+  /***************************************************************************/
+  /* Iterate through the linked lists, freeing memory.                       */
+  /***************************************************************************/
+  suppressed_name = dlist_pop_last(&nv_pairs->suppressed_nv_pair_names);
+  while (suppressed_name != NULL)
+  {
+    free(suppressed_name);
+    suppressed_name = dlist_pop_last(&nv_pairs->suppressed_nv_pair_names);
+  }
+  if (nv_pairs->nv_pair_field_name != NULL)
+  {
+    free(nv_pairs->nv_pair_field_name);
+  }
+  free(nv_pairs);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Handle a JSON response from the listener, as a list of tokens from JSMN.
+ *
+ * @param chunk         Memory chunk containing the JSON buffer.
+ * @param json_tokens   Array of tokens to handle.
+ * @param num_tokens    The number of tokens to handle.
+ * @param post          The memory chunk in which to place any resulting POST.
+ * @return true if the command was handled, false otherwise.
+ *****************************************************************************/
+bool evel_handle_command_list(const MEMORY_CHUNK * const chunk,
+                              const jsmntok_t * const json_tokens,
+                              const int num_tokens,
+                              MEMORY_CHUNK * const post)
+{
+  EVEL_JSON_STACK stack;
+  EVEL_JSON_STACK * json_stack = &stack;
+  EVEL_JSON_STACK_ENTRY * entry;
+
+  bool json_ok = true;
+  int token_index = 0;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(chunk != NULL);
+  assert(json_tokens != NULL);
+  assert(num_tokens < EVEL_MAX_RESPONSE_TOKENS);
+
+  /***************************************************************************/
+  /* Collect one top-level item.                                             */
+  /***************************************************************************/
+  evel_init_json_stack(json_stack, chunk);
+
+  /***************************************************************************/
+  /* Initialize JSON processing variables.                                   */
+  /***************************************************************************/
+  evel_provide_throttling_state = false;
+  evel_command_type_value = NULL;
+  evel_measurement_interval_value = NULL;
+  evel_throttle_spec_domain_value = NULL;
+  evel_throttle_spec_domain = EVEL_MAX_DOMAINS;
+  evel_temp_throttle = NULL;
+  evel_json_command_state = EVEL_JCS_START;
+
+  /***************************************************************************/
+  /* Loop through the tokens, keeping a stack of state representing the      */
+  /* nested JSON structure (see json_state). We also track our way through   */
+  /* the ::EVEL_JSON_COMMAND_STATE as we go.                                 */
+  /***************************************************************************/
+  while (json_ok && (token_index < num_tokens))
+  {
+    const jsmntok_t * const token = &json_tokens[token_index];
+
+    if (EVEL_DEBUG_ON())
+    {
+      evel_debug_token(chunk, token);
+    }
+
+    /*************************************************************************/
+    /* We may have popped or pushed, so always re-evaluate the stack entry.  */
+    /*************************************************************************/
+    entry = &json_stack->entry[json_stack->level];
+
+    switch(token->type)
+    {
+      case JSMN_OBJECT:
+        if ((entry->json_state == EVEL_JSON_ITEM) ||
+            (entry->json_state == EVEL_JSON_VALUE))
+        {
+          json_ok = evel_stack_push(json_stack, token->size, EVEL_JSON_KEY);
+        }
+        else
+        {
+          EVEL_ERROR("Unexpected JSON state %d at token %d (%d)",
+                     entry->json_state, token_index, token->type);
+          json_ok = false;
+        }
+        break;
+
+      case JSMN_ARRAY:
+        if ((entry->json_state == EVEL_JSON_ITEM) ||
+            (entry->json_state == EVEL_JSON_VALUE))
+        {
+          json_ok = evel_stack_push(json_stack, token->size, EVEL_JSON_ITEM);
+        }
+        else
+        {
+          EVEL_ERROR("Unexpected JSON state %d at token %d (%d)",
+                     entry->json_state, token_index, token->type);
+          json_ok = false;
+        }
+        break;
+
+      case JSMN_STRING:
+        if (entry->json_state == EVEL_JSON_KEY)
+        {
+          evel_stack_store_key(json_stack, token);
+        }
+        else if (entry->json_state == EVEL_JSON_VALUE)
+        {
+          evel_stack_store_value(json_stack, token);
+        }
+        else if (entry->json_state == EVEL_JSON_ITEM)
+        {
+          evel_stack_store_item(json_stack, token);
+        }
+        else
+        {
+          EVEL_ERROR("Unexpected JSON state %d at token %d (%d)",
+                     entry->json_state, token_index, token->type);
+          json_ok = false;
+        }
+        break;
+
+      case JSMN_PRIMITIVE:
+        if (entry->json_state == EVEL_JSON_VALUE)
+        {
+          evel_stack_store_value(json_stack, token);
+        }
+        else if (entry->json_state == EVEL_JSON_ITEM)
+        {
+          evel_stack_store_item(json_stack, token);
+        }
+        else
+        {
+          EVEL_ERROR("Unexpected JSON state %d at token %d (%d)",
+                     entry->json_state, token_index, token->type);
+          json_ok = false;
+        }
+        break;
+
+      case JSMN_UNDEFINED:
+      default:
+        EVEL_ERROR("Unexpected JSON format at token %d (%d)",
+                   token_index, token->type);
+        json_ok = false;
+        break;
+    }
+
+    /*************************************************************************/
+    /* Pop the stack if we're counted enough nested items.                   */
+    /*************************************************************************/
+    evel_stack_pop(json_stack);
+
+    token_index++;
+  }
+
+  /***************************************************************************/
+  /* Cleanup the stack - we may have exited without winding it back, if the  */
+  /* input was not well formed.                                              */
+  /***************************************************************************/
+  evel_stack_cleanup(json_stack);
+
+  /***************************************************************************/
+  /* We may want to generate and POST a response to the command list.        */
+  /***************************************************************************/
+  if (json_ok)
+  {
+    evel_command_list_response(post);
+  }
+
+  /***************************************************************************/
+  /* Make sure we're clean on exit.                                          */
+  /***************************************************************************/
+  assert(evel_command_type_value == NULL);
+  assert(evel_measurement_interval_value == NULL);
+  assert(evel_throttle_spec_domain_value == NULL);
+  assert(evel_throttle_spec_domain == EVEL_MAX_DOMAINS);
+  assert(evel_temp_throttle == NULL);
+
+  EVEL_EXIT();
+
+  return json_ok;
+}
+
+/**************************************************************************//**
+ * Copy a copy of an element, in string form.
+ *
+ * The caller must manage memory allocated for the copied string.
+ *
+ * @param chunk         Memory chunk containing the JSON buffer.
+ * @param token         The token to copy from.
+ * @return the copy of the element.
+ *****************************************************************************/
+char * evel_stack_strdup(const MEMORY_CHUNK * const chunk,
+                         const jsmntok_t * const token)
+{
+  char temp_char;
+  char * result;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Call strdup to copy the string, inserting a temporary \0 for the call.  */
+  /***************************************************************************/
+  temp_char = chunk->memory[token->end];
+  chunk->memory[token->end] = '\0';
+  result = strdup(chunk->memory + token->start);
+  assert(result != NULL);
+  chunk->memory[token->end] = temp_char;
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Copy a copy of an element, in string form.
+ *
+ * @param json_stack    The JSON stack to initialize.
+ * @param chunk         The underlying memory chunk used for parsing.
+ *****************************************************************************/
+void evel_init_json_stack(EVEL_JSON_STACK * json_stack,
+                          const MEMORY_CHUNK * const chunk)
+{
+  EVEL_JSON_STACK_ENTRY * entry;
+
+  EVEL_ENTER();
+
+  json_stack->level = 0;
+  entry = json_stack->entry;
+  entry->json_state = EVEL_JSON_ITEM;
+  entry->json_count = 0;
+  entry->num_required = 1;
+  entry->json_key = NULL;
+  json_stack->chunk = chunk;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Push a new entry on the stack
+ *
+ * @param json_stack    The stack.
+ * @param num_required  The number of elements required.
+ * @param new_state     The state for the new entry.
+ * @return false if we cannot push onto the stack.
+ *****************************************************************************/
+bool evel_stack_push(EVEL_JSON_STACK * const json_stack,
+                     const int num_required,
+                     const EVEL_JSON_STATE new_state)
+{
+  EVEL_JSON_STACK_ENTRY * entry;
+  char * key;
+  bool result;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(json_stack != NULL);
+  assert(json_stack->level >= 0);
+  assert(json_stack->level < EVEL_JSON_STACK_DEPTH);
+  assert((new_state == EVEL_JSON_ITEM) || (new_state == EVEL_JSON_KEY));
+
+  /***************************************************************************/
+  /* Check nesting depth, and stop processing if we hit the limit.           */
+  /***************************************************************************/
+  if ((json_stack->level + 1) >= EVEL_JSON_STACK_DEPTH)
+  {
+    EVEL_ERROR("JSON Nesting is too deep - stop processing");
+    result = false;
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Evaluate cases where we recurse and are interested in the contents.     */
+  /***************************************************************************/
+  entry = &json_stack->entry[json_stack->level];
+  key = entry->json_key;
+
+  /***************************************************************************/
+  /* Note that this is the key before we drop a level.                       */
+  /***************************************************************************/
+  if (key != NULL)
+  {
+    EVEL_DEBUG("Push with key: %s", key);
+
+    switch (evel_json_command_state)
+    {
+      case EVEL_JCS_START:
+        if (strcmp(key, "commandList") == 0)
+        {
+          evel_set_command_state(EVEL_JCS_COMMAND_LIST);
+        }
+        break;
+
+      case EVEL_JCS_COMMAND_LIST_ENTRY:
+        if (strcmp(key, "command") == 0)
+        {
+          evel_open_command();
+          evel_set_command_state(EVEL_JCS_COMMAND);
+        }
+        break;
+
+      case EVEL_JCS_COMMAND:
+        if (strcmp(key, "eventDomainThrottleSpecification") == 0)
+        {
+          evel_open_throttle_spec();
+          evel_set_command_state(EVEL_JCS_SPEC);
+        }
+        break;
+
+      case EVEL_JCS_SPEC:
+        if (strcmp(key, "suppressedFieldNames") == 0)
+        {
+          evel_set_command_state(EVEL_JCS_FIELD_NAMES);
+        }
+        else if (strcmp(key, "suppressedNvPairsList") == 0)
+        {
+          evel_set_command_state(EVEL_JCS_PAIRS_LIST);
+        }
+        break;
+
+      case EVEL_JCS_PAIRS_LIST_ENTRY:
+        if (strcmp(key, "suppressedNvPairNames") == 0)
+        {
+          evel_set_command_state(EVEL_JCS_NV_PAIR_NAMES);
+        }
+        break;
+
+      case EVEL_JCS_FIELD_NAMES:
+      case EVEL_JCS_PAIRS_LIST:
+      case EVEL_JCS_NV_PAIR_NAMES:
+      default:
+        EVEL_ERROR("Unexpected JSON key %s in state %d",
+                   key,
+                   evel_json_command_state);
+        break;
+    }
+  }
+  else
+  {
+    EVEL_DEBUG("Push with no key");
+
+    /*************************************************************************/
+    /* If we're pushing without a key, then we're in an array.  We switch    */
+    /* state based on the existing state and stack level.                    */
+    /*************************************************************************/
+    const int COMMAND_LIST_LEVEL = 2;
+    const int NV_PAIRS_LIST_LEVEL = 6;
+
+    if ((evel_json_command_state == EVEL_JCS_PAIRS_LIST) &&
+        (json_stack->level == NV_PAIRS_LIST_LEVEL))
+    {
+      /***********************************************************************/
+      /* We are entering an object within the "suppressedNvPairsList" array. */
+      /***********************************************************************/
+      evel_open_nv_pairs_list_entry();
+      evel_set_command_state(EVEL_JCS_PAIRS_LIST_ENTRY);
+    }
+
+    if ((evel_json_command_state == EVEL_JCS_COMMAND_LIST) &&
+        (json_stack->level == COMMAND_LIST_LEVEL))
+    {
+      /***********************************************************************/
+      /* We are entering an object within the "commandList" array.           */
+      /***********************************************************************/
+      evel_set_command_state(EVEL_JCS_COMMAND_LIST_ENTRY);
+    }
+  }
+
+  /***************************************************************************/
+  /* Push the stack and initialize the entry.                                */
+  /***************************************************************************/
+  json_stack->level++;
+  entry++;
+  EVEL_DEBUG("Stack Push -> %d", json_stack->level);
+  entry = &json_stack->entry[json_stack->level];
+  entry->json_count = 0;
+  entry->num_required = num_required;
+  entry->json_state = new_state;
+  entry->json_key = NULL;
+  result = true;
+
+exit_label:
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Pop any stack entries which have collected the required number of items.
+ *
+ * @param json_stack    The stack.
+ *****************************************************************************/
+void evel_stack_pop(EVEL_JSON_STACK * const json_stack)
+{
+  EVEL_JSON_STACK_ENTRY * entry;
+  char * key;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(json_stack != NULL);
+  assert(json_stack->level >= 0);
+  assert(json_stack->level < EVEL_JSON_STACK_DEPTH);
+
+  entry = &json_stack->entry[json_stack->level];
+  while ((json_stack->level > 0) && (entry->json_count == entry->num_required))
+  {
+    key = entry->json_key;
+
+    switch (evel_json_command_state)
+    {
+      case EVEL_JCS_COMMAND_LIST:
+        evel_set_command_state(EVEL_JCS_START);
+        break;
+
+      case EVEL_JCS_COMMAND_LIST_ENTRY:
+        evel_set_command_state(EVEL_JCS_COMMAND_LIST);
+        break;
+
+      case EVEL_JCS_COMMAND:
+        evel_close_command();
+        evel_set_command_state(EVEL_JCS_COMMAND_LIST_ENTRY);
+        break;
+
+      case EVEL_JCS_SPEC:
+        evel_close_throttle_spec();
+        evel_set_command_state(EVEL_JCS_COMMAND);
+        break;
+
+      case EVEL_JCS_FIELD_NAMES:
+        evel_set_command_state(EVEL_JCS_SPEC);
+        break;
+
+      case EVEL_JCS_PAIRS_LIST:
+        evel_set_command_state(EVEL_JCS_SPEC);
+        break;
+
+      case EVEL_JCS_PAIRS_LIST_ENTRY:
+        evel_close_nv_pairs_list_entry();
+        evel_set_command_state(EVEL_JCS_PAIRS_LIST);
+        break;
+
+      case EVEL_JCS_NV_PAIR_NAMES:
+        evel_set_command_state(EVEL_JCS_PAIRS_LIST_ENTRY);
+        break;
+
+      default:
+        break;
+    }
+
+    /*************************************************************************/
+    /* Free off any key that was duplicated and stored.                      */
+    /*************************************************************************/
+    if (key != NULL)
+    {
+      free(key);
+      entry->json_key = NULL;
+    }
+
+    /*************************************************************************/
+    /* We just reached the required number of key-value pairs or items, so   */
+    /* pop the stack.                                                        */
+    /*************************************************************************/
+    json_stack->level--;
+    entry--;
+
+    EVEL_DEBUG("Stack Pop  -> %d", json_stack->level);
+
+    /*************************************************************************/
+    /* We just completed collection of an ITEM (within an ARRAY) or a VALUE  */
+    /* (within an OBJECT).  Either way, we need to count it.                 */
+    /*************************************************************************/
+    entry->json_count++;
+
+    /*************************************************************************/
+    /* If we just completed a VALUE, then we expect the next element to be a */
+    /* key, if there is a next element.                                      */
+    /*************************************************************************/
+    if (entry->json_state == EVEL_JSON_VALUE)
+    {
+      entry->json_state = EVEL_JSON_KEY;
+    }
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Pop all stack entries, freeing any memory as we go.
+ *
+ * @param json_stack    The stack.
+ *****************************************************************************/
+void evel_stack_cleanup(EVEL_JSON_STACK * const json_stack)
+{
+  EVEL_JSON_STACK_ENTRY * entry;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(json_stack != NULL);
+  assert(json_stack->level >= 0);
+  assert(json_stack->level < EVEL_JSON_STACK_DEPTH);
+
+  entry = &json_stack->entry[json_stack->level];
+  while ((json_stack->level > 0))
+  {
+    /*************************************************************************/
+    /* Free off any key that was duplicated and stored.                      */
+    /*************************************************************************/
+    if (entry->json_key != NULL)
+    {
+      free(entry->json_key);
+      entry->json_key = NULL;
+    }
+
+    /*************************************************************************/
+    /* We just reached the required number of key-value pairs or items, so   */
+    /* pop the stack.                                                        */
+    /*************************************************************************/
+    json_stack->level--;
+    entry--;
+  }
+
+  /***************************************************************************/
+  /* If we hit EVEL_JSON_STACK_DEPTH, we exit the loop and can leave these   */
+  /* values hanging - so clean them up.                                      */
+  /***************************************************************************/
+  if (evel_command_type_value != NULL)
+  {
+    free(evel_command_type_value);
+    evel_command_type_value = NULL;
+  }
+  if (evel_measurement_interval_value != NULL)
+  {
+    free(evel_measurement_interval_value);
+    evel_measurement_interval_value = NULL;
+  }
+  if (evel_throttle_spec_domain_value != NULL)
+  {
+    free(evel_throttle_spec_domain_value);
+    evel_throttle_spec_domain_value = NULL;
+  }
+  evel_throttle_spec_domain = EVEL_MAX_DOMAINS;
+  if (evel_temp_throttle != NULL)
+  {
+    evel_throttle_free(evel_temp_throttle);
+    evel_temp_throttle = NULL;
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Store a key in the JSON stack.
+ *
+ * We always store the most recent key at each level in the stack.
+ *
+ * @param json_stack    The stack.
+ * @param token         The token holding the key.
+ *****************************************************************************/
+void evel_stack_store_key(EVEL_JSON_STACK * const json_stack,
+                          const jsmntok_t * const token)
+{
+  EVEL_JSON_STACK_ENTRY * entry;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(json_stack != NULL);
+  assert(json_stack->level >= 0);
+  assert(json_stack->level < EVEL_JSON_STACK_DEPTH);
+
+  /***************************************************************************/
+  /* Free any previously stored key, replacing it with the new one.          */
+  /***************************************************************************/
+  entry = &json_stack->entry[json_stack->level];
+  if (entry->json_key != NULL)
+  {
+    free(entry->json_key);
+  }
+  entry->json_key = evel_stack_strdup(json_stack->chunk, token);
+
+  /***************************************************************************/
+  /* Switch state to collecting the corresponding value.                     */
+  /***************************************************************************/
+  entry->json_state = EVEL_JSON_VALUE;
+
+  EVEL_DEBUG("Stored key: %s", entry->json_key);
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Store a value in the JSON stack.
+ *
+ * @param json_stack    The stack.
+ * @param token         The token holding the value.
+ *****************************************************************************/
+void evel_stack_store_value(EVEL_JSON_STACK * const json_stack,
+                            const jsmntok_t * const token)
+{
+  EVEL_JSON_STACK_ENTRY * entry;
+  char * value;
+  bool stored;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(json_stack != NULL);
+  assert(json_stack->level >= 0);
+  assert(json_stack->level < EVEL_JSON_STACK_DEPTH);
+
+  /***************************************************************************/
+  /* Based on the (key, state), work out whether we're expecting a value,    */
+  /* then store or ignore it as required.                                    */
+  /***************************************************************************/
+  entry = &json_stack->entry[json_stack->level];
+  value = evel_stack_strdup(json_stack->chunk, token);
+  stored = false;
+  EVEL_DEBUG("Store value: %s", value);
+
+  switch (evel_json_command_state)
+  {
+    case EVEL_JCS_COMMAND:
+      if (strcmp(entry->json_key, "commandType") == 0)
+      {
+        evel_command_type_value = value;
+        stored = true;
+      }
+      else if (strcmp(entry->json_key, "measurementInterval") == 0)
+      {
+        evel_measurement_interval_value = value;
+        stored = true;
+      }
+      break;
+
+    case EVEL_JCS_SPEC:
+      if (strcmp(entry->json_key, "eventDomain") == 0)
+      {
+        evel_throttle_spec_domain_value = value;
+        stored = true;
+      }
+      break;
+
+    case EVEL_JCS_PAIRS_LIST_ENTRY:
+      if (strcmp(entry->json_key, "nvPairFieldName") == 0)
+      {
+        evel_store_nv_pair_field_name(value);
+        stored = true;
+      }
+      break;
+
+    default:
+      EVEL_DEBUG("Ignoring value in state: %s",
+                 evel_jcs_strings[evel_json_command_state]);
+      break;
+  }
+
+  if (!stored)
+  {
+    EVEL_DEBUG("Ignored value: %s", value);
+    free(value);
+  }
+
+  /***************************************************************************/
+  /* Switch state to another key.                                            */
+  /***************************************************************************/
+  entry->json_state = EVEL_JSON_KEY;
+
+  /***************************************************************************/
+  /* Count the key-value pair.                                               */
+  /***************************************************************************/
+  entry->json_count++;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Store an item in the JSON stack - a string or primitive in an array.
+ *
+ * @param json_stack    The stack.
+ * @param token         The token holding the item.
+ *****************************************************************************/
+void evel_stack_store_item(EVEL_JSON_STACK * const json_stack,
+                           const jsmntok_t * const token)
+{
+  EVEL_JSON_STACK_ENTRY * entry;
+  char * item;
+  bool stored;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(json_stack != NULL);
+  assert(json_stack->level >= 0);
+  assert(json_stack->level < EVEL_JSON_STACK_DEPTH);
+
+  /***************************************************************************/
+  /* Based on the state, work out whether we're expecting an item, then      */
+  /* store or ignore it as required.                                         */
+  /***************************************************************************/
+  entry = &json_stack->entry[json_stack->level];
+  item = evel_stack_strdup(json_stack->chunk, token);
+  stored = false;
+  EVEL_DEBUG("Store item: %s", item);
+
+  switch (evel_json_command_state)
+  {
+    case EVEL_JCS_NV_PAIR_NAMES:
+      evel_store_nv_pair_name(item);
+      stored = true;
+      break;
+
+    case EVEL_JCS_FIELD_NAMES:
+      evel_store_suppressed_field_name(item);
+      stored = true;
+      break;
+
+    default:
+      EVEL_DEBUG("Ignoring item in state: %s",
+                 evel_jcs_strings[evel_json_command_state]);
+      break;
+  }
+
+  if (!stored)
+  {
+    EVEL_DEBUG("Ignored item: %s", item);
+    free(item);
+  }
+
+  /***************************************************************************/
+  /* We need another item.  This is purely defensive.                        */
+  /***************************************************************************/
+  entry->json_state = EVEL_JSON_ITEM;
+
+  /***************************************************************************/
+  /* Count the item.                                                         */
+  /***************************************************************************/
+  entry->json_count++;
+}
+
+/**************************************************************************//**
+ * Set the JSON command state to a new value.
+ *
+ * @param new_state     The new state to set.
+ *****************************************************************************/
+void evel_set_command_state(const EVEL_JSON_COMMAND_STATE new_state)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(evel_json_command_state < EVEL_JCS_MAX);
+  assert(new_state < EVEL_JCS_MAX);
+
+  /***************************************************************************/
+  /* Provide common debug, and set the new state.                            */
+  /***************************************************************************/
+  EVEL_DEBUG("Command State: %s -> %s",
+             evel_jcs_strings[evel_json_command_state],
+             evel_jcs_strings[new_state]);
+  evel_json_command_state = new_state;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Produce debug output from a JSON token.
+ *
+ * @param chunk         Memory chunk containing the JSON buffer.
+ * @param token         Token to dump.
+ *****************************************************************************/
+void evel_debug_token(const MEMORY_CHUNK * const chunk,
+                      const jsmntok_t * const token)
+{
+  char temp_char;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(token->type > 0);
+  assert(token->type < JSON_TOKEN_TYPES);
+
+  /***************************************************************************/
+  /* Log the token, leaving it in the state in which it started.             */
+  /***************************************************************************/
+  temp_char = chunk->memory[token->end];
+  chunk->memory[token->end] = '\0';
+  EVEL_DEBUG("JSON token type: %s", evel_json_token_strings[token->type]);
+  EVEL_DEBUG("JSON token: %s", chunk->memory + token->start);
+  chunk->memory[token->end] = temp_char;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Post a response to the commandList.
+ *
+ * @param post          Memory chunk in which to post a response.
+ *****************************************************************************/
+void evel_command_list_response(MEMORY_CHUNK * const post)
+{
+  char * json_post;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(post != NULL);
+  assert(post->memory == NULL);
+
+  if (evel_provide_throttling_state)
+  {
+    EVEL_DEBUG("Provide throttling state");
+
+    /*************************************************************************/
+    /* Encode the response, making it printf-able for debug.                 */
+    /*************************************************************************/
+    json_post = malloc(EVEL_MAX_JSON_BODY);
+    assert(json_post != NULL);
+    post->size = evel_json_encode_throttle(json_post, EVEL_MAX_JSON_BODY - 1);
+    post->memory = json_post;
+    post->memory[post->size] = '\0';
+    evel_provide_throttling_state = false;
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the full throttling specification according to AT&T's schema.
+ *
+ * @param json          Pointer to where to store the JSON encoded data.
+ * @param max_size      Size of storage available in json_body.
+ * @returns Number of bytes actually written.
+ *****************************************************************************/
+int evel_json_encode_throttle(char * const json, const int max_size)
+{
+  bool throttled;
+  int domain;
+  int offset;
+  bool domain_added;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(json != NULL);
+  assert(max_size > 0);
+
+  /***************************************************************************/
+  /* Work out if we're throttled.                                            */
+  /***************************************************************************/
+  throttled = false;
+  for (domain = EVEL_DOMAIN_FAULT; domain < EVEL_MAX_DOMAINS; domain++)
+  {
+    if (evel_throttle_spec[domain] != NULL)
+    {
+      throttled = true;
+    }
+  }
+
+  /***************************************************************************/
+  /* Encode the response.                                                    */
+  /***************************************************************************/
+  offset = 0;
+  offset += snprintf(json + offset, max_size - offset,
+                     "{\"eventThrottlingState\": {");
+  offset += snprintf(json + offset, max_size - offset,
+                     "\"eventThrottlingMode\": \"%s\"",
+                     throttled ? "throttled" : "normal");
+  if (throttled)
+  {
+    offset += snprintf(json + offset, max_size - offset,
+                       ", \"eventDomainThrottleSpecificationList\": [");
+
+    domain_added = false;
+    for (domain = EVEL_DOMAIN_FAULT; domain < EVEL_MAX_DOMAINS; domain++)
+    {
+      if (evel_throttle_spec[domain] != NULL)
+      {
+        if (domain_added)
+        {
+          offset += snprintf(json + offset, max_size - offset, ", ");
+        }
+
+        offset += evel_json_encode_throttle_spec(json + offset,
+                                                 max_size - offset,
+                                                 domain);
+        domain_added = true;
+      }
+    }
+
+    offset += snprintf(json + offset, max_size - offset, "]");
+  }
+
+  offset += snprintf(json + offset, max_size - offset, "}}");
+
+  EVEL_EXIT();
+
+  return offset;
+}
+
+/**************************************************************************//**
+ * Encode a throttling specification for a domain.
+ *
+ * @param json          Pointer to where to store the JSON encoded data.
+ * @param max_size      Size of storage available in json_body.
+ * @returns Number of bytes actually written.
+ *****************************************************************************/
+int evel_json_encode_throttle_spec(char * const json,
+                                   const int max_size,
+                                   const EVEL_EVENT_DOMAINS domain)
+{
+  int offset;
+  EVEL_THROTTLE_SPEC * throttle_spec;
+  DLIST_ITEM * dlist_item;
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(domain >= EVEL_DOMAIN_FAULT);
+  assert(domain < EVEL_MAX_DOMAINS);
+  assert(evel_throttle_spec[domain] != NULL);
+
+  throttle_spec = evel_throttle_spec[domain];
+
+  /***************************************************************************/
+  /* Encode the domain.                                                      */
+  /***************************************************************************/
+  offset = 0;
+  offset += snprintf(json + offset, max_size - offset,
+                     "{");
+  offset += snprintf(json + offset, max_size - offset,
+                     "\"eventDomain\": \"%s\"",
+                     evel_domain_strings[domain]);
+
+  /***************************************************************************/
+  /* Encode "suppressedFieldNames".                                          */
+  /***************************************************************************/
+  dlist_item = dlist_get_first(&throttle_spec->suppressed_field_names);
+  if (dlist_item != NULL)
+  {
+    offset += snprintf(json + offset, max_size - offset,
+                       ", \"suppressedFieldNames\": [");
+    while (dlist_item != NULL)
+    {
+      char * suppressed_field = dlist_item->item;
+      assert(suppressed_field != NULL);
+
+      offset += snprintf(json + offset, max_size - offset,
+                         "\"%s\"", suppressed_field);
+      dlist_item = dlist_get_next(dlist_item);
+      if (dlist_item != NULL)
+      {
+        offset += snprintf(json + offset, max_size - offset, ", ");
+      }
+    }
+
+    offset += snprintf(json + offset, max_size - offset, "]");
+  }
+
+  /***************************************************************************/
+  /* Encode "suppressedNvPairsList".                                         */
+  /***************************************************************************/
+  dlist_item = dlist_get_first(&throttle_spec->suppressed_nv_pairs_list);
+  if (dlist_item != NULL)
+  {
+    offset += snprintf(json + offset, max_size - offset,
+                       ", \"suppressedNvPairsList\": [");
+    while (dlist_item != NULL)
+    {
+      offset += evel_json_encode_nv_pairs(json + offset,
+                                          max_size - offset,
+                                          dlist_item->item);
+      dlist_item = dlist_get_next(dlist_item);
+      if (dlist_item != NULL)
+      {
+        offset += snprintf(json + offset, max_size - offset, ", ");
+      }
+    }
+
+    offset += snprintf(json + offset, max_size - offset, "]");
+  }
+
+  offset += snprintf(json + offset, max_size - offset, "}");
+
+  EVEL_EXIT();
+
+  return offset;
+}
+
+/**************************************************************************//**
+ * Encode a single "suppressedNvPairsListEntry".
+ *
+ * @param json          Pointer to where to store the JSON encoded data.
+ * @param max_size      Size of storage available in json_body.
+ * @returns Number of bytes actually written.
+ *****************************************************************************/
+int evel_json_encode_nv_pairs(char * const json,
+                              const int max_size,
+                              EVEL_SUPPRESSED_NV_PAIRS * nv_pairs)
+{
+  DLIST_ITEM * dlist_item;
+  char * name;
+  int offset;
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(nv_pairs != NULL);
+  assert(nv_pairs->nv_pair_field_name != NULL);
+  assert(!dlist_is_empty(&nv_pairs->suppressed_nv_pair_names));
+
+  /***************************************************************************/
+  /* Encode it.                                                              */
+  /***************************************************************************/
+  offset = 0;
+  offset += snprintf(json + offset, max_size - offset, "{");
+  offset += snprintf(json + offset, max_size - offset,
+                     "\"nvPairFieldName\": \"%s\"",
+                     nv_pairs->nv_pair_field_name);
+  dlist_item = dlist_get_first(&nv_pairs->suppressed_nv_pair_names);
+  offset += snprintf(json + offset, max_size - offset,
+                     ", \"suppressedNvPairNames\": [");
+  while (dlist_item != NULL)
+  {
+    name = dlist_item->item;
+    assert(name != NULL);
+    offset += snprintf(json + offset, max_size - offset, "\"%s\"", name);
+    dlist_item = dlist_get_next(dlist_item);
+    if (dlist_item != NULL)
+    {
+      offset += snprintf(json + offset, max_size - offset, ", ");
+    }
+  }
+  offset += snprintf(json + offset, max_size - offset, "]");
+  offset += snprintf(json + offset, max_size - offset, "}");
+
+  EVEL_EXIT();
+
+  return offset;
+}
+
+/**************************************************************************//**
+ * Method called when we open a "command" object.
+ *****************************************************************************/
+void evel_open_command()
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Make some assertions.                                                   */
+  /***************************************************************************/
+  assert(evel_command_type_value == NULL);
+  assert(evel_measurement_interval_value == NULL);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Method called when we close a "command" object.
+ *****************************************************************************/
+void evel_close_command()
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* If a commandType was provided, fan out and handle it now what we have   */
+  /* fathered all related information.                                       */
+  /*                                                                         */
+  /* Note that we handle throttling specification and measurement interval   */
+  /* updates immediately on closing the command (not the list). We could     */
+  /* reject *all* commands in a list if any of them are invalid, but we are  */
+  /* take a best-effort strategy here - any valid-looking command gets       */
+  /* implemented regardless of what follows.                                 */
+  /***************************************************************************/
+  if (evel_command_type_value != NULL)
+  {
+    EVEL_DEBUG("Closing command %s", evel_command_type_value);
+
+    if (strcmp(evel_command_type_value, "provideThrottlingState") == 0)
+    {
+      evel_provide_throttling_state = true;
+    }
+    else if (strcmp(evel_command_type_value, "throttlingSpecification") == 0)
+    {
+      evel_set_throttling_spec();
+    }
+    else if (strcmp(evel_command_type_value, "measurementIntervalChange") == 0)
+    {
+      evel_set_measurement_interval();
+    }
+    else
+    {
+      EVEL_ERROR("Ignoring unknown commandType: %s\n",
+                 evel_command_type_value);
+    }
+
+    /*************************************************************************/
+    /* Free the captured "commandType" value.                                */
+    /*************************************************************************/
+    free(evel_command_type_value);
+    evel_command_type_value = NULL;
+  }
+
+  /***************************************************************************/
+  /* There could be an unused working throttle spec at this point - if the   */
+  /* "throttlingSpecification" commandType was not provided, or an invalid   */
+  /* domain was provided, or was not provided at all.                        */
+  /***************************************************************************/
+  if (evel_temp_throttle != NULL)
+  {
+    evel_throttle_free(evel_temp_throttle);
+    evel_temp_throttle = NULL;
+  }
+
+  /***************************************************************************/
+  /* Similarly, the domain could be set.                                     */
+  /***************************************************************************/
+  evel_throttle_spec_domain = EVEL_MAX_DOMAINS;
+
+  /***************************************************************************/
+  /* There could be an unused measurement interval value at this point - if  */
+  /* the "measurementIntervalChange" command was not provided.               */
+  /***************************************************************************/
+  if (evel_measurement_interval_value != NULL)
+  {
+    free(evel_measurement_interval_value);
+    evel_measurement_interval_value = NULL;
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the provided throttling specification, when the command closes.
+ *****************************************************************************/
+void evel_set_throttling_spec()
+{
+  EVEL_ENTER();
+
+  if ((evel_throttle_spec_domain >= 0) &&
+      (evel_throttle_spec_domain < EVEL_MAX_DOMAINS))
+  {
+    EVEL_DEBUG("Updating throttle spec for domain: %s",
+               evel_domain_strings[evel_throttle_spec_domain]);
+
+    /*************************************************************************/
+    /* Free off the previous throttle specification for the domain, if there */
+    /* is one.                                                               */
+    /*************************************************************************/
+    if (evel_throttle_spec[evel_throttle_spec_domain] != NULL)
+    {
+      evel_throttle_free(evel_throttle_spec[evel_throttle_spec_domain]);
+    }
+
+    /*************************************************************************/
+    /* Finalize the working throttling spec, if there is one.                */
+    /*************************************************************************/
+    if (evel_temp_throttle != NULL)
+    {
+      evel_throttle_finalize(evel_temp_throttle);
+    }
+
+    /*************************************************************************/
+    /* Replace the throttle specification for the domain with the working    */
+    /* throttle specification.  This could be NULL, if an empty throttle     */
+    /* specification has been received for a domain.                         */
+    /*************************************************************************/
+    evel_throttle_spec[evel_throttle_spec_domain] = evel_temp_throttle;
+    evel_temp_throttle = NULL;
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the provided measurement interval, when the command closes.
+ *****************************************************************************/
+void evel_set_measurement_interval()
+{
+  EVEL_ENTER();
+
+  if (evel_measurement_interval_value != NULL)
+  {
+    const long int value = strtol(evel_measurement_interval_value, NULL, 10);
+
+    if ((value >= 0) && (value <= INT_MAX))
+    {
+      /***********************************************************************/
+      /* Lock, update, unlock.                                               */
+      /***********************************************************************/
+      EVEL_DEBUG("Updating measurement interval to %d\n", value);
+
+      pthread_mutex_lock(&evel_measurement_interval_mutex);
+      evel_measurement_interval = value;
+      pthread_mutex_unlock(&evel_measurement_interval_mutex);
+    }
+    else
+    {
+      EVEL_ERROR("Ignoring invalid measurement interval: %s",
+                 evel_measurement_interval_value);
+    }
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Method called when we open an "eventDomainThrottleSpecification" object.
+ *****************************************************************************/
+void evel_open_throttle_spec()
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(evel_throttle_spec_domain_value == NULL);
+  assert(evel_throttle_spec_domain == EVEL_MAX_DOMAINS);
+  assert(evel_temp_throttle == NULL);
+
+  /***************************************************************************/
+  /* Allocate and initialize an ::EVEL_THROTTLE_SPEC in which to hold        */
+  /* captured JSON elements.                                                 */
+  /***************************************************************************/
+  evel_temp_throttle = malloc(sizeof(EVEL_THROTTLE_SPEC));
+  assert(evel_temp_throttle != NULL);
+  dlist_initialize(&evel_temp_throttle->suppressed_field_names);
+  dlist_initialize(&evel_temp_throttle->suppressed_nv_pairs_list);
+  evel_temp_throttle->hash_field_names = NULL;
+  evel_temp_throttle->hash_nv_pairs_list = NULL;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Method called when we close an "eventDomainThrottleSpecification" object.
+ *****************************************************************************/
+void evel_close_throttle_spec()
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Decode, free and blank a captured event domain value.                   */
+  /***************************************************************************/
+  if (evel_throttle_spec_domain_value != NULL)
+  {
+    evel_throttle_spec_domain =
+                           evel_decode_domain(evel_throttle_spec_domain_value);
+    free(evel_throttle_spec_domain_value);
+    evel_throttle_spec_domain_value = NULL;
+  }
+
+  /***************************************************************************/
+  /* Free off an empty working throttle spec, to stop it being used.  This   */
+  /* state should be represented by a NULL pointer for the domain.           */
+  /***************************************************************************/
+  if (evel_temp_throttle != NULL)
+  {
+    if (dlist_is_empty(&evel_temp_throttle->suppressed_field_names) &&
+        dlist_is_empty(&evel_temp_throttle->suppressed_nv_pairs_list))
+    {
+      free(evel_temp_throttle);
+      evel_temp_throttle = NULL;
+    }
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Convert a value for an "eventDomain" into an ::EVEL_EVENT_DOMAINS.
+ *
+ * @param domain_value  The domain string value to decode.
+ * @returns The matching ::EVEL_EVENT_DOMAINS, or ::EVEL_MAX_DOMAINS on error.
+ *****************************************************************************/
+EVEL_EVENT_DOMAINS evel_decode_domain(char * domain_value)
+{
+  EVEL_EVENT_DOMAINS result;
+  int ii;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(domain_value != NULL);
+
+  result = EVEL_MAX_DOMAINS;
+  for (ii = EVEL_DOMAIN_FAULT; ii < EVEL_MAX_DOMAINS; ii++)
+  {
+    assert(evel_domain_strings[ii] != NULL);
+    if (strcmp(evel_domain_strings[ii], domain_value) == 0)
+    {
+      result = ii;
+    }
+  }
+
+  EVEL_EXIT();
+
+  return result;
+}
+
+/**************************************************************************//**
+ * Method called when we open a "suppressedNvPairsListEntry" object.
+ *****************************************************************************/
+void evel_open_nv_pairs_list_entry()
+{
+  EVEL_SUPPRESSED_NV_PAIRS * nv_pairs;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(evel_temp_throttle != NULL);
+
+  /***************************************************************************/
+  /* Allocate and initialize an ::EVEL_SUPPRESSED_NV_PAIRS, and add it to    */
+  /* the list.                                                               */
+  /***************************************************************************/
+  nv_pairs = malloc(sizeof(EVEL_SUPPRESSED_NV_PAIRS));
+  assert(nv_pairs != NULL);
+  nv_pairs->nv_pair_field_name = NULL;
+  dlist_initialize(&nv_pairs->suppressed_nv_pair_names);
+  nv_pairs->hash_nv_pair_names = NULL;
+  dlist_push_last(&evel_temp_throttle->suppressed_nv_pairs_list, nv_pairs);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Method called when we close a "suppressedNvPairsListEntry" object.
+ *****************************************************************************/
+void evel_close_nv_pairs_list_entry()
+{
+  EVEL_SUPPRESSED_NV_PAIRS * nv_pairs;
+  EVEL_SUPPRESSED_NV_PAIRS * popped;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Get the latest nv pairs.  This also performs the required checks.       */
+  /***************************************************************************/
+  nv_pairs = evel_get_last_nv_pairs();
+
+  /***************************************************************************/
+  /* For a "suppressedNvPairsListEntry" to have any meaning, we need both    */
+  /* "nvPairFieldName" and "suppressedNvPairNames".  If we don't, then pop   */
+  /* and free whatever we just collected.                                    */
+  /***************************************************************************/
+  if ((nv_pairs->nv_pair_field_name == NULL) ||
+      dlist_is_empty(&nv_pairs->suppressed_nv_pair_names))
+  {
+    popped = dlist_pop_last(&evel_temp_throttle->suppressed_nv_pairs_list);
+    assert(popped == nv_pairs);
+    evel_throttle_free_nv_pair(popped);
+  }
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Store an "nvPairFieldName" value in the working throttle spec.
+ *
+ * @param value         The value to store.
+ *****************************************************************************/
+void evel_store_nv_pair_field_name(char * const value)
+{
+  EVEL_SUPPRESSED_NV_PAIRS * nv_pairs;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Get the latest nv pairs.  This also performs the required checks.       */
+  /***************************************************************************/
+  nv_pairs = evel_get_last_nv_pairs();
+
+  /***************************************************************************/
+  /* Store the value.                                                        */
+  /***************************************************************************/
+  nv_pairs->nv_pair_field_name = value;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Store a "suppressedNvPairNames" item in the working throttle spec.
+ *
+ * @param item          The item to store.
+ *****************************************************************************/
+void evel_store_nv_pair_name(char * const item)
+{
+  EVEL_SUPPRESSED_NV_PAIRS * nv_pairs;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Get the latest nv pairs.  This also performs the required checks.       */
+  /***************************************************************************/
+  nv_pairs = evel_get_last_nv_pairs();
+
+  /***************************************************************************/
+  /* Store the item.                                                         */
+  /***************************************************************************/
+  dlist_push_last(&nv_pairs->suppressed_nv_pair_names, item);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Store a "suppressedFieldNames" item in the working throttle spec.
+ *
+ * @param item          The item to store.
+ *****************************************************************************/
+void evel_store_suppressed_field_name(char * const item)
+{
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(evel_temp_throttle != NULL);
+
+  /***************************************************************************/
+  /* Store the item.                                                         */
+  /***************************************************************************/
+  dlist_push_last(&evel_temp_throttle->suppressed_field_names, item);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Get the last added suppressed nv pairs list entry in the working spec.
+ *
+ * @returns The last entry.
+ *****************************************************************************/
+EVEL_SUPPRESSED_NV_PAIRS * evel_get_last_nv_pairs()
+{
+  DLIST_ITEM * dlist_item;
+  EVEL_SUPPRESSED_NV_PAIRS * nv_pairs;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(evel_temp_throttle != NULL);
+
+  /***************************************************************************/
+  /* Get the pair that was added when we opened the list entry.              */
+  /***************************************************************************/
+  dlist_item = dlist_get_last(&evel_temp_throttle->suppressed_nv_pairs_list);
+  assert(dlist_item != NULL);
+  nv_pairs = dlist_item->item;
+  assert(nv_pairs != NULL);
+
+  EVEL_EXIT();
+
+  return nv_pairs;
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_throttle.h b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_throttle.h
new file mode 100644 (file)
index 0000000..c97b3c3
--- /dev/null
@@ -0,0 +1,214 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * EVEL throttle definitions.
+ *
+ * These are internal definitions related to throttling specicications, which
+ * are required within the library but are not intended for external
+ * consumption.
+ *
+ ****************************************************************************/
+
+#ifndef EVEL_THROTTLE_INCLUDED
+#define EVEL_THROTTLE_INCLUDED
+
+#include "evel_internal.h"
+#include "jsmn.h"
+
+/*****************************************************************************/
+/* Maximum depth of JSON response that we can handle.                        */
+/*****************************************************************************/
+#define EVEL_JSON_STACK_DEPTH           10
+
+/**************************************************************************//**
+ * Maximum number of tokens that we allow for in a JSON response.
+ *****************************************************************************/
+#define EVEL_MAX_RESPONSE_TOKENS        1024
+
+/**************************************************************************//**
+ * The nature of the next token that we are iterating through.  Within an
+ * object, we alternate between collecting keys and values.  Within an array,
+ * we only collect items.
+ *****************************************************************************/
+typedef enum {
+  EVEL_JSON_KEY,
+  EVEL_JSON_VALUE,
+  EVEL_JSON_ITEM
+} EVEL_JSON_STATE;
+
+/**************************************************************************//**
+ * States which we move through during JSON processing, tracking our way
+ * through the supported JSON structure.
+ *****************************************************************************/
+typedef enum
+{
+  /***************************************************************************/
+  /* Initial state.                                                          */
+  /***************************************************************************/
+  EVEL_JCS_START,
+
+  /***************************************************************************/
+  /* {"commandList": [                                                       */
+  /***************************************************************************/
+  EVEL_JCS_COMMAND_LIST,
+
+  /***************************************************************************/
+  /* {"commandList": [{                                                      */
+  /***************************************************************************/
+  EVEL_JCS_COMMAND_LIST_ENTRY,
+
+  /***************************************************************************/
+  /* {"commandList": [{"command": {                                          */
+  /***************************************************************************/
+  EVEL_JCS_COMMAND,
+
+  /***************************************************************************/
+  /* ... "eventDomainThrottleSpecification": {                               */
+  /***************************************************************************/
+  EVEL_JCS_SPEC,
+
+  /***************************************************************************/
+  /* ... "suppressedFieldNames": [                                           */
+  /***************************************************************************/
+  EVEL_JCS_FIELD_NAMES,
+
+  /***************************************************************************/
+  /* ... "suppressedNvPairsList": [                                          */
+  /***************************************************************************/
+  EVEL_JCS_PAIRS_LIST,
+
+  /***************************************************************************/
+  /* ... "suppressedNvPairsList": [{                                         */
+  /***************************************************************************/
+  EVEL_JCS_PAIRS_LIST_ENTRY,
+
+  /***************************************************************************/
+  /* ... "suppressedNvPairNames": [                                          */
+  /***************************************************************************/
+  EVEL_JCS_NV_PAIR_NAMES,
+
+  EVEL_JCS_MAX
+} EVEL_JSON_COMMAND_STATE;
+
+/**************************************************************************//**
+ * An entry in the JSON stack.
+ *****************************************************************************/
+typedef struct evel_json_stack_entry {
+
+  /***************************************************************************/
+  /* The number of elements required at this level.                          */
+  /***************************************************************************/
+  int num_required;
+
+  /***************************************************************************/
+  /* The number of elements collected at this level.                         */
+  /***************************************************************************/
+  int json_count;
+
+  /***************************************************************************/
+  /* The collection state at this level in the JSON stack.                   */
+  /***************************************************************************/
+  EVEL_JSON_STATE json_state;
+
+  /***************************************************************************/
+  /* The key being collected (if json_state is EVEL_JSON_VALUE), or NULL.    */
+  /***************************************************************************/
+  char * json_key;
+
+} EVEL_JSON_STACK_ENTRY;
+
+/**************************************************************************//**
+ * The JSON stack.
+ *****************************************************************************/
+typedef struct evel_json_stack {
+
+  /***************************************************************************/
+  /* The current position of the stack - starting at zero.                   */
+  /***************************************************************************/
+  int level;
+
+  /***************************************************************************/
+  /* The stack itself.                                                       */
+  /***************************************************************************/
+  EVEL_JSON_STACK_ENTRY entry[EVEL_JSON_STACK_DEPTH];
+
+  /***************************************************************************/
+  /* The underlying memory chunk.                                            */
+  /***************************************************************************/
+  const MEMORY_CHUNK * chunk;
+
+} EVEL_JSON_STACK;
+
+/**************************************************************************//**
+ * Initialize event throttling to the default state.
+ *
+ * Called from ::evel_initialize.
+ *****************************************************************************/
+void evel_throttle_initialize();
+
+/**************************************************************************//**
+ * Clean up event throttling.
+ *
+ * Called from ::evel_terminate.
+ *****************************************************************************/
+void evel_throttle_terminate();
+
+/**************************************************************************//**
+ * Handle a JSON response from the listener, as a list of tokens from JSMN.
+ *
+ * @param chunk         Memory chunk containing the JSON buffer.
+ * @param json_tokens   Array of tokens to handle.
+ * @param num_tokens    The number of tokens to handle.
+ * @param post          The memory chunk in which to place any resulting POST.
+ * @return true if the command was handled, false otherwise.
+ *****************************************************************************/
+bool evel_handle_command_list(const MEMORY_CHUNK * const chunk,
+                              const jsmntok_t * const json_tokens,
+                              const int num_tokens,
+                              MEMORY_CHUNK * const post);
+
+/**************************************************************************//**
+ * Return the ::EVEL_THROTTLE_SPEC for a given domain.
+ *
+ * @param domain        The domain for which to return state.
+ *****************************************************************************/
+EVEL_THROTTLE_SPEC * evel_get_throttle_spec(EVEL_EVENT_DOMAINS domain);
+
+/**************************************************************************//**
+ * Determine whether a field_name should be suppressed.
+ *
+ * @param throttle_spec Throttle specification for the domain being encoded.
+ * @param field_name    The field name to encoded or suppress.
+ * @return true if the field_name should be suppressed, false otherwise.
+ *****************************************************************************/
+bool evel_throttle_suppress_field(EVEL_THROTTLE_SPEC * throttle_spec,
+                                  const char * const field_name);
+
+/**************************************************************************//**
+ * Determine whether a name-value pair should be allowed (not suppressed).
+ *
+ * @param throttle_spec Throttle specification for the domain being encoded.
+ * @param field_name    The field name holding the name-value pairs.
+ * @param name          The name of the name-value pair to encoded or suppress.
+ * @return true if the name-value pair should be suppressed, false otherwise.
+ *****************************************************************************/
+bool evel_throttle_suppress_nv_pair(EVEL_THROTTLE_SPEC * throttle_spec,
+                                    const char * const field_name,
+                                    const char * const name);
+
+#endif
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_voicequality.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_voicequality.c
new file mode 100644 (file)
index 0000000..cf2ec87
--- /dev/null
@@ -0,0 +1,640 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * Implementation of EVEL functions relating to the Voice Quality.
+ *****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "evel.h"
+#include "evel_internal.h"
+#include "evel_throttle.h"
+
+/**************************************************************************//**
+ * Create a new voice quality event.
+ *
+ * @note    The mandatory fields on the Voice Quality must be supplied to this 
+ *          factory function and are immutable once set.  Optional fields have 
+ *          explicit setter functions, but again values may only be set once 
+ *          so that the Voice Quality has immutable properties.
+ * @param event_name    Unique Event Name
+ * @param event_id    A universal identifier of the event for analysis etc.
+ * @param   calleeSideCodec         Callee codec for the call.
+ * @param   callerSideCodec         Caller codec for the call.
+ * @param   correlator              Constant across all events on this call.
+ * @param   midCallRtcp             Base64 encoding of the binary RTCP data
+ *                                  (excluding Eth/IP/UDP headers).
+ * @param   vendorVnfNameFields     Vendor, VNF and VfModule names.
+ * @returns pointer to the newly manufactured ::EVENT_VOICE_QUALITY.  If the 
+ *          event is not used (i.e. posted) it must be released using
+            ::evel_free_voice_quality.
+ * @retval  NULL  Failed to create the event.
+ *****************************************************************************/
+EVENT_VOICE_QUALITY * evel_new_voice_quality(const char* ev_name, const char *ev_id,
+                                       const char * const calleeSideCodec,
+    const char * const callerSideCodec, const char * const correlator,
+    const char * const midCallRtcp, const char * const vendorName) {
+    
+    bool inError = false;
+    EVENT_VOICE_QUALITY *voiceQuality = NULL;
+    EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check preconditions.                                                    */
+    /***************************************************************************/
+    assert(calleeSideCodec != NULL);
+    assert(callerSideCodec != NULL);
+    assert(correlator != NULL);
+    assert(midCallRtcp != NULL);
+    assert(vendorName != NULL);
+
+    /***************************************************************************/
+    /* Allocate the Voice Quality.                                                     */
+    /***************************************************************************/
+    voiceQuality = malloc(sizeof(EVENT_VOICE_QUALITY));
+    
+    if (voiceQuality == NULL)
+    {
+        log_error_state("Out of memory");
+        inError = true;
+    }
+
+    //Only in case of successful allocation initialize data.
+    if (inError == false) {
+        memset(voiceQuality, 0, sizeof(EVENT_VOICE_QUALITY));
+        EVEL_DEBUG("New Voice Quality is at %lp", voiceQuality);
+
+        /***************************************************************************/
+        /* Initialize the header & the fault fields.  Optional integer values are   */
+        /* initialized as 0.                                                        */
+        /***************************************************************************/
+        evel_init_header_nameid(&voiceQuality->header,ev_name,ev_id);
+        voiceQuality->header.event_domain = EVEL_DOMAIN_VOICE_QUALITY;
+        voiceQuality->major_version = EVEL_VOICEQ_MAJOR_VERSION;
+        voiceQuality->minor_version = EVEL_VOICEQ_MINOR_VERSION;
+
+        voiceQuality->calleeSideCodec = strdup(calleeSideCodec);
+        voiceQuality->callerSideCodec = strdup(callerSideCodec);
+        voiceQuality->correlator = strdup(correlator);
+        voiceQuality->midCallRtcp = strdup(midCallRtcp);
+        evel_init_vendor_field(&voiceQuality->vendorVnfNameFields, vendorName);
+        dlist_initialize(&voiceQuality->additionalInformation);
+        voiceQuality->endOfCallVqmSummaries = NULL;
+        evel_init_option_string(&voiceQuality->phoneNumber);
+    }
+
+    EVEL_EXIT();
+    return voiceQuality;
+
+}
+
+/**************************************************************************//**
+ * Add an additional value name/value pair to the Voice Quality.
+ *
+ * The name and value are null delimited ASCII strings.  The library takes
+ * a copy so the caller does not have to preserve values after the function
+ * returns.
+ *
+ * @param fault     Pointer to the fault.
+ * @param name      ASCIIZ string with the attribute's name.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ * @param value     ASCIIZ string with the attribute's value.  The caller
+ *                  does not need to preserve the value once the function
+ *                  returns.
+ *****************************************************************************/
+void evel_voice_quality_addl_info_add(EVENT_VOICE_QUALITY * voiceQ, char * name, char * value) {
+    VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
+    EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check preconditions.                                                    */
+    /***************************************************************************/
+    assert(voiceQ != NULL);
+    assert(voiceQ->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
+    assert(name != NULL);
+    assert(value != NULL);
+
+    EVEL_DEBUG("Adding name=%s value=%s", name, value);
+    addlInfo = malloc(sizeof(VOICE_QUALITY_ADDL_INFO));
+    assert(addlInfo != NULL);
+    memset(addlInfo, 0, sizeof(VOICE_QUALITY_ADDL_INFO));
+    addlInfo->name = strdup(name);
+    addlInfo->value = strdup(value);
+    assert(addlInfo->name != NULL);
+    assert(addlInfo->value != NULL);
+
+    dlist_push_last(&voiceQ->additionalInformation, addlInfo);
+
+    EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Callee side codec for Call for domain Voice Quality
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param voiceQuality              Pointer to the Voice Quality Event.
+ * @param calleeCodecForCall        The Callee Side Codec to be set.  ASCIIZ 
+ *                                  string. The caller does not need to 
+ *                                  preserve the value once the function
+ *                                  returns.
+ *****************************************************************************/
+void evel_voice_quality_callee_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
+    const char * const calleeCodecForCall) {
+    EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check preconditions.                                                    */
+    /***************************************************************************/
+    assert(voiceQuality != NULL);
+    assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
+    assert(calleeCodecForCall != NULL);
+
+    voiceQuality->calleeSideCodec = strdup(calleeCodecForCall);
+
+    EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Caller side codec for Call for domain Voice Quality
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param voiceQuality              Pointer to the Voice Quality Event.
+ * @param callerCodecForCall        The Caller Side Codec to be set.  ASCIIZ 
+ *                                  string. The caller does not need to 
+ *                                  preserve the value once the function
+ *                                  returns.
+ *****************************************************************************/
+void evel_voice_quality_caller_codec_set(EVENT_VOICE_QUALITY * voiceQuality,
+    const char * const callerCodecForCall) {
+    EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check preconditions.                                                    */
+    /***************************************************************************/
+    assert(voiceQuality != NULL);
+    assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
+    assert(callerCodecForCall != NULL);
+
+    voiceQuality->calleeSideCodec = strdup(callerCodecForCall);
+
+    EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the correlator for domain Voice Quality
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param voiceQuality              Pointer to the Voice Quality Event.
+ * @param correlator                The correlator value to be set.  ASCIIZ 
+ *                                  string. The caller does not need to 
+ *                                  preserve the value once the function
+ *                                  returns.
+ *****************************************************************************/
+void evel_voice_quality_correlator_set(EVENT_VOICE_QUALITY * voiceQuality,
+    const char * const vCorrelator) {
+    EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check preconditions.                                                    */
+    /***************************************************************************/
+    assert(voiceQuality != NULL);
+    assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
+    assert(vCorrelator != NULL);
+
+    voiceQuality->correlator = strdup(vCorrelator);
+
+    EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the RTCP Call Data for domain Voice Quality
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param voiceQuality              Pointer to the Voice Quality Event.
+ * @param rtcpCallData              The RTCP Call Data to be set.  ASCIIZ 
+ *                                  string. The caller does not need to 
+ *                                  preserve the value once the function
+ *                                  returns.
+ *****************************************************************************/
+void evel_voice_quality_rtcp_data_set(EVENT_VOICE_QUALITY * voiceQuality,
+    const char * const rtcpCallData) {
+    EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check preconditions.                                                    */
+    /***************************************************************************/
+    assert(voiceQuality != NULL);
+    assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
+    assert(rtcpCallData != NULL);
+
+    voiceQuality->midCallRtcp = strdup(rtcpCallData);
+
+    EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Vendor VNF Name fields for domain Voice Quality
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param voiceQuality              Pointer to the Voice Quality Event.
+ * @param modulename                The Vendor, VNF and VfModule names to be set.   
+ *                                  ASCIIZ string. The caller does not need to 
+ *                                  preserve the value once the function
+ *                                  returns.
+ *****************************************************************************/
+void evel_voice_quality_vnfmodule_name_set(EVENT_VOICE_QUALITY * voiceQuality,
+    const char * const module_name) {
+    EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check preconditions.                                                    */
+    /***************************************************************************/
+    assert(voiceQuality != NULL);
+    assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
+    assert(module_name != NULL);
+
+    evel_vendor_field_module_set(&voiceQuality->vendorVnfNameFields, module_name);
+
+    EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Vendor VNF Name fields for domain Voice Quality
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param voiceQuality              Pointer to the Voice Quality Event.
+ * @param modulename                The Vendor, VNF and VfModule names to be set.   
+ *                                  ASCIIZ string. The caller does not need to 
+ *                                  preserve the value once the function
+ *                                  returns.
+ *****************************************************************************/
+void evel_voice_quality_vnfname_set(EVENT_VOICE_QUALITY * voiceQuality,
+    const char * const vnfname) {
+    EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check preconditions.                                                    */
+    /***************************************************************************/
+    assert(voiceQuality != NULL);
+    assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
+    assert(vnfname != NULL);
+
+    evel_vendor_field_vnfname_set(&voiceQuality->vendorVnfNameFields, vnfname);
+
+    EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Set the Phone Number associated with the Correlator for domain Voice Quality
+ *
+ * @note  The property is treated as immutable: it is only valid to call
+ *        the setter once.  However, we don't assert if the caller tries to
+ *        overwrite, just ignoring the update instead.
+ *
+ * @param voiceQuality              Pointer to the Voice Quality Event.
+ * @param calleeCodecForCall        The Phone Number to be set.  ASCIIZ 
+ *                                  string. The caller does not need to 
+ *                                  preserve the value once the function
+ *                                  returns.
+ *****************************************************************************/
+void evel_voice_quality_phone_number_set(EVENT_VOICE_QUALITY * voiceQuality,
+    const char * const phoneNumber) {
+    EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check preconditions.                                                    */
+    /***************************************************************************/
+    assert(voiceQuality != NULL);
+    assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
+    assert(phoneNumber != NULL);
+
+    evel_set_option_string(&voiceQuality->phoneNumber, phoneNumber, "Phone_Number");
+
+    EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add an End of Call Voice Quality Metrices
+
+ * The adjacencyName and endpointDescription is null delimited ASCII string.  
+ * The library takes a copy so the caller does not have to preserve values
+ * after the function returns.
+ *
+ * @param voiceQuality     Pointer to the measurement.
+ * @param adjacencyName                     Adjacency name
+ * @param endpointDescription               Enumeration: ‘Caller’, ‘Callee’.
+ * @param endpointJitter                    Endpoint jitter
+ * @param endpointRtpOctetsDiscarded        Endpoint RTP octets discarded.
+ * @param endpointRtpOctetsReceived         Endpoint RTP octets received.
+ * @param endpointRtpOctetsSent             Endpoint RTP octets sent
+ * @param endpointRtpPacketsDiscarded       Endpoint RTP packets discarded.
+ * @param endpointRtpPacketsReceived        Endpoint RTP packets received.
+ * @param endpointRtpPacketsSent            Endpoint RTP packets sent.
+ * @param localJitter                       Local jitter.
+ * @param localRtpOctetsDiscarded           Local RTP octets discarded.
+ * @param localRtpOctetsReceived            Local RTP octets received.
+ * @param localRtpOctetsSent                Local RTP octets sent.
+ * @param localRtpPacketsDiscarded          Local RTP packets discarded.
+ * @param localRtpPacketsReceived           Local RTP packets received.
+ * @param localRtpPacketsSent               Local RTP packets sent.
+ * @param mosCqe                            Decimal range from 1 to 5
+ *                                          (1 decimal place)
+ * @param packetsLost                       No  Packets lost
+ * @param packetLossPercent                 Calculated percentage packet loss 
+ * @param rFactor                           rFactor from 0 to 100
+ * @param roundTripDelay                    Round trip delay in milliseconds
+ *****************************************************************************/
+void evel_voice_quality_end_metrics_add(EVENT_VOICE_QUALITY * voiceQuality,
+    const char * adjacencyName, EVEL_SERVICE_ENDPOINT_DESC endpointDescription,
+    int endpointJitter,
+    int endpointRtpOctetsDiscarded,
+    int endpointRtpOctetsReceived,
+    int endpointRtpOctetsSent,
+    int endpointRtpPacketsDiscarded,
+    int endpointRtpPacketsReceived,
+    int endpointRtpPacketsSent,
+    int localJitter,
+    int localRtpOctetsDiscarded,
+    int localRtpOctetsReceived,
+    int localRtpOctetsSent,
+    int localRtpPacketsDiscarded,
+    int localRtpPacketsReceived,
+    int localRtpPacketsSent,
+    int mosCqe,
+    int packetsLost,
+    int packetLossPercent,
+    int rFactor,
+    int roundTripDelay) {
+    
+    END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL;
+    EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check assumptions.                                                      */
+    /***************************************************************************/
+    assert(voiceQuality != NULL);
+    assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
+    assert(adjacencyName != NULL);
+    assert(endpointDescription >= 0);
+    assert(mosCqe >= 1 && mosCqe <= 5);
+    assert(rFactor >= 0 && rFactor <= 100);
+    assert(voiceQuality->endOfCallVqmSummaries == NULL);
+    
+    /***************************************************************************/
+    /* Allocate a container for the value and push onto the list.              */
+    /***************************************************************************/
+    EVEL_DEBUG("Adding adjacencyName=%s endpointDescription=%d", adjacencyName, endpointDescription);
+    vQMetrices = malloc(sizeof(END_OF_CALL_VOICE_QUALITY_METRICS));
+    assert(vQMetrices != NULL);
+    memset(vQMetrices, 0, sizeof(END_OF_CALL_VOICE_QUALITY_METRICS));
+
+    vQMetrices->adjacencyName = strdup(adjacencyName);
+    vQMetrices->endpointDescription = evel_service_endpoint_desc(endpointDescription);
+
+    evel_set_option_int(&vQMetrices->endpointJitter, endpointJitter, "Endpoint jitter");
+    evel_set_option_int(&vQMetrices->endpointRtpOctetsDiscarded, endpointRtpOctetsDiscarded, "Endpoint RTP octets discarded");
+    evel_set_option_int(&vQMetrices->endpointRtpOctetsReceived, endpointRtpOctetsReceived, "Endpoint RTP octets received");
+    evel_set_option_int(&vQMetrices->endpointRtpOctetsSent, endpointRtpOctetsSent, "Endpoint RTP octets sent");
+    evel_set_option_int(&vQMetrices->endpointRtpPacketsDiscarded, endpointRtpPacketsDiscarded, "Endpoint RTP packets discarded");
+    evel_set_option_int(&vQMetrices->endpointRtpPacketsReceived, endpointRtpPacketsReceived, "Endpoint RTP packets received");
+    evel_set_option_int(&vQMetrices->endpointRtpPacketsSent, endpointRtpPacketsSent, "Endpoint RTP packets sent");
+    evel_set_option_int(&vQMetrices->localJitter, localJitter, "Local jitter");
+    evel_set_option_int(&vQMetrices->localRtpOctetsDiscarded, localRtpOctetsDiscarded, "Local RTP octets discarded");
+    evel_set_option_int(&vQMetrices->localRtpOctetsReceived, localRtpOctetsReceived, "Local RTP octets received");
+    evel_set_option_int(&vQMetrices->localRtpOctetsSent, localRtpOctetsSent, "Local RTP octets sent");
+    evel_set_option_int(&vQMetrices->localRtpPacketsDiscarded, localRtpPacketsDiscarded, "Local RTP packets discarded");
+    evel_set_option_int(&vQMetrices->localRtpPacketsReceived, localRtpPacketsReceived, "Local RTP packets received");
+    evel_set_option_int(&vQMetrices->localRtpPacketsSent, localRtpPacketsSent, "Local RTP packets sent");
+    evel_set_option_int(&vQMetrices->mosCqe, mosCqe, "Decimal range from 1 to 5 (1 decimal place)");
+    evel_set_option_int(&vQMetrices->packetsLost, packetsLost, "Packets lost");
+    evel_set_option_int(&vQMetrices->packetLossPercent, packetLossPercent, "Calculated percentage packet loss");
+    evel_set_option_int(&vQMetrices->rFactor, rFactor, "rFactor ");
+    evel_set_option_int(&vQMetrices->roundTripDelay, roundTripDelay, "Round trip delay in milliseconds ");
+
+    voiceQuality->endOfCallVqmSummaries = vQMetrices;
+
+    EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode the Voce Quality in JSON according to AT&T's schema for the voice
+ * quality type.
+ *
+ * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
+ * @param event         Pointer to the ::EVENT_HEADER to encode.
+ *****************************************************************************/
+void evel_json_encode_voice_quality(EVEL_JSON_BUFFER * jbuf,
+                            EVENT_VOICE_QUALITY * event)
+{
+  VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
+  DLIST_ITEM * addlInfoItem = NULL;
+
+  END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrics = NULL;
+  DLIST_ITEM * vQMetricsItem = NULL;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(event != NULL);
+  assert(event->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
+
+  evel_json_encode_header(jbuf, &event->header);
+  evel_json_open_named_object(jbuf, "voiceQualityFields");
+
+  /***************************************************************************/
+  /* Mandatory fields.                                                       */
+  /***************************************************************************/
+  evel_enc_kv_string(jbuf, "calleeSideCodec", event->calleeSideCodec);
+  evel_enc_kv_string(jbuf, "callerSideCodec", event->callerSideCodec);
+  evel_enc_kv_string(jbuf, "correlator", event->correlator);
+  evel_enc_kv_string(jbuf, "midCallRtcp", event->midCallRtcp);
+  evel_json_encode_vendor_field(jbuf, &event->vendorVnfNameFields);
+  evel_enc_version(
+    jbuf, "voiceQualityFieldsVersion", event->major_version, event->minor_version);
+
+  /***************************************************************************/
+  /* Optional fields.                                                        */
+  /***************************************************************************/
+  evel_enc_kv_opt_string(jbuf, "phoneNumber", &event->phoneNumber);
+  /***************************************************************************/
+  /* Checkpoint, so that we can wind back if all fields are suppressed.      */
+  /***************************************************************************/
+  //additionalInformation for Voice Quality
+  bool item_added = false;
+  evel_json_checkpoint(jbuf);
+  if (evel_json_open_opt_named_list(jbuf, "additionalInformation"))
+  {
+
+    addlInfoItem = dlist_get_first(&event->additionalInformation);
+    while (addlInfoItem != NULL)
+    {
+      addlInfo = (VOICE_QUALITY_ADDL_INFO*)addlInfoItem->item;
+      assert(addlInfo != NULL);
+
+      if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                                          "additionalInformation",
+                                          addlInfo->name))
+      {
+        evel_json_open_object(jbuf);
+        evel_enc_kv_string(jbuf, "name", addlInfo->name);
+        evel_enc_kv_string(jbuf, "value", addlInfo->value);
+        evel_json_close_object(jbuf);
+        item_added = true;
+      }
+      addlInfoItem = dlist_get_next(addlInfoItem);
+    }
+    evel_json_close_list(jbuf);
+    /*************************************************************************/
+    /* If we've not written anything, rewind to before we opened the list.   */
+    /*************************************************************************/
+    if (!item_added)
+    {
+      evel_json_rewind(jbuf);
+    }
+  }
+
+    //endOfCallVqmSummaries
+  if( event->endOfCallVqmSummaries != NULL )
+  {
+     evel_json_open_named_object(jbuf, "endOfCallVqmSummaries");
+     vQMetrics = event->endOfCallVqmSummaries;
+     assert(vQMetrics != NULL);
+
+            if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
+                "endOfCallVqmSummaries", vQMetrics->adjacencyName))
+            {
+                evel_enc_kv_string(jbuf, "adjacencyName", vQMetrics->adjacencyName);
+                evel_enc_kv_string(jbuf, "endpointDescription", vQMetrics->endpointDescription);
+                evel_enc_kv_opt_int(jbuf, "endpointJitter", &vQMetrics->endpointJitter);
+                evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsDiscarded", &vQMetrics->endpointRtpOctetsDiscarded);
+                evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsReceived", &vQMetrics->endpointRtpOctetsReceived);
+                evel_enc_kv_opt_int(jbuf, "endpointRtpOctetsSent", &vQMetrics->endpointRtpOctetsSent);
+                evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsDiscarded", &vQMetrics->endpointRtpPacketsDiscarded);
+                evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsReceived", &vQMetrics->endpointRtpPacketsReceived);
+                evel_enc_kv_opt_int(jbuf, "endpointRtpPacketsSent", &vQMetrics->endpointRtpPacketsSent);
+                evel_enc_kv_opt_int(jbuf, "localJitter", &vQMetrics->localJitter);
+                evel_enc_kv_opt_int(jbuf, "localRtpOctetsDiscarded", &vQMetrics->localRtpOctetsDiscarded);
+                evel_enc_kv_opt_int(jbuf, "localRtpOctetsReceived", &vQMetrics->localRtpOctetsReceived);
+                evel_enc_kv_opt_int(jbuf, "localRtpOctetsSent", &vQMetrics->localRtpOctetsSent);
+                evel_enc_kv_opt_int(jbuf, "localRtpPacketsDiscarded", &vQMetrics->localRtpPacketsDiscarded);
+                evel_enc_kv_opt_int(jbuf, "localRtpPacketsReceived", &vQMetrics->localRtpPacketsReceived);
+                evel_enc_kv_opt_int(jbuf, "localRtpPacketsSent", &vQMetrics->localRtpPacketsSent);
+                evel_enc_kv_opt_int(jbuf, "mosCqe", &vQMetrics->mosCqe);
+                evel_enc_kv_opt_int(jbuf, "packetsLost", &vQMetrics->packetsLost);
+                evel_enc_kv_opt_int(jbuf, "packetLossPercent", &vQMetrics->packetLossPercent);
+                evel_enc_kv_opt_int(jbuf, "rFactor", &vQMetrics->rFactor);
+                evel_enc_kv_opt_int(jbuf, "roundTripDelay", &vQMetrics->roundTripDelay);
+
+            }
+
+    evel_json_close_object(jbuf);
+  }
+
+  evel_json_close_object(jbuf);
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Free a Voice Quality.
+ *
+ * Free off the Voce Quality supplied.  Will free all the contained allocated
+ * memory.
+ *
+ * @note It does not free the Voice Quality itself, since that may be part of a
+ * larger structure.
+ *****************************************************************************/
+void evel_free_voice_quality(EVENT_VOICE_QUALITY * voiceQuality) {
+    END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrices = NULL;
+    VOICE_QUALITY_ADDL_INFO * addlInfo = NULL;
+
+    EVEL_ENTER();
+
+    /***************************************************************************/
+    /* Check preconditions.  As an internal API we don't allow freeing NULL    */
+    /* events as we do on the public API.                                      */
+    /***************************************************************************/
+    assert(voiceQuality != NULL);
+    assert(voiceQuality->header.event_domain == EVEL_DOMAIN_VOICE_QUALITY);
+
+    /***************************************************************************/
+    /* Free all internal strings then the header itself.                       */
+    /***************************************************************************/
+    
+    //Additional Information
+    addlInfo = dlist_pop_last(&voiceQuality->additionalInformation);
+    while (addlInfo != NULL)
+    {
+        EVEL_DEBUG("Freeing Additional Info (%s, %s)",
+            addlInfo->name,
+            addlInfo->value);
+        free(addlInfo->name);
+        free(addlInfo->value);
+        free(addlInfo);
+        addlInfo = dlist_pop_last(&voiceQuality->additionalInformation);
+    }
+
+    //Summary Information
+    if(voiceQuality->endOfCallVqmSummaries != NULL)
+    {
+        vQMetrices = voiceQuality->endOfCallVqmSummaries;
+        EVEL_DEBUG("Freeing End of Call Voice Measurements Info (%s, %s)",
+            vQMetrices->adjacencyName,
+            vQMetrices->endpointDescription);
+        free(vQMetrices->adjacencyName);
+        free(vQMetrices);
+    }
+
+    //Members
+    free(voiceQuality->calleeSideCodec);
+    free(voiceQuality->callerSideCodec);
+    free(voiceQuality->correlator);
+    free(voiceQuality->midCallRtcp);
+    evel_free_option_string(&voiceQuality->phoneNumber);
+    evel_free_event_vendor_field(&voiceQuality->vendorVnfNameFields);
+
+    //header
+    evel_free_header(&voiceQuality->header);
+
+    EVEL_EXIT();
+}
+
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/hashtable.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/hashtable.c
new file mode 100644 (file)
index 0000000..0e2f764
--- /dev/null
@@ -0,0 +1,222 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * A simple Hashtable.
+ *
+ * @note  No thread protection so you will need to use appropriate
+ * synchronization if use spans multiple threads.
+ *
+ ****************************************************************************/
+
+#include <limits.h>
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "hashtable.h"
+
+/**************************************************************************//**
+ * Hashtable initialization.
+ *
+ * Initialize the list supplied to be empty.
+ *
+ * @param   size  Size of hashtable
+
+ * @returns Hashtable pointer
+******************************************************************************/
+/* Create a new hashtable. */
+HASHTABLE_T *ht_create( size_t size ) {
+
+       HASHTABLE_T *hashtable = NULL;
+       size_t i;
+
+       if( size < 1 ) return NULL;
+
+       /* Allocate the table itself. */
+       if( ( hashtable = malloc( sizeof( HASHTABLE_T ) ) ) == NULL ) {
+               return NULL;
+       }
+
+       /* Allocate pointers to the head nodes. */
+       if( ( hashtable->table = malloc( sizeof( ENTRY_T * ) * size ) ) == NULL ) {
+               return NULL;
+       }
+       for( i = 0; i < size; i++ ) {
+               hashtable->table[i] = NULL;
+       }
+
+       hashtable->size = size;
+
+       return hashtable;       
+}
+
+/**************************************************************************//**
+ * Hash a string for a particular hash table. 
+ *
+ * Initialize the list supplied to be empty.
+ *
+ * @param   hashtable    Pointer to the hashtable
+ * @param   key          String
+
+ * @returns hashvalue
+******************************************************************************/
+size_t ht_hash( HASHTABLE_T *hashtable, char *key )
+{
+
+    size_t hash, i;
+
+#ifdef HASHTABLE_USE_SIMPLE_HASH
+    for ( hash = i = 0; i < strlen(key); hash = hash << 8, hash += key[ i++ ] );
+#else /* Use: Jenkins' "One At a Time Hash" === Perl "Like" Hashing */
+    // http://en.wikipedia.org/wiki/Jenkins_hash_function
+    for ( hash = i = 0; i < strlen(key); ++i ) {
+        hash += key[i], hash += ( hash << 10 ), hash ^= ( hash >> 6 );
+    }
+    hash += ( hash << 3 ), hash ^= ( hash >> 11 ), hash += ( hash << 15 );
+#endif
+
+    return hash % hashtable->size;
+
+}
+
+/**************************************************************************//**
+ * Create a key-value pair.
+ *
+ * @param   key     key string
+ * @param   value   value string
+ *
+ * @returns hashtable entry
+******************************************************************************/
+ENTRY_T *ht_newpair( char *key, void *value )
+{
+       ENTRY_T *newpair;
+
+       if( ( newpair = malloc( sizeof( ENTRY_T ) ) ) == NULL ) {
+               return NULL;
+       }
+
+       if( ( newpair->key = strdup( key ) ) == NULL ) {
+               return NULL;
+       }
+
+       if( ( newpair->value =  value ) == NULL ) {
+               return NULL;
+       }
+
+       newpair->next = NULL;
+
+       return newpair;
+}
+
+/**************************************************************************//**
+ * Insert a key-value pair into a hash table.
+ *
+ * @param   key     key string
+ * @param   value   value string
+ *
+ * @returns Nothing
+******************************************************************************/
+void ht_set( HASHTABLE_T *hashtable, char *key, void *value ) {
+       size_t bin = 0;
+       ENTRY_T *newpair = NULL;
+       ENTRY_T *next = NULL;
+       ENTRY_T *last = NULL;
+
+       bin = ht_hash( hashtable, key );
+
+       next = hashtable->table[ bin ];
+
+       while( next != NULL && next->key != NULL && strcmp( key, next->key ) > 0 ) {
+               last = next;
+               next = next->next;
+       }
+
+       /* There's already a pair.  Let's replace that string. */
+       if( next != NULL && next->key != NULL && strcmp( key, next->key ) == 0 ) {
+
+               free( next->value );
+               next->value = value ;
+
+       /* Nope, could't find it.  Time to grow a pair. */
+       } else {
+               newpair = ht_newpair( key, value );
+
+               /* We're at the start of the linked list in this bin. */
+               if( next == hashtable->table[ bin ] ) {
+                       newpair->next = next;
+                       hashtable->table[ bin ] = newpair;
+       
+               /* We're at the end of the linked list in this bin. */
+               } else if ( next == NULL ) {
+                       last->next = newpair;
+       
+               /* We're in the middle of the list. */
+               } else  {
+                       newpair->next = next;
+                       last->next = newpair;
+               }
+       }
+}
+
+/**************************************************************************//**
+ *  Retrieve a key-value pair from a hash table.
+ *
+ * @param   key     key string
+ *
+ * @returns  value string
+******************************************************************************/
+void *ht_get( HASHTABLE_T *hashtable, char *key ) {
+       size_t bin = 0;
+       ENTRY_T *pair;
+
+       bin = ht_hash( hashtable, key );
+
+       /* Step through the bin, looking for our value. */
+       pair = hashtable->table[ bin ];
+       while( pair != NULL && pair->key != NULL && strcmp( key, pair->key ) > 0 ) {
+               pair = pair->next;
+       }
+
+       /* Did we actually find anything? */
+       if( pair == NULL || pair->key == NULL || strcmp( key, pair->key ) != 0 ) {
+               return NULL;
+
+       } else {
+               return pair->value;
+       }
+       
+}
+
+/*
+int main( int argc, char **argv ) {
+
+       HASHTABLE_T *hashtable = ht_create( 65536 );
+
+       ht_set( hashtable, "key1", "inky" );
+       ht_set( hashtable, "key2", "pinky" );
+       ht_set( hashtable, "key3", "blinky" );
+       ht_set( hashtable, "key4", "floyd" );
+
+       printf( "%s\n", ht_get( hashtable, "key1" ) );
+       printf( "%s\n", ht_get( hashtable, "key2" ) );
+       printf( "%s\n", ht_get( hashtable, "key3" ) );
+       printf( "%s\n", ht_get( hashtable, "key4" ) );
+
+       return 0;
+}
+*/
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/hashtable.h b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/hashtable.h
new file mode 100644 (file)
index 0000000..8be17dc
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef HASHTABLE_INCLUDED
+#define HASHTABLE_INCLUDED
+
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * A simple hashtable.
+ *
+ * @note  No thread protection so you will need to use appropriate
+ * synchronization if use spans multiple threads.
+*****************************************************************************/
+
+typedef struct entry_s {
+       char *key;
+       void *value;
+       struct entry_s *next;
+} ENTRY_T;
+
+/**************************************************************************//**
+ * Hashtable structure
+ *****************************************************************************/
+
+typedef struct hashtable_s {
+       size_t size;
+       struct entry_s **table; 
+} HASHTABLE_T;
+
+/**************************************************************************//**
+ * Hashtable initialization.
+ *
+ * Initialize the list supplied to be empty.
+ *
+ * @param   size  Size of hashtable
+
+ * @returns Hashtable pointer
+******************************************************************************/
+/* Create a new hashtable. */
+HASHTABLE_T *ht_create( size_t size );
+
+/**************************************************************************//**
+ * Hash a string for a particular hash table.
+ *
+ * Initialize the list supplied to be empty.
+ *
+ * @param   hashtable    Pointer to the hashtable
+ * @param   key          String
+
+ * @returns hashvalue
+******************************************************************************/
+size_t ht_hash( HASHTABLE_T *hashtable, char *key );
+
+/**************************************************************************//**
+ * Create a key-value pair.
+ *
+ * @param   key     key string
+ * @param   value   value string
+ *
+ * @returns hashtable entry
+******************************************************************************/
+ENTRY_T *ht_newpair( char *key, void *value );
+
+/**************************************************************************//**
+ * Insert a key-value pair into a hash table.
+ *
+ * @param   key     key string
+ * @param   value   value string
+ *
+ * @returns Nothing
+******************************************************************************/
+void ht_set( HASHTABLE_T *hashtable, char *key, void *value );
+
+/**************************************************************************//**
+ *  Retrieve a key-value pair from a hash table.
+ *
+ * @param   key     key string
+ *
+ * @returns  value string
+******************************************************************************/
+void *ht_get( HASHTABLE_T *hashtable, char *key );
+
+#endif
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/jsmn.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/jsmn.c
new file mode 100644 (file)
index 0000000..f374a57
--- /dev/null
@@ -0,0 +1,328 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#include "jsmn.h"
+
+/**
+ * Allocates a fresh unused token from the token pull.
+ */
+static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
+               jsmntok_t *tokens, size_t num_tokens) {
+       jsmntok_t *tok;
+       if (parser->toknext >= num_tokens) {
+               return NULL;
+       }
+       tok = &tokens[parser->toknext++];
+       tok->start = tok->end = -1;
+       tok->size = 0;
+#ifdef JSMN_PARENT_LINKS
+       tok->parent = -1;
+#endif
+       return tok;
+}
+
+/**
+ * Fills token type and boundaries.
+ */
+static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
+                            int start, int end) {
+       token->type = type;
+       token->start = start;
+       token->end = end;
+       token->size = 0;
+}
+
+/**
+ * Fills next available token with JSON primitive.
+ */
+static int jsmn_parse_primitive(jsmn_parser *parser, const char *js,
+               size_t len, jsmntok_t *tokens, size_t num_tokens) {
+       jsmntok_t *token;
+       int start;
+
+       start = parser->pos;
+
+       for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
+               switch (js[parser->pos]) {
+#ifndef JSMN_STRICT
+                       /* In strict mode primitive must be followed by "," or "}" or "]" */
+                       case ':':
+#endif
+                       case '\t' : case '\r' : case '\n' : case ' ' :
+                       case ','  : case ']'  : case '}' :
+                               goto found;
+               }
+               if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
+                       parser->pos = start;
+                       return JSMN_ERROR_INVAL;
+               }
+       }
+#ifdef JSMN_STRICT
+       /* In strict mode primitive must be followed by a comma/object/array */
+       parser->pos = start;
+       return JSMN_ERROR_PART;
+#endif
+
+found:
+       if (tokens == NULL) {
+               parser->pos--;
+               return 0;
+       }
+       token = jsmn_alloc_token(parser, tokens, num_tokens);
+       if (token == NULL) {
+               parser->pos = start;
+               return JSMN_ERROR_NOMEM;
+       }
+       jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
+#ifdef JSMN_PARENT_LINKS
+       token->parent = parser->toksuper;
+#endif
+       parser->pos--;
+       return 0;
+}
+
+/**
+ * Fills next token with JSON string.
+ */
+static int jsmn_parse_string(jsmn_parser *parser, const char *js,
+               size_t len, jsmntok_t *tokens, size_t num_tokens) {
+       jsmntok_t *token;
+
+       int start = parser->pos;
+
+       parser->pos++;
+
+       /* Skip starting quote */
+       for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
+               char c = js[parser->pos];
+
+               /* Quote: end of string */
+               if (c == '\"') {
+                       if (tokens == NULL) {
+                               return 0;
+                       }
+                       token = jsmn_alloc_token(parser, tokens, num_tokens);
+                       if (token == NULL) {
+                               parser->pos = start;
+                               return JSMN_ERROR_NOMEM;
+                       }
+                       jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
+#ifdef JSMN_PARENT_LINKS
+                       token->parent = parser->toksuper;
+#endif
+                       return 0;
+               }
+
+               /* Backslash: Quoted symbol expected */
+               if (c == '\\' && parser->pos + 1 < len) {
+                       int i;
+                       parser->pos++;
+                       switch (js[parser->pos]) {
+                               /* Allowed escaped symbols */
+                               case '\"': case '/' : case '\\' : case 'b' :
+                               case 'f' : case 'r' : case 'n'  : case 't' :
+                                       break;
+                               /* Allows escaped symbol \uXXXX */
+                               case 'u':
+                                       parser->pos++;
+                                       for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) {
+                                               /* If it isn't a hex character we have an error */
+                                               if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
+                                                                       (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
+                                                                       (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
+                                                       parser->pos = start;
+                                                       return JSMN_ERROR_INVAL;
+                                               }
+                                               parser->pos++;
+                                       }
+                                       parser->pos--;
+                                       break;
+                               /* Unexpected symbol */
+                               default:
+                                       parser->pos = start;
+                                       return JSMN_ERROR_INVAL;
+                       }
+               }
+       }
+       parser->pos = start;
+       return JSMN_ERROR_PART;
+}
+
+/**
+ * Parse JSON string and fill tokens.
+ */
+int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
+               jsmntok_t *tokens, unsigned int num_tokens) {
+       int r;
+       int i;
+       jsmntok_t *token;
+       int count = parser->toknext;
+
+       for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
+               char c;
+               jsmntype_t type;
+
+               c = js[parser->pos];
+               switch (c) {
+                       case '{': case '[':
+                               count++;
+                               if (tokens == NULL) {
+                                       break;
+                               }
+                               token = jsmn_alloc_token(parser, tokens, num_tokens);
+                               if (token == NULL)
+                                       return JSMN_ERROR_NOMEM;
+                               if (parser->toksuper != -1) {
+                                       tokens[parser->toksuper].size++;
+#ifdef JSMN_PARENT_LINKS
+                                       token->parent = parser->toksuper;
+#endif
+                               }
+                               token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
+                               token->start = parser->pos;
+                               parser->toksuper = parser->toknext - 1;
+                               break;
+                       case '}': case ']':
+                               if (tokens == NULL)
+                                       break;
+                               type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
+#ifdef JSMN_PARENT_LINKS
+                               if (parser->toknext < 1) {
+                                       return JSMN_ERROR_INVAL;
+                               }
+                               token = &tokens[parser->toknext - 1];
+                               for (;;) {
+                                       if (token->start != -1 && token->end == -1) {
+                                               if (token->type != type) {
+                                                       return JSMN_ERROR_INVAL;
+                                               }
+                                               token->end = parser->pos + 1;
+                                               parser->toksuper = token->parent;
+                                               break;
+                                       }
+                                       if (token->parent == -1) {
+                                               break;
+                                       }
+                                       token = &tokens[token->parent];
+                               }
+#else
+                               for (i = parser->toknext - 1; i >= 0; i--) {
+                                       token = &tokens[i];
+                                       if (token->start != -1 && token->end == -1) {
+                                               if (token->type != type) {
+                                                       return JSMN_ERROR_INVAL;
+                                               }
+                                               parser->toksuper = -1;
+                                               token->end = parser->pos + 1;
+                                               break;
+                                       }
+                               }
+                               /* Error if unmatched closing bracket */
+                               if (i == -1) return JSMN_ERROR_INVAL;
+                               for (; i >= 0; i--) {
+                                       token = &tokens[i];
+                                       if (token->start != -1 && token->end == -1) {
+                                               parser->toksuper = i;
+                                               break;
+                                       }
+                               }
+#endif
+                               break;
+                       case '\"':
+                               r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
+                               if (r < 0) return r;
+                               count++;
+                               if (parser->toksuper != -1 && tokens != NULL)
+                                       tokens[parser->toksuper].size++;
+                               break;
+                       case '\t' : case '\r' : case '\n' : case ' ':
+                               break;
+                       case ':':
+                               parser->toksuper = parser->toknext - 1;
+                               break;
+                       case ',':
+                               if (tokens != NULL && parser->toksuper != -1 &&
+                                               tokens[parser->toksuper].type != JSMN_ARRAY &&
+                                               tokens[parser->toksuper].type != JSMN_OBJECT) {
+#ifdef JSMN_PARENT_LINKS
+                                       parser->toksuper = tokens[parser->toksuper].parent;
+#else
+                                       for (i = parser->toknext - 1; i >= 0; i--) {
+                                               if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
+                                                       if (tokens[i].start != -1 && tokens[i].end == -1) {
+                                                               parser->toksuper = i;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+#endif
+                               }
+                               break;
+#ifdef JSMN_STRICT
+                       /* In strict mode primitives are: numbers and booleans */
+                       case '-': case '0': case '1' : case '2': case '3' : case '4':
+                       case '5': case '6': case '7' : case '8': case '9':
+                       case 't': case 'f': case 'n' :
+                               /* And they must not be keys of the object */
+                               if (tokens != NULL && parser->toksuper != -1) {
+                                       jsmntok_t *t = &tokens[parser->toksuper];
+                                       if (t->type == JSMN_OBJECT ||
+                                                       (t->type == JSMN_STRING && t->size != 0)) {
+                                               return JSMN_ERROR_INVAL;
+                                       }
+                               }
+#else
+                       /* In non-strict mode every unquoted value is a primitive */
+                       default:
+#endif
+                               r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
+                               if (r < 0) return r;
+                               count++;
+                               if (parser->toksuper != -1 && tokens != NULL)
+                                       tokens[parser->toksuper].size++;
+                               break;
+
+#ifdef JSMN_STRICT
+                       /* Unexpected char in strict mode */
+                       default:
+                               return JSMN_ERROR_INVAL;
+#endif
+               }
+       }
+
+       if (tokens != NULL) {
+               for (i = parser->toknext - 1; i >= 0; i--) {
+                       /* Unmatched opened object or array */
+                       if (tokens[i].start != -1 && tokens[i].end == -1) {
+                               return JSMN_ERROR_PART;
+                       }
+               }
+       }
+
+       return count;
+}
+
+/**
+ * Creates a new parser based over a given  buffer with an array of tokens
+ * available.
+ */
+void jsmn_init(jsmn_parser *parser) {
+       parser->pos = 0;
+       parser->toknext = 0;
+       parser->toksuper = -1;
+}
+
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/jsmn.h b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/jsmn.h
new file mode 100644 (file)
index 0000000..4ae6d9b
--- /dev/null
@@ -0,0 +1,93 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __JSMN_H_
+#define __JSMN_H_
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * JSON type identifier. Basic types are:
+ *     o Object
+ *     o Array
+ *     o String
+ *     o Other primitive: number, boolean (true/false) or null
+ */
+typedef enum {
+       JSMN_UNDEFINED = 0,
+       JSMN_OBJECT = 1,
+       JSMN_ARRAY = 2,
+       JSMN_STRING = 3,
+       JSMN_PRIMITIVE = 4
+} jsmntype_t;
+
+enum jsmnerr {
+       /* Not enough tokens were provided */
+       JSMN_ERROR_NOMEM = -1,
+       /* Invalid character inside JSON string */
+       JSMN_ERROR_INVAL = -2,
+       /* The string is not a full JSON packet, more bytes expected */
+       JSMN_ERROR_PART = -3
+};
+
+/**
+ * JSON token description.
+ * @param              type    type (object, array, string etc.)
+ * @param              start   start position in JSON data string
+ * @param              end             end position in JSON data string
+ */
+typedef struct {
+       jsmntype_t type;
+       int start;
+       int end;
+       int size;
+#ifdef JSMN_PARENT_LINKS
+       int parent;
+#endif
+} jsmntok_t;
+
+/**
+ * JSON parser. Contains an array of token blocks available. Also stores
+ * the string being parsed now and current position in that string
+ */
+typedef struct {
+       unsigned int pos; /* offset in the JSON string */
+       unsigned int toknext; /* next token to allocate */
+       int toksuper; /* superior token node, e.g parent object or array */
+} jsmn_parser;
+
+/**
+ * Create JSON parser over an array of tokens
+ */
+void jsmn_init(jsmn_parser *parser);
+
+/**
+ * Run JSON parser. It parses a JSON data string into and array of tokens, each describing
+ * a single JSON object.
+ */
+int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
+               jsmntok_t *tokens, unsigned int num_tokens);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __JSMN_H_ */
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/license.md b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/license.md
new file mode 100644 (file)
index 0000000..95e459a
--- /dev/null
@@ -0,0 +1,81 @@
+# Licensing {#licensing}
+
+# Introduction {#lic_intro}
+
+This Licensing section describes licensing of IPR in the EVEL Library.
+  
+# Licensed Software {#lic_software}
+
+## EVEL Library {#lic_evel}
+
+
+Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+       http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and 
+limitations under the License.
+
+## libcurl {#lic_libcurl}
+
+The EVEL Library makes use of the the [cURL Library]
+(https://curl.haxx.se/libcurl/) in order to send and receive HTTP data.
+
+### License
+
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright (c) 1996 - 2016, Daniel Stenberg, daniel@haxx.se, and many 
+contributors, see the THANKS file.
+
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software for any purpose 
+with or without fee is hereby granted, provided that the above copyright notice 
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN 
+NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 
+OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder shall not be 
+used in advertising or otherwise to promote the sale, use or other dealings in 
+this Software without prior written authorization of the copyright holder.
+
+## JSMN {#lic_jsmn}
+
+The EVEL Library makes use of the [JSMN library](http://zserge.com/jsmn.html)
+in order to decode JSON data.
+
+### License {#lic_jsmn_license}
+
+Copyright (c) 2010 Serge A. Zaitsev
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+  
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/metadata.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/metadata.c
new file mode 100644 (file)
index 0000000..11fef1b
--- /dev/null
@@ -0,0 +1,592 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * Wrap the OpenStack metadata service.
+ ****************************************************************************/
+
+#include <string.h>
+#include <assert.h>
+#include <malloc.h>
+
+#include <curl/curl.h>
+
+#include "evel.h"
+#include "evel_internal.h"
+#include "jsmn.h"
+#include "metadata.h"
+
+/**************************************************************************//**
+ * URL on the link-local IP address where we can get the metadata in
+ * machine-friendly format.
+ *****************************************************************************/
+static const char * OPENSTACK_METADATA_URL =
+                      "http://169.254.169.254/openstack/latest/meta_data.json";
+
+/**************************************************************************//**
+ * How long we're prepared to wait for the metadata service to respond in
+ * seconds.
+ *****************************************************************************/
+static const int OPENSTACK_METADATA_TIMEOUT = 2;
+
+/**************************************************************************//**
+ * Size of fields extracted from metadata service.
+ *****************************************************************************/
+#define MAX_METADATA_STRING  64
+
+/**************************************************************************//**
+ * UUID of the VM extracted from the OpenStack metadata service.
+ *****************************************************************************/
+static char vm_uuid[MAX_METADATA_STRING+1] = {0};
+
+/**************************************************************************//**
+ * Name of the VM extracted from the OpenStack metadata service.
+ *****************************************************************************/
+static char vm_name[MAX_METADATA_STRING+1] = {0};
+
+/**************************************************************************//**
+ * How many metadata elements we allow for in the retrieved JSON.
+ *****************************************************************************/
+static const int MAX_METADATA_TOKENS = 128;
+
+/*****************************************************************************/
+/* Local prototypes.                                                         */
+/*****************************************************************************/
+static EVEL_ERR_CODES json_get_top_level_string(const char * json_string,
+                                                const jsmntok_t *tokens,
+                                                int json_token_count,
+                                                const char * key,
+                                                char * value);
+static EVEL_ERR_CODES json_get_string(const char * json_string,
+                                      const jsmntok_t *tokens,
+                                      int json_token_count,
+                                      const char * key,
+                                      char * value);
+static int jsoneq(const char *json, const jsmntok_t *tok, const char *s);
+
+/**************************************************************************//**
+ * Download metadata from the OpenStack metadata service.
+ *
+ * @param verbosity   Controls whether to generate debug to stdout.  Zero:
+ *                    none.  Non-zero: generate debug.
+ * @returns Status code
+ * @retval  EVEL_SUCCESS      On success
+ * @retval  ::EVEL_ERR_CODES  On failure.
+ *****************************************************************************/
+EVEL_ERR_CODES openstack_metadata(int verbosity)
+{
+  int rc = EVEL_SUCCESS;
+  CURLcode curl_rc = CURLE_OK;
+  CURL * curl_handle = NULL;
+  MEMORY_CHUNK rx_chunk;
+  char curl_err_string[CURL_ERROR_SIZE] = "<NULL>";
+  jsmn_parser json_parser;
+  jsmntok_t tokens[MAX_METADATA_TOKENS];
+  int json_token_count = 0;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Initialize dummy values for the metadata - needed for test              */
+  /* environments.                                                           */
+  /***************************************************************************/
+  openstack_metadata_initialize();
+
+  /***************************************************************************/
+  /* Get a curl handle which we'll use for accessing the metadata service.   */
+  /***************************************************************************/
+  curl_handle = curl_easy_init();
+  if (curl_handle == NULL)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    EVEL_ERROR("Failed to get libcurl handle");
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Prime the library to give friendly error codes.                         */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle,
+                             CURLOPT_ERRORBUFFER,
+                             curl_err_string);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    EVEL_ERROR("Failed to initialize libcurl to provide friendly errors. "
+               "Error code=%d", curl_rc);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Set the URL for the metadata API.                                       */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, OPENSTACK_METADATA_URL);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    EVEL_ERROR("Failed to initialize libcurl with the API URL. "
+               "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* send all data to this function.                                         */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle,
+                             CURLOPT_WRITEFUNCTION,
+                             evel_write_callback);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    EVEL_ERROR("Failed to initialize libcurl with the write callback. "
+             "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* some servers don't like requests that are made without a user-agent     */
+  /* field, so we provide one.                                               */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle,
+                             CURLOPT_USERAGENT,
+                             "libcurl-agent/1.0");
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    EVEL_ERROR("Failed to initialize libcurl to upload.  Error code=%d (%s)",
+               curl_rc, curl_err_string);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Set the timeout for the operation.                                      */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle,
+                             CURLOPT_TIMEOUT,
+                             OPENSTACK_METADATA_TIMEOUT);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_NO_METADATA;
+    EVEL_ERROR("Failed to initialize libcurl to set timeout. "
+               "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+
+  /***************************************************************************/
+  /* Create the memory chunk to be used for the response to the post.  The   */
+  /* will be realloced.                                                      */
+  /***************************************************************************/
+  rx_chunk.memory = malloc(1);
+  assert(rx_chunk.memory != NULL);
+  rx_chunk.size = 0;
+
+  /***************************************************************************/
+  /* Point to the data to be received.                                       */
+  /***************************************************************************/
+  curl_rc = curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&rx_chunk);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    EVEL_ERROR("Failed to initialize libcurl to receive metadata. "
+               "Error code=%d (%s)", curl_rc, curl_err_string);
+    goto exit_label;
+  }
+  EVEL_DEBUG("Initialized data to receive");
+
+  /***************************************************************************/
+  /* If running in verbose mode generate more output.                        */
+  /***************************************************************************/
+  if (verbosity > 0)
+  {
+    curl_rc = curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
+    if (curl_rc != CURLE_OK)
+    {
+      rc = EVEL_CURL_LIBRARY_FAIL;
+      log_error_state("Failed to initialize libcurl to be verbose. "
+                      "Error code=%d", curl_rc);
+      goto exit_label;
+    }
+  }
+
+  /***************************************************************************/
+  /* Now run off and do what you've been told!                               */
+  /***************************************************************************/
+  curl_rc = curl_easy_perform(curl_handle);
+  if (curl_rc != CURLE_OK)
+  {
+    rc = EVEL_CURL_LIBRARY_FAIL;
+    EVEL_ERROR("Failed to transfer the data from metadata service. "
+               "Error code=%d (%s)", curl_rc, curl_err_string);
+  }
+  else
+  {
+    /*************************************************************************/
+    /* We have some metadata available, so break it out into tokens.         */
+    /*************************************************************************/
+    EVEL_DEBUG("Received metadata size = %d", rx_chunk.size);
+    EVEL_INFO("Received metadata = %s", rx_chunk.memory);
+    jsmn_init(&json_parser);
+    json_token_count = jsmn_parse(&json_parser,
+                                  rx_chunk.memory, rx_chunk.size,
+                                  tokens, MAX_METADATA_TOKENS);
+
+    /*************************************************************************/
+    /* Check that we parsed some data and that the top level is as expected. */
+    /*************************************************************************/
+    if (json_token_count < 0 || tokens[0].type != JSMN_OBJECT)
+    {
+      rc = EVEL_BAD_METADATA;
+      EVEL_ERROR("Failed to parse received JSON OpenStack metadata.  "
+                 "Error code=%d", json_token_count);
+      goto exit_label;
+    }
+    else
+    {
+      EVEL_DEBUG("Extracted %d tokens from the JSON OpenStack metadata.  ",
+                                                             json_token_count);
+    }
+
+    /*************************************************************************/
+    /* Find the keys we want from the metadata.                              */
+    /*************************************************************************/
+    if (json_get_string(rx_chunk.memory,
+                        tokens,
+                        json_token_count,
+                        "uuid",
+                        vm_uuid) != EVEL_SUCCESS)
+    {
+      rc = EVEL_BAD_METADATA;
+      EVEL_ERROR("Failed to extract UUID from OpenStack metadata");
+    }
+    else
+    {
+      EVEL_DEBUG("UUID: %s", vm_uuid);
+    }
+    if (json_get_top_level_string(rx_chunk.memory,
+                                  tokens,
+                                  json_token_count,
+                                  "name",
+                                  vm_name) != EVEL_SUCCESS)
+    {
+      rc = EVEL_BAD_METADATA;
+      EVEL_ERROR("Failed to extract VM Name from OpenStack metadata");
+    }
+    else
+    {
+      EVEL_DEBUG("VM Name: %s", vm_name);
+    }
+  }
+
+exit_label:
+
+  /***************************************************************************/
+  /* Shut down the cURL library in a tidy manner.                            */
+  /***************************************************************************/
+  if (curl_handle != NULL)
+  {
+    curl_easy_cleanup(curl_handle);
+    curl_handle = NULL;
+  }
+  free(rx_chunk.memory);
+
+  EVEL_EXIT();
+  return rc;
+}
+
+/**************************************************************************//**
+ * Initialize default values for vm_name and vm_uuid - for testing purposes.
+ *****************************************************************************/
+void openstack_metadata_initialize()
+{
+  strncpy(vm_uuid,
+          "Dummy VM UUID - No Metadata available",
+          MAX_METADATA_STRING);
+  strncpy(vm_name,
+          "Dummy VM name - No Metadata available",
+          MAX_METADATA_STRING);
+}
+
+/**************************************************************************//**
+ * Get a string value from supplied JSON by matching the key.
+ *
+ * As the structure of the metadata we're looking at is pretty straightforward
+ * we don't do anything complex (a la XPath) to extract nested keys with the
+ * same leaf name, for example.  Simply walk the structure until we find a
+ * string with the correct value.
+ *
+ * @param[in] json_string   The string which contains the JSON and has already
+ *                          been parsed.
+ * @param[in] tokens        The tokens which the JSON parser found in the JSON.
+ * @param[in] json_token_count  How many tokens were found.
+ * @param[in] key           The key we're looking for.
+ * @param[out] value        The string we found at @p key.
+ *
+ * @returns Status code
+ * @retval  EVEL_SUCCESS      On success - contents of @p value updated.
+ * @retval  EVEL_JSON_KEY_NOT_FOUND  Key not found - @p value not updated.
+ * @retval  EVEL_BAD_JSON     Parser hit unexpected data - @p value not
+ *                            updated.
+ *****************************************************************************/
+static EVEL_ERR_CODES json_get_string(const char * json_string,
+                                      const jsmntok_t * tokens,
+                                      int json_token_count,
+                                      const char * key,
+                                      char * value)
+{
+  EVEL_ERR_CODES rc = EVEL_JSON_KEY_NOT_FOUND;
+  int token_num = 0;
+  int token_len = 0;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(json_string != NULL);
+  assert(tokens != NULL);
+  assert(json_token_count >= 0);
+  assert(key != NULL);
+  assert(value != NULL);
+
+  for (token_num = 0; token_num < json_token_count; token_num++)
+  {
+    switch(tokens[token_num].type)
+    {
+    case JSMN_OBJECT:
+      EVEL_DEBUG("Skipping object");
+      break;
+
+    case JSMN_ARRAY:
+      EVEL_DEBUG("Skipping array");
+      break;
+
+    case JSMN_STRING:
+      /***********************************************************************/
+      /* This is a string, so may be what we want.  Compare keys.            */
+      /***********************************************************************/
+      if (jsoneq(json_string, &tokens[token_num], key) == 0)
+      {
+        token_len = tokens[token_num + 1].end - tokens[token_num + 1].start;
+        EVEL_DEBUG("Token %d len %d matches at %d to %d", token_num,
+                                                   tokens[token_num + 1].start,
+                                                   tokens[token_num + 1].end);
+        strncpy(value, json_string + tokens[token_num + 1].start, token_len);
+        value[token_len] = '\0';
+        EVEL_DEBUG("Extracted key: \"%s\" Value: \"%s\"", key, value);
+        rc = EVEL_SUCCESS;
+        goto exit_label;
+      }
+      else
+      {
+        EVEL_DEBUG("String key did not match");
+      }
+
+      /***********************************************************************/
+      /* Step over the value, whether we used it or not.                     */
+      /***********************************************************************/
+      token_num++;
+      break;
+
+    case JSMN_PRIMITIVE:
+      EVEL_INFO("Skipping primitive");
+      break;
+
+    case JSMN_UNDEFINED:
+    default:
+      rc = EVEL_BAD_JSON_FORMAT;
+      EVEL_ERROR("Unexpected JSON format at token %d (%d)",
+                  token_num,
+                  tokens[token_num].type);
+      goto exit_label;
+    }
+  }
+
+exit_label:
+  EVEL_EXIT();
+  return rc;
+}
+
+/**************************************************************************//**
+ * Get a top-level string value from supplied JSON by matching the key.
+ *
+ * Unlike json_get_string, this only returns a value that is in the top-level
+ * JSON object.
+ *
+ * @param[in] json_string   The string which contains the JSON and has already
+ *                          been parsed.
+ * @param[in] tokens        The tokens which the JSON parser found in the JSON.
+ * @param[in] json_token_count  How many tokens were found.
+ * @param[in] key           The key we're looking for.
+ * @param[out] value        The string we found at @p key.
+ *
+ * @returns Status code
+ * @retval  EVEL_SUCCESS      On success - contents of @p value updated.
+ * @retval  EVEL_JSON_KEY_NOT_FOUND  Key not found - @p value not updated.
+ * @retval  EVEL_BAD_JSON     Parser hit unexpected data - @p value not
+ *                            updated.
+ *****************************************************************************/
+static EVEL_ERR_CODES json_get_top_level_string(const char * json_string,
+                                                const jsmntok_t * tokens,
+                                                int json_token_count,
+                                                const char * key,
+                                                char * value)
+{
+  EVEL_ERR_CODES rc = EVEL_JSON_KEY_NOT_FOUND;
+  int token_num = 0;
+  int token_len = 0;
+  int bracket_count = 0;
+  int string_index = 0;
+  int increment = 0;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(json_string != NULL);
+  assert(tokens != NULL);
+  assert(json_token_count >= 0);
+  assert(key != NULL);
+  assert(value != NULL);
+
+  for (token_num = 0; token_num < json_token_count; token_num++)
+  {
+    switch(tokens[token_num].type)
+    {
+    case JSMN_OBJECT:
+      EVEL_DEBUG("Skipping object");
+      break;
+
+    case JSMN_ARRAY:
+      EVEL_DEBUG("Skipping array");
+      break;
+
+    case JSMN_STRING:
+      /***********************************************************************/
+      /* This is a string, so may be what we want.  Compare keys.            */
+      /***********************************************************************/
+      if (jsoneq(json_string, &tokens[token_num], key) == 0)
+      {
+        /*********************************************************************/
+        /* Count the difference in the number of opening and closing         */
+        /* brackets up to this token.  This needs to be 1 for a top-level    */
+        /* string.  Let's just hope we don't have any strings containing     */
+        /* brackets.                                                         */
+        /*********************************************************************/
+        increment = ((string_index < tokens[token_num].start) ? 1 : -1);
+
+        while (string_index != tokens[token_num].start)
+        {
+          if (json_string[string_index] == '{')
+          {
+            bracket_count += increment;
+          }
+          else if (json_string[string_index] == '}')
+          {
+            bracket_count -= increment;
+          }
+
+          string_index += increment;
+        }
+
+        if (bracket_count == 1)
+        {
+          token_len = tokens[token_num + 1].end - tokens[token_num + 1].start;
+          EVEL_DEBUG("Token %d len %d matches at top level at %d to %d",
+                     token_num,
+                     tokens[token_num + 1].start,
+                     tokens[token_num + 1].end);
+          strncpy(value, json_string + tokens[token_num + 1].start, token_len);
+          value[token_len] = '\0';
+          EVEL_DEBUG("Extracted key: \"%s\" Value: \"%s\"", key, value);
+          rc = EVEL_SUCCESS;
+          goto exit_label;
+        }
+        else
+        {
+          EVEL_DEBUG("String key did match, but not at top level");
+        }
+      }
+      else
+      {
+        EVEL_DEBUG("String key did not match");
+      }
+
+      /***********************************************************************/
+      /* Step over the value, whether we used it or not.                     */
+      /***********************************************************************/
+      token_num++;
+      break;
+
+    case JSMN_PRIMITIVE:
+      EVEL_INFO("Skipping primitive");
+      break;
+
+    case JSMN_UNDEFINED:
+    default:
+      rc = EVEL_BAD_JSON_FORMAT;
+      EVEL_ERROR("Unexpected JSON format at token %d (%d)",
+                  token_num,
+                  tokens[token_num].type);
+      goto exit_label;
+    }
+  }
+
+exit_label:
+  EVEL_EXIT();
+  return rc;
+}
+
+/**************************************************************************//**
+ * Compare a JSON string token with a value.
+ *
+ * @param[in] json The string which contains the JSON and has already been
+ *                 parsed.
+ * @param[in] tok  The token which the JSON parser found in the JSON.
+ * @param[in] s    The string we're looking for.
+ *
+ * @returns        Whether the token matches the string or not.
+ * @retval  0      Value matches
+ * @retval  -1     Value does not match.
+ *****************************************************************************/
+static int jsoneq(const char *json, const jsmntok_t *tok, const char *s) {
+  if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start &&
+      strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
+    return 0;
+  }
+  return -1;
+}
+
+/**************************************************************************//**
+ * Get the VM name provided by the metadata service.
+ *
+ * @returns VM name
+ *****************************************************************************/
+const char *openstack_vm_name()
+{
+  return vm_name;
+}
+
+/**************************************************************************//**
+ * Get the VM UUID provided by the metadata service.
+ *
+ * @returns VM UUID
+ *****************************************************************************/
+const char *openstack_vm_uuid()
+{
+  return vm_uuid;
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/metadata.h b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/metadata.h
new file mode 100644 (file)
index 0000000..1ee4409
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef METADATA_INCLUDED
+#define METADATA_INCLUDED
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Wrap the OpenStack metadata service.
+ *
+ ****************************************************************************/
+
+#include "evel.h"
+
+/**************************************************************************//**
+ * Download metadata from the OpenStack metadata service.
+ *
+ * @param verbosity   Controls whether to generate debug to stdout.  Zero:
+ *                    none.  Non-zero: generate debug.
+ * @returns Status code
+ * @retval  EVEL_SUCCESS      On success
+ * @retval  ::EVEL_ERR_CODES  On failure.
+ *****************************************************************************/
+EVEL_ERR_CODES openstack_metadata(int verbosity);
+
+/**************************************************************************//**
+ * Initialize default values for vm_name and vm_uuid - for testing purposes.
+ *****************************************************************************/
+void openstack_metadata_initialize();
+
+/**************************************************************************//**
+ * Get the VM name provided by the metadata service.
+ *
+ * @returns VM name
+ *****************************************************************************/
+const char *openstack_vm_name();
+
+/**************************************************************************//**
+ * Get the VM UUID provided by the metadata service.
+ *
+ * @returns VM UUID
+ *****************************************************************************/
+const char *openstack_vm_uuid();
+
+#endif
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/quickstart.md b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/quickstart.md
new file mode 100644 (file)
index 0000000..1c735cc
--- /dev/null
@@ -0,0 +1,445 @@
+# Quick Start Guide {#quickstart}
+
+# Introduction {#qs_intro}
+
+This Quick-Start section describes how to:
+
+  *  Install and compile the supplied library code
+  *  Integrate an existing project to use the EVEL library
+  
+# Installation {#qs_install}
+
+The library is supplied as a source-code compressed-tar file. It is 
+straightforward to install and build to integrate with an existing or new
+development project.
+
+## Unpack the Source Code {#qs_unpack}
+
+The file should unpacked into your development environment:
+```
+$ mkdir evel
+$ cd evel
+$ tar zxvf evel-library-package.tgz
+```
+### Satisfy Dependencies {#qs_depend}
+
+Note that all commands in this section are based on CentOS package management
+tools and you may need to substitute the appropriate tools/packages for your
+distribution, for example `apt-get` for Ubuntu.
+
+Ensure that GCC development tools are available.
+
+```
+$ sudo yum install gcc
+```
+Additionally, the library has a dependency on the cURL library, so you'll need 
+the development tools for libCurl installed. (At runtime, only the runtime 
+library is required, of course.)
+
+```
+$ sudo yum install libcurl-devel
+```
+If you wish to make the project documentation, then Doxygen and Graphviz are
+required. (Again, this is only in the development environment, not the runtime 
+environment!)
+
+```
+$ sudo yum install doxygen graphviz
+```
+
+Note that some distributions have quite old versions of Doxygen by default and 
+it may be necessary to install a later version to use all the features.
+
+If you want to build PDFs from the LaTeX you will need a texlive install.
+
+```
+$ sudo yum install texlive
+```
+
+### Test Build {#qs_build}
+Make sure that the library makes cleanly:
+
+```
+$ cd bldjobs
+$ make
+Making dependency file evel_unit.d for evel_unit.c
+Making dependency file evel_test_control.d for evel_test_control.c
+Making dependency file evel_demo.d for evel_demo.c
+Making dependency file jsmn.d for jsmn.c
+Making dependency file evel_logging.d for evel_logging.c
+Making dependency file evel_event_mgr.d for evel_event_mgr.c
+Making dependency file evel_internal_event.d for evel_internal_event.c
+Making dependency file evel_throttle.d for evel_throttle.c
+Making dependency file evel_syslog.d for evel_syslog.c
+Making dependency file evel_strings.d for evel_strings.c
+Making dependency file evel_state_change.d for evel_state_change.c
+Making dependency file evel_scaling_measurement.d for evel_scaling_measurement.c
+Making dependency file evel_signaling.d for evel_signaling.c
+Making dependency file evel_service.d for evel_service.c
+Making dependency file evel_reporting_measurement.d for evel_reporting_measurement.c
+Making dependency file evel_json_buffer.d for evel_json_buffer.c
+Making dependency file evel_other.d for evel_other.c
+Making dependency file evel_option.d for evel_option.c
+Making dependency file evel_mobile_flow.d for evel_mobile_flow.c
+Making dependency file evel_fault.d for evel_fault.c
+Making dependency file evel_event.d for evel_event.c
+Making dependency file double_list.d for double_list.c
+Making dependency file ring_buffer.d for ring_buffer.c
+Making dependency file metadata.d for metadata.c
+Making dependency file evel.d for evel.c
+Making evel.o from evel.c
+Making metadata.o from metadata.c
+Making ring_buffer.o from ring_buffer.c
+Making double_list.o from double_list.c
+Making evel_event.o from evel_event.c
+Making evel_fault.o from evel_fault.c
+Making evel_mobile_flow.o from evel_mobile_flow.c
+Making evel_option.o from evel_option.c
+Making evel_other.o from evel_other.c
+Making evel_json_buffer.o from evel_json_buffer.c
+Making evel_reporting_measurement.o from evel_reporting_measurement.c
+Making evel_service.o from evel_service.c
+Making evel_signaling.o from evel_signaling.c
+Making evel_scaling_measurement.o from evel_scaling_measurement.c
+Making evel_state_change.o from evel_state_change.c
+Making evel_strings.o from evel_strings.c
+Making evel_syslog.o from evel_syslog.c
+Making evel_throttle.o from evel_throttle.c
+Making evel_internal_event.o from evel_internal_event.c
+Making evel_event_mgr.o from evel_event_mgr.c
+Making evel_logging.o from evel_logging.c
+Making jsmn.o from jsmn.c
+Linking API Shared Library
+Linking API Static Library
+Making evel_demo.o from evel_demo.c
+Making evel_test_control.o from evel_test_control.c
+Linking EVEL demo
+Making EVEL training
+$
+``` 
+You should now be able to run the demo CLI application.  Since it will want to
+dynamically link to the library that you've just made, you will need to set 
+your `LD_LIBRARY_PATH` appropriately first. Make sure that you specify
+your actual directory paths correctly in the following:
+
+```
+$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/centos/evel/libs/x86_64
+$ ../output/x86_64/evel_demo
+evel_demo [--help]
+          --fqdn <domain>
+          --port <port_number>
+          [--path <path>]
+          [--topic <topic>]
+          [--username <username>]
+          [--password <password>]
+          [--https]
+          [--cycles <cycles>]
+          [--nothrott]
+
+Demonstrate use of the ECOMP Vendor Event Listener API.
+
+  -h         Display this usage message.
+  --help
+
+  -f         The FQDN or IP address to the RESTful API.
+  --fqdn
+
+  -n         The port number the RESTful API.
+  --port
+
+  -p         The optional path prefix to the RESTful API.
+  --path
+
+  -t         The optional topic part of the RESTful API.
+  --topic
+
+  -u         The optional username for basic authentication of requests.
+  --username
+
+  -w         The optional password for basic authentication of requests.
+  --password
+
+  -s         Use HTTPS rather than HTTP for the transport.
+  --https
+
+  -c         Loop <cycles> times round the main loop.  Default = 1.
+  --cycles
+
+  -v         Generate much chattier logs.
+  --verbose
+
+  -x         Exclude throttling commands from demonstration.
+  --nothrott
+
+$
+```
+Assuming that all worked as expected, you are ready to start integrating with 
+your application. It probably makes sense to make the LD_LIBRARY_PATH change
+above permanent by incorporating it into your `.bash_profile` file.
+
+### Project Documentation {#qs_build_docs}
+
+The source comes with its own documentation included. The documentation can be
+built using the `docs` target in the Makefile. By default this builds HTML
+and LaTeX documentation, the latter being used to prepare PDFs.
+
+To make the documentation:
+```
+$ cd bldjobs
+$ make docs
+Cleaning docs...
+Making Doxygen documentation
+$ 
+```
+
+There is a make target that is intended to install the documentation on a
+"team server" - it will need adaptation for your team's environment - see the 
+`docs_install` target in the Makefile:
+
+```
+$ make docs_install
+Cleaning docs...
+Making Doxygen documentation
+Copying docs to team web-server...
+Enter passphrase for key '/data/home/.ssh/id_rsa':
+annotated.html                           100% 8088     7.9KB/s   00:00    
+arrowdown.png                            100%  246     0.2KB/s   00:00    
+arrowright.png                           100%  229     0.2KB/s   00:00    
+  ...
+$
+```
+
+# Project Integration {#qs_integrate}
+
+There are two key steps to the integration which have to be undertaken:
+
+  * Initialization/Termination of the library.
+  * Creation & posting of individual events.
+  
+Additionally, it may be necessary to consider changes to the EVEL library's
+source code if assumptions made by the library are either not satisfied or 
+inconvenient.  In particular:
+
+  * If the project already uses libcurl then the global initialization of the
+    library should be removed from the _EVEL Library_.
+  * The _EVEL Library_ uses `syslog` for event logging. If the project uses a
+    different event logging process, then EVEL's event logging macros should be
+    rewritten appropriately.
+
+These steps are considered in the [Normal Use](@ref qs_normal_use) and 
+[EVEL Adaptation](@ref qs_adaptation) sections below.
+
+## Normal Use         {#qs_normal_use}
+
+The _EVEL Library_ should be integrated with your project at a per-process 
+level: each process is an independent client of the ECOMP Vendor Event Listener
+API.
+
+### Initialization {#qs_initialize}
+
+The _EVEL Library_ should be initialized before the process becomes 
+multi-threaded. This constraint arises from the use of libcurl which imposes 
+the constraint that initialization occurs before the system is multi-threaded.
+This is described in more detail in the libcurl documentation for the
+[curl_global_init](https://curl.haxx.se/libcurl/c/curl_global_init.html) 
+function.
+
+Initialization stores configuration of the Vendor Event Listener API's details,
+such as the FQDN or IP address of the service, so the initializing process must
+have either extracted this information from its configuration or have this 
+information "hard-wired" into the application, so that it is available at the 
+point the `evel_initialize()` function is called:
+
+```C
+  #include "evel.h"
+  ...
+  if (evel_initialize(api_fqdn,
+                      api_port,
+                      api_path,
+                      api_topic,
+                      api_secure,
+                      "Alice",
+                      "This isn't very secure!",
+                      EVEL_SOURCE_VIRTUAL_MACHINE,
+                      "EVEL demo client",
+                      verbose_mode))
+  {
+    fprintf(stderr, "Failed to initialize the EVEL library!!!");
+    exit(-1);
+  }
+  ...
+```
+Once initialization has occurred successfully, the application may raise events
+and may also use the logging functions such as EVEL_INFO().
+
+Initialization is entirely local (there is no interaction with the service) so
+it is very unlikely to fail, unless the application environment is seriously 
+degraded.
+
+### Event Generation {#qs_generate}
+
+Generating events is a two stage process:
+
+  1.  Firstly, the _EVEL Library_ is called to allocate an event of the correct
+      type. 
+    * If this is successful, the caller is given a pointer to the event.
+    * All mandatory fields on the event are provided to this factory function
+      and are thereafter immutable.
+    * The application may add any necessary optional fields to the event, using
+      the pointer previously returned.
+  2.  The event is sent to the JSON API using the evel_post_event() function.
+    * At this point, the application relinquishes all responsibility for the 
+      event:
+      * It will be posted to the JSON API, if possible.
+      * Whether or not the posting is successful, the memory used will be 
+        freed.
+        
+In practice this looks like:
+
+```C
+  #include "evel.h"
+  ...
+
+  /***************************************************************************/
+  /* Create a new Fault object, setting mandatory fields as we do so...      */
+  /***************************************************************************/
+  fault = evel_new_fault("My alarm condition",
+                         "It broke very badly",
+                         EVEL_PRIORITY_NORMAL,
+                         EVEL_SEVERITY_MAJOR);
+  if (fault != NULL)
+  {
+    /*************************************************************************/
+    /* We have a Fault object - add some optional fields to it...            */
+    /*************************************************************************/
+    evel_fault_type_set(fault, "Bad things happen...");
+    evel_fault_interface_set(fault, "My Interface Card");
+    evel_fault_addl_info_add(fault, "name1", "value1");
+    evel_fault_addl_info_add(fault, "name2", "value2");
+    
+    /*************************************************************************/
+    /* Finally, post the Fault.  In practice this will only ever fail if     */
+    /* local ring-buffer is full because of event overload.                  */
+    /*************************************************************************/
+    evel_rc = evel_post_event((EVENT_HEADER *)fault);
+    if (evel_rc != EVEL_SUCCESS)
+    {
+      EVEL_ERROR("Post failed %d (%s)", evel_rc, evel_error_string());
+    }
+  }
+  ...
+```
+### Event Types {#qs_event_types}
+
+The _EVEL Library_ supports the following types of events:
+
+  1.  Faults
+  
+      These represent the **fault** domain in the event schema.
+      
+  2.  Measurements
+  
+      These represent the **measurementsForVfScaling** domain in the event
+      schema.
+      
+  3.  Reports
+  
+      This is an experimental type, designed to allow VNFs to report 
+      application-level statistics unencumbered with platform measurements.
+      The formal AT&T schema has been updated to include this experimental
+      type as **measurementsForVfReporting**. 
+
+  4.  Mobile Flow
+
+      These represent the **mobileFlow** domain in the event schema.
+
+  5.  Other
+
+      These represent the **other** domain in the event schema.
+
+  6.  Service Events
+
+      These represent the **serviceEvents** domain in the event schema.
+
+  7.  Signaling
+
+      These represent the **signaling** domain in the event schema.
+
+  8.  State Change
+
+      These represent the **stateChange** domain in the event schema.
+
+  9.  Syslog
+
+      These represent the **syslog** domain in the event schema.
+
+### Throttling {#qs_throttling}
+
+The _EVEL library_ supports the following command types as defined in the JSON API:
+
+  1.  commandType: throttlingSpecification
+
+    This is handled internally by the EVEL library, which stores the provided
+    throttling specification internally and applies it to all subsequent events.
+
+  2. commandType: provideThrottlingState
+
+    This is handled internally by the EVEL library, which returns the current
+    throttling specification for each domain.
+
+  3. commandType: measurementIntervalChange
+
+    This is handled by the EVEL library, which makes the latest measurement
+    interval available via the ::evel_get_measurement_interval function.
+    The application is responsible for checking and adhering to the latest
+    provided interval.
+
+### Termination {#qs_termination}
+
+Termination of the _EVEL Library_ is swift and brutal!  Events in the buffer
+at the time are "dropped on the floor" rather than waiting for the buffer to 
+deplete first.
+
+```C
+  #include "evel.h"
+  ...
+  
+  /***************************************************************************/
+  /* Shutdown the library.                                                   */
+  /***************************************************************************/
+  evel_terminate();
+  
+  ...
+``` 
+
+## EVEL Adaptation       {#qs_adaptation}
+
+The _EVEL Library_ is relatively simple and should be easy to adapt into other
+project environments.
+
+### LibcURL Lifecycle
+
+There are two circumstances where initialization of libcurl may be required:
+
+  1.  If libcurl is used by the project already, and therefore already takes 
+      responsibility of its initialization, then the libcurl initialization and 
+      termination functions should be removed from evel_initialize() and 
+      evel_terminate() respectively.
+  2.  If the project is unable to satisfy the constraint that libcurl 
+      initialization takes place in a single-threaded environment at the point
+      that the _EVEL Library_ can be initialized (for example, if MT code is 
+      necessary to read the configuration parameters required for 
+      _EVEL Library_ initialization) then it may be necessary to extract the 
+      libcurl functions and call them separately, earlier in the program's 
+      operation.
+      
+### Event Logging
+
+The _EVEL Library_ uses `syslog` for logging.  If this is inappropriate then
+the log_debug() and log_initialize() functions should be rewritten accordingly.
+
+**Note**: it would be a really bad idea to use the _EVEL Library_ itself for this 
+logging function. 
+[Turtles all the way down...](https://en.wikipedia.org/wiki/Turtles_all_the_way_down)
+  
+  
\ No newline at end of file
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/readme.md b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/readme.md
new file mode 100644 (file)
index 0000000..3cf5708
--- /dev/null
@@ -0,0 +1,236 @@
+# EVEL Library Overview {#mainpage}
+
+# Introduction
+
+The ECOMP Vendor Event Listener ("EVEL") library encapsulates the use of
+AT&T's JSON API to the collector function within the ECOMP infrastructure.
+
+As such, it provides a reference implementation of the EVEL JSON API which
+can either be directly as part of a project or can be used to inform the
+independent implementation of an equivalent binding to the API in another
+development environment.
+
+This section provides an overview of the library and how it is integrated
+into the target application.  If all you want is a set of instructions to
+get you started, the @ref quickstart "Quick Start" section is for you.  If
+you want a more in-depth understanding of the _EVEL Library_ then this section
+provides an overview and then you can read the detailed API documentation for 
+each function. The documentation for evel.h is a good starting point, since 
+that defines the public API of the _EVEL Library_.
+
+# Library Structure 
+
+The API is designed to be used on multi-process platforms where each process
+may be multi-threaded.  Each process using this library will create an
+independent HTTP client (using libcURL).  Each process will have a single
+thread running the HTTP client but that thread receives work on a
+ring-buffer from however may threads are required to implement the function.
+
+**Note**: libcurl imposes a constraint that it is initialized before
+the process starts multi-threaded operation.
+
+# Typical Usage
+
+The library is designed to be very straightforward to use and lightweight to
+integrate into projects. The only serious external dependency is on libcURL.
+
+The supplied Makefile produces a single library **libevel.so** or
+**libevel.a** which your application needs to be linked against.
+
+Each process within the application which wants to generate events needs to
+call ::evel_initialize at the start of day (observing the above warning
+about not being MT safe at this stage.)   The initialization specifies the
+details of where the API is located.  Management of configuration is the
+responsibility of the client.
+
+Once initialized, and now MT-safe, there are factory functions to produce
+new events:
+- Faults  - ::evel_new_fault
+- Measurements - ::evel_new_measurement
+- Report - ::evel_new_report
+- State Change - ::evel_new_state_change
+- Syslog - ::evel_new_syslog
+- Other - ::evel_new_other
+- Mobile Flow - ::evel_new_mobile_flow
+
+There is also a factory function ::evel_new_mobile_gtp_flow_metrics to create
+the parameter gtp_per_flow_metrics, which is then configured and passed to the
+::evel_new_mobile_flow factory function.
+
+The event structures are initialized with mandatory fields at the point of
+creation and optional fields may be added thereafter.  Once set, values in
+the structures are immutable.
+
+Once the event is prepared, it may be posted, using ::evel_post_event,  at
+which point the calling thread relinquishes all responsibility for the
+event.  It will be freed once successfully or unsuccessfully posted to the
+API.  If, for any reason, you change your mind and don't want to post a
+created event, it must be destroyed with ::evel_free_event.
+
+Finally, at the end of day, the library can be terminated cleanly by calling
+::evel_terminate.
+
+## Example Code
+
+The following fragment illustrates the above usage:
+
+```C
+
+  if (evel_initialize(api_fqdn,
+                      api_port,
+                      api_path,
+                      api_topic,
+                      api_secure,
+                      "Alice",
+                      "This isn't very secure!",
+                      EVEL_SOURCE_VIRTUAL_MACHINE,
+                      "EVEL demo client",
+                      verbose_mode))
+  {
+    fprintf(stderr, "Failed to initialize the EVEL library!!!");
+    exit(-1);
+  }
+
+  ...
+
+  fault = evel_new_fault("My alarm condition",
+                         "It broke very badly",
+                         EVEL_PRIORITY_NORMAL,
+                         EVEL_SEVERITY_MAJOR);
+  if (fault != NULL)
+  {
+    evel_fault_type_set(fault, "Bad things happen...");
+    evel_fault_interface_set(fault, "My Interface Card");
+    evel_fault_addl_info_add(fault, "name1", "value1");
+    evel_fault_addl_info_add(fault, "name2", "value2");
+    evel_rc = evel_post_event((EVENT_HEADER *)fault);
+    if (evel_rc != EVEL_SUCCESS)
+    {
+      EVEL_ERROR("Post failed %d (%s)", evel_rc, evel_error_string());
+    }
+  }
+
+```
+
+The public API to the library is defined in evel.h.  The internal APIs
+within library are defined in separate headers (<em>e.g.</em>
+evel_internal.h), but these should not need to be included by the code
+using the library.
+
+# Example Application
+
+A simple command-line application to generate events is provided as part of
+the source package (the above code fragment is taken from that application).
+
+The following illustrates its operation to a co-located "test-collector":
+```
+$ ./evel_demo --fqdn 127.0.0.1 --port 30000 --path vendor_event_listener --topic example_vnf --verbose
+./evel_demo built Feb 26 2016 18:14:48
+* About to connect() to 169.254.169.254 port 80 (#0)
+*   Trying 169.254.169.254... * Timeout
+* connect() timed out!
+* Closing connection #0
+* About to connect() to 127.0.0.1 port 30000 (#0)
+*   Trying 127.0.0.1... * connected
+* Connected to 127.0.0.1 (127.0.0.1) port 30000 (#0)
+* Server auth using Basic with user 'Alice'
+> POST /vendor_event_listener/eventListener/v1/example_vnf HTTP/1.1
+Authorization: Basic QWxpY2U6VGhpcyBpc24ndCB2ZXJ5IHNlY3VyZSE=
+User-Agent: libcurl-agent/1.0
+Host: 127.0.0.1:30000
+Accept: */*
+Content-type: application/json
+Content-Length: 510
+
+* HTTP 1.0, assume close after body
+< HTTP/1.0 204 No Content
+< Date: Fri, 04 Mar 2016 15:37:22 GMT
+< Server: WSGIServer/0.1 Python/2.6.6
+< 
+* Closing connection #0
+* About to connect() to 127.0.0.1 port 30000 (#0)
+*   Trying 127.0.0.1... * connected
+* Connected to 127.0.0.1 (127.0.0.1) port 30000 (#0)
+* Server auth using Basic with user 'Alice'
+> POST /vendor_event_listener/eventListener/v1/example_vnf HTTP/1.1
+Authorization: Basic QWxpY2U6VGhpcyBpc24ndCB2ZXJ5IHNlY3VyZSE=
+User-Agent: libcurl-agent/1.0
+Host: 127.0.0.1:30000
+Accept: */*
+Content-type: application/json
+Content-Length: 865
+
+* HTTP 1.0, assume close after body
+< HTTP/1.0 204 No Content
+< Date: Fri, 04 Mar 2016 15:37:22 GMT
+< Server: WSGIServer/0.1 Python/2.6.6
+< 
+* Closing connection #0
+* About to connect() to 127.0.0.1 port 30000 (#0)
+*   Trying 127.0.0.1... * connected
+* Connected to 127.0.0.1 (127.0.0.1) port 30000 (#0)
+* Server auth using Basic with user 'Alice'
+> POST /vendor_event_listener/eventListener/v1/example_vnf HTTP/1.1
+Authorization: Basic QWxpY2U6VGhpcyBpc24ndCB2ZXJ5IHNlY3VyZSE=
+User-Agent: libcurl-agent/1.0
+Host: 127.0.0.1:30000
+Accept: */*
+Content-type: application/json
+Content-Length: 2325
+
+* HTTP 1.0, assume close after body
+< HTTP/1.0 204 No Content
+< Date: Fri, 04 Mar 2016 15:37:22 GMT
+< Server: WSGIServer/0.1 Python/2.6.6
+< 
+* Closing connection #0
+^C
+
+Interrupted - quitting!
+$
+```
+
+# Restrictions and Limitations
+
+## Constraint Validation
+
+The _EVEL Library_ has been designed to be production-safe code with the
+emphasis at this stage being in correctness of operation rather than
+raw performance.
+
+The API tries to check as much information as possible to avoid misuse and
+will **assert()** if constraints are not satisfied.  This is likely to lead
+to the rapid discovery of coding errors by programmers, but does mean that
+the application can fail abruptly if the library is misused in any way.
+
+## Performance
+
+The default Makefile avoids aggressive optimizations so that any core-files
+are easy to interpret.  Production code should use greater optimization
+levels.
+
+As described above, the HTTP client is single threaded and will run all
+transactions synchronously.  As transactions are serialized, a client that
+generates a lot of events will be paced by the round-trip time.
+
+It would be a straightforward enhancement to use the multi-thread API into
+libcurl and use a pool of client threads to run transactions in parallel if
+this ever became a bottleneck.
+
+## Logging
+
+The initialization of the library includes the log verbosity.  The verbose
+operation makes the library very chatty so syslog may get rather clogged
+with detailed diagnostics.  It is possible to configure syslog to put these
+events into a separate file.  A trivial syslog.conf file would be:
+
+```
+
+# Log all user messages so debug information is captured.
+
+user.*      /var/log/debug
+```
+
+If verbose logging is enabled, the cURL library will generate information 
+about the HTTP operations on **stdout**. 
+
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/ring_buffer.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/ring_buffer.c
new file mode 100644 (file)
index 0000000..8080e02
--- /dev/null
@@ -0,0 +1,192 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * A ring buffer with multi-threaded synchronization.
+ *
+ ****************************************************************************/
+
+#include <assert.h>
+#include <malloc.h>
+
+#include "ring_buffer.h"
+#include "evel.h"
+
+/**************************************************************************//**
+ * Ring buffer initialization.
+ *
+ * Initialize the buffer supplied to the specified size.
+ *
+ * @param   buffer  Pointer to the ring-buffer to be initialized.
+ * @param   size    How many elements to be stored in the ring-buffer.
+ *
+ * @returns Nothing
+******************************************************************************/
+void ring_buffer_initialize(ring_buffer * buffer, int size)
+{
+  int pthread_rc = 0;
+
+  EVEL_ENTER();
+
+  /***************************************************************************/
+  /* Check assumptions.                                                      */
+  /***************************************************************************/
+  assert(buffer != NULL);
+  assert(size > 0);
+
+  /***************************************************************************/
+  /* Initialize the synchronization objects.                                 */
+  /***************************************************************************/
+  pthread_rc = pthread_mutex_init(&buffer->ring_mutex, NULL);
+  assert(pthread_rc == 0);
+  pthread_rc = pthread_cond_init(&buffer->ring_cv, NULL);
+  assert(pthread_rc == 0);
+
+  /***************************************************************************/
+  /* Allocate the ring buffer itself.                                        */
+  /***************************************************************************/
+  buffer->ring = malloc(size * sizeof(void *));
+  assert(buffer->ring != NULL);
+
+  /***************************************************************************/
+  /* Initialize the ring as empty.                                           */
+  /***************************************************************************/
+  buffer->next_write = 0;
+  buffer->next_read = 0;
+  buffer->size = size;
+
+  EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Read an element from a ring_buffer.
+ *
+ * Reads an element from the ring_buffer, advancing the next-read position.
+ * Operation is synchronized and therefore MT-safe.  Blocks if no data is
+ * available.
+ *
+ * @param   buffer  Pointer to the ring-buffer to be read.
+ *
+ * @returns Pointer to the element read from the buffer.
+******************************************************************************/
+void * ring_buffer_read(ring_buffer * buffer)
+{
+  void *msg = NULL;
+  EVEL_DEBUG("RBR: Ring buffer read");
+
+  pthread_mutex_lock(&buffer->ring_mutex);
+  while (1)
+  {
+    EVEL_DEBUG("RBR: got lock. NR=%d NW=%d",
+               buffer->next_read,
+               buffer->next_write);
+    if(buffer->next_read != buffer->next_write)
+    {
+      EVEL_DEBUG("RBR: buffer has item available");
+      msg = (buffer->ring)[buffer->next_read];
+      buffer->ring[buffer->next_read] = NULL;
+      buffer->next_read = (buffer->next_read + 1) % buffer->size;
+      EVEL_DEBUG("RBR: next read location is %d", buffer->next_read);
+      pthread_mutex_unlock(&buffer->ring_mutex);
+      break;
+    }
+    else
+    {
+      EVEL_DEBUG("RBR: Waiting for condition variable");
+      pthread_cond_wait(&buffer->ring_cv, &buffer->ring_mutex);
+      EVEL_DEBUG("RBR: Condition variable wait completed");
+    }
+  }
+  EVEL_DEBUG("RBR: Ring buffer read returning data at %lp", msg);
+  return msg;
+}
+
+/**************************************************************************//**
+ * Write an element into a ring_buffer.
+ *
+ * Writes an element into the ring_buffer, advancing the next-write position.
+ * Operation is synchronized and therefore MT-safe.  Fails if the buffer is
+ * full without blocking.
+ *
+ * @param   buffer  Pointer to the ring-buffer to be written.
+ * @param   msg     Pointer to data to be stored in the ring_buffer.
+ *
+ * @returns Number of items written.
+ * @retval  1       The data was written successfully.
+ * @retval  0       The ring_buffer was full so no data written.
+******************************************************************************/
+int ring_buffer_write(ring_buffer * buffer, void * msg)
+{
+  int item_count = 0;
+  int items_written = 0;
+  EVEL_DEBUG("RBW: Ring Buffer Write message at %lp", msg);
+
+  pthread_mutex_lock(&buffer->ring_mutex);
+  EVEL_DEBUG("RBW: got lock. NR=%d NW=%d SZ=%d",
+             buffer->next_read,
+             buffer->next_write,
+             buffer->size);
+
+  item_count = (buffer->next_write - buffer->next_read) % buffer->size;
+  if (item_count < 0)
+  {
+    item_count += buffer->size;
+  }
+  if (item_count < buffer->size - 1)
+  {
+    EVEL_DEBUG("RBW: %d items in buffer", item_count);
+    buffer->ring[buffer->next_write] = msg;
+    buffer->next_write = (buffer->next_write + 1) % buffer->size;
+    EVEL_DEBUG("RBW: next write location is %d", buffer->next_write);
+    items_written = 1;
+  }
+  else
+  {
+    EVEL_ERROR("RBW: ring buffer full - unable to write event");
+  }
+
+  pthread_mutex_unlock(&buffer->ring_mutex);
+  EVEL_DEBUG("RBW: released lock");
+  pthread_cond_signal(&buffer->ring_cv);
+
+  return items_written;
+}
+
+/**************************************************************************//**
+ * Tests whether there is data in the ring_buffer.
+ *
+ * Tests whether there is currently data in the ring_buffer without blocking.
+ *
+ * @param   buffer  Pointer to the ring-buffer to be tested.
+ *
+ * @returns Whether there is data in the ring_buffer.
+ * @retval  0       There isn't any data in the ring_buffer.
+ * @retval  1       There is data in the ring_buffer.
+******************************************************************************/
+int ring_buffer_is_empty(ring_buffer * buffer)
+{
+  int is_empty = 0;
+  EVEL_DEBUG("RBE: Ring empty check");
+
+  pthread_mutex_lock(&buffer->ring_mutex);
+  is_empty = (buffer->next_read == buffer->next_write);
+  pthread_mutex_unlock(&buffer->ring_mutex);
+
+  EVEL_DEBUG("RBE: Ring state= %d", is_empty);
+  return is_empty;
+}
+
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/ring_buffer.h b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/ring_buffer.h
new file mode 100644 (file)
index 0000000..1236b78
--- /dev/null
@@ -0,0 +1,96 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#ifndef RING_BUFFER_INCLUDED
+#define RING_BUFFER_INCLUDED
+
+/**************************************************************************//**
+ * @file
+ * Ring  buffer to handle message requests.
+ *
+ ****************************************************************************/
+
+#include <pthread.h>
+
+/**************************************************************************//**
+ * Ring buffer structure.
+ *****************************************************************************/
+typedef struct ring_buffer
+{
+    int size;
+    int next_write;
+    int next_read;
+    void ** ring;
+    pthread_cond_t ring_cv;
+    pthread_mutex_t ring_mutex;
+} ring_buffer;
+
+/**************************************************************************//**
+ * Ring buffer initialization.
+ *
+ * Initialize the buffer supplied to the specified size.
+ *
+ * @param   buffer  Pointer to the ring-buffer to be initialized.
+ * @param   size    How many elements to be stored in the ring-buffer.
+ *
+ * @returns Nothing
+******************************************************************************/
+void ring_buffer_initialize(ring_buffer * buffer, int size);
+
+/**************************************************************************//**
+ * Read an element from a ring_buffer.
+ *
+ * Reads an element from the ring_buffer, advancing the next-read position.
+ * Operation is synchronized and therefore MT-safe.  Blocks if no data is
+ * available.
+ *
+ * @param   buffer  Pointer to the ring-buffer to be read.
+ *
+ * @returns Pointer to the element read from the buffer.
+******************************************************************************/
+void * ring_buffer_read(ring_buffer * buffer);
+
+/**************************************************************************//**
+ * Write an element into a ring_buffer.
+ *
+ * Writes an element into the ring_buffer, advancing the next-write position.
+ * Operation is synchronized and therefore MT-safe.  Fails if the buffer is
+ * full without blocking.
+ *
+ * @param   buffer  Pointer to the ring-buffer to be written.
+ * @param   msg     Pointer to data to be stored in the ring_buffer.
+ *
+ * @returns Number of items written.
+ * @retval  1       The data was written successfully.
+ * @retval  0       The ring_buffer was full so no data written.
+******************************************************************************/
+int ring_buffer_write(ring_buffer * buffer, void * msg);
+
+/**************************************************************************//**
+ * Tests whether there is data in the ring_buffer.
+ *
+ * Tests whether there is currently data in the ring_buffer without blocking.
+ *
+ * @param   buffer  Pointer to the ring-buffer to be tested.
+ *
+ * @returns Whether there is data in the ring_buffer.
+ * @retval  0       There isn't any data in the ring_buffer.
+ * @retval  1       There is data in the ring_buffer.
+******************************************************************************/
+int ring_buffer_is_empty(ring_buffer * buffer);
+
+#endif
diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_unit/evel_unit.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_unit/evel_unit.c
new file mode 100644 (file)
index 0000000..f52dc27
--- /dev/null
@@ -0,0 +1,3484 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+/**************************************************************************//**
+ * @file
+ * Unit tests for JSON encoding and throttling.
+ *
+ * This software is intended to show the essential elements of the library's
+ * use.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include "evel.h"
+#include "evel_internal.h"
+#include "evel_throttle.h"
+#include "metadata.h"
+
+typedef enum {
+  SERVICE_NONE,
+  SERVICE_CODEC,
+  SERVICE_TRANSCODING,
+  SERVICE_RTCP,
+  SERVICE_EOC_VQM,
+  SERVICE_MARKER
+} SERVICE_TEST;
+
+/*****************************************************************************/
+/* Local prototypes.                                                         */
+/*****************************************************************************/
+static void test_encode_heartbeat();
+static void test_encode_header_overrides();
+static void test_encode_fault();
+static void test_encode_fault_with_escaping();
+static void test_encode_measurement();
+static void test_encode_mobile_mand();
+static void test_encode_mobile_opts();
+static void test_encode_other();
+static void test_encode_report();
+static void test_encode_service();
+static void test_encode_service_subset(const SERVICE_TEST service_test);
+static void test_encode_signaling();
+static void test_encode_state_change();
+static void test_encode_syslog();
+static void test_json_response_junk();
+static void test_json_provide_throttle_state();
+static void test_json_measurement_interval();
+static void test_json_throttle_spec_field();
+static void test_json_throttle_spec_nv_pair();
+static void test_json_throttle_spec_two_domains();
+static void test_json_throttle_spec_bad_command_type();
+static void test_encode_fault_throttled();
+static void test_encode_measurement_throttled();
+static void test_encode_mobile_throttled();
+static void test_encode_other_throttled();
+static void test_encode_report_throttled();
+static void test_encode_service_throttled();
+static void test_encode_signaling_throttled();
+static void test_encode_state_change_throttled();
+static void test_encode_syslog_throttled();
+static void compare_strings(char * expected,
+                            char * actual,
+                            int max_size,
+                            char * description);
+
+/**************************************************************************//**
+ * Main function.
+ *
+ * Runs all unit test cases, and fails hard on the first failure.
+ *
+ * @param[in] argc  Argument count.
+ * @param[in] argv  Argument vector - for usage see usage_text.
+ *****************************************************************************/
+int main(int argc, char ** argv)
+{
+  assert(argc >= 0);
+  assert(argv != NULL);
+
+  /***************************************************************************/
+  /* Fix our timezone to UTC.                                                */
+  /***************************************************************************/
+  putenv("TZ=UTC");
+
+  /***************************************************************************/
+  /* Initialize metadata.                                                    */
+  /***************************************************************************/
+  openstack_metadata_initialize();
+
+  /***************************************************************************/
+  /* Minimal initialisation to exercise the encoders.                        */
+  /***************************************************************************/
+  functional_role = "UNIT TEST";
+  log_initialize(EVEL_LOG_DEBUG, "EVEL");
+
+  /***************************************************************************/
+  /* Test each encoder.                                                      */
+  /***************************************************************************/
+  test_encode_heartbeat();
+  test_encode_header_overrides();
+  test_encode_fault();
+  test_encode_measurement();
+  test_encode_mobile_mand();
+  test_encode_mobile_opts();
+  test_encode_other();
+  test_encode_report();
+  test_encode_service();
+  test_encode_signaling();
+  test_encode_state_change();
+  test_encode_syslog();
+
+  /***************************************************************************/
+  /* Test JSON Throttle.                                                     */
+  /***************************************************************************/
+  test_json_response_junk();
+  test_json_provide_throttle_state();
+  test_json_measurement_interval();
+  test_json_throttle_spec_field();
+  test_json_throttle_spec_nv_pair();
+  test_json_throttle_spec_two_domains();
+  test_json_throttle_spec_bad_command_type();
+
+  /***************************************************************************/
+  /* Test each encoder with throttling applied.                              */
+  /***************************************************************************/
+  test_encode_fault_throttled();
+  test_encode_measurement_throttled();
+  test_encode_mobile_throttled();
+  test_encode_other_throttled();
+  test_encode_report_throttled();
+  test_encode_service_throttled();
+  test_encode_signaling_throttled();
+  test_encode_state_change_throttled();
+  test_encode_syslog_throttled();
+
+  /***************************************************************************/
+  /* Test character escaping.                                                */
+  /***************************************************************************/
+  test_encode_fault_with_escaping();
+
+  printf ("\nAll Tests Passed\n");
+
+  return 0;
+}
+
+/*****************************************************************************/
+/* We link with this gettimeofday so that we get a fixed result              */
+/*****************************************************************************/
+int gettimeofday(struct timeval *tv,
+                 struct timezone *tz __attribute__((unused)))
+{
+  tv->tv_sec = 1;
+  tv->tv_usec = 2;
+  return 0;
+}
+
+void test_encode_heartbeat()
+{
+  char * expected =
+    "{\"event\": {"
+    "\"commonEventHeader\": {"
+    "\"domain\": \"heartbeat\", "
+    "\"eventId\": \"121\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 121, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2, "
+    "\"eventType\": \"Autonomous heartbeat\", "
+    "\"reportingEntityId\": \"Dummy VM UUID - No Metadata available\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}}}";
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+
+  /***************************************************************************/
+  /* Test the VM name/uuid once.                                             */
+  /***************************************************************************/
+  evel_set_next_event_sequence(121);
+
+  EVENT_HEADER * heartbeat = evel_new_heartbeat();
+  assert(heartbeat != NULL);
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) heartbeat);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Heartbeat");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(heartbeat);
+}
+
+void test_encode_header_overrides()
+{
+  char * expected =
+    "{\"event\": {"
+    "\"commonEventHeader\": {"
+    "\"domain\": \"heartbeat\", "
+    "\"eventId\": \"121\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"entity_name_override\", "
+    "\"sequence\": 121, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1001, "
+    "\"version\": 1.2, "
+    "\"eventType\": \"Autonomous heartbeat\", "
+    "\"reportingEntityId\": \"entity_id_override\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}}}";
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+
+  /***************************************************************************/
+  /* Test the VM name/uuid once.                                             */
+  /***************************************************************************/
+  evel_set_next_event_sequence(121);
+
+  EVENT_HEADER * heartbeat = evel_new_heartbeat();
+  assert(heartbeat != NULL);
+
+  evel_start_epoch_set(heartbeat, 1001);
+  evel_last_epoch_set(heartbeat, 1000);
+  evel_reporting_entity_name_set(heartbeat, "entity_name_override");
+  evel_reporting_entity_id_set(heartbeat, "entity_id_override");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) heartbeat);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Heartbeat");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(heartbeat);
+}
+
+void test_encode_fault()
+{
+  char * expected =
+    "{\"event\": {"
+    "\"commonEventHeader\": {"
+    "\"domain\": \"fault\", "
+    "\"eventId\": \"122\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 122, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2, "
+    "\"eventType\": \"Bad things happen...\", "
+    "\"reportingEntityId\": \"Dummy VM UUID - No Metadata available\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}, "
+    "\"faultFields\": {"
+    "\"alarmCondition\": \"My alarm condition\", "
+    "\"eventSeverity\": \"MAJOR\", "
+    "\"eventSourceType\": \"other\", "
+    "\"specificProblem\": \"It broke very badly\", "
+    "\"eventCategory\": \"link\", "
+    "\"vfStatus\": \"Active\", "
+    "\"faultFieldsVersion\": 1.1, "
+    "\"alarmAdditionalInformation\": ["
+    "{\"name\": \"name1\", "
+    "\"value\": \"value1\"}, "
+    "{\"name\": \"name2\", "
+    "\"value\": \"value2\"}], "
+    "\"alarmInterfaceA\": \"My Interface Card\""
+    "}}}";
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  evel_set_next_event_sequence(122);
+  EVENT_FAULT * fault = evel_new_fault("My alarm condition",
+                                       "It broke very badly",
+                                       EVEL_PRIORITY_NORMAL,
+                                       EVEL_SEVERITY_MAJOR,
+                                       EVEL_SOURCE_HOST,
+                             EVEL_VF_STATUS_PREP_TERMINATE);
+  assert(fault != NULL);
+  evel_fault_type_set(fault, "Bad things happen...");
+  evel_fault_interface_set(fault, "My Interface Card");
+  evel_fault_addl_info_add(fault, "name1", "value1");
+  evel_fault_addl_info_add(fault, "name2", "value2");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) fault);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Fault");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(fault);
+}
+
+void test_encode_measurement()
+{
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"measurementsForVfScaling\", "
+    "\"eventId\": \"123\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 3000, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"entity_name\", "
+    "\"sequence\": 123, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 2000, "
+    "\"version\": 1.2, "
+    "\"eventType\": \"Perf management...\", "
+    "\"reportingEntityId\": \"entity_id\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}, "
+    "\"measurementsForVfScalingFields\": "
+    "{"
+    "\"measurementInterval\": 5.500000, "
+    "\"concurrentSessions\": 1, "
+    "\"configuredEntities\": 2, "
+    "\"cpuUsageArray\": ["
+    "{\"cpuIdentifier\": \"cpu1\", "
+    "\"percentUsage\": 11.110000}, "
+    "{\"cpuIdentifier\": \"cpu2\", "
+    "\"percentUsage\": 22.220000}], "
+    "\"filesystemUsageArray\": ["
+    "{\"blockConfigured\": 100.110000, "
+    "\"blockIops\": 33, "
+    "\"blockUsed\": 100.220000, "
+    "\"ephemeralConfigured\": 100.110000, "
+    "\"ephemeralIops\": 44, "
+    "\"ephemeralUsed\": 200.220000, "
+    "\"filesystemName\": \"00-11-22\"}, "
+    "{\"blockConfigured\": 300.110000, "
+    "\"blockIops\": 55, "
+    "\"blockUsed\": 300.220000, "
+    "\"ephemeralConfigured\": 300.110000, "
+    "\"ephemeralIops\": 66, "
+    "\"ephemeralUsed\": 400.220000, "
+    "\"filesystemName\": \"33-44-55\"}], "
+    "\"latencyDistribution\": ["
+    "{\"countsInTheBucket\": 20}, "
+    "{\"lowEndOfLatencyBucket\": 10.000000, "
+    "\"highEndOfLatencyBucket\": 20.000000, "
+    "\"countsInTheBucket\": 30}], "
+    "\"meanRequestLatency\": 4.400000, "
+    "\"memoryConfigured\": 6.600000, "
+    "\"memoryUsed\": 3.300000, "
+    "\"requestRate\": 7, "
+    "\"vNicUsageArray\": ["
+    "{"
+    "\"bytesIn\": 3, "
+    "\"bytesOut\": 4, "
+    "\"packetsIn\": 100, "
+    "\"packetsOut\": 200, "
+    "\"vNicIdentifier\": \"eth0\""
+    "}, "
+    "{"
+    "\"bytesIn\": 13, "
+    "\"bytesOut\": 14, "
+    "\"packetsIn\": 110, "
+    "\"packetsOut\": 240, "
+    "\"vNicIdentifier\": \"eth1\", "
+    "\"broadcastPacketsIn\": 11, "
+    "\"broadcastPacketsOut\": 12, "
+    "\"multicastPacketsIn\": 15, "
+    "\"multicastPacketsOut\": 16, "
+    "\"unicastPacketsIn\": 17, "
+    "\"unicastPacketsOut\": 18"
+    "}"
+    "], "
+    "\"aggregateCpuUsage\": 8.800000, "
+    "\"numberOfMediaPortsInUse\": 1234, "
+    "\"vnfcScalingMetric\": 1234.567800, "
+    "\"errors\": {"
+    "\"receiveDiscards\": 1, "
+    "\"receiveErrors\": 0, "
+    "\"transmitDiscards\": 2, "
+    "\"transmitErrors\": 1}, "
+    "\"featureUsageArray\": ["
+    "{\"featureIdentifier\": \"FeatureA\", "
+    "\"featureUtilization\": 123}, "
+    "{\"featureIdentifier\": \"FeatureB\", "
+    "\"featureUtilization\": 567}], "
+    "\"codecUsageArray\": ["
+    "{\"codecIdentifier\": \"G711a\", "
+    "\"numberInUse\": 91}, "
+    "{\"codecIdentifier\": \"G729ab\", "
+    "\"numberInUse\": 92}], "
+    "\"additionalMeasurements\": ["
+    "{\"name\": \"Group1\", "
+    "\"measurements\": ["
+    "{\"name\": \"Name1\", "
+    "\"value\": \"Value1\"}]}, "
+    "{\"name\": \"Group2\", "
+    "\"measurements\": ["
+    "{\"name\": \"Name1\", "
+    "\"value\": \"Value1\"}, "
+    "{\"name\": \"Name2\", "
+    "\"value\": \"Value2\"}]}], "
+    "\"measurementsForVfScalingVersion\": 1.1}}}";
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_MEASUREMENT * measurement = NULL;
+  MEASUREMENT_LATENCY_BUCKET * bucket = NULL;
+  MEASUREMENT_VNIC_PERFORMANCE * vnic_use = NULL;
+  MEASUREMENT_CPU_USE *cpu_use;
+
+  /***************************************************************************/
+  /* Measurement.                                                            */
+  /***************************************************************************/
+  evel_set_next_event_sequence(123);
+  measurement = evel_new_measurement(5.5);
+  assert(measurement != NULL);
+  evel_measurement_type_set(measurement, "Perf management...");
+  evel_measurement_conc_sess_set(measurement, 1);
+  evel_measurement_cfg_ents_set(measurement, 2);
+  evel_measurement_mean_req_lat_set(measurement, 4.4);
+  evel_measurement_request_rate_set(measurement, 7);
+
+  cpu_use = evel_measurement_new_cpu_use_add(measurement, "cpu1", 11.11);
+  evel_measurement_cpu_use_idle_set(cpu_use,22.22);
+  evel_measurement_cpu_use_interrupt_set(cpu_use,33.33);
+  evel_measurement_cpu_use_nice_set(cpu_use,44.44);
+  evel_measurement_cpu_use_softirq_set(cpu_use,55.55);
+  evel_measurement_cpu_use_steal_set(cpu_use,66.66);
+  evel_measurement_cpu_use_system_set(cpu_use,77.77);
+  evel_measurement_cpu_use_usageuser_set(cpu_use,88.88);
+  evel_measurement_cpu_use_wait_set(cpu_use,99.99);
+
+  cpu_use = evel_measurement_new_cpu_use_add(measurement, "cpu2", 22.22);
+  evel_measurement_cpu_use_idle_set(cpu_use,12.22);
+  evel_measurement_cpu_use_interrupt_set(cpu_use,33.33);
+  evel_measurement_cpu_use_nice_set(cpu_use,44.44);
+  evel_measurement_cpu_use_softirq_set(cpu_use,55.55);
+  evel_measurement_cpu_use_steal_set(cpu_use,66.66);
+  evel_measurement_cpu_use_system_set(cpu_use,77.77);
+  evel_measurement_cpu_use_usageuser_set(cpu_use,88.88);
+  evel_measurement_cpu_use_wait_set(cpu_use,19.99);
+
+
+  evel_measurement_fsys_use_add(measurement,"00-11-22",100.11, 100.22, 33,
+                                200.11, 200.22, 44);
+  evel_measurement_fsys_use_add(measurement,"33-44-55",300.11, 300.22, 55,
+                                400.11, 400.22, 66);
+  evel_start_epoch_set(&measurement->header, 2000);
+  evel_last_epoch_set(&measurement->header, 3000);
+  evel_reporting_entity_name_set(&measurement->header, "entity_name");
+  evel_reporting_entity_id_set(&measurement->header, "entity_id");
+
+  /***************************************************************************/
+  /* Latency Bucket with no optional parameters.                             */
+  /***************************************************************************/
+  bucket = evel_new_meas_latency_bucket(20);
+  evel_meas_latency_bucket_add(measurement, bucket);
+
+  /***************************************************************************/
+  /* Latency Bucket with all optional parameters.                            */
+  /***************************************************************************/
+  bucket = evel_new_meas_latency_bucket(30);
+  evel_meas_latency_bucket_low_end_set(bucket, 10.0);
+  evel_meas_latency_bucket_high_end_set(bucket, 20.0);
+  evel_meas_latency_bucket_add(measurement, bucket);
+
+  /***************************************************************************/
+  /* vNIC Use with no optional parameters.                                   */
+  /***************************************************************************/
+  vnic_use = evel_new_measurement_vnic_use("eth0", 100, 200, 3, 4);
+  evel_meas_vnic_use_add(measurement, vnic_use);
+
+  /***************************************************************************/
+  /* vNIC Use with all optional parameters.                                  */
+  /***************************************************************************/
+  vnic_use = evel_new_measurement_vnic_use("eth1", 110, 240, 13, 14);
+  evel_vnic_use_bcast_pkt_in_set(vnic_use, 11);
+  evel_vnic_use_bcast_pkt_out_set(vnic_use, 12);
+  evel_vnic_use_mcast_pkt_in_set(vnic_use, 15);
+  evel_vnic_use_mcast_pkt_out_set(vnic_use, 16);
+  evel_vnic_use_ucast_pkt_in_set(vnic_use, 17);
+  evel_vnic_use_ucast_pkt_out_set(vnic_use, 18);
+  evel_meas_vnic_use_add(measurement, vnic_use);
+
+  evel_measurement_errors_set(measurement, 1, 0, 2, 1);
+
+  evel_measurement_feature_use_add(measurement, "FeatureA", 123);
+  evel_measurement_feature_use_add(measurement, "FeatureB", 567);
+
+  evel_measurement_codec_use_add(measurement, "G711a", 91);
+  evel_measurement_codec_use_add(measurement, "G729ab", 92);
+
+  evel_measurement_media_port_use_set(measurement, 1234);
+
+  evel_measurement_vnfc_scaling_metric_set(measurement, 1234.5678);
+
+  evel_measurement_custom_measurement_add(measurement,
+                                          "Group1", "Name1", "Value1");
+  evel_measurement_custom_measurement_add(measurement,
+                                          "Group2", "Name1", "Value1");
+  evel_measurement_custom_measurement_add(measurement,
+                                          "Group2", "Name2", "Value2");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) measurement);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Measurement");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(measurement);
+}
+
+void test_encode_mobile_mand()
+{
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"mobileFlow\", "
+    "\"eventId\": \"1241\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 1241, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2, "
+    "\"reportingEntityId\": \"Dummy VM UUID - No Metadata available\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}, "
+    "\"mobileFlowFields\": {"
+    "\"flowDirection\": \"Outbound\", "
+    "\"gtpPerFlowMetrics\": {"
+    "\"avgBitErrorRate\": 12.300000, "
+    "\"avgPacketDelayVariation\": 3.120000, "
+    "\"avgPacketLatency\": 100, "
+    "\"avgReceiveThroughput\": 2100, "
+    "\"avgTransmitThroughput\": 500, "
+    "\"flowActivationEpoch\": 1470409421, "
+    "\"flowActivationMicrosec\": 987, "
+    "\"flowDeactivationEpoch\": 1470409431, "
+    "\"flowDeactivationMicrosec\": 11, "
+    "\"flowDeactivationTime\": \"Fri, 05 Aug 2016 15:03:51 +0000\", "
+    "\"flowStatus\": \"Working\", "
+    "\"maxPacketDelayVariation\": 87, "
+    "\"numActivationFailures\": 3, "
+    "\"numBitErrors\": 17, "
+    "\"numBytesReceived\": 123654, "
+    "\"numBytesTransmitted\": 4561, "
+    "\"numDroppedPackets\": 0, "
+    "\"numL7BytesReceived\": 12, "
+    "\"numL7BytesTransmitted\": 10, "
+    "\"numLostPackets\": 1, "
+    "\"numOutOfOrderPackets\": 3, "
+    "\"numPacketErrors\": 7, "
+    "\"numPacketsReceivedExclRetrans\": 899, "
+    "\"numPacketsReceivedInclRetrans\": 901, "
+    "\"numPacketsTransmittedInclRetrans\": 302, "
+    "\"numRetries\": 6, "
+    "\"numTimeouts\": 2, "
+    "\"numTunneledL7BytesReceived\": 0, "
+    "\"roundTripTime\": 110, "
+    "\"timeToFirstByte\": 225"
+    "}, "
+    "\"ipProtocolType\": \"TCP\", "
+    "\"ipVersion\": \"IPv4\", "
+    "\"otherEndpointIpAddress\": \"2.3.4.1\", "
+    "\"otherEndpointPort\": 2341, "
+    "\"reportingEndpointIpAddr\": \"4.2.3.1\", "
+    "\"reportingEndpointPort\": 4321"
+    "}}}";
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  MOBILE_GTP_PER_FLOW_METRICS * metrics = NULL;
+  EVENT_MOBILE_FLOW * mobile_flow = NULL;
+
+  /***************************************************************************/
+  /* Mobile.                                                                 */
+  /***************************************************************************/
+  evel_set_next_event_sequence(1241);
+
+  metrics = evel_new_mobile_gtp_flow_metrics(12.3,
+                                             3.12,
+                                             100,
+                                             2100,
+                                             500,
+                                             1470409421,
+                                             987,
+                                             1470409431,
+                                             11,
+                                             (time_t)1470409431,
+                                             "Working",
+                                             87,
+                                             3,
+                                             17,
+                                             123654,
+                                             4561,
+                                             0,
+                                             12,
+                                             10,
+                                             1,
+                                             3,
+                                             7,
+                                             899,
+                                             901,
+                                             302,
+                                             6,
+                                             2,
+                                             0,
+                                             110,
+                                             225);
+  assert(metrics != NULL);
+  mobile_flow = evel_new_mobile_flow("Outbound",
+                                     metrics,
+                                     "TCP",
+                                     "IPv4",
+                                     "2.3.4.1",
+                                     2341,
+                                     "4.2.3.1",
+                                     4321);
+  assert(mobile_flow != NULL);
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) mobile_flow);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Mobile");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(mobile_flow);
+}
+
+void test_encode_mobile_opts()
+{
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"mobileFlow\", "
+    "\"eventId\": \"1242\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 1242, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2, "
+    "\"eventType\": \"Mobile flow...\", "
+    "\"reportingEntityId\": \"Dummy VM UUID - No Metadata available\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}, "
+    "\"mobileFlowFields\": {"
+    "\"flowDirection\": \"Inbound\", "
+    "\"gtpPerFlowMetrics\": {"
+    "\"avgBitErrorRate\": 132.000100, "
+    "\"avgPacketDelayVariation\": 31.200000, "
+    "\"avgPacketLatency\": 101, "
+    "\"avgReceiveThroughput\": 2101, "
+    "\"avgTransmitThroughput\": 501, "
+    "\"flowActivationEpoch\": 1470409422, "
+    "\"flowActivationMicrosec\": 988, "
+    "\"flowDeactivationEpoch\": 1470409432, "
+    "\"flowDeactivationMicrosec\": 12, "
+    "\"flowDeactivationTime\": \"Fri, 05 Aug 2016 15:03:52 +0000\", "
+    "\"flowStatus\": \"Inactive\", "
+    "\"maxPacketDelayVariation\": 88, "
+    "\"numActivationFailures\": 4, "
+    "\"numBitErrors\": 18, "
+    "\"numBytesReceived\": 123655, "
+    "\"numBytesTransmitted\": 4562, "
+    "\"numDroppedPackets\": 1, "
+    "\"numL7BytesReceived\": 13, "
+    "\"numL7BytesTransmitted\": 11, "
+    "\"numLostPackets\": 2, "
+    "\"numOutOfOrderPackets\": 4, "
+    "\"numPacketErrors\": 8, "
+    "\"numPacketsReceivedExclRetrans\": 900, "
+    "\"numPacketsReceivedInclRetrans\": 902, "
+    "\"numPacketsTransmittedInclRetrans\": 303, "
+    "\"numRetries\": 7, "
+    "\"numTimeouts\": 3, "
+    "\"numTunneledL7BytesReceived\": 1, "
+    "\"roundTripTime\": 111, "
+    "\"timeToFirstByte\": 226, "
+    "\"ipTosCountList\": ["
+    "[\"1\", 13], "
+    "[\"4\", 99], "
+    "[\"17\", 1]], "
+    "\"ipTosList\": [\"1\", \"4\", \"17\"], "
+    "\"tcpFlagList\": [\"CWR\", \"URG\"], "
+    "\"tcpFlagCountList\": [[\"CWR\", 10], [\"URG\", 121]], "
+    "\"mobileQciCosList\": [\"conversational\", \"65\"], "
+    "\"mobileQciCosCountList\": [[\"conversational\", 11], [\"65\", 122]], "
+    "\"durConnectionFailedStatus\": 12, "
+    "\"durTunnelFailedStatus\": 13, "
+    "\"flowActivatedBy\": \"Remote\", "
+    "\"flowActivationTime\": \"Fri, 05 Aug 2016 15:03:43 +0000\", "
+    "\"flowDeactivatedBy\": \"Remote\", "
+    "\"gtpConnectionStatus\": \"Connected\", "
+    "\"gtpTunnelStatus\": \"Not tunneling\", "
+    "\"largePacketRtt\": 80, "
+    "\"largePacketThreshold\": 600.000000, "
+    "\"maxReceiveBitRate\": 1357924680, "
+    "\"maxTransmitBitRate\": 235711, "
+    "\"numGtpEchoFailures\": 1, "
+    "\"numGtpTunnelErrors\": 4, "
+    "\"numHttpErrors\": 2"
+    "}, "
+    "\"ipProtocolType\": \"UDP\", "
+    "\"ipVersion\": \"IPv6\", "
+    "\"otherEndpointIpAddress\": \"2.3.4.2\", "
+    "\"otherEndpointPort\": 2342, "
+    "\"reportingEndpointIpAddr\": \"4.2.3.2\", "
+    "\"reportingEndpointPort\": 4322, "
+    "\"applicationType\": \"Demo application\", "
+    "\"appProtocolType\": \"GSM\", "
+    "\"appProtocolVersion\": \"1\", "
+    "\"cid\": \"65535\", "
+    "\"connectionType\": \"S1-U\", "
+    "\"ecgi\": \"e65535\", "
+    "\"gtpProtocolType\": \"GTP-U\", "
+    "\"gtpVersion\": \"1\", "
+    "\"httpHeader\": \"http://www.something.com\", "
+    "\"imei\": \"209917614823\", "
+    "\"imsi\": \"355251/05/850925/8\", "
+    "\"lac\": \"1\", "
+    "\"mcc\": \"410\", "
+    "\"mnc\": \"04\", "
+    "\"msisdn\": \"6017123456789\", "
+    "\"otherFunctionalRole\": \"MME\", "
+    "\"rac\": \"514\", "
+    "\"radioAccessTechnology\": \"LTE\", "
+    "\"sac\": \"1\", "
+    "\"samplingAlgorithm\": 1, "
+    "\"tac\": \"2099\", "
+    "\"tunnelId\": \"Tunnel 1\", "
+    "\"vlanId\": \"15\""
+    "}}}";
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  MOBILE_GTP_PER_FLOW_METRICS * metrics = NULL;
+  EVENT_MOBILE_FLOW * mobile_flow = NULL;
+
+  /***************************************************************************/
+  /* Mobile.                                                                 */
+  /***************************************************************************/
+  evel_set_next_event_sequence(1242);
+
+  metrics = evel_new_mobile_gtp_flow_metrics(132.0001,
+                                             31.2,
+                                             101,
+                                             2101,
+                                             501,
+                                             1470409422,
+                                             988,
+                                             1470409432,
+                                             12,
+                                             (time_t)1470409432,
+                                             "Inactive",
+                                             88,
+                                             4,
+                                             18,
+                                             123655,
+                                             4562,
+                                             1,
+                                             13,
+                                             11,
+                                             2,
+                                             4,
+                                             8,
+                                             900,
+                                             902,
+                                             303,
+                                             7,
+                                             3,
+                                             1,
+                                             111,
+                                             226);
+  assert(metrics != NULL);
+
+  evel_mobile_gtp_metrics_dur_con_fail_set(metrics, 12);
+  evel_mobile_gtp_metrics_dur_tun_fail_set(metrics, 13);
+  evel_mobile_gtp_metrics_act_by_set(metrics, "Remote");
+  evel_mobile_gtp_metrics_act_time_set(metrics, (time_t)1470409423);
+  evel_mobile_gtp_metrics_deact_by_set(metrics, "Remote");
+  evel_mobile_gtp_metrics_con_status_set(metrics, "Connected");
+  evel_mobile_gtp_metrics_tun_status_set(metrics, "Not tunneling");
+  evel_mobile_gtp_metrics_iptos_set(metrics, 1, 13);
+  evel_mobile_gtp_metrics_iptos_set(metrics, 17, 1);
+  evel_mobile_gtp_metrics_iptos_set(metrics, 4, 99);
+  evel_mobile_gtp_metrics_large_pkt_rtt_set(metrics, 80);
+  evel_mobile_gtp_metrics_large_pkt_thresh_set(metrics, 600.0);
+  evel_mobile_gtp_metrics_max_rcv_bit_rate_set(metrics, 1357924680);
+  evel_mobile_gtp_metrics_max_trx_bit_rate_set(metrics, 235711);
+  evel_mobile_gtp_metrics_num_echo_fail_set(metrics, 1);
+  evel_mobile_gtp_metrics_num_tun_fail_set(metrics, 4);
+  evel_mobile_gtp_metrics_num_http_errors_set(metrics, 2);
+  evel_mobile_gtp_metrics_tcp_flag_count_add(metrics, EVEL_TCP_CWR, 10);
+  evel_mobile_gtp_metrics_tcp_flag_count_add(metrics, EVEL_TCP_URG, 121);
+  evel_mobile_gtp_metrics_qci_cos_count_add(
+                                metrics, EVEL_QCI_COS_UMTS_CONVERSATIONAL, 11);
+  evel_mobile_gtp_metrics_qci_cos_count_add(
+                                            metrics, EVEL_QCI_COS_LTE_65, 122);
+
+  mobile_flow = evel_new_mobile_flow("Inbound",
+                                     metrics,
+                                     "UDP",
+                                     "IPv6",
+                                     "2.3.4.2",
+                                     2342,
+                                     "4.2.3.2",
+                                     4322);
+  assert(mobile_flow != NULL);
+
+  evel_mobile_flow_type_set(mobile_flow, "Mobile flow...");
+  evel_mobile_flow_app_type_set(mobile_flow, "Demo application");
+  evel_mobile_flow_app_prot_type_set(mobile_flow, "GSM");
+  evel_mobile_flow_app_prot_ver_set(mobile_flow, "1");
+  evel_mobile_flow_cid_set(mobile_flow, "65535");
+  evel_mobile_flow_con_type_set(mobile_flow, "S1-U");
+  evel_mobile_flow_ecgi_set(mobile_flow, "e65535");
+  evel_mobile_flow_gtp_prot_type_set(mobile_flow, "GTP-U");
+  evel_mobile_flow_gtp_prot_ver_set(mobile_flow, "1");
+  evel_mobile_flow_http_header_set(mobile_flow,
+                                   "http://www.something.com");
+  evel_mobile_flow_imei_set(mobile_flow, "209917614823");
+  evel_mobile_flow_imsi_set(mobile_flow, "355251/05/850925/8");
+  evel_mobile_flow_lac_set(mobile_flow, "1");
+  evel_mobile_flow_mcc_set(mobile_flow, "410");
+  evel_mobile_flow_mnc_set(mobile_flow, "04");
+  evel_mobile_flow_msisdn_set(mobile_flow, "6017123456789");
+  evel_mobile_flow_other_func_role_set(mobile_flow, "MME");
+  evel_mobile_flow_rac_set(mobile_flow, "514");
+  evel_mobile_flow_radio_acc_tech_set(mobile_flow, "LTE");
+  evel_mobile_flow_sac_set(mobile_flow, "1");
+  evel_mobile_flow_samp_alg_set(mobile_flow, 1);
+  evel_mobile_flow_tac_set(mobile_flow, "2099");
+  evel_mobile_flow_tunnel_id_set(mobile_flow, "Tunnel 1");
+  evel_mobile_flow_vlan_id_set(mobile_flow, "15");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) mobile_flow);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Mobile");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(mobile_flow);
+}
+
+void test_encode_report()
+{
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"measurementsForVfReporting\", "
+    "\"eventId\": \"125\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 125, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2, "
+    "\"eventType\": \"Perf reporting...\", "
+    "\"reportingEntityId\": \"Dummy VM UUID - No Metadata available\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}, "
+    "\"measurementsForVfReportingFields\": "
+    "{\"measurementInterval\": 1.100000, "
+    "\"featureUsageArray\": ["
+    "{\"featureIdentifier\": \"FeatureA\", "
+    "\"featureUtilization\": 123}, "
+    "{\"featureIdentifier\": \"FeatureB\", "
+    "\"featureUtilization\": 567}], "
+    "\"additionalMeasurements\": ["
+    "{\"name\": \"Group1\", "
+    "\"measurements\": ["
+    "{\"name\": \"Name1\", "
+    "\"value\": \"Value1\"}]}, "
+    "{\"name\": \"Group2\", "
+    "\"measurements\": ["
+    "{\"name\": \"Name1\", "
+    "\"value\": \"Value1\"}, "
+    "{\"name\": \"Name2\", "
+    "\"value\": \"Value2\"}]}], "
+    "\"measurementFieldsVersion\": 1.1}}}";
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_REPORT * report = NULL;
+
+  /***************************************************************************/
+  /* Report.                                                                 */
+  /***************************************************************************/
+  evel_set_next_event_sequence(125);
+  report = evel_new_report(1.1);
+  assert(report != NULL);
+  evel_report_type_set(report, "Perf reporting...");
+  evel_report_feature_use_add(report, "FeatureA", 123);
+  evel_report_feature_use_add(report, "FeatureB", 567);
+  evel_report_custom_measurement_add(report, "Group1", "Name1", "Value1");
+  evel_report_custom_measurement_add(report, "Group2", "Name1", "Value1");
+  evel_report_custom_measurement_add(report, "Group2", "Name2", "Value2");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) report);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Report");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(report);
+}
+
+void test_encode_service()
+{
+  test_encode_service_subset(SERVICE_NONE);
+  test_encode_service_subset(SERVICE_CODEC);
+  test_encode_service_subset(SERVICE_TRANSCODING);
+  test_encode_service_subset(SERVICE_RTCP);
+  test_encode_service_subset(SERVICE_EOC_VQM);
+  test_encode_service_subset(SERVICE_MARKER);
+}
+
+void test_encode_service_subset(const SERVICE_TEST service_test)
+{
+  char * expected_start =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"serviceEvents\", "
+    "\"eventId\": \"2000\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 2000, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2, "
+    "\"eventType\": \"Service Event\", "
+    "\"reportingEntityId\": \"Dummy VM UUID - No Metadata available\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}, "
+    "\"serviceEventsFields\": {"
+    "\"eventInstanceIdentifier\": "
+    "{"
+    "\"vendorId\": \"vendor_x_id\", "
+    "\"eventId\": \"vendor_x_event_id\", "
+    "\"productId\": \"vendor_x_product_id\", "
+    "\"subsystemId\": \"vendor_x_subsystem_id\", "
+    "\"eventFriendlyName\": \"vendor_x_frieldly_name\""
+    "}, "
+    "\"serviceEventsFieldsVersion\": 1.1, "
+    "\"correlator\": \"vendor_x_correlator\", "
+    "\"additionalFields\": ["
+    "{\"name\": \"Name1\", \"value\": \"Value1\"}, "
+    "{\"name\": \"Name2\", \"value\": \"Value2\"}, "
+    "{\"name\": \"Name3\", \"value\": \"Value3\"}, "
+    "{\"name\": \"Name4\", \"value\": \"Value4\"}]";
+  char * expected_codec =
+    ", "
+    "\"codecSelected\": {"
+    "\"codec\": \"PCMA\""
+    "}";
+  char * expected_transcoding =
+    ", "
+    "\"codecSelectedTranscoding\": {"
+    "\"calleeSideCodec\": \"PCMA\", "
+    "\"callerSideCodec\": \"G729A\""
+    "}";
+  char * expected_rtcp =
+    ", "
+    "\"midCallRtcp\": {"
+    "\"rtcpData\": \"some_rtcp_data\""
+    "}";
+  char * expected_eoc_vqm =
+    ", "
+    "\"endOfCallVqmSummaries\": {"
+    "\"adjacencyName\": \"vendor_x_adjacency\", "
+    "\"endpointDescription\": \"Caller\", "
+    "\"endpointJitter\": 66, "
+    "\"endpointRtpOctetsDiscarded\": 100, "
+    "\"endpointRtpOctetsReceived\": 200, "
+    "\"endpointRtpOctetsSent\": 300, "
+    "\"endpointRtpPacketsDiscarded\": 400, "
+    "\"endpointRtpPacketsReceived\": 500, "
+    "\"endpointRtpPacketsSent\": 600, "
+    "\"localJitter\": 99, "
+    "\"localRtpOctetsDiscarded\": 150, "
+    "\"localRtpOctetsReceived\": 250, "
+    "\"localRtpOctetsSent\": 350, "
+    "\"localRtpPacketsDiscarded\": 450, "
+    "\"localRtpPacketsReceived\": 550, "
+    "\"localRtpPacketsSent\": 650, "
+    "\"mosCqe\": 12.255000, "
+    "\"packetsLost\": 157, "
+    "\"packetLossPercent\": 0.232000, "
+    "\"rFactor\": 11, "
+    "\"roundTripDelay\": 15"
+    "}";
+  char * expected_marker =
+    ", "
+    "\"marker\": {"
+    "\"phoneNumber\": \"0888888888\""
+    "}";
+  char * expected_end =
+    "}}}";
+
+  char * expected_middle = NULL;
+  switch (service_test)
+  {
+    case SERVICE_NONE:
+      expected_middle = "";
+      break;
+    case SERVICE_CODEC:
+      expected_middle = expected_codec;
+      break;
+    case SERVICE_TRANSCODING:
+      expected_middle = expected_transcoding;
+      break;
+    case SERVICE_RTCP:
+      expected_middle = expected_rtcp;
+      break;
+    case SERVICE_EOC_VQM:
+      expected_middle = expected_eoc_vqm;
+      break;
+    case SERVICE_MARKER:
+      expected_middle = expected_marker;
+      break;
+  }
+  assert(expected_middle != NULL);
+
+  int offset = 0;
+  char expected[EVEL_MAX_JSON_BODY];
+  offset = snprintf(expected + offset,
+                    EVEL_MAX_JSON_BODY - offset,
+                    "%s%s%s",
+                    expected_start,
+                    expected_middle,
+                    expected_end);
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_SGNALING * event = NULL;
+  evel_set_next_event_sequence(2000);
+  event = evel_new_signaling("vendor_x_id",
+           "correlator", "1.0.3.1", "1234", "192.168.1.3","3456");
+  assert(event != NULL);
+  evel_signaling_type_set(event, "Signaling");
+  evel_signaling_correlator_set(event, "vendor_x_correlator");
+  evel_signaling_vnfmodule_name_set(event, "vendor_x_module");
+  evel_signaling_vnfname_set(event, "vendor_x_vnf");
+
+  switch (service_test)
+  {
+    case SERVICE_NONE:
+      break;
+    case SERVICE_CODEC:
+      evel_signaling_addl_info_add(event, "codec", "PCMA");
+      break;
+    case SERVICE_TRANSCODING:
+      evel_signaling_addl_info_add(event, "calleecodec", "PCMA");
+      evel_signaling_addl_info_add(event, "callercodec", "G729A");
+      break;
+    case SERVICE_RTCP:
+      evel_signaling_addl_info_add(event, "rtcpdata", "abcdefgh");
+      break;
+    case SERVICE_EOC_VQM:
+      evel_signaling_addl_info_add(event, "adjacency", "vendor_x");
+      /*evel_service_adjacency_name_set(event, "vendor_x_adjacency");
+      evel_service_endpoint_desc_set(event, EVEL_SERVICE_ENDPOINT_CALLER);
+      evel_service_endpoint_jitter_set(event, 66);
+      evel_service_endpoint_rtp_oct_disc_set(event, 100);
+      evel_service_endpoint_rtp_oct_recv_set(event, 200);
+      evel_service_endpoint_rtp_oct_sent_set(event, 300);
+      evel_service_endpoint_rtp_pkt_disc_set(event, 400);
+      evel_service_endpoint_rtp_pkt_recv_set(event, 500);
+      evel_service_endpoint_rtp_pkt_sent_set(event, 600);
+      evel_service_local_jitter_set(event, 99);
+      evel_service_local_rtp_oct_disc_set(event, 150);
+      evel_service_local_rtp_oct_recv_set(event, 250);
+      evel_service_local_rtp_oct_sent_set(event, 350);
+      evel_service_local_rtp_pkt_disc_set(event, 450);
+      evel_service_local_rtp_pkt_recv_set(event, 550);
+      evel_service_local_rtp_pkt_sent_set(event, 650);
+      evel_service_mos_cqe_set(event, 12.255);
+      evel_service_packets_lost_set(event, 157);
+      evel_service_packet_loss_percent_set(event, 0.232);
+      evel_service_r_factor_set(event, 11);
+      evel_service_round_trip_delay_set(event, 15);*/
+      break;
+    case SERVICE_MARKER:
+      evel_signaling_addl_info_add(event, "service_phone", "0888888888");
+      break;
+  }
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) event);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Service");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(event);
+}
+
+void test_encode_signaling()
+{
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"signaling\", "
+    "\"eventId\": \"2001\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 2001, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2, "
+    "\"eventType\": \"Signaling\", "
+    "\"reportingEntityId\": \"Dummy VM UUID - No Metadata available\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}, "
+    "\"signalingFields\": {"
+    "\"eventInstanceIdentifier\": "
+    "{"
+    "\"vendorId\": \"vendor_x_id\", "
+    "\"eventId\": \"vendor_x_event_id\", "
+    "\"productId\": \"vendor_x_product_id\", "
+    "\"subsystemId\": \"vendor_x_subsystem_id\", "
+    "\"eventFriendlyName\": \"vendor_x_frieldly_name\""
+    "}, "
+    "\"signalingFieldsVersion\": 1.1, "
+    "\"correlator\": \"vendor_x_correlator\", "
+    "\"localIpAddress\": \"1.0.3.1\", "
+    "\"localPort\": \"1031\", "
+    "\"remoteIpAddress\": \"5.3.3.0\", "
+    "\"remotePort\": \"5330\", "
+    "\"compressedSip\": \"compressed_sip\", "
+    "\"summarySip\": \"summary_sip\""
+    "}}}";
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_SIGNALING * event = NULL;
+  evel_set_next_event_sequence(2001);
+  event = evel_new_signaling("vendor_x_id",
+           "correlator", "1.0.3.1", "1234", "192.168.1.3","3456");
+  assert(event != NULL);
+  evel_signaling_vnfmodule_name_set(event, "vendor_x_module");
+  evel_signaling_vnfname_set(event, "vendor_x_vnf");
+  evel_signaling_type_set(event, "Signaling");
+  evel_signaling_product_id_set(event, "vendor_x_product_id");
+  evel_signaling_subsystem_id_set(event, "vendor_x_subsystem_id");
+  evel_signaling_friendly_name_set(event, "vendor_x_frieldly_name");
+  evel_signaling_correlator_set(event, "vendor_x_correlator");
+  evel_signaling_local_ip_address_set(event, "1.0.3.1");
+  evel_signaling_local_port_set(event, "1031");
+  evel_signaling_remote_ip_address_set(event, "5.3.3.0");
+  evel_signaling_remote_port_set(event, "5330");
+  evel_signaling_compressed_sip_set(event, "compressed_sip");
+  evel_signaling_summary_sip_set(event, "summary_sip");
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) event);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Signaling");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(event);
+}
+
+void test_encode_state_change()
+{
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"stateChange\", "
+    "\"eventId\": \"128\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 128, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2, "
+    "\"eventType\": \"SC Type\", "
+    "\"reportingEntityId\": \"Dummy VM UUID - No Metadata available\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}, "
+    "\"stateChangeFields\": {"
+    "\"newState\": \"inService\", "
+    "\"oldState\": \"outOfService\", "
+    "\"stateInterface\": \"An Interface\", "
+    "\"additionalFields\": ["
+    "{\"name\": \"Name1\", "
+    "\"value\": \"Value1\"}, "
+    "{\"name\": \"Name2\", "
+    "\"value\": \"Value2\"}"
+    "], "
+    "\"stateChangeFieldsVersion\": 1.1"
+    "}}}";
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_STATE_CHANGE * state_change = NULL;
+  evel_set_next_event_sequence(128);
+  state_change = evel_new_state_change(EVEL_ENTITY_STATE_IN_SERVICE,
+                                       EVEL_ENTITY_STATE_OUT_OF_SERVICE,
+                                       "An Interface");
+  assert(state_change != NULL);
+  evel_state_change_type_set(state_change, "SC Type");
+  evel_state_change_addl_field_add(state_change, "Name1", "Value1");
+  evel_state_change_addl_field_add(state_change, "Name2", "Value2");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) state_change);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "StateChange");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(state_change);
+}
+
+void test_encode_syslog()
+{
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"syslog\", "
+    "\"eventId\": \"126\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 126, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2, "
+    "\"eventType\": \"SL Type\", "
+    "\"reportingEntityId\": \"Dummy VM UUID - No Metadata available\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}, "
+    "\"syslogFields\": {"
+    "\"eventSourceType\": \"virtualNetworkFunction\", "
+    "\"syslogMsg\": \"SL Message\", "
+    "\"syslogTag\": \"SL Tag\", "
+    "\"syslogFieldsVersion\": 1.1, "
+    "\"eventSourceHost\": \"SL Host\", "
+    "\"syslogFacility\": 6, "
+    "\"syslogProc\": \"SL Proc\", "
+    "\"syslogProcId\": 2, "
+    "\"syslogSData\": \"SL SDATA\", "
+    "\"syslogVer\": 1"
+    "}}}";
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_SYSLOG * syslog = NULL;
+  evel_set_next_event_sequence(126);
+  syslog = evel_new_syslog(EVEL_SOURCE_VIRTUAL_NETWORK_FUNCTION,
+                           "SL Message",
+                           "SL Tag");
+  assert(syslog != NULL);
+  evel_syslog_type_set(syslog, "SL Type");
+  evel_syslog_event_source_host_set(syslog, "SL Host");
+  evel_syslog_facility_set(syslog, EVEL_SYSLOG_FACILITY_LINE_PRINTER);
+  evel_syslog_proc_set(syslog, "SL Proc");
+  evel_syslog_proc_id_set(syslog, 2);
+  evel_syslog_version_set(syslog, 1);
+  evel_syslog_s_data_set(syslog, "SL SDATA");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) syslog);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Syslog");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(syslog);
+}
+
+void test_encode_other()
+{
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"other\", "
+    "\"eventId\": \"129\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 129, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2, "
+    "\"eventType\": \"Other Type\", "
+    "\"reportingEntityId\": \"Dummy VM UUID - No Metadata available\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}, "
+    "\"otherFields\": ["
+    "{\"name\": \"Other field 1\", "
+    "\"value\": \"Other value 1\"}, "
+    "{\"name\": \"Other field 2\", "
+    "\"value\": \"Other value 2\"}"
+    "]"
+    "}}";
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_OTHER * other = NULL;
+  evel_set_next_event_sequence(129);
+  other = evel_new_other();
+  assert(other != NULL);
+  evel_other_type_set(other, "Other Type");
+  evel_other_field_add(other,
+                       "Other field 1",
+                       "Other value 1");
+  evel_other_field_add(other,
+                       "Other field 2",
+                       "Other value 2");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) other);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Other");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(other);
+}
+
+void compare_strings(char * expected,
+                     char * actual,
+                     int max_size,
+                     char * description)
+{
+  if (strncmp(expected, actual, max_size) != 0)
+  {
+    int diff = 0;
+    while (diff < max_size)
+    {
+      if (expected[diff] != actual[diff])
+      {
+        break;
+      }
+      diff++;
+    }
+
+    printf("Comparison Failure at Offset %d\n\n", diff);
+    printf("Expected:\n%s\n", expected);
+    printf("Actual:\n%s\n", actual);
+    printf("Description: %s\n", description);
+    assert(0);
+  }
+}
+
+/**************************************************************************//**
+ * Copy a json string to a ::MEMORY_CHUNK for testing.
+ *
+ * @param chunk         The memory chunk.
+ * @param string        The json string.
+ *****************************************************************************/
+void copy_string_to_chunk(MEMORY_CHUNK * chunk, char * string)
+{
+  int mem_size;
+
+  /***************************************************************************/
+  /* Check preconditions.                                                    */
+  /***************************************************************************/
+  assert(chunk != NULL);
+  assert(string != NULL);
+
+  mem_size = strlen(string) + 1;
+  chunk->memory = malloc(mem_size);
+  memcpy(chunk->memory, string, mem_size);
+  chunk->size = mem_size;
+}
+
+/**************************************************************************//**
+ * Copy a json string to a ::MEMORY_CHUNK for testing.
+ *
+ * @param json          The JSON string.
+ * @param post          Memory chunk to post a response.
+ *****************************************************************************/
+void handle_json_response(char * json, MEMORY_CHUNK * post)
+{
+  MEMORY_CHUNK chunk;
+  post->memory = NULL;
+  post->size = 0;
+  copy_string_to_chunk(&chunk, json);
+  evel_handle_event_response(&chunk, post);
+  free(chunk.memory);
+}
+
+/**************************************************************************//**
+ * Test that a non-"commandList" JSON buffer leaves the throttle state off.
+ *****************************************************************************/
+void test_json_response_junk()
+{
+  MEMORY_CHUNK post;
+  int domain;
+  char * json_junk =
+    "{"
+    "\"junk1\": ["
+    "\"1\", \"2\", \"3\"], "
+    "\"junk2\": ["
+    "\"1\", \"2\", \"3\"]"
+    "}";
+
+  evel_throttle_initialize();
+  handle_json_response(json_junk, &post);
+
+  /***************************************************************************/
+  /* Check that all domains are not throttled.                               */
+  /***************************************************************************/
+  for (domain = EVEL_DOMAIN_FAULT; domain < EVEL_MAX_DOMAINS; domain++)
+  {
+    assert(evel_get_throttle_spec(domain) == NULL);
+  }
+
+  /***************************************************************************/
+  /* Check that we generated no post.                                        */
+  /***************************************************************************/
+  assert(post.memory == NULL);
+
+  evel_throttle_terminate();
+}
+
+char * json_command_list_provide =
+  "{"
+  "\"commandList\": ["
+  "{"
+  "\"command\": {"
+  "\"commandType\": \"provideThrottlingState\""
+  "}"
+  "}"
+  "]"
+  "}";
+
+char * json_command_list_fault_clear =
+  "{"
+  "\"commandList\": ["
+  "{"
+  "\"command\": {"
+  "\"commandType\": \"throttlingSpecification\", "
+  "\"eventDomainThrottleSpecification\": {"
+  "\"eventDomain\": \"fault\""
+  "}"
+  "}"
+  "}"
+  "]"
+  "}";
+
+char * json_command_list_syslog_clear =
+  "{"
+  "\"commandList\": ["
+  "{"
+  "\"command\": {"
+  "\"commandType\": \"throttlingSpecification\", "
+  "\"eventDomainThrottleSpecification\": {"
+  "\"eventDomain\": \"syslog\""
+  "}"
+  "}"
+  "}"
+  "]"
+  "}";
+
+char * expected_throttle_state_normal =
+  "{"
+  "\"eventThrottlingState\": {"
+  "\"eventThrottlingMode\": \"normal\"}"
+  "}";
+
+/**************************************************************************//**
+ * Test that we can return the default throttling state.
+ *****************************************************************************/
+void test_json_provide_throttle_state()
+{
+  MEMORY_CHUNK post;
+  int domain;
+
+  char * expected_post = expected_throttle_state_normal;
+
+  evel_throttle_initialize();
+  handle_json_response(json_command_list_provide, &post);
+
+  /***************************************************************************/
+  /* Check that all domains are not throttled.                               */
+  /***************************************************************************/
+  for (domain = EVEL_DOMAIN_FAULT; domain < EVEL_MAX_DOMAINS; domain++)
+  {
+    assert(evel_get_throttle_spec(domain) == NULL);
+  }
+
+  /***************************************************************************/
+  /* Check that we generated a throttling specification post.                */
+  /***************************************************************************/
+  assert(post.memory != NULL);
+  compare_strings(expected_post, post.memory, strlen(expected_post),
+                  "Throttle State Normal");
+  free(post.memory);
+
+  evel_throttle_terminate();
+}
+
+/**************************************************************************//**
+ * Test the measurement interval handling and API.
+ *****************************************************************************/
+void test_json_measurement_interval()
+{
+  MEMORY_CHUNK post;
+  char * json_command_list_interval_only =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"measurementInterval\": 60"
+    "}"
+    "}"
+    "]"
+    "}";
+
+  char * json_command_list_interval_first =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"measurementInterval\": 30, "
+    "\"commandType\": \"measurementIntervalChange\""
+    "}"
+    "}"
+    "]"
+    "}";
+
+  char * json_command_list_command_first =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"measurementIntervalChange\", "
+    "\"measurementInterval\": 60"
+    "}"
+    "}"
+    "]"
+    "}";
+
+  evel_throttle_initialize();
+  assert(evel_get_measurement_interval() == EVEL_MEASUREMENT_INTERVAL_UKNOWN);
+
+  /***************************************************************************/
+  /* Check that we're not handling stuff when we shouldn't.                  */
+  /***************************************************************************/
+  handle_json_response(json_command_list_interval_only, &post);
+  assert(post.memory == NULL);
+  assert(evel_get_measurement_interval() == EVEL_MEASUREMENT_INTERVAL_UKNOWN);
+
+  /***************************************************************************/
+  /* Check that we're OK with the interval coming first.                     */
+  /***************************************************************************/
+  handle_json_response(json_command_list_interval_first, &post);
+  assert(post.memory == NULL);
+  assert(evel_get_measurement_interval() == 30);
+
+  /***************************************************************************/
+  /* Check that we're OK with the command type coming first.                 */
+  /***************************************************************************/
+  handle_json_response(json_command_list_command_first, &post);
+  assert(post.memory == NULL);
+  assert(evel_get_measurement_interval() == 60);
+
+  evel_throttle_terminate();
+}
+
+/**************************************************************************//**
+ * Test a single domain, single field suppression.
+ *****************************************************************************/
+void test_json_throttle_spec_field()
+{
+  MEMORY_CHUNK post;
+  int domain;
+
+  char * json_command_list_fault_single =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"]"
+    "}"
+    "}"
+    "}"
+    "]"
+    "}";
+
+  char * json_command_list_fault_double =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": ["
+    "\"alarmInterfaceA\", \"alarmAdditionalInformation\"]"
+    "}"
+    "}"
+    "}"
+    "]"
+    "}";
+
+  char * expected_post_fault_single =
+    "{"
+    "\"eventThrottlingState\": {"
+    "\"eventThrottlingMode\": \"throttled\", "
+    "\"eventDomainThrottleSpecificationList\": ["
+    "{"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"]"
+    "}"
+    "]"
+    "}"
+    "}";
+
+  char * expected_post_fault_double =
+    "{"
+    "\"eventThrottlingState\": {"
+    "\"eventThrottlingMode\": \"throttled\", "
+    "\"eventDomainThrottleSpecificationList\": ["
+    "{"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": ["
+    "\"alarmInterfaceA\", \"alarmAdditionalInformation\"]"
+    "}"
+    "]"
+    "}"
+    "}";
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single fault suppressed.  */
+  /***************************************************************************/
+  evel_throttle_initialize();
+  handle_json_response(json_command_list_fault_single, &post);
+
+  /***************************************************************************/
+  /* Check that the FAULT domain is throttled.                               */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_FAULT) != NULL);
+  for (domain = EVEL_DOMAIN_MEASUREMENT; domain < EVEL_MAX_DOMAINS; domain++)
+  {
+    if (domain != EVEL_DOMAIN_FAULT)
+    {
+      assert(evel_get_throttle_spec(domain) == NULL);
+    }
+  }
+  assert(post.memory == NULL);
+
+  /***************************************************************************/
+  /* Request and verify the throttling state.                                */
+  /***************************************************************************/
+  handle_json_response(json_command_list_provide, &post);
+  assert(post.memory != NULL);
+  compare_strings(expected_post_fault_single,
+                  post.memory,
+                  strlen(expected_post_fault_single),
+                  "Fault - Single Field");
+  free(post.memory);
+  post.memory = NULL;
+
+  /***************************************************************************/
+  /* Update a specification with two faults suppressed.                      */
+  /***************************************************************************/
+  handle_json_response(json_command_list_fault_double, &post);
+
+  /***************************************************************************/
+  /* Check that the FAULT domain is throttled.                               */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_FAULT) != NULL);
+  for (domain = EVEL_DOMAIN_MEASUREMENT; domain < EVEL_MAX_DOMAINS; domain++)
+  {
+    if (domain != EVEL_DOMAIN_FAULT)
+    {
+      assert(evel_get_throttle_spec(domain) == NULL);
+    }
+  }
+  assert(post.memory == NULL);
+
+  /***************************************************************************/
+  /* Request and verify the throttling state.                                */
+  /***************************************************************************/
+  handle_json_response(json_command_list_provide, &post);
+  assert(post.memory != NULL);
+  compare_strings(expected_post_fault_double,
+                  post.memory,
+                  strlen(expected_post_fault_double),
+                  "Fault - Double Field");
+  free(post.memory);
+  post.memory = NULL;
+
+  /***************************************************************************/
+  /* Now clear the FAULT domain.                                             */
+  /***************************************************************************/
+  handle_json_response(json_command_list_fault_clear, &post);
+  for (domain = EVEL_DOMAIN_FAULT; domain < EVEL_MAX_DOMAINS; domain++)
+  {
+    assert(evel_get_throttle_spec(domain) == NULL);
+  }
+
+  evel_throttle_terminate();
+}
+
+/**************************************************************************//**
+ * Test a single domain, nv_pair suppression.
+ *****************************************************************************/
+void test_json_throttle_spec_nv_pair()
+{
+  MEMORY_CHUNK post;
+  int domain;
+
+  char * json_command_list_fault_pair_single =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}"
+    "]"
+    "}"
+    "}"
+    "}"
+    "]"
+    "}";
+
+  char * json_command_list_fault_pair_double =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\", \"name2\"]"
+    "}"
+    "]"
+    "}"
+    "}"
+    "}"
+    "]"
+    "}";
+
+  char * expected_post_fault_pair_single =
+    "{"
+    "\"eventThrottlingState\": {"
+    "\"eventThrottlingMode\": \"throttled\", "
+    "\"eventDomainThrottleSpecificationList\": ["
+    "{"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}"
+    "]"
+    "}"
+    "]"
+    "}"
+    "}";
+
+  char * expected_post_fault_pair_double =
+    "{"
+    "\"eventThrottlingState\": {"
+    "\"eventThrottlingMode\": \"throttled\", "
+    "\"eventDomainThrottleSpecificationList\": ["
+    "{"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\", \"name2\"]"
+    "}"
+    "]"
+    "}"
+    "]"
+    "}"
+    "}";
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single nvpair with a      */
+  /* single sub-field suppressed.                                            */
+  /***************************************************************************/
+  evel_throttle_initialize();
+  handle_json_response(json_command_list_fault_pair_single, &post);
+
+  /***************************************************************************/
+  /* Check that the FAULT domain is throttled.                               */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_FAULT) != NULL);
+  for (domain = EVEL_DOMAIN_MEASUREMENT; domain < EVEL_MAX_DOMAINS; domain++)
+  {
+    if (domain != EVEL_DOMAIN_FAULT)
+    {
+      assert(evel_get_throttle_spec(domain) == NULL);
+    }
+  }
+  assert(post.memory == NULL);
+
+  /***************************************************************************/
+  /* Request and verify the throttling state.                                */
+  /***************************************************************************/
+  handle_json_response(json_command_list_provide, &post);
+  assert(post.memory != NULL);
+  compare_strings(expected_post_fault_pair_single,
+                  post.memory,
+                  strlen(expected_post_fault_pair_single),
+                  "Fault - Single Pair, Single Field");
+  free(post.memory);
+  post.memory = NULL;
+
+  /***************************************************************************/
+  /* Update a specification with a single nvpair with two sub-fields         */
+  /* suppressed.                                                             */
+  /***************************************************************************/
+  handle_json_response(json_command_list_fault_pair_double, &post);
+
+  /***************************************************************************/
+  /* Check that the FAULT domain is throttled.                               */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_FAULT) != NULL);
+  for (domain = EVEL_DOMAIN_MEASUREMENT; domain < EVEL_MAX_DOMAINS; domain++)
+  {
+    if (domain != EVEL_DOMAIN_FAULT)
+    {
+      assert(evel_get_throttle_spec(domain) == NULL);
+    }
+  }
+  assert(post.memory == NULL);
+
+  /***************************************************************************/
+  /* Request and verify the throttling state.                                */
+  /***************************************************************************/
+  handle_json_response(json_command_list_provide, &post);
+  assert(post.memory != NULL);
+  compare_strings(expected_post_fault_pair_double,
+                  post.memory,
+                  strlen(expected_post_fault_pair_double),
+                  "Fault - Double Field");
+  free(post.memory);
+  post.memory = NULL;
+
+  /***************************************************************************/
+  /* Now clear the FAULT domain.                                             */
+  /***************************************************************************/
+  handle_json_response(json_command_list_fault_clear, &post);
+  for (domain = EVEL_DOMAIN_FAULT; domain < EVEL_MAX_DOMAINS; domain++)
+  {
+    assert(evel_get_throttle_spec(domain) == NULL);
+  }
+
+  evel_throttle_terminate();
+}
+
+/**************************************************************************//**
+ * Test two domains, nv_pair suppression.
+ *****************************************************************************/
+void test_json_throttle_spec_two_domains()
+{
+  MEMORY_CHUNK post;
+  int domain;
+
+  char * json_command_list_two_domains =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}]}}}, "
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"syslog\", "
+    "\"suppressedFieldNames\": [\"syslogProcId\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"additionalFields\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}]}}}"
+    "]"
+    "}";
+
+  char * expected_post_two_domains =
+    "{"
+    "\"eventThrottlingState\": {"
+    "\"eventThrottlingMode\": \"throttled\", "
+    "\"eventDomainThrottleSpecificationList\": ["
+    "{"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}]}, "
+    "{"
+    "\"eventDomain\": \"syslog\", "
+    "\"suppressedFieldNames\": [\"syslogProcId\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"additionalFields\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}]}"
+    "]"
+    "}"
+    "}";
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single nvpair with a      */
+  /* single sub-field suppressed.                                            */
+  /***************************************************************************/
+  evel_throttle_initialize();
+  handle_json_response(json_command_list_two_domains, &post);
+
+  /***************************************************************************/
+  /* Check that the FAULT and SYSLOG domains are throttled.                  */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_FAULT) != NULL);
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_SYSLOG) != NULL);
+  for (domain = EVEL_DOMAIN_MEASUREMENT; domain < EVEL_MAX_DOMAINS; domain++)
+  {
+    if ((domain != EVEL_DOMAIN_FAULT) && (domain != EVEL_DOMAIN_SYSLOG))
+    {
+      assert(evel_get_throttle_spec(domain) == NULL);
+    }
+  }
+  assert(post.memory == NULL);
+
+  /***************************************************************************/
+  /* Request and verify the throttling state.                                */
+  /***************************************************************************/
+  handle_json_response(json_command_list_provide, &post);
+  assert(post.memory != NULL);
+  compare_strings(expected_post_two_domains,
+                  post.memory,
+                  strlen(expected_post_two_domains),
+                  "Fault - Two Domains");
+  free(post.memory);
+  post.memory = NULL;
+
+  /***************************************************************************/
+  /* Now clear the FAULT and SYSLOG domains.                                 */
+  /***************************************************************************/
+  handle_json_response(json_command_list_fault_clear, &post);
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_FAULT) == NULL);
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_SYSLOG) != NULL);
+  handle_json_response(json_command_list_syslog_clear, &post);
+  for (domain = EVEL_DOMAIN_FAULT; domain < EVEL_MAX_DOMAINS; domain++)
+  {
+    assert(evel_get_throttle_spec(domain) == NULL);
+  }
+
+  evel_throttle_terminate();
+}
+
+/**************************************************************************//**
+ * Test bad command type.
+ *****************************************************************************/
+void test_json_throttle_spec_bad_command_type()
+{
+  MEMORY_CHUNK post;
+  int domain;
+
+  /***************************************************************************/
+  /* Search for "dodgy" in the JSON, and you will see the dodgy bits we're   */
+  /* handling in these tests.                                                */
+  /***************************************************************************/
+  #define NUM_BAD_COMMANDS 8
+  char * json_command_list_dodgy_command =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"dodgyCommand\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}]}}}"
+    "]"
+    "}";
+
+  char * json_command_list_dodgy_spec =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"dodgyEventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}]}}}"
+    "]"
+    "}";
+
+  char * json_command_list_dodgy_event_domain_key =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"dodgyEventDomainKey\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}]}}}"
+    "]"
+    "}";
+
+  char * json_command_list_dodgy_event_domain =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"dodgyEventDomain\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}]}}}"
+    "]"
+    "}";
+
+  char * json_command_list_dodgy_field_names_key =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}]}}}"
+    "]"
+    "}";
+
+  char * json_command_list_dodgy_pair_names_list_key =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"], "
+    "\"dodgySuppressedNvPairsListKey\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}]}}}"
+    "]"
+    "}";
+
+  char * json_command_list_dodgy_pair_field_name_key =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"dodgyNvPairFieldNameKey\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}]}}}"
+    "]"
+    "}";
+
+  char * json_command_list_dodgy_pair_names_key =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"dodgySuppressedNvPairNamesKey\": [\"name1\"]"
+    "}]}}}"
+    "]"
+    "}";
+
+  char * json_command_list_dodgy_depth =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"dodgySuppressedNvPairNamesKey\": "
+    "[\"name1\", [[[[[[[[]]]]]]]]]"
+    "}]}}}"
+    "]"
+    "}";
+
+  char * expected_throttle_state_dodgy_field_names_key =
+    "{"
+    "\"eventThrottlingState\": {"
+    "\"eventThrottlingMode\": \"throttled\", "
+    "\"eventDomainThrottleSpecificationList\": ["
+    "{"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name1\"]"
+    "}]}"
+    "]"
+    "}"
+    "}";
+
+  char * expected_throttle_state_dodgy_pair_names_list_key =
+    "{"
+    "\"eventThrottlingState\": {"
+    "\"eventThrottlingMode\": \"throttled\", "
+    "\"eventDomainThrottleSpecificationList\": ["
+    "{"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"]"
+    "}"
+    "]"
+    "}"
+    "}";
+
+  char * expected_throttle_state_dodgy_pair_field_name_key =
+    "{"
+    "\"eventThrottlingState\": {"
+    "\"eventThrottlingMode\": \"throttled\", "
+    "\"eventDomainThrottleSpecificationList\": ["
+    "{"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"]"
+    "}"
+    "]"
+    "}"
+    "}";
+
+  char * expected_throttle_state_dodgy_pair_names_key =
+    "{"
+    "\"eventThrottlingState\": {"
+    "\"eventThrottlingMode\": \"throttled\", "
+    "\"eventDomainThrottleSpecificationList\": ["
+    "{"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": [\"alarmInterfaceA\"]"
+    "}"
+    "]"
+    "}"
+    "}";
+
+  char * json_command_lists[] = {
+    json_command_list_dodgy_command,
+    json_command_list_dodgy_spec,
+    json_command_list_dodgy_event_domain_key,
+    json_command_list_dodgy_event_domain,
+    json_command_list_dodgy_depth,
+    json_command_list_dodgy_field_names_key,
+    json_command_list_dodgy_pair_names_list_key,
+    json_command_list_dodgy_pair_field_name_key,
+    json_command_list_dodgy_pair_names_key
+  };
+
+  char * expected_posts[] = {
+    expected_throttle_state_normal,
+    expected_throttle_state_normal,
+    expected_throttle_state_normal,
+    expected_throttle_state_normal,
+    expected_throttle_state_normal,
+    expected_throttle_state_dodgy_field_names_key,
+    expected_throttle_state_dodgy_pair_names_list_key,
+    expected_throttle_state_dodgy_pair_field_name_key,
+    expected_throttle_state_dodgy_pair_names_key
+   };
+
+  const int num_commands =
+    sizeof(json_command_lists) / sizeof(json_command_lists[0]);
+  const int num_posts =
+    sizeof(expected_posts) / sizeof(expected_posts[0]);
+  assert(num_commands == num_posts);
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single nvpair with a      */
+  /* single sub-field suppressed.                                            */
+  /***************************************************************************/
+  evel_throttle_initialize();
+
+  int ii;
+  for (ii = 0; ii < num_commands; ii++)
+  {
+    EVEL_DEBUG("Testing commandList[%d] = %s\n", ii, json_command_lists[ii]);
+    handle_json_response(json_command_lists[ii], &post);
+
+    /*************************************************************************/
+    /* Check that throttling is in a normal state - because we ignored the   */
+    /* command / .....                                                       */
+    /*************************************************************************/
+    for (domain = EVEL_DOMAIN_MEASUREMENT; domain < EVEL_MAX_DOMAINS; domain++)
+    {
+      assert(evel_get_throttle_spec(domain) == NULL);
+    }
+    if (expected_posts[ii] == expected_throttle_state_normal)
+    {
+      assert(evel_get_throttle_spec(EVEL_DOMAIN_FAULT) == NULL);
+    }
+    else
+    {
+      assert(evel_get_throttle_spec(EVEL_DOMAIN_FAULT) != NULL);
+    }
+    assert(post.memory == NULL);
+
+    /*************************************************************************/
+    /* Request and verify the throttling state.                              */
+    /*************************************************************************/
+    handle_json_response(json_command_list_provide, &post);
+    assert(post.memory != NULL);
+    compare_strings(expected_posts[ii],
+                    post.memory,
+                    strlen(expected_posts[ii]),
+                    "Throttle State Normal");
+    free(post.memory);
+    post.memory = NULL;
+  }
+
+  evel_throttle_terminate();
+}
+
+void test_encode_fault_throttled()
+{
+  MEMORY_CHUNK post;
+
+  /***************************************************************************/
+  /* We also test suppression of the event header parameters here.           */
+  /***************************************************************************/
+  char * json_command_list =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"fault\", "
+    "\"suppressedFieldNames\": ["
+    "\"alarmInterfaceA\", "
+    "\"eventType\", "
+    "\"reportingEntityId\", "
+    "\"sourceId\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"alarmAdditionalInformation\", "
+    "\"suppressedNvPairNames\": [\"name3\", \"name4\"]"
+    "}]}}}"
+    "]"
+    "}";
+
+  char * expected =
+    "{\"event\": {"
+    "\"commonEventHeader\": {"
+    "\"domain\": \"fault\", "
+    "\"eventId\": \"122\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 122, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2"
+    "}, "
+    "\"faultFields\": {"
+    "\"alarmCondition\": \"My alarm condition\", "
+    "\"eventSeverity\": \"MAJOR\", "
+    "\"eventSourceType\": \"other\", "
+    "\"specificProblem\": \"It broke very badly\", "
+    "\"vfStatus\": \"Active\", "
+    "\"faultFieldsVersion\": 1.1, "
+    "\"alarmAdditionalInformation\": ["
+    "{\"name\": \"name1\", "
+    "\"value\": \"value1\"}, "
+    "{\"name\": \"name2\", "
+    "\"value\": \"value2\"}]"
+    "}}}";
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single fault suppressed.  */
+  /***************************************************************************/
+  evel_throttle_initialize();
+  handle_json_response(json_command_list, &post);
+
+  /***************************************************************************/
+  /* Check that the domain is throttled.                                     */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_FAULT) != NULL);
+  assert(post.memory == NULL);
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  evel_set_next_event_sequence(122);
+  EVENT_FAULT * fault = evel_new_fault("My alarm condition",
+                                       "It broke very badly",
+                                       EVEL_PRIORITY_NORMAL,
+                                       EVEL_SEVERITY_MAJOR,
+                                       EVEL_SOURCE_HOST,
+                          EVEL_VF_STATUS_PREP_TERMINATE);
+  assert(fault != NULL);
+  evel_fault_type_set(fault, "Bad things happen...");
+  evel_fault_addl_info_add(fault, "name1", "value1");
+  evel_fault_addl_info_add(fault, "name2", "value2");
+
+  /***************************************************************************/
+  /* Suppressed fields.                                                      */
+  /***************************************************************************/
+  evel_fault_interface_set(fault, "My Interface Card");
+  evel_fault_addl_info_add(fault, "name3", "value3");
+  evel_fault_addl_info_add(fault, "name4", "value4");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) fault);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Fault");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(fault);
+  evel_throttle_terminate();
+}
+
+void test_encode_measurement_throttled()
+{
+  MEMORY_CHUNK post;
+
+  /***************************************************************************/
+  /* We also test suppression of the event header parameters here.           */
+  /***************************************************************************/
+  char * json_command_list =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"measurementsForVfScaling\", "
+    "\"suppressedFieldNames\": ["
+    "\"errors\", "
+    "\"vnfcScalingMetric\", "
+    "\"numberOfMediaPortsInUse\", "
+    "\"aggregateCpuUsage\", "
+    "\"requestRate\", "
+    "\"memoryUsed\", "
+    "\"memoryConfigured\", "
+    "\"meanRequestLatency\", "
+    "\"latencyDistribution\", "
+    "\"concurrentSessions\", "
+    "\"configuredEntities\", "
+    "\"eventType\", "
+    "\"reportingEntityId\", "
+    "\"sourceId\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"cpuUsageArray\", "
+    "\"suppressedNvPairNames\": [\"cpu3\", \"cpu4\"]"
+    "}, "
+    "{"
+    "\"nvPairFieldName\": \"filesystemUsageArray\", "
+    "\"suppressedNvPairNames\": [\"00-11-22\", \"33-44-55\"]"
+    "}, "
+    "{"
+    "\"nvPairFieldName\": \"vNicUsageArray\", "
+    "\"suppressedNvPairNames\": [\"eth1\", \"eth0\"]"
+    "}, "
+    "{"
+    "\"nvPairFieldName\": \"featureUsageArray\", "
+    "\"suppressedNvPairNames\": [\"FeatureB\", \"FeatureC\"]"
+    "},"
+    "{"
+    "\"nvPairFieldName\": \"codecUsageArray\", "
+    "\"suppressedNvPairNames\": [\"G729ab\"]"
+    "},"
+    "{"
+    "\"nvPairFieldName\": \"additionalMeasurements\", "
+    "\"suppressedNvPairNames\": [\"Group2\"]"
+    "}"
+    "]}}}"
+    "]"
+    "}";
+
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"measurementsForVfScaling\", "
+    "\"eventId\": \"123\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 123, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2"
+    "}, "
+    "\"measurementsForVfScalingFields\": "
+    "{"
+    "\"measurementInterval\": 5.500000, "
+    "\"cpuUsageArray\": ["
+    "{\"cpuIdentifier\": \"cpu1\", "
+    "\"percentUsage\": 11.110000}, "
+    "{\"cpuIdentifier\": \"cpu2\", "
+    "\"percentUsage\": 22.220000}], "
+    "\"filesystemUsageArray\": ["
+    "{\"blockConfigured\": 500.110000, "
+    "\"blockIops\": 77, "
+    "\"blockUsed\": 500.220000, "
+    "\"ephemeralConfigured\": 500.110000, "
+    "\"ephemeralIops\": 88, "
+    "\"ephemeralUsed\": 600.220000, "
+    "\"filesystemName\": \"66-77-88\"}], "
+    "\"featureUsageArray\": ["
+    "{\"featureIdentifier\": \"FeatureA\", "
+    "\"featureUtilization\": 123}], "
+    "\"codecUsageArray\": ["
+    "{\"codecIdentifier\": \"G711a\", "
+    "\"numberInUse\": 91}], "
+    "\"additionalMeasurements\": ["
+    "{\"name\": \"Group1\", "
+    "\"measurements\": ["
+    "{\"name\": \"Name1\", "
+    "\"value\": \"Value1\"}]}], "
+    "\"measurementsForVfScalingVersion\": 1.1}}}";
+     MEASUREMENT_CPU_USE *cpu_use;
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single fault suppressed.  */
+  /***************************************************************************/
+  evel_throttle_initialize();
+  handle_json_response(json_command_list, &post);
+
+  /***************************************************************************/
+  /* Check that the domain is throttled.                                     */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_MEASUREMENT) != NULL);
+  assert(post.memory == NULL);
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  evel_set_next_event_sequence(123);
+  EVENT_MEASUREMENT * measurement = evel_new_measurement(5.5);
+  MEASUREMENT_LATENCY_BUCKET * bucket = NULL;
+  MEASUREMENT_VNIC_PERFORMANCE * vnic_use = NULL;
+  assert(measurement != NULL);
+
+  evel_measurement_type_set(measurement, "Perf management...");
+  evel_measurement_conc_sess_set(measurement, 1);
+  evel_measurement_cfg_ents_set(measurement, 2);
+  evel_measurement_mean_req_lat_set(measurement, 4.4);
+  evel_measurement_mem_cfg_set(measurement, 6.6);
+  evel_measurement_mem_used_set(measurement, 3.3);
+  evel_measurement_request_rate_set(measurement, 7);
+
+  cpu_use = evel_measurement_new_cpu_use_add(measurement, "cpu1", 11.11);
+  evel_measurement_cpu_use_idle_set(cpu_use,22.22);
+  evel_measurement_cpu_use_interrupt_set(cpu_use,33.33);
+  evel_measurement_cpu_use_nice_set(cpu_use,44.44);
+  evel_measurement_cpu_use_softirq_set(cpu_use,55.55);
+  evel_measurement_cpu_use_steal_set(cpu_use,66.66);
+  evel_measurement_cpu_use_system_set(cpu_use,77.77);
+  evel_measurement_cpu_use_usageuser_set(cpu_use,88.88);
+  evel_measurement_cpu_use_wait_set(cpu_use,99.99);
+
+  cpu_use = evel_measurement_new_cpu_use_add(measurement, "cpu2", 22.22);
+  evel_measurement_cpu_use_idle_set(cpu_use,12.22);
+  evel_measurement_cpu_use_interrupt_set(cpu_use,33.33);
+  evel_measurement_cpu_use_nice_set(cpu_use,44.44);
+  evel_measurement_cpu_use_softirq_set(cpu_use,55.55);
+  evel_measurement_cpu_use_steal_set(cpu_use,66.66);
+  evel_measurement_cpu_use_system_set(cpu_use,77.77);
+  evel_measurement_cpu_use_usageuser_set(cpu_use,88.88);
+  evel_measurement_cpu_use_wait_set(cpu_use,19.99);
+
+  evel_measurement_fsys_use_add(measurement, "00-11-22",
+                                100.11, 100.22, 33,
+                                200.11, 200.22, 44);
+  evel_measurement_fsys_use_add(measurement, "33-44-55",
+                                300.11, 300.22, 55,
+                                400.11, 400.22, 66);
+  evel_measurement_fsys_use_add(measurement, "66-77-88",
+                                500.11, 500.22, 77,
+                                600.11, 600.22, 88);
+
+  bucket = evel_new_meas_latency_bucket(20);
+  evel_meas_latency_bucket_add(measurement, bucket);
+
+  bucket = evel_new_meas_latency_bucket(30);
+  evel_meas_latency_bucket_low_end_set(bucket, 10.0);
+  evel_meas_latency_bucket_high_end_set(bucket, 20.0);
+  evel_meas_latency_bucket_add(measurement, bucket);
+
+  vnic_use = evel_new_measurement_vnic_use("eth0", 100, 200, 3, 4);
+  evel_vnic_use_bcast_pkt_in_set(vnic_use, 1);
+  evel_vnic_use_bcast_pkt_out_set(vnic_use, 2);
+  evel_vnic_use_mcast_pkt_in_set(vnic_use, 5);
+  evel_vnic_use_mcast_pkt_out_set(vnic_use, 6);
+  evel_vnic_use_ucast_pkt_in_set(vnic_use, 7);
+  evel_vnic_use_ucast_pkt_out_set(vnic_use, 8);
+  evel_meas_vnic_use_add(measurement, vnic_use);
+
+  vnic_use = evel_new_measurement_vnic_use("eth1", 110, 240, 13, 14);
+  evel_vnic_use_bcast_pkt_in_set(vnic_use, 11);
+  evel_vnic_use_bcast_pkt_out_set(vnic_use, 12);
+  evel_vnic_use_mcast_pkt_in_set(vnic_use, 15);
+  evel_vnic_use_mcast_pkt_out_set(vnic_use, 16);
+  evel_vnic_use_ucast_pkt_in_set(vnic_use, 17);
+  evel_vnic_use_ucast_pkt_out_set(vnic_use, 18);
+  evel_meas_vnic_use_add(measurement, vnic_use);
+
+  evel_measurement_errors_set(measurement, 1, 0, 2, 1);
+  evel_measurement_feature_use_add(measurement, "FeatureA", 123);
+  evel_measurement_feature_use_add(measurement, "FeatureB", 567);
+  evel_measurement_codec_use_add(measurement, "G711a", 91);
+  evel_measurement_codec_use_add(measurement, "G729ab", 92);
+  evel_measurement_media_port_use_set(measurement, 1234);
+  evel_measurement_vnfc_scaling_metric_set(measurement, 1234.5678);
+  evel_measurement_custom_measurement_add(measurement,
+                                          "Group1", "Name1", "Value1");
+  evel_measurement_custom_measurement_add(measurement,
+                                          "Group2", "Name1", "Value1");
+  evel_measurement_custom_measurement_add(measurement,
+                                          "Group2", "Name2", "Value2");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) measurement);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Measurement");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(measurement);
+  evel_throttle_terminate();
+}
+
+void test_encode_mobile_throttled()
+{
+  MEMORY_CHUNK post;
+
+  /***************************************************************************/
+  /* We also test suppression of the event header parameters here.           */
+  /***************************************************************************/
+  char * json_command_list =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"mobileFlow\", "
+    "\"suppressedFieldNames\": ["
+    "\"applicationType\", "
+    "\"appProtocolType\", "
+    "\"appProtocolVersion\", "
+    "\"cid\", "
+    "\"connectionType\", "
+    "\"ecgi\", "
+    "\"gtpProtocolType\", "
+    "\"gtpVersion\", "
+    "\"httpHeader\", "
+    "\"imei\", "
+    "\"imsi\", "
+    "\"lac\", "
+    "\"mcc\", "
+    "\"mnc\", "
+    "\"msisdn\", "
+    "\"otherFunctionalRole\", "
+    "\"rac\", "
+    "\"radioAccessTechnology\", "
+    "\"sac\", "
+    "\"samplingAlgorithm\", "
+    "\"tac\", "
+    "\"tunnelId\", "
+    "\"vlanId\", "
+    "\"eventType\", "
+    "\"reportingEntityId\", "
+    "\"sourceId\"], "
+    "\"suppressedNvPairsList\": ["
+    "]}}}"
+    "]"
+    "}";
+
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"mobileFlow\", "
+    "\"eventId\": \"1242\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 1242, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2"
+    "}, "
+    "\"mobileFlowFields\": {"
+    "\"flowDirection\": \"Inbound\", "
+    "\"gtpPerFlowMetrics\": {"
+    "\"avgBitErrorRate\": 132.000100, "
+    "\"avgPacketDelayVariation\": 31.200000, "
+    "\"avgPacketLatency\": 101, "
+    "\"avgReceiveThroughput\": 2101, "
+    "\"avgTransmitThroughput\": 501, "
+    "\"flowActivationEpoch\": 1470409422, "
+    "\"flowActivationMicrosec\": 988, "
+    "\"flowDeactivationEpoch\": 1470409432, "
+    "\"flowDeactivationMicrosec\": 12, "
+    "\"flowDeactivationTime\": \"Fri, 05 Aug 2016 15:03:52 +0000\", "
+    "\"flowStatus\": \"Inactive\", "
+    "\"maxPacketDelayVariation\": 88, "
+    "\"numActivationFailures\": 4, "
+    "\"numBitErrors\": 18, "
+    "\"numBytesReceived\": 123655, "
+    "\"numBytesTransmitted\": 4562, "
+    "\"numDroppedPackets\": 1, "
+    "\"numL7BytesReceived\": 13, "
+    "\"numL7BytesTransmitted\": 11, "
+    "\"numLostPackets\": 2, "
+    "\"numOutOfOrderPackets\": 4, "
+    "\"numPacketErrors\": 8, "
+    "\"numPacketsReceivedExclRetrans\": 900, "
+    "\"numPacketsReceivedInclRetrans\": 902, "
+    "\"numPacketsTransmittedInclRetrans\": 303, "
+    "\"numRetries\": 7, "
+    "\"numTimeouts\": 3, "
+    "\"numTunneledL7BytesReceived\": 1, "
+    "\"roundTripTime\": 111, "
+    "\"timeToFirstByte\": 226, "
+    "\"ipTosCountList\": ["
+    "[\"1\", 13], "
+    "[\"4\", 99], "
+    "[\"17\", 1]], "
+    "\"ipTosList\": [\"1\", \"4\", \"17\"], "
+    "\"tcpFlagList\": [\"CWR\", \"URG\"], "
+    "\"tcpFlagCountList\": [[\"CWR\", 10], [\"URG\", 121]], "
+    "\"mobileQciCosList\": [\"conversational\", \"65\"], "
+    "\"mobileQciCosCountList\": [[\"conversational\", 11], [\"65\", 122]], "
+    "\"durConnectionFailedStatus\": 12, "
+    "\"durTunnelFailedStatus\": 13, "
+    "\"flowActivatedBy\": \"Remote\", "
+    "\"flowActivationTime\": \"Fri, 05 Aug 2016 15:03:43 +0000\", "
+    "\"flowDeactivatedBy\": \"Remote\", "
+    "\"gtpConnectionStatus\": \"Connected\", "
+    "\"gtpTunnelStatus\": \"Not tunneling\", "
+    "\"largePacketRtt\": 80, "
+    "\"largePacketThreshold\": 600.000000, "
+    "\"maxReceiveBitRate\": 1357924680, "
+    "\"maxTransmitBitRate\": 235711, "
+    "\"numGtpEchoFailures\": 1, "
+    "\"numGtpTunnelErrors\": 4, "
+    "\"numHttpErrors\": 2"
+    "}, "
+    "\"ipProtocolType\": \"UDP\", "
+    "\"ipVersion\": \"IPv6\", "
+    "\"otherEndpointIpAddress\": \"2.3.4.2\", "
+    "\"otherEndpointPort\": 2342, "
+    "\"reportingEndpointIpAddr\": \"4.2.3.2\", "
+    "\"reportingEndpointPort\": 4322"
+    "}}}";
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single fault suppressed.  */
+  /***************************************************************************/
+  evel_throttle_initialize();
+  handle_json_response(json_command_list, &post);
+
+  /***************************************************************************/
+  /* Check that the domain is throttled.                                     */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_MOBILE_FLOW) != NULL);
+  assert(post.memory == NULL);
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  MOBILE_GTP_PER_FLOW_METRICS * metrics = NULL;
+  EVENT_MOBILE_FLOW * mobile_flow = NULL;
+
+  /***************************************************************************/
+  /* Mobile.                                                                 */
+  /***************************************************************************/
+  evel_set_next_event_sequence(1242);
+
+  metrics = evel_new_mobile_gtp_flow_metrics(132.0001,
+                                             31.2,
+                                             101,
+                                             2101,
+                                             501,
+                                             1470409422,
+                                             988,
+                                             1470409432,
+                                             12,
+                                             (time_t)1470409432,
+                                             "Inactive",
+                                             88,
+                                             4,
+                                             18,
+                                             123655,
+                                             4562,
+                                             1,
+                                             13,
+                                             11,
+                                             2,
+                                             4,
+                                             8,
+                                             900,
+                                             902,
+                                             303,
+                                             7,
+                                             3,
+                                             1,
+                                             111,
+                                             226);
+  assert(metrics != NULL);
+
+  evel_mobile_gtp_metrics_dur_con_fail_set(metrics, 12);
+  evel_mobile_gtp_metrics_dur_tun_fail_set(metrics, 13);
+  evel_mobile_gtp_metrics_act_by_set(metrics, "Remote");
+  evel_mobile_gtp_metrics_act_time_set(metrics, (time_t)1470409423);
+  evel_mobile_gtp_metrics_deact_by_set(metrics, "Remote");
+  evel_mobile_gtp_metrics_con_status_set(metrics, "Connected");
+  evel_mobile_gtp_metrics_tun_status_set(metrics, "Not tunneling");
+  evel_mobile_gtp_metrics_iptos_set(metrics, 1, 13);
+  evel_mobile_gtp_metrics_iptos_set(metrics, 17, 1);
+  evel_mobile_gtp_metrics_iptos_set(metrics, 4, 99);
+  evel_mobile_gtp_metrics_large_pkt_rtt_set(metrics, 80);
+  evel_mobile_gtp_metrics_large_pkt_thresh_set(metrics, 600.0);
+  evel_mobile_gtp_metrics_max_rcv_bit_rate_set(metrics, 1357924680);
+  evel_mobile_gtp_metrics_max_trx_bit_rate_set(metrics, 235711);
+  evel_mobile_gtp_metrics_num_echo_fail_set(metrics, 1);
+  evel_mobile_gtp_metrics_num_tun_fail_set(metrics, 4);
+  evel_mobile_gtp_metrics_num_http_errors_set(metrics, 2);
+  evel_mobile_gtp_metrics_tcp_flag_count_add(metrics, EVEL_TCP_CWR, 10);
+  evel_mobile_gtp_metrics_tcp_flag_count_add(metrics, EVEL_TCP_URG, 121);
+  evel_mobile_gtp_metrics_qci_cos_count_add(
+                                metrics, EVEL_QCI_COS_UMTS_CONVERSATIONAL, 11);
+  evel_mobile_gtp_metrics_qci_cos_count_add(
+                                            metrics, EVEL_QCI_COS_LTE_65, 122);
+
+  mobile_flow = evel_new_mobile_flow("Inbound",
+                                     metrics,
+                                     "UDP",
+                                     "IPv6",
+                                     "2.3.4.2",
+                                     2342,
+                                     "4.2.3.2",
+                                     4322);
+  assert(mobile_flow != NULL);
+
+  evel_mobile_flow_type_set(mobile_flow, "Mobile flow...");
+  evel_mobile_flow_app_type_set(mobile_flow, "Demo application");
+  evel_mobile_flow_app_prot_type_set(mobile_flow, "GSM");
+  evel_mobile_flow_app_prot_ver_set(mobile_flow, "1");
+  evel_mobile_flow_cid_set(mobile_flow, "65535");
+  evel_mobile_flow_con_type_set(mobile_flow, "S1-U");
+  evel_mobile_flow_ecgi_set(mobile_flow, "e65535");
+  evel_mobile_flow_gtp_prot_type_set(mobile_flow, "GTP-U");
+  evel_mobile_flow_gtp_prot_ver_set(mobile_flow, "1");
+  evel_mobile_flow_http_header_set(mobile_flow,
+                                   "http://www.something.com");
+  evel_mobile_flow_imei_set(mobile_flow, "209917614823");
+  evel_mobile_flow_imsi_set(mobile_flow, "355251/05/850925/8");
+  evel_mobile_flow_lac_set(mobile_flow, "1");
+  evel_mobile_flow_mcc_set(mobile_flow, "410");
+  evel_mobile_flow_mnc_set(mobile_flow, "04");
+  evel_mobile_flow_msisdn_set(mobile_flow, "6017123456789");
+  evel_mobile_flow_other_func_role_set(mobile_flow, "MME");
+  evel_mobile_flow_rac_set(mobile_flow, "514");
+  evel_mobile_flow_radio_acc_tech_set(mobile_flow, "LTE");
+  evel_mobile_flow_sac_set(mobile_flow, "1");
+  evel_mobile_flow_samp_alg_set(mobile_flow, 1);
+  evel_mobile_flow_tac_set(mobile_flow, "2099");
+  evel_mobile_flow_tunnel_id_set(mobile_flow, "Tunnel 1");
+  evel_mobile_flow_vlan_id_set(mobile_flow, "15");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) mobile_flow);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Mobile");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(mobile_flow);
+  evel_throttle_terminate();
+}
+
+void test_encode_other_throttled()
+{
+  MEMORY_CHUNK post;
+
+  /***************************************************************************/
+  /* We also test suppression of the event header parameters here.           */
+  /***************************************************************************/
+  char * json_command_list =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"other\", "
+    "\"suppressedFieldNames\": ["
+    "\"eventType\", "
+    "\"reportingEntityId\", "
+    "\"sourceId\"], "
+    "\"suppressedNvPairsList\": ["
+    "]}}}"
+    "]"
+    "}";
+
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"other\", "
+    "\"eventId\": \"129\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 129, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2"
+    "}, "
+    "\"otherFields\": ["
+    "{\"name\": \"Other field 1\", "
+    "\"value\": \"Other value 1\"}, "
+    "{\"name\": \"Other field 2\", "
+    "\"value\": \"Other value 2\"}"
+    "]"
+    "}}";
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single fault suppressed.  */
+  /***************************************************************************/
+  evel_throttle_initialize();
+  handle_json_response(json_command_list, &post);
+
+  /***************************************************************************/
+  /* Check that the domain is throttled.                                     */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_OTHER) != NULL);
+  assert(post.memory == NULL);
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_OTHER * other = NULL;
+  evel_set_next_event_sequence(129);
+  other = evel_new_other();
+  assert(other != NULL);
+  evel_other_type_set(other, "Other Type");
+  evel_other_field_add(other,
+                       "Other field 1",
+                       "Other value 1");
+  evel_other_field_add(other,
+                       "Other field 2",
+                       "Other value 2");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) other);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Other");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(other);
+  evel_throttle_terminate();
+}
+
+void test_encode_report_throttled()
+{
+  MEMORY_CHUNK post;
+
+  /***************************************************************************/
+  /* We also test suppression of the event header parameters here.           */
+  /***************************************************************************/
+  char * json_command_list =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"report\", "
+    "\"suppressedFieldNames\": ["
+    "\"eventType\", "
+    "\"reportingEntityId\", "
+    "\"sourceId\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"featureUsageArray\", "
+    "\"suppressedNvPairNames\": [\"FeatureB\", \"FeatureC\"]"
+    "},"
+    "{"
+    "\"nvPairFieldName\": \"additionalMeasurements\", "
+    "\"suppressedNvPairNames\": [\"Group2\"]"
+    "}"
+    "]}}}"
+    "]"
+    "}";
+
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"measurementsForVfReporting\", "
+    "\"eventId\": \"125\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 125, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2"
+    "}, "
+    "\"measurementsForVfReportingFields\": "
+    "{\"measurementInterval\": 1.100000, "
+    "\"featureUsageArray\": ["
+    "{\"featureIdentifier\": \"FeatureA\", "
+    "\"featureUtilization\": 123}], "
+    "\"additionalMeasurements\": ["
+    "{\"name\": \"Group1\", "
+    "\"measurements\": ["
+    "{\"name\": \"Name1\", "
+    "\"value\": \"Value1\"}]}], "
+    "\"measurementFieldsVersion\": 1.1}}}";
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single fault suppressed.  */
+  /***************************************************************************/
+  evel_throttle_initialize();
+  handle_json_response(json_command_list, &post);
+
+  /***************************************************************************/
+  /* Check that the domain is throttled.                                     */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_REPORT) != NULL);
+  assert(post.memory == NULL);
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_REPORT * report = NULL;
+
+  /***************************************************************************/
+  /* Report.                                                                 */
+  /***************************************************************************/
+  evel_set_next_event_sequence(125);
+  report = evel_new_report(1.1);
+  assert(report != NULL);
+  evel_report_type_set(report, "Perf reporting...");
+  evel_report_feature_use_add(report, "FeatureA", 123);
+  evel_report_feature_use_add(report, "FeatureB", 567);
+  evel_report_custom_measurement_add(report, "Group1", "Name1", "Value1");
+  evel_report_custom_measurement_add(report, "Group2", "Name1", "Value1");
+  evel_report_custom_measurement_add(report, "Group2", "Name2", "Value2");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) report);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Report");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(report);
+  evel_throttle_terminate();
+}
+
+void test_encode_service_throttled()
+{
+  MEMORY_CHUNK post;
+
+  /***************************************************************************/
+  /* We also test suppression of the event header parameters here.           */
+  /***************************************************************************/
+  char * json_command_list =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"serviceEvents\", "
+    "\"suppressedFieldNames\": ["
+    "\"eventType\", "
+    "\"correlator\", "
+    "\"codecSelected\", "
+    "\"codecSelectedTranscoding\", "
+    "\"endOfCallVqmSummaries\", "
+    "\"midCallRtcp\", "
+    "\"marker\", "
+    "\"reportingEntityId\", "
+    "\"sourceId\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"additionalFields\", "
+    "\"suppressedNvPairNames\": [\"Name1\", \"Name3\"]"
+    "}"
+    "]}}}"
+    "]"
+    "}";
+
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"serviceEvents\", "
+    "\"eventId\": \"2000\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 2000, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2"
+    "}, "
+    "\"serviceEventsFields\": {"
+    "\"eventInstanceIdentifier\": "
+    "{"
+    "\"vendorId\": \"vendor_x_id\", "
+    "\"eventId\": \"vendor_x_event_id\", "
+    "\"productId\": \"vendor_x_product_id\", "
+    "\"subsystemId\": \"vendor_x_subsystem_id\", "
+    "\"eventFriendlyName\": \"vendor_x_frieldly_name\""
+    "}, "
+    "\"serviceEventsFieldsVersion\": 1.1, "
+    "\"additionalFields\": ["
+    "{\"name\": \"Name2\", \"value\": \"Value2\"}, "
+    "{\"name\": \"Name4\", \"value\": \"Value4\"}]"
+    "}}}";
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single fault suppressed.  */
+  /***************************************************************************/
+  evel_throttle_initialize();
+  handle_json_response(json_command_list, &post);
+
+  /***************************************************************************/
+  /* Check that the domain is throttled.                                     */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_SERVICE) != NULL);
+  assert(post.memory == NULL);
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_SERVICE * event = NULL;
+  evel_set_next_event_sequence(2000);
+  event = evel_new_service("vendor_x_id", "vendor_x_event_id");
+  assert(event != NULL);
+  evel_service_type_set(event, "Service Event");
+  evel_service_product_id_set(event, "vendor_x_product_id");
+  evel_service_subsystem_id_set(event, "vendor_x_subsystem_id");
+  evel_service_friendly_name_set(event, "vendor_x_frieldly_name");
+  evel_service_correlator_set(event, "vendor_x_correlator");
+  evel_service_codec_set(event, "PCMA");
+  evel_service_codec_set(event, "PCMA");
+  evel_service_callee_codec_set(event, "PCMA");
+  evel_service_caller_codec_set(event, "G729A");
+  evel_service_rtcp_data_set(event, "some_rtcp_data");
+  evel_service_adjacency_name_set(event, "vendor_x_adjacency");
+  evel_service_endpoint_desc_set(event, EVEL_SERVICE_ENDPOINT_CALLER);
+  evel_service_endpoint_jitter_set(event, 66);
+  evel_service_endpoint_rtp_oct_disc_set(event, 100);
+  evel_service_endpoint_rtp_oct_recv_set(event, 200);
+  evel_service_endpoint_rtp_oct_sent_set(event, 300);
+  evel_service_endpoint_rtp_pkt_disc_set(event, 400);
+  evel_service_endpoint_rtp_pkt_recv_set(event, 500);
+  evel_service_endpoint_rtp_pkt_sent_set(event, 600);
+  evel_service_local_jitter_set(event, 99);
+  evel_service_local_rtp_oct_disc_set(event, 150);
+  evel_service_local_rtp_oct_recv_set(event, 250);
+  evel_service_local_rtp_oct_sent_set(event, 350);
+  evel_service_local_rtp_pkt_disc_set(event, 450);
+  evel_service_local_rtp_pkt_recv_set(event, 550);
+  evel_service_local_rtp_pkt_sent_set(event, 650);
+  evel_service_mos_cqe_set(event, 12.255);
+  evel_service_packets_lost_set(event, 157);
+  evel_service_packet_loss_percent_set(event, 0.232);
+  evel_service_r_factor_set(event, 11);
+  evel_service_round_trip_delay_set(event, 15);
+  evel_service_phone_number_set(event, "0888888888");
+  evel_service_addl_field_add(event, "Name1", "Value1");
+  evel_service_addl_field_add(event, "Name2", "Value2");
+  evel_service_addl_field_add(event, "Name3", "Value3");
+  evel_service_addl_field_add(event, "Name4", "Value4");
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) event);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Service");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(event);
+  evel_throttle_terminate();
+}
+
+void test_encode_signaling_throttled()
+{
+  MEMORY_CHUNK post;
+
+  /***************************************************************************/
+  /* We also test suppression of the event header parameters here.           */
+  /***************************************************************************/
+  char * json_command_list =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"signaling\", "
+    "\"suppressedFieldNames\": ["
+    "\"correlator\", "
+    "\"eventType\", "
+    "\"reportingEntityId\", "
+    "\"sourceId\", "
+    "\"localIpAddress\", "
+    "\"localPort\", "
+    "\"remoteIpAddress\", "
+    "\"remotePort\", "
+    "\"compressedSip\", "
+    "\"summarySip\"], "
+    "\"suppressedNvPairsList\": ["
+    "]}}}"
+    "]"
+    "}";
+
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"signaling\", "
+    "\"eventId\": \"2001\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 2001, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2"
+    "}, "
+    "\"signalingFields\": {"
+    "\"eventInstanceIdentifier\": "
+    "{"
+    "\"vendorId\": \"vendor_x_id\", "
+    "\"eventId\": \"vendor_x_event_id\", "
+    "\"productId\": \"vendor_x_product_id\", "
+    "\"subsystemId\": \"vendor_x_subsystem_id\", "
+    "\"eventFriendlyName\": \"vendor_x_frieldly_name\""
+    "}, "
+    "\"signalingFieldsVersion\": 1.1"
+    "}}}";
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single fault suppressed.  */
+  /***************************************************************************/
+  evel_throttle_initialize();
+  handle_json_response(json_command_list, &post);
+
+  /***************************************************************************/
+  /* Check that the domain is throttled.                                     */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_SIGNALING) != NULL);
+  assert(post.memory == NULL);
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_SIGNALING * event = NULL;
+  evel_set_next_event_sequence(2001);
+  event = evel_new_signaling("vendor_x_id",
+           "correlator", "1.0.3.1", "1234", "192.168.1.3","3456");
+  assert(event != NULL);
+  evel_signaling_vnfmodule_name_set(event, "vendor_x_module");
+  evel_signaling_vnfname_set(event, "vendor_x_vnf");
+  evel_signaling_type_set(event, "Signaling");
+  evel_signaling_product_id_set(event, "vendor_x_product_id");
+  evel_signaling_subsystem_id_set(event, "vendor_x_subsystem_id");
+  evel_signaling_friendly_name_set(event, "vendor_x_frieldly_name");
+  evel_signaling_correlator_set(event, "vendor_x_correlator");
+  evel_signaling_local_ip_address_set(event, "1.0.3.1");
+  evel_signaling_local_port_set(event, "1031");
+  evel_signaling_remote_ip_address_set(event, "5.3.3.0");
+  evel_signaling_remote_port_set(event, "5330");
+  evel_signaling_compressed_sip_set(event, "compressed_sip");
+  evel_signaling_summary_sip_set(event, "summary_sip");
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) event);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Signaling");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(event);
+  evel_throttle_terminate();
+}
+
+void test_encode_state_change_throttled()
+{
+  MEMORY_CHUNK post;
+
+  /***************************************************************************/
+  /* We also test suppression of the event header parameters here.           */
+  /***************************************************************************/
+  char * json_command_list =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"stateChange\", "
+    "\"suppressedFieldNames\": ["
+    "\"eventType\", "
+    "\"reportingEntityId\", "
+    "\"sourceId\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"additionalFields\", "
+    "\"suppressedNvPairNames\": [\"Name1\"]"
+    "},"
+    "]}}}"
+    "]"
+    "}";
+
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"stateChange\", "
+    "\"eventId\": \"128\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 128, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2"
+    "}, "
+    "\"stateChangeFields\": {"
+    "\"newState\": \"inService\", "
+    "\"oldState\": \"outOfService\", "
+    "\"stateInterface\": \"An Interface\", "
+    "\"additionalFields\": ["
+    "{\"name\": \"Name2\", "
+    "\"value\": \"Value2\"}"
+    "], "
+    "\"stateChangeFieldsVersion\": 1.1"
+    "}}}";
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single fault suppressed.  */
+  /***************************************************************************/
+  evel_throttle_initialize();
+  handle_json_response(json_command_list, &post);
+
+  /***************************************************************************/
+  /* Check that the domain is throttled.                                     */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_STATE_CHANGE) != NULL);
+  assert(post.memory == NULL);
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_STATE_CHANGE * state_change = NULL;
+  evel_set_next_event_sequence(128);
+  state_change = evel_new_state_change(EVEL_ENTITY_STATE_IN_SERVICE,
+                                       EVEL_ENTITY_STATE_OUT_OF_SERVICE,
+                                       "An Interface");
+  assert(state_change != NULL);
+  evel_state_change_type_set(state_change, "SC Type");
+  evel_state_change_addl_field_add(state_change, "Name1", "Value1");
+  evel_state_change_addl_field_add(state_change, "Name2", "Value2");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) state_change);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "StateChange");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(state_change);
+  evel_throttle_terminate();
+}
+
+void test_encode_syslog_throttled()
+{
+  MEMORY_CHUNK post;
+
+  /***************************************************************************/
+  /* We also test suppression of the event header parameters here.           */
+  /***************************************************************************/
+  char * json_command_list =
+    "{"
+    "\"commandList\": ["
+    "{"
+    "\"command\": {"
+    "\"commandType\": \"throttlingSpecification\", "
+    "\"eventDomainThrottleSpecification\": {"
+    "\"eventDomain\": \"syslog\", "
+    "\"suppressedFieldNames\": ["
+    "\"eventSourceHost\", "
+    "\"syslogFacility\", "
+    "\"syslogProc\", "
+    "\"syslogProcId\", "
+    "\"syslogSData\", "
+    "\"syslogVer\", "
+    "\"eventType\", "
+    "\"reportingEntityId\", "
+    "\"sourceId\"], "
+    "\"suppressedNvPairsList\": ["
+    "{"
+    "\"nvPairFieldName\": \"additionalFields\", "
+    "\"suppressedNvPairNames\": [\"Name2\"]"
+    "},"
+    "]}}}"
+    "]"
+    "}";
+
+  char * expected =
+    "{\"event\": "
+    "{\"commonEventHeader\": {"
+    "\"domain\": \"syslog\", "
+    "\"eventId\": \"126\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 126, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2"
+    "}, "
+    "\"syslogFields\": {"
+    "\"eventSourceType\": \"virtualNetworkFunction\", "
+    "\"syslogMsg\": \"SL Message\", "
+    "\"syslogTag\": \"SL Tag\", "
+    "\"syslogFieldsVersion\": 1.1, "
+    "\"additionalFields\": ["
+    "{\"name\": \"Name1\", "
+    "\"value\": \"Value1\"}"
+    "]"
+    "}}}";
+
+  /***************************************************************************/
+  /* Initialize and provide a specification with a single fault suppressed.  */
+  /***************************************************************************/
+  evel_throttle_initialize();
+  handle_json_response(json_command_list, &post);
+
+  /***************************************************************************/
+  /* Check that the domain is throttled.                                     */
+  /***************************************************************************/
+  assert(evel_get_throttle_spec(EVEL_DOMAIN_SYSLOG) != NULL);
+  assert(post.memory == NULL);
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  EVENT_SYSLOG * syslog = NULL;
+  evel_set_next_event_sequence(126);
+  syslog = evel_new_syslog(EVEL_SOURCE_VIRTUAL_NETWORK_FUNCTION,
+                           "SL Message",
+                           "SL Tag");
+  assert(syslog != NULL);
+  evel_syslog_type_set(syslog, "SL Type");
+  evel_syslog_event_source_host_set(syslog, "SL Host");
+  evel_syslog_facility_set(syslog, EVEL_SYSLOG_FACILITY_LINE_PRINTER);
+  evel_syslog_proc_set(syslog, "SL Proc");
+  evel_syslog_proc_id_set(syslog, 2);
+  evel_syslog_version_set(syslog, 1);
+  evel_syslog_s_data_set(syslog, "SL SDATA");
+  evel_syslog_addl_field_add(syslog, "Name1", "Value1");
+  evel_syslog_addl_field_add(syslog, "Name2", "Value2");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) syslog);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Syslog");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(syslog);
+  evel_throttle_terminate();
+}
+
+void test_encode_fault_with_escaping()
+{
+  char * expected =
+    "{\"event\": {"
+    "\"commonEventHeader\": {"
+    "\"domain\": \"fault\", "
+    "\"eventId\": \"122\", "
+    "\"functionalRole\": \"UNIT TEST\", "
+    "\"lastEpochMicrosec\": 1000002, "
+    "\"priority\": \"Normal\", "
+    "\"reportingEntityName\": \"Dummy VM name - No Metadata available\", "
+    "\"sequence\": 122, "
+    "\"sourceName\": \"Dummy VM name - No Metadata available\", "
+    "\"startEpochMicrosec\": 1000002, "
+    "\"version\": 1.2, "
+    "\"eventType\": \"Bad things happen...\\\\\", "
+    "\"reportingEntityId\": \"Dummy VM UUID - No Metadata available\", "
+    "\"sourceId\": \"Dummy VM UUID - No Metadata available\""
+    "}, "
+    "\"faultFields\": {"
+    "\"alarmCondition\": \"My alarm condition\", "
+    "\"eventSeverity\": \"MAJOR\", "
+    "\"eventSourceType\": \"other\", "
+    "\"specificProblem\": \"It broke \\\"very\\\" badly\", "
+    "\"vfStatus\": \"Active\", "
+    "\"faultFieldsVersion\": 1.1, "
+    "\"alarmAdditionalInformation\": ["
+    "{\"name\": \"name1\", "
+    "\"value\": \"value1\"}, "
+    "{\"name\": \"name2\", "
+    "\"value\": \"value2\"}], "
+    "\"alarmInterfaceA\": \"My Interface Card\""
+    "}}}";
+
+  size_t json_size = 0;
+  char json_body[EVEL_MAX_JSON_BODY];
+  evel_set_next_event_sequence(122);
+  EVENT_FAULT * fault = evel_new_fault("My alarm condition",
+                                       "It broke \"very\" badly",
+                                       EVEL_PRIORITY_NORMAL,
+                                       EVEL_SEVERITY_MAJOR,
+                                       EVEL_SOURCE_HOST,
+                          EVEL_VF_STATUS_PREP_TERMINATE);
+  assert(fault != NULL);
+  evel_fault_type_set(fault, "Bad things happen...\\");
+  evel_fault_interface_set(fault, "My Interface Card");
+  evel_fault_addl_info_add(fault, "name1", "value1");
+  evel_fault_addl_info_add(fault, "name2", "value2");
+
+  json_size = evel_json_encode_event(
+    json_body, EVEL_MAX_JSON_BODY, (EVENT_HEADER *) fault);
+  compare_strings(expected, json_body, EVEL_MAX_JSON_BODY, "Fault");
+  assert((json_size == strlen(json_body)) && "Bad size returned");
+
+  evel_free_event(fault);
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-library/docs/source/evel/README b/veslibrary/ves_clibrary/evel/evel-library/docs/source/evel/README
new file mode 100644 (file)
index 0000000..89e7a3a
--- /dev/null
@@ -0,0 +1 @@
+Generated source code documentation.
\ No newline at end of file
diff --git a/veslibrary/ves_clibrary/evel/evel-library/libs/x86_64/README b/veslibrary/ves_clibrary/evel/evel-library/libs/x86_64/README
new file mode 100644 (file)
index 0000000..760fdc1
--- /dev/null
@@ -0,0 +1 @@
+Generated libraries.
\ No newline at end of file
diff --git a/veslibrary/ves_clibrary/evel/evel-library/output/x86_64/README b/veslibrary/ves_clibrary/evel/evel-library/output/x86_64/README
new file mode 100644 (file)
index 0000000..d1c9f1f
--- /dev/null
@@ -0,0 +1 @@
+Generated executables.
\ No newline at end of file
diff --git a/veslibrary/ves_clibrary/evel/evel-library/readme.md b/veslibrary/ves_clibrary/evel/evel-library/readme.md
new file mode 100644 (file)
index 0000000..65ce4ef
--- /dev/null
@@ -0,0 +1,28 @@
+# ECOMP Vendor Event Listener Library
+
+This project contains a C library that supports interfacing to AT&T's ECOMP
+Vendor Event Listener. For an overview of ECOMP, see the 
+[ECOMP White Paper](http://att.com/ECOMP).
+
+Developed in 2016 for AT&T by:
+ * Alok Gupta (https://github.com/ag1367)
+ * Paul Potochniak (https://github.com/pp8491)
+ * Gayathri Patrachari(https://github.com/gp2421)
+
+Current Maintainers: 
+ * Alok Gupta (https://github.com/ag1367)
+ * Paul Potochniak (https://github.com/pp8491)
+ * Gayathri Patrachari(https://github.com/gp2421)
+
+# Installation
+
+For installation instructions, clone this repo and load the 
+[installation guide](./docs/source/evel/html/quickstart.html) in your web browser.
+
+Full source-code documentation is included with the code and can be built from 
+the included Makefile. See the [readme file](./code/evel_library/readme.md).
+
+# Use
+
+Clone this repo and load the [user guide](./docs/source/evel/html/index.html)
+in your web browser.
\ No newline at end of file
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/LICENSE.md b/veslibrary/ves_clibrary/evel/evel-test-collector/LICENSE.md
new file mode 100644 (file)
index 0000000..afb56c9
--- /dev/null
@@ -0,0 +1,18 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/README.md b/veslibrary/ves_clibrary/evel/evel-test-collector/README.md
new file mode 100644 (file)
index 0000000..b81ada3
--- /dev/null
@@ -0,0 +1,30 @@
+# ECOMP Vendor Event Listener API Test Collector
+
+This project contains a Python application that represents a test version of 
+the ECOMP Vendor Event Listener API. For an overview of ECOMP, see the 
+[ECOMP White Paper](http://att.com/ECOMP). For an overview of the 
+ECOMP Vendor Event Listener, see the 
+[ECOMP Vendor Event Listener Library project](http://github.com/blsaws/evel-library).
+
+Developed in 2016 for AT&T by:
+ * Alok Gupta (https://github.com/ag1367)
+ * Paul Potochniak (https://github.com/pp8491)
+ * Gayathri Patrachari(https://github.com/gp2421)
+
+Current Maintainers: 
+ * Alok Gupta (https://github.com/ag1367)
+ * Paul Potochniak (https://github.com/pp8491)
+ * Gayathri Patrachari(https://github.com/gp2421)
+
+# Installation
+
+Clone this project, and follow the instructions in the [Test Collector User 
+Guide](./docs/test_collector_user_guide/test_collector_user_guide.md).
+
+# Use
+
+The code is documented using docstrings - start from the
+[Test Collector](./code/collector/collector.py).
+
+For further information see the [Vendor Event Listener 
+specification](./docs/att_interface_definition/att_service_specification.docx).
\ No newline at end of file
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/LICENSE.TXT b/veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/LICENSE.TXT
new file mode 100644 (file)
index 0000000..ae12da2
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * ============LICENSE_START==========================================
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ *
+ * ECOMP and OpenECOMP are trademarks 
+ * and service marks of AT&T Intellectual Property.
+ *
+ */
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/__init__.py b/veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/collector.py b/veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/collector.py
new file mode 100644 (file)
index 0000000..8e702aa
--- /dev/null
@@ -0,0 +1,643 @@
+#!/usr/bin/env python
+'''
+Program which acts as the collector for the Vendor Event Listener REST API.
+
+Only intended for test purposes.
+
+License
+-------
+
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+'''
+
+from rest_dispatcher import PathDispatcher, set_404_content
+from wsgiref.simple_server import make_server
+import sys
+import os
+import platform
+import traceback
+import time
+from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
+import ConfigParser
+import logging.handlers
+from base64 import b64decode
+import string
+import json
+import jsonschema
+from functools import partial
+
+_hello_resp = '''\
+<html>
+  <head>
+     <title>Hello {name}</title>
+   </head>
+   <body>
+     <h1>Hello {name}!</h1>
+   </body>
+</html>'''
+
+_localtime_resp = '''\
+<?xml version="1.0"?>
+<time>
+  <year>{t.tm_year}</year>
+  <month>{t.tm_mon}</month>
+  <day>{t.tm_mday}</day>
+  <hour>{t.tm_hour}</hour>
+  <minute>{t.tm_min}</minute>
+  <second>{t.tm_sec}</second>
+</time>'''
+
+__all__ = []
+__version__ = 0.1
+__date__ = '2015-12-04'
+__updated__ = '2015-12-04'
+
+TESTRUN = False
+DEBUG = False
+PROFILE = False
+
+#------------------------------------------------------------------------------
+# Credentials we expect clients to authenticate themselves with.
+#------------------------------------------------------------------------------
+vel_username = ''
+vel_password = ''
+
+#------------------------------------------------------------------------------
+# The JSON schema which we will use to validate events.
+#------------------------------------------------------------------------------
+vel_schema = None
+
+#------------------------------------------------------------------------------
+# The JSON schema which we will use to validate client throttle state.
+#------------------------------------------------------------------------------
+throttle_schema = None
+
+#------------------------------------------------------------------------------
+# The JSON schema which we will use to provoke throttling commands for testing.
+#------------------------------------------------------------------------------
+test_control_schema = None
+
+#------------------------------------------------------------------------------
+# Pending command list from the testControl API
+# This is sent as a response commandList to the next received event.
+#------------------------------------------------------------------------------
+pending_command_list = None
+
+#------------------------------------------------------------------------------
+# Logger for this module.
+#------------------------------------------------------------------------------
+logger = None
+
+def listener(environ, start_response, schema):
+    '''
+    Handler for the Vendor Event Listener REST API.
+
+    Extract headers and the body and check that:
+
+      1)  The client authenticated themselves correctly.
+      2)  The body validates against the provided schema for the API.
+
+    '''
+    logger.info('Got a Vendor Event request')
+    print('==== ' + time.asctime() + ' ' + '=' * 49)
+
+    #--------------------------------------------------------------------------
+    # Extract the content from the request.
+    #--------------------------------------------------------------------------
+    length = int(environ.get('CONTENT_LENGTH', '0'))
+    logger.debug('Content Length: {0}'.format(length))
+    body = environ['wsgi.input'].read(length)
+    logger.debug('Content Body: {0}'.format(body))
+
+    mode, b64_credentials = string.split(environ.get('HTTP_AUTHORIZATION',
+                                                     'None None'))
+    # logger.debug('Auth. Mode: {0} Credentials: {1}'.format(mode,
+    #                                                     b64_credentials))
+    logger.debug('Auth. Mode: {0} Credentials: ****'.format(mode))
+    if (b64_credentials != 'None'):
+        credentials = b64decode(b64_credentials)
+    else:
+        credentials = None
+
+    logger.debug('Credentials: {0}'.format(credentials))
+    #logger.debug('Credentials: ****')
+
+    #--------------------------------------------------------------------------
+    # If we have a schema file then check that the event matches that expected.
+    #--------------------------------------------------------------------------
+    if (schema is not None):
+        logger.debug('Attempting to validate data: {0}\n'
+                     'Against schema: {1}'.format(body, schema))
+        try:
+            decoded_body = json.loads(body)
+            jsonschema.validate(decoded_body, schema)
+            logger.info('Event is valid!')
+            print('Valid body decoded & checked against schema OK:\n'
+                  '{0}'.format(json.dumps(decoded_body,
+                                          sort_keys=True,
+                                          indent=4,
+                                          separators=(',', ': '))))
+
+        except jsonschema.SchemaError as e:
+            logger.error('Schema is not valid! {0}'.format(e))
+            print('Schema is not valid! {0}'.format(e))
+
+        except jsonschema.ValidationError as e:
+            logger.warn('Event is not valid against schema! {0}'.format(e))
+            print('Event is not valid against schema! {0}'.format(e))
+            print('Bad JSON body decoded:\n'
+                  '{0}'.format(json.dumps(decoded_body,
+                                         sort_keys=True,
+                                         indent=4,
+                                         separators=(',', ': '))))
+
+        except Exception as e:
+            logger.error('Event invalid for unexpected reason! {0}'.format(e))
+            print('Schema is not valid for unexpected reason! {0}'.format(e))
+    else:
+        logger.debug('No schema so just decode JSON: {0}'.format(body))
+        try:
+            decoded_body = json.loads(body)
+            print('Valid JSON body (no schema checking) decoded:\n'
+                  '{0}'.format(json.dumps(decoded_body,
+                                         sort_keys=True,
+                                         indent=4,
+                                         separators=(',', ': '))))
+            logger.info('Event is valid JSON but not checked against schema!')
+
+        except Exception as e:
+            logger.error('Event invalid for unexpected reason! {0}'.format(e))
+            print('JSON body not valid for unexpected reason! {0}'.format(e))
+
+    #--------------------------------------------------------------------------
+    # See whether the user authenticated themselves correctly.
+    #--------------------------------------------------------------------------
+    if (credentials == (vel_username + ':' + vel_password)):
+        logger.debug('Authenticated OK')
+        print('Authenticated OK')
+
+        #----------------------------------------------------------------------
+        # Respond to the caller. If we have a pending commandList from the
+        # testControl API, send it in response.
+        #----------------------------------------------------------------------
+        global pending_command_list
+        if pending_command_list is not None:
+            start_response('202 Accepted',
+                           [('Content-type', 'application/json')])
+            response = pending_command_list
+            pending_command_list = None
+
+            print('\n'+ '='*80)
+            print('Sending pending commandList in the response:\n'
+                  '{0}'.format(json.dumps(response,
+                                          sort_keys=True,
+                                          indent=4,
+                                          separators=(',', ': '))))
+            print('='*80 + '\n')
+            yield json.dumps(response)
+        else:
+            start_response('202 Accepted', [])
+            yield ''
+    else:
+        logger.warn('Failed to authenticate OK'+vel_username + ':' + vel_password)
+        print('Failed to authenticate OK'+vel_username + ':' + vel_password)
+
+        #----------------------------------------------------------------------
+        # Respond to the caller.
+        #----------------------------------------------------------------------
+        start_response('401 Unauthorized', [ ('Content-type',
+                                              'application/json')])
+        req_error = { 'requestError': {
+                        'policyException': {
+                            'messageId': 'POL0001',
+                            'text': 'Failed to authenticate'
+                            }
+                        }
+                    }
+        yield json.dumps(req_error)
+
+def test_listener(environ, start_response, schema):
+    '''
+    Handler for the Test Collector Test Control API.
+
+    There is no authentication on this interface.
+
+    This simply stores a commandList which will be sent in response to the next
+    incoming event on the EVEL interface.
+    '''
+    global pending_command_list
+    logger.info('Got a Test Control input')
+    print('============================')
+    print('==== TEST CONTROL INPUT ====')
+
+    #--------------------------------------------------------------------------
+    # GET allows us to get the current pending request.
+    #--------------------------------------------------------------------------
+    if environ.get('REQUEST_METHOD') == 'GET':
+        start_response('200 OK', [('Content-type', 'application/json')])
+        yield json.dumps(pending_command_list)
+        return
+
+    #--------------------------------------------------------------------------
+    # Extract the content from the request.
+    #--------------------------------------------------------------------------
+    length = int(environ.get('CONTENT_LENGTH', '0'))
+    logger.debug('TestControl Content Length: {0}'.format(length))
+    body = environ['wsgi.input'].read(length)
+    logger.debug('TestControl Content Body: {0}'.format(body))
+
+    #--------------------------------------------------------------------------
+    # If we have a schema file then check that the event matches that expected.
+    #--------------------------------------------------------------------------
+    if (schema is not None):
+        logger.debug('Attempting to validate data: {0}\n'
+                     'Against schema: {1}'.format(body, schema))
+        try:
+            decoded_body = json.loads(body)
+            jsonschema.validate(decoded_body, schema)
+            logger.info('TestControl is valid!')
+            print('TestControl:\n'
+                  '{0}'.format(json.dumps(decoded_body,
+                                          sort_keys=True,
+                                          indent=4,
+                                          separators=(',', ': '))))
+
+        except jsonschema.SchemaError as e:
+            logger.error('TestControl Schema is not valid: {0}'.format(e))
+            print('TestControl Schema is not valid: {0}'.format(e))
+
+        except jsonschema.ValidationError as e:
+            logger.warn('TestControl input not valid: {0}'.format(e))
+            print('TestControl input not valid: {0}'.format(e))
+            print('Bad JSON body decoded:\n'
+                  '{0}'.format(json.dumps(decoded_body,
+                                          sort_keys=True,
+                                          indent=4,
+                                          separators=(',', ': '))))
+
+        except Exception as e:
+            logger.error('TestControl input not valid: {0}'.format(e))
+            print('TestControl Schema not valid: {0}'.format(e))
+    else:
+        logger.debug('Missing schema just decode JSON: {0}'.format(body))
+        try:
+            decoded_body = json.loads(body)
+            print('Valid JSON body (no schema checking) decoded:\n'
+                  '{0}'.format(json.dumps(decoded_body,
+                                          sort_keys=True,
+                                          indent=4,
+                                          separators=(',', ': '))))
+            logger.info('TestControl input not checked against schema!')
+
+        except Exception as e:
+            logger.error('TestControl input not valid: {0}'.format(e))
+            print('TestControl input not valid: {0}'.format(e))
+
+    #--------------------------------------------------------------------------
+    # Respond to the caller. If we received otherField 'ThrottleRequest',
+    # generate the appropriate canned response.
+    #--------------------------------------------------------------------------
+    pending_command_list = decoded_body
+    print('===== TEST CONTROL END =====')
+    print('============================')
+    start_response('202 Accepted', [])
+    yield ''
+
+def main(argv=None):
+    '''
+    Main function for the collector start-up.
+
+    Called with command-line arguments:
+        *    --config *<file>*
+        *    --section *<section>*
+        *    --verbose
+
+    Where:
+
+        *<file>* specifies the path to the configuration file.
+
+        *<section>* specifies the section within that config file.
+
+        *verbose* generates more information in the log files.
+
+    The process listens for REST API invocations and checks them. Errors are
+    displayed to stdout and logged.
+    '''
+
+    if argv is None:
+        argv = sys.argv
+    else:
+        sys.argv.extend(argv)
+
+    program_name = os.path.basename(sys.argv[0])
+    program_version = 'v{0}'.format(__version__)
+    program_build_date = str(__updated__)
+    program_version_message = '%%(prog)s {0} ({1})'.format(program_version,
+                                                         program_build_date)
+    if (__import__('__main__').__doc__ is not None):
+        program_shortdesc = __import__('__main__').__doc__.split('\n')[1]
+    else:
+        program_shortdesc = 'Running in test harness'
+    program_license = '''{0}
+
+  Created  on {1}.
+  Copyright 2015 Metaswitch Networks Ltd. All rights reserved.
+
+  Distributed on an "AS IS" basis without warranties
+  or conditions of any kind, either express or implied.
+
+USAGE
+'''.format(program_shortdesc, str(__date__))
+
+    try:
+        #----------------------------------------------------------------------
+        # Setup argument parser so we can parse the command-line.
+        #----------------------------------------------------------------------
+        parser = ArgumentParser(description=program_license,
+                                formatter_class=ArgumentDefaultsHelpFormatter)
+        parser.add_argument('-v', '--verbose',
+                            dest='verbose',
+                            action='count',
+                            help='set verbosity level')
+        parser.add_argument('-V', '--version',
+                            action='version',
+                            version=program_version_message,
+                            help='Display version information')
+        parser.add_argument('-a', '--api-version',
+                            dest='api_version',
+                            default='5',
+                            help='set API version')
+        parser.add_argument('-c', '--config',
+                            dest='config',
+                            default='/etc/opt/att/collector.conf',
+                            help='Use this config file.',
+                            metavar='<file>')
+        parser.add_argument('-s', '--section',
+                            dest='section',
+                            default='default',
+                            metavar='<section>',
+                            help='section to use in the config file')
+
+        #----------------------------------------------------------------------
+        # Process arguments received.
+        #----------------------------------------------------------------------
+        args = parser.parse_args()
+        verbose = args.verbose
+        api_version = args.api_version
+        config_file = args.config
+        config_section = args.section
+
+        #----------------------------------------------------------------------
+        # Now read the config file, using command-line supplied values as
+        # overrides.
+        #----------------------------------------------------------------------
+        defaults = {'log_file': 'collector.log',
+                    'vel_port': '12233',
+                    'vel_path': '',
+                    'vel_topic_name': ''
+                   }
+        overrides = {}
+        config = ConfigParser.SafeConfigParser(defaults)
+        config.read(config_file)
+
+        #----------------------------------------------------------------------
+        # extract the values we want.
+        #----------------------------------------------------------------------
+        log_file = config.get(config_section, 'log_file', vars=overrides)
+        vel_port = config.get(config_section, 'vel_port', vars=overrides)
+        vel_path = config.get(config_section, 'vel_path', vars=overrides)
+        vel_topic_name = config.get(config_section,
+                                    'vel_topic_name',
+                                    vars=overrides)
+        global vel_username
+        global vel_password
+        vel_username = config.get(config_section,
+                                  'vel_username',
+                                  vars=overrides)
+        vel_password = config.get(config_section,
+                                  'vel_password',
+                                  vars=overrides)
+        vel_schema_file = config.get(config_section,
+                                     'schema_file',
+                                     vars=overrides)
+        base_schema_file = config.get(config_section,
+                                      'base_schema_file',
+                                      vars=overrides)
+        throttle_schema_file = config.get(config_section,
+                                          'throttle_schema_file',
+                                          vars=overrides)
+        test_control_schema_file = config.get(config_section,
+                                           'test_control_schema_file',
+                                           vars=overrides)
+
+        #----------------------------------------------------------------------
+        # Finally we have enough info to start a proper flow trace.
+        #----------------------------------------------------------------------
+        global logger
+        print('Logfile: {0}'.format(log_file))
+        logger = logging.getLogger('collector')
+        if verbose > 0:
+            print('Verbose mode on')
+            logger.setLevel(logging.DEBUG)
+        else:
+            logger.setLevel(logging.INFO)
+        handler = logging.handlers.RotatingFileHandler(log_file,
+                                                       maxBytes=1000000,
+                                                       backupCount=10)
+        if (platform.system() == 'Windows'):
+            date_format = '%Y-%m-%d %H:%M:%S'
+        else:
+            date_format = '%Y-%m-%d %H:%M:%S.%f %z'
+        formatter = logging.Formatter('%(asctime)s %(name)s - '
+                                      '%(levelname)s - %(message)s',
+                                      date_format)
+        handler.setFormatter(formatter)
+        logger.addHandler(handler)
+        logger.info('Started')
+
+        #----------------------------------------------------------------------
+        # Log the details of the configuration.
+        #----------------------------------------------------------------------
+        logger.debug('Log file = {0}'.format(log_file))
+        logger.debug('Event Listener Port = {0}'.format(vel_port))
+        logger.debug('Event Listener Path = {0}'.format(vel_path))
+        logger.debug('Event Listener Topic = {0}'.format(vel_topic_name))
+        logger.debug('Event Listener Username = {0}'.format(vel_username))
+        # logger.debug('Event Listener Password = {0}'.format(vel_password))
+        logger.debug('Event Listener JSON Schema File = {0}'.format(
+                                                              vel_schema_file))
+        logger.debug('Base JSON Schema File = {0}'.format(base_schema_file))
+        logger.debug('Throttle JSON Schema File = {0}'.format(
+                                                         throttle_schema_file))
+        logger.debug('Test Control JSON Schema File = {0}'.format(
+                                                     test_control_schema_file))
+
+        #----------------------------------------------------------------------
+        # Perform some basic error checking on the config.
+        #----------------------------------------------------------------------
+        if (int(vel_port) < 1024 or int(vel_port) > 65535):
+            logger.error('Invalid Vendor Event Listener port ({0}) '
+                         'specified'.format(vel_port))
+            raise RuntimeError('Invalid Vendor Event Listener port ({0}) '
+                               'specified'.format(vel_port))
+
+        if (len(vel_path) > 0 and vel_path[-1] != '/'):
+            logger.warning('Event Listener Path ({0}) should have terminating '
+                           '"/"!  Adding one on to configured string.'.format(
+                                                                     vel_path))
+            vel_path += '/'
+
+        #----------------------------------------------------------------------
+        # Load up the vel_schema, if it exists.
+        #----------------------------------------------------------------------
+        if not os.path.exists(vel_schema_file):
+            logger.warning('Event Listener Schema File ({0}) not found. '
+                           'No validation will be undertaken.'.format(
+                                                              vel_schema_file))
+        else:
+            global vel_schema
+            global throttle_schema
+            global test_control_schema
+            vel_schema = json.load(open(vel_schema_file, 'r'))
+            logger.debug('Loaded the JSON schema file')
+
+            #------------------------------------------------------------------
+            # Load up the throttle_schema, if it exists.
+            #------------------------------------------------------------------
+            if (os.path.exists(throttle_schema_file)):
+                logger.debug('Loading throttle schema')
+                throttle_fragment = json.load(open(throttle_schema_file, 'r'))
+                throttle_schema = {}
+                throttle_schema.update(vel_schema)
+                throttle_schema.update(throttle_fragment)
+                logger.debug('Loaded the throttle schema')
+
+            #------------------------------------------------------------------
+            # Load up the test control _schema, if it exists.
+            #------------------------------------------------------------------
+            if (os.path.exists(test_control_schema_file)):
+                logger.debug('Loading test control schema')
+                test_control_fragment = json.load(
+                    open(test_control_schema_file, 'r'))
+                test_control_schema = {}
+                test_control_schema.update(vel_schema)
+                test_control_schema.update(test_control_fragment)
+                logger.debug('Loaded the test control schema')
+
+            #------------------------------------------------------------------
+            # Load up the base_schema, if it exists.
+            #------------------------------------------------------------------
+            if (os.path.exists(base_schema_file)):
+                logger.debug('Updating the schema with base definition')
+                base_schema = json.load(open(base_schema_file, 'r'))
+                vel_schema.update(base_schema)
+                logger.debug('Updated the JSON schema file')
+
+        #----------------------------------------------------------------------
+        # We are now ready to get started with processing. Start-up the various
+        # components of the system in order:
+        #
+        #  1) Create the dispatcher.
+        #  2) Register the functions for the URLs of interest.
+        #  3) Run the webserver.
+        #----------------------------------------------------------------------
+        root_url = '/{0}eventListener/v{1}{2}'.\
+                   format(vel_path,
+                          api_version,
+                          '/' + vel_topic_name
+                          if len(vel_topic_name) > 0
+                          else '')
+        throttle_url = '/{0}eventListener/v{1}/clientThrottlingState'.\
+                       format(vel_path, api_version)
+        set_404_content(root_url)
+        dispatcher = PathDispatcher()
+        vendor_event_listener = partial(listener, schema = vel_schema)
+        dispatcher.register('GET', root_url, vendor_event_listener)
+        dispatcher.register('POST', root_url, vendor_event_listener)
+        vendor_throttle_listener = partial(listener, schema = throttle_schema)
+        dispatcher.register('GET', throttle_url, vendor_throttle_listener)
+        dispatcher.register('POST', throttle_url, vendor_throttle_listener)
+
+        #----------------------------------------------------------------------
+        # We also add a POST-only mechanism for test control, so that we can
+        # send commands to a single attached client.
+        #----------------------------------------------------------------------
+        test_control_url = '/testControl/v{0}/commandList'.format(api_version)
+        test_control_listener = partial(test_listener,
+                                        schema = test_control_schema)
+        dispatcher.register('POST', test_control_url, test_control_listener)
+        dispatcher.register('GET', test_control_url, test_control_listener)
+
+        httpd = make_server('', int(vel_port), dispatcher)
+        print('Serving on port {0}...'.format(vel_port))
+        httpd.serve_forever()
+
+        logger.error('Main loop exited unexpectedly!')
+        return 0
+
+    except KeyboardInterrupt:
+        #----------------------------------------------------------------------
+        # handle keyboard interrupt
+        #----------------------------------------------------------------------
+        logger.info('Exiting on keyboard interrupt!')
+        return 0
+
+    except Exception as e:
+        #----------------------------------------------------------------------
+        # Handle unexpected exceptions.
+        #----------------------------------------------------------------------
+        if DEBUG or TESTRUN:
+            raise(e)
+        indent = len(program_name) * ' '
+        sys.stderr.write(program_name + ': ' + repr(e) + '\n')
+        sys.stderr.write(indent + '  for help use --help\n')
+        sys.stderr.write(traceback.format_exc())
+        logger.critical('Exiting because of exception: {0}'.format(e))
+        logger.critical(traceback.format_exc())
+        return 2
+
+#------------------------------------------------------------------------------
+# MAIN SCRIPT ENTRY POINT.
+#------------------------------------------------------------------------------
+if __name__ == '__main__':
+    if TESTRUN:
+        #----------------------------------------------------------------------
+        # Running tests - note that doctest comments haven't been included so
+        # this is a hook for future improvements.
+        #----------------------------------------------------------------------
+        import doctest
+        doctest.testmod()
+
+    if PROFILE:
+        #----------------------------------------------------------------------
+        # Profiling performance.  Performance isn't expected to be a major
+        # issue, but this should all work as expected.
+        #----------------------------------------------------------------------
+        import cProfile
+        import pstats
+        profile_filename = 'collector_profile.txt'
+        cProfile.run('main()', profile_filename)
+        statsfile = open('collector_profile_stats.txt', 'wb')
+        p = pstats.Stats(profile_filename, stream=statsfile)
+        stats = p.strip_dirs().sort_stats('cumulative')
+        stats.print_stats()
+        statsfile.close()
+        sys.exit(0)
+
+    #--------------------------------------------------------------------------
+    # Normal operation - call through to the main function.
+    #--------------------------------------------------------------------------
+    sys.exit(main())
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/rest_dispatcher.py b/veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/rest_dispatcher.py
new file mode 100644 (file)
index 0000000..e3b51aa
--- /dev/null
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+'''
+Simple dispatcher for the REST API.
+
+Only intended for test purposes.
+
+License
+-------
+
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+'''
+
+import logging
+logger = logging.getLogger('collector.disp')
+
+base_url = ''
+
+template_404 = b'''POST {0}'''
+
+def set_404_content(url):
+    '''
+    Called at initialization to set the base URL so that we can serve helpful
+    diagnostics as part of the 404 response. 
+    '''
+    global base_url
+    base_url = url
+    return
+
+def notfound_404(environ, start_response):
+    '''
+    Serve the 404 Not Found response.
+    
+    Provides diagnostics in the 404 response showing the hierarchy of valid
+    REST resources.
+    '''
+    logger.warning('Unexpected URL/Method: {0} {1}'.format(
+                                             environ['REQUEST_METHOD'].upper(),
+                                             environ['PATH_INFO']))
+    start_response('404 Not Found', [ ('Content-type', 'text/plain') ])
+    return [template_404.format(base_url)]
+
+class PathDispatcher:
+    '''
+    A dispatcher which can take HTTP requests in a WSGI environment and invoke
+    appropriate methods for each request.
+    '''
+    def __init__(self):
+        '''Constructor: initialize the pathmap to be empty.'''
+        self.pathmap = { }
+
+    def __call__(self, environ, start_response):
+        '''
+        The main callable that the WSGI app will invoke with each request.
+        '''
+        #----------------------------------------------------------------------
+        # Extract the method and path from the environment.
+        #----------------------------------------------------------------------
+        method = environ['REQUEST_METHOD'].lower()
+        path = environ['PATH_INFO']
+        logger.info('Dispatcher called for: {0} {1}'.format(method, path))
+        logger.debug('Dispatcher environment is: {0}'.format(environ))
+
+        #----------------------------------------------------------------------
+        # See if we have a handler for this path, and if so invoke it.
+        # Otherwise, return a 404.
+        #----------------------------------------------------------------------
+        handler = self.pathmap.get((method, path), notfound_404)
+        logger.debug('Dispatcher will use handler: {0}'.format(handler))
+        return handler(environ, start_response)
+
+    def register(self, method, path, function):
+        '''
+        Register a handler for a method/path, adding it to the pathmap.
+        '''
+        logger.debug('Registering for {0} at {1}'.format(method, path))
+        print('Registering for {0} at {1}'.format(method, path))
+        self.pathmap[method.lower(), path] = function
+        return function
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/test_control.py b/veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/test_control.py
new file mode 100644 (file)
index 0000000..8783d30
--- /dev/null
@@ -0,0 +1,180 @@
+#!/usr/bin/env python
+'''
+Example script to inject a throttling command list to the test_collector.
+
+Only intended for test purposes.
+
+License
+-------
+
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+'''
+import optparse
+import requests
+import json
+
+###############################################################################
+# Functions to build up commandList contents
+###############################################################################
+def command_state():
+    "return a provideThrottlingState command"
+    return {'command':
+            {'commandType': 'provideThrottlingState'}}
+
+def command_interval(interval):
+    "return a measurementIntervalChange command"
+    return {'command':
+            {'commandType': 'measurementIntervalChange',
+             'measurementInterval': interval}}
+
+def command_throttle(domain, fields, pairs):
+    "return a throttlingSpecification"
+    throttle_spec = {'eventDomain' : domain}
+    if len(fields):
+        throttle_spec['suppressedFieldNames'] = fields
+    if len(pairs):
+        throttle_spec['suppressedNvPairsList'] = pairs
+    return {'command':
+            {'commandType': 'throttlingSpecification',
+             'eventDomainThrottleSpecification': throttle_spec}}
+
+def command_nvpairs(field_name, pair_names):
+    "return a suppressedNvPairs"
+    return {'nvPairFieldName' : field_name,
+            'suppressedNvPairNames' : pair_names}
+
+###############################################################################
+# Example functions to build up commandLists for various domains.
+###############################################################################
+def command_list_empty():
+    return {'commandList' : []}
+
+def command_list_provide():
+    return {'commandList' : [command_state()]}
+
+def command_list_interval(interval):
+    return {'commandList' : [command_interval(interval)]}
+
+def command_list_fault_suppress_fields():
+    "Throttling Specification - two suppressedFieldNames"
+    fields = ['alarmInterfaceA', 'alarmAdditionalInformation']
+    pairs = []
+    command_list = [command_throttle('fault', fields, pairs)]
+    return {'commandList' : command_list}
+
+def command_list_fault_suppress_nothing():
+    "Throttling Specification - no suppression"
+    fields = []
+    pairs = []
+    command_list = [command_throttle('fault', fields, pairs)]
+    return {'commandList' : command_list}
+
+def command_list_fault_suppress_pairs():
+    "Throttling Specification - two suppressedNvPairNames"
+    fields = []
+    pairs = [command_nvpairs('alarmAdditionalInformation',
+                                   ['name1', 'name2'])]
+    command_list = [command_throttle('fault', fields, pairs)]
+    return {'commandList' : command_list}
+
+def command_list_fault_suppress_fields_and_pairs():
+    "Throttling Specification - a mixture of fields and pairs"
+    fields = ['alarmInterfaceA']
+    pairs = [command_nvpairs('alarmAdditionalInformation',
+                                   ['name1', 'name2'])]
+    command_list = [command_throttle('fault', fields, pairs)]
+    return {'commandList' : command_list}
+
+def command_list_measurements_suppress_example():
+    "Throttling Specification - measurements"
+    fields = ['numberOfMediaPortsInUse', 'aggregateCpuUsage']
+    pairs = [command_nvpairs('cpuUsageArray',
+                             ['cpu1', 'cpu3'])]
+    command_list = [command_throttle('measurementsForVfScaling',
+                                     fields, pairs)]
+    return {'commandList' : command_list}
+
+def command_list_mobile_flow_suppress_example():
+    "Throttling Specification - mobile flow"
+    fields = ['radioAccessTechnology', 'samplingAlgorithm']
+    pairs = []
+    command_list = [command_throttle('mobileFlow', fields, pairs)]
+    return {'commandList' : command_list}
+
+def command_list_state_change_suppress_example():
+    "Throttling Specification - state change"
+    fields = ['reportingEntityId', 'eventType', 'sourceId']
+    pairs = [command_nvpairs('additionalFields', ['Name1'])]
+    command_list = [command_throttle('stateChange', fields, pairs)]
+    return {'commandList' : command_list}
+
+def command_list_syslog_suppress_example():
+    "Throttling Specification - syslog"
+    fields = ['syslogFacility', 'syslogProc', 'syslogProcId']
+    pairs = [command_nvpairs('additionalFields', ['Name1', 'Name4'])]
+    command_list = [command_throttle('syslog', fields, pairs)]
+    return {'commandList' : command_list}
+
+def command_list_reset_all_domains():
+    "Throttling Specification - reset all domains"
+    command_list = [command_throttle('fault', [], []),
+                    command_throttle('measurementsForVfScaling', [], []),
+                    command_throttle('mobileFlow', [], []),
+                    command_throttle('stateChange', [], []),
+                    command_throttle('syslog', [], [])]
+    return {'commandList' : command_list}
+
+def mixed_example():
+    fields = ['alarmInterfaceA']
+    pairs = [command_nvpairs('alarmAdditionalInformation',
+                             ['name1', 'name2'])]
+    command_list = [command_throttle('fault', fields, pairs),
+                    command_interval(10),
+                    command_state()]
+    return {'commandList' : command_list}
+
+###############################################################################
+# Default command line values
+###############################################################################
+DEFAULT_FQDN = "127.0.0.1"
+DEFAULT_PORT = 30000
+
+###############################################################################
+# Command Line Parsing
+###############################################################################
+parser = optparse.OptionParser()
+parser.add_option('--fqdn',
+                  action="store",
+                  dest="fqdn",
+                  default=DEFAULT_FQDN)
+parser.add_option('--port',
+                  action="store",
+                  dest="port",
+                  default=DEFAULT_PORT,
+                  type="int")
+options, remainder = parser.parse_args()
+
+###############################################################################
+# Derive the Test Control URL
+###############################################################################
+url = 'http://%s:%d/testControl/v1.1/commandList'%(options.fqdn, options.port)
+
+###############################################################################
+# Create JSON and POST it to the Test Control URL.
+###############################################################################
+command_list = command_list_fault_suppress_fields_and_pairs()
+requests.post(url, json = command_list)
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/config/collector.conf b/veslibrary/ves_clibrary/evel/evel-test-collector/config/collector.conf
new file mode 100644 (file)
index 0000000..3e23c59
--- /dev/null
@@ -0,0 +1,99 @@
+# * ===================================================================
+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+# * ===================================================================
+# * Licensed under the Apache License, Version 2.0 (the "License");
+# * you may not use this file except in compliance with the License.
+# * You may obtain a copy of the License at
+# *
+# *        http://www.apache.org/licenses/LICENSE-2.0
+# *
+# * Unless required by applicable law or agreed to in writing, software
+# * distributed under the License is distributed on an "AS IS" BASIS,
+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# * See the License for the specific language governing permissions and
+# * limitations under the License.
+# * ECOMP and OpenECOMP are trademarks
+# * and service marks of AT&T Intellectual Property.
+#------------------------------------------------------------------------------
+# This is a config file for the collector test harness.
+#
+# On the target platform is is expected to be located in:
+#
+#   /etc/opt/att/collector.conf
+#
+# However, the location can be overridden by setting the --config <file>
+# argument to the collector code.
+#------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------
+# The default section to be used. Alternative configuration sections can be
+# provided by using the --section <name> command-line parameter.
+#------------------------------------------------------------------------------
+[default]
+log_file = /var/log/att/collector.log
+schema_file = ../../docs/att_interface_definition/event_format_updated.json
+base_schema_file = ../../docs/att_interface_definition/base_schema.json
+throttle_schema_file = ../../docs/att_interface_definition/throttle_schema.json
+test_control_schema_file = ../../docs/att_interface_definition/test_control_schema.json
+
+#------------------------------------------------------------------------------
+# Details of the Vendor Event Listener REST service.
+#
+# REST resources are defined with respect to a ServerRoot:
+#    ServerRoot = https://{Domain}:{Port}/{optionalRoutingPath}
+#
+# REST resources are of the form:
+#   *   {ServerRoot}/eventListener/v{apiVersion}
+#   *   {ServerRoot}/eventListener/v{apiVersion}/{topicName}
+#   *   {ServerRoot}/eventListener/v{apiVersion}/eventBatch
+#   *   {ServerRoot}/eventListener/v{apiVersion}/clientThrottlingState
+#
+# The "vel_topic_name" parameter is used as the "topicName" element in the path
+# and may be empty.
+#
+# Note that the path, if present,  should have no leading "/" but should have a
+# training "/".
+#------------------------------------------------------------------------------
+vel_domain = 127.0.0.1
+vel_port = 30000
+vel_path = vendor_event_listener/
+vel_username =
+vel_password =
+vel_topic_name = example_vnf
+
+#------------------------------------------------------------------------------
+# Settings to be used when running in a windows test environment rather than
+# the target environment.
+#------------------------------------------------------------------------------
+[windows]
+log_file = ../../logs/collector.log
+schema_file = ../../docs/att_interface_definition/event_format_updated.json
+base_schema_file =
+throttle_schema_file = ../../docs/att_interface_definition/throttle_schema.json
+test_control_schema_file = ../../docs/att_interface_definition/test_control_schema.json
+
+#------------------------------------------------------------------------------
+# Details of the Vendor Event Listener REST service.
+#
+# REST resources are defined with respect to a ServerRoot:
+#    ServerRoot = https://{Domain}:{Port}/{optionalRoutingPath}
+#
+# REST resources are of the form:
+#   *   {ServerRoot}/eventListener/v{apiVersion}
+#   *   {ServerRoot}/eventListener/v{apiVersion}/{topicName}
+#   *   {ServerRoot}/eventListener/v{apiVersion}/eventBatch
+#   *   {ServerRoot}/eventListener/v{apiVersion}/clientThrottlingState
+#
+# The "vel_topic_name" parameter is used as the "topicName" element in the path
+# and may be empty.
+#
+# Note that the path, if present,  should have no leading "/" but should have a
+# training "/".
+#------------------------------------------------------------------------------
+vel_domain = 127.0.0.1
+vel_port = 30000
+vel_path =
+vel_username = will
+vel_password = pill
+vel_topic_name =
+
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/LICENSE.TXT b/veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/LICENSE.TXT
new file mode 100644 (file)
index 0000000..ae12da2
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * ============LICENSE_START==========================================
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ *
+ * ECOMP and OpenECOMP are trademarks 
+ * and service marks of AT&T Intellectual Property.
+ *
+ */
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/base_schema.json b/veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/base_schema.json
new file mode 100644 (file)
index 0000000..8efd08a
--- /dev/null
@@ -0,0 +1,10 @@
+       {
+               "$schema": "http://json-schema.org/draft-04/schema#",
+
+    "title": "Vendor Event Listener API updated",
+               "type": "object",
+               "properties": {
+                 "event": {"$ref": "#/definitions/event"}
+                 },
+               "required": ["event"]
+}
\ No newline at end of file
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/event_format_updated.json b/veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/event_format_updated.json
new file mode 100644 (file)
index 0000000..82339b0
--- /dev/null
@@ -0,0 +1,1885 @@
+{\r
+    "$schema": "http://json-schema.org/draft-04/schema#",\r
+       \r
+       "definitions": {\r
+                       "attCopyrightNotice": {\r
+                               "description": "Copyright (c) <2017>, AT&T Intellectual Property. All rights reserved. Licensed under the Apache License, Version 2.0 (the License)",\r
+                               "type": "object",\r
+                               "properties": {\r
+                                       "useAndRedistribution": {\r
+                                               "description": "You may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0",\r
+                                               "type": "string"\r
+                                       },\r
+                                       "licenseLink": "http://www.apache.org/licenses/LICENSE-2.0",\r
+                                       "condition1": {\r
+                                               "description": "Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an AS IS BASIS,",\r
+                                               "type": "string"\r
+                                       },\r
+                                       "condition2": {\r
+                                               "description": "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.",\r
+                                               "type": "string"\r
+                                       },\r
+                                       "condition3": {\r
+                                               "description": "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.",\r
+                                               "type": "string"\r
+                                       },\r
+                                       "condition4": {\r
+                                               "description": "See the License for the specific language governing permissions and limitations under the License.",\r
+                                               "type": "string"\r
+                                       },\r
+                                       "Trademarks": {\r
+                                               "description": "ECOMP and OpenECOMP are trademarks and service marks of AT&T Intellectual Property.",\r
+                                               "type": "string"\r
+                                       }\r
+                                  }\r
+                               },\r
+               "codecsInUse": {\r
+                       "description": "number of times an identified codec was used over the measurementInterval",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "codecIdentifier": { "type": "string" },\r
+                               "numberInUse": { "type": "integer" }\r
+                       },\r
+                       "required": [ "codecIdentifier", "numberInUse" ]\r
+               },\r
+               "command": {\r
+                       "description": "command from an event collector toward an event source",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "commandType": {\r
+                                       "type": "string",\r
+                                       "enum": [\r
+                                               "heartbeatIntervalChange",\r
+                                               "measurementIntervalChange",\r
+                                               "provideThrottlingState",\r
+                                               "throttlingSpecification"\r
+                                       ]\r
+                               },\r
+                               "eventDomainThrottleSpecification": { "$ref": "#/definitions/eventDomainThrottleSpecification" },\r
+                               "heartbeatInterval": { "type": "integer" },\r
+                               "measurementInterval": { "type": "integer" }\r
+                       },\r
+                       "required": [ "commandType" ]\r
+               },\r
+               "commandList": {\r
+                       "description": "array of commands from an event collector toward an event source",\r
+                       "type": "array",\r
+                       "items": {\r
+                           "$ref": "#/definitions/commandListEntry"\r
+                       },\r
+                       "minItems": 0\r
+               },\r
+               "commandListEntry": {\r
+                       "description": "reference to a command object",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "command": {"$ref": "#/definitions/command"}\r
+                       },\r
+                       "required": [ "command" ]\r
+               },\r
+               "commonEventHeader": {\r
+                       "description": "fields common to all events",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "domain": {\r
+                                       "description": "the eventing domain associated with the event",\r
+                                       "type": "string",\r
+                                       "enum": [\r
+                                               "fault",\r
+                                               "heartbeat",\r
+                                               "measurementsForVfScaling",\r
+                                               "mobileFlow",\r
+                                               "other",\r
+                                               "sipSignaling",\r
+                                               "stateChange",\r
+                                               "syslog",\r
+                                               "thresholdCrossingAlert",\r
+                                               "voiceQuality"\r
+                                       ]\r
+                               },\r
+                               "eventId": {\r
+                                       "description": "event key that is unique to the event source",\r
+                                       "type": "string"\r
+                               },\r
+                               "eventName": {\r
+                                       "description": "unique event name",\r
+                                       "type": "string"\r
+                               },\r
+                               "eventType": {\r
+                                       "description": "for example - applicationVnf, guestOS, hostOS, platform",\r
+                                       "type": "string"\r
+                               },\r
+                               "internalHeaderFields": { "$ref": "#/definitions/internalHeaderFields" },\r
+                               "lastEpochMicrosec": {\r
+                                       "description": "the latest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",\r
+                                       "type": "number"\r
+                               },\r
+                               "nfcNamingCode": {\r
+                                       "description": "3 character network function component type, aligned with vfc naming standards",\r
+                                       "type": "string"\r
+                               },\r
+                               "nfNamingCode": {\r
+                                       "description": "4 character network function type, aligned with vnf naming standards",\r
+                                       "type": "string"\r
+                               },\r
+                               "priority": {\r
+                                       "description": "processing priority",\r
+                                       "type": "string",\r
+                                       "enum": [\r
+                                               "High",\r
+                                               "Medium",\r
+                                               "Normal",\r
+                                               "Low"\r
+                                       ]\r
+                               },\r
+                               "reportingEntityId": {\r
+                                       "description": "UUID identifying the entity reporting the event, for example an OAM VM; must be populated by the ATT enrichment process",\r
+                                       "type": "string"\r
+                               },\r
+                               "reportingEntityName": {\r
+                                       "description": "name of the entity reporting the event, for example, an EMS name; may be the same as sourceName",\r
+                                       "type": "string"\r
+                               },\r
+                               "sequence": {\r
+                                       "description": "ordering of events communicated by an event source instance or 0 if not needed",\r
+                                       "type": "integer"\r
+                               },\r
+                               "sourceId": {\r
+                                       "description": "UUID identifying the entity experiencing the event issue; must be populated by the ATT enrichment process",\r
+                                       "type": "string"\r
+                               },\r
+                               "sourceName": {\r
+                                       "description": "name of the entity experiencing the event issue",\r
+                                       "type": "string"\r
+                               },\r
+                               "startEpochMicrosec": {\r
+                                       "description": "the earliest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",\r
+                                       "type": "number"\r
+                               },\r
+                               "version": {\r
+                                       "description": "version of the event header",\r
+                                       "type": "number"\r
+                               }\r
+                       },\r
+                       "required": [ "domain", "eventId", "eventName", "lastEpochMicrosec", \r
+                                                 "priority", "reportingEntityName", "sequence", "sourceName",\r
+                                     "startEpochMicrosec", "version" ]\r
+               },\r
+               "counter": {\r
+                       "description": "performance counter",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "criticality": { "type": "string", "enum": [ "CRIT", "MAJ" ] },\r
+                               "name":  { "type": "string" },\r
+                               "thresholdCrossed": { "type": "string" },\r
+                               "value": { "type": "string"}\r
+                       },\r
+                       "required": [ "criticality", "name", "thresholdCrossed", "value" ]\r
+               },\r
+               "cpuUsage": {\r
+                       "description": "usage of an identified CPU",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "cpuIdentifier": { \r
+                    "description": "cpu identifer",\r
+                    "type": "string" \r
+                },\r
+                               "cpuIdle": { \r
+                    "description": "percentage of CPU time spent in the idle task",\r
+                    "type": "number" \r
+                },\r
+                               "cpuUsageInterrupt": { \r
+                    "description": "percentage of time spent servicing interrupts",\r
+                    "type": "number" \r
+                },\r
+                               "cpuUsageNice": { \r
+                    "description": "percentage of time spent running user space processes that have been niced",\r
+                    "type": "number" \r
+                },\r
+                               "cpuUsageSoftIrq": { \r
+                    "description": "percentage of time spent handling soft irq interrupts",\r
+                    "type": "number" \r
+                },\r
+                               "cpuUsageSteal": { \r
+                    "description": "percentage of time spent in involuntary wait which is neither user, system or idle time and is effectively time that went missing",\r
+                    "type": "number" \r
+                },\r
+                               "cpuUsageSystem": { \r
+                    "description": "percentage of time spent on system tasks running the kernel",\r
+                    "type": "number" \r
+                },\r
+                               "cpuUsageUser": { \r
+                    "description": "percentage of time spent running un-niced user space processes",\r
+                    "type": "number" \r
+                },\r
+                               "cpuWait": { \r
+                    "description": "percentage of CPU time spent waiting for I/O operations to complete",\r
+                    "type": "number" \r
+                },\r
+                               "percentUsage": { \r
+                    "description": "aggregate cpu usage of the virtual machine on which the VNFC reporting the event is running",\r
+                    "type": "number" \r
+                }\r
+                       },\r
+                       "required": [ "cpuIdentifier", "percentUsage" ]\r
+               },\r
+               "diskUsage": {\r
+                       "description": "usage of an identified disk",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "diskIdentifier": { \r
+                    "description": "disk identifier", \r
+                    "type": "string" \r
+                },\r
+                "diskIoTimeAvg": {\r
+                    "description": "milliseconds spent doing input/output operations over 1 sec; treat this metric as a device load percentage where 1000ms  matches 100% load; provide the average over the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskIoTimeLast": {\r
+                    "description": "milliseconds spent doing input/output operations over 1 sec; treat this metric as a device load percentage where 1000ms  matches 100% load; provide the last value measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskIoTimeMax": {\r
+                    "description": "milliseconds spent doing input/output operations over 1 sec; treat this metric as a device load percentage where 1000ms  matches 100% load; provide the maximum value measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskIoTimeMin": {\r
+                    "description": "milliseconds spent doing input/output operations over 1 sec; treat this metric as a device load percentage where 1000ms  matches 100% load; provide the minimum value measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskMergedReadAvg": {\r
+                    "description": "number of logical read operations that were merged into physical read operations, e.g., two logical reads were served by one physical disk access; provide the average measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskMergedReadLast": {\r
+                    "description": "number of logical read operations that were merged into physical read operations, e.g., two logical reads were served by one physical disk access; provide the last value measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskMergedReadMax": {\r
+                    "description": "number of logical read operations that were merged into physical read operations, e.g., two logical reads were served by one physical disk access; provide the maximum value measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskMergedReadMin": {\r
+                    "description": "number of logical read operations that were merged into physical read operations, e.g., two logical reads were served by one physical disk access; provide the minimum value measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskMergedWriteAvg": {\r
+                    "description": "number of logical write operations that were merged into physical write operations, e.g., two logical writes were served by one physical disk access; provide the average measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskMergedWriteLast": {\r
+                    "description": "number of logical write operations that were merged into physical write operations, e.g., two logical writes were served by one physical disk access; provide the last value measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskMergedWriteMax": {\r
+                    "description": "number of logical write operations that were merged into physical write operations, e.g., two logical writes were served by one physical disk access; provide the maximum value measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskMergedWriteMin": {\r
+                    "description": "number of logical write operations that were merged into physical write operations, e.g., two logical writes were served by one physical disk access; provide the minimum value measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOctetsReadAvg": {\r
+                    "description": "number of octets per second read from a disk or partition; provide the average measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOctetsReadLast": {\r
+                    "description": "number of octets per second read from a disk or partition; provide the last measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOctetsReadMax": {\r
+                    "description": "number of octets per second read from a disk or partition; provide the maximum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOctetsReadMin": {\r
+                    "description": "number of octets per second read from a disk or partition; provide the minimum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOctetsWriteAvg": {\r
+                    "description": "number of octets per second written to a disk or partition; provide the average measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOctetsWriteLast": {\r
+                    "description": "number of octets per second written to a disk or partition; provide the last measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOctetsWriteMax": {\r
+                    "description": "number of octets per second written to a disk or partition; provide the maximum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOctetsWriteMin": {\r
+                    "description": "number of octets per second written to a disk or partition; provide the minimum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOpsReadAvg": {\r
+                    "description": "number of read operations per second issued to the disk; provide the average measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOpsReadLast": {\r
+                    "description": "number of read operations per second issued to the disk; provide the last measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOpsReadMax": {\r
+                    "description": "number of read operations per second issued to the disk; provide the maximum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOpsReadMin": {\r
+                    "description": "number of read operations per second issued to the disk; provide the minimum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOpsWriteAvg": {\r
+                    "description": "number of write operations per second issued to the disk; provide the average measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOpsWriteLast": {\r
+                    "description": "number of write operations per second issued to the disk; provide the last measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOpsWriteMax": {\r
+                    "description": "number of write operations per second issued to the disk; provide the maximum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskOpsWriteMin": {\r
+                    "description": "number of write operations per second issued to the disk; provide the minimum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskPendingOperationsAvg": {\r
+                    "description": "queue size of pending I/O operations per second; provide the average measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskPendingOperationsLast": {\r
+                    "description": "queue size of pending I/O operations per second; provide the last measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskPendingOperationsMax": {\r
+                    "description": "queue size of pending I/O operations per second; provide the maximum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskPendingOperationsMin": {\r
+                    "description": "queue size of pending I/O operations per second; provide the minimum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskTimeReadAvg": {\r
+                    "description": "milliseconds a read operation took to complete; provide the average measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskTimeReadLast": {\r
+                    "description": "milliseconds a read operation took to complete; provide the last measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskTimeReadMax": {\r
+                    "description": "milliseconds a read operation took to complete; provide the maximum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskTimeReadMin": {\r
+                    "description": "milliseconds a read operation took to complete; provide the minimum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskTimeWriteAvg": {\r
+                    "description": "milliseconds a write operation took to complete; provide the average measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskTimeWriteLast": {\r
+                    "description": "milliseconds a write operation took to complete; provide the last measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskTimeWriteMax": {\r
+                    "description": "milliseconds a write operation took to complete; provide the maximum measurement within the measurement interval",\r
+                    "type": "number"\r
+                },\r
+                "diskTimeWriteMin": {\r
+                    "description": "milliseconds a write operation took to complete; provide the minimum measurement within the measurement interval",\r
+                    "type": "number"\r
+                }\r
+                       },\r
+                       "required": [ "diskIdentifier" ]\r
+               },\r
+        "endOfCallVqmSummaries": {\r
+            "description": "provides end of call voice quality metrics",\r
+                       "type": "object",\r
+                       "properties": {\r
+                "adjacencyName": {\r
+                    "description": " adjacency name",\r
+                    "type": "string"\r
+                },\r
+                "endpointDescription": {\r
+                    "description": "Either Caller or Callee",\r
+                    "type": "string",\r
+                    "enum": ["Caller", "Callee"]\r
+                },\r
+                "endpointJitter": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "endpointRtpOctetsDiscarded": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "endpointRtpOctetsReceived": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "endpointRtpOctetsSent": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "endpointRtpPacketsDiscarded": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "endpointRtpPacketsReceived": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "endpointRtpPacketsSent": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "localJitter": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "localRtpOctetsDiscarded": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "localRtpOctetsReceived": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "localRtpOctetsSent": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "localRtpPacketsDiscarded": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "localRtpPacketsReceived": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "localRtpPacketsSent": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "mosCqe": {\r
+                    "description": "1-5 1dp",\r
+                    "type": "number"\r
+                },\r
+                "packetsLost": {\r
+                    "description": "",\r
+                    "type": "number"\r
+                },\r
+                "packetLossPercent": {\r
+                    "description" : "Calculated percentage packet loss based on Endpoint RTP packets lost (as reported in RTCP) and Local RTP packets sent. Direction is based on Endpoint description (Caller, Callee). Decimal (2 dp)",\r
+                    "type": "number"\r
+                },\r
+                "rFactor": {\r
+                    "description": "0-100",\r
+                    "type": "number"\r
+                },\r
+                "roundTripDelay": {\r
+                    "description": "millisecs",\r
+                    "type": "number"\r
+                }\r
+            },\r
+            "required": [ "adjacencyName", "endpointDescription" ]\r
+        },\r
+        "event": {\r
+            "description": "the root level of the common event format",\r
+               "type": "object",\r
+               "properties": {\r
+                       "commonEventHeader": { "$ref": "#/definitions/commonEventHeader" },\r
+                       "faultFields": { "$ref": "#/definitions/faultFields" },\r
+                       "heartbeatFields": { "$ref": "#/definitions/heartbeatFields" },\r
+                       "measurementsForVfScalingFields": { "$ref": "#/definitions/measurementsForVfScalingFields" },\r
+                               "mobileFlowFields": { "$ref": "#/definitions/mobileFlowFields" },\r
+                       "otherFields": { "$ref": "#/definitions/otherFields" },\r
+                       "sipSignalingFields": { "$ref": "#/definitions/sipSignalingFields" },\r
+                       "stateChangeFields": { "$ref": "#/definitions/stateChangeFields" },\r
+                               "syslogFields": { "$ref": "#/definitions/syslogFields" },\r
+                       "thresholdCrossingAlertFields": { "$ref": "#/definitions/thresholdCrossingAlertFields" },\r
+                       "voiceQualityFields": { "$ref": "#/definitions/voiceQualityFields" }\r
+               },\r
+            "required": [ "commonEventHeader" ]\r
+        },\r
+               "eventDomainThrottleSpecification": {\r
+                       "description": "specification of what information to suppress within an event domain",\r
+                       "type": "object",\r
+                       "properties": {\r
+                       "eventDomain": {\r
+                               "description": "Event domain enum from the commonEventHeader domain field",\r
+                               "type": "string"\r
+                       },\r
+                       "suppressedFieldNames": {\r
+                               "description": "List of optional field names in the event block that should not be sent to the Event Listener",\r
+                               "type": "array",\r
+                                       "items": {\r
+                                           "type": "string"\r
+                                       }\r
+                       },\r
+                               "suppressedNvPairsList": {\r
+                                       "description": "Optional list of specific NvPairsNames to suppress within a given Name-Value Field",\r
+                               "type": "array",\r
+                                       "items": {\r
+                                           "$ref": "#/definitions/suppressedNvPairs"\r
+                                       }\r
+                       }\r
+                       },\r
+                       "required": [ "eventDomain" ]\r
+               },\r
+               "eventDomainThrottleSpecificationList": {\r
+                       "description": "array of eventDomainThrottleSpecifications",\r
+                       "type": "array",\r
+                       "items": {\r
+                           "$ref": "#/definitions/eventDomainThrottleSpecification"\r
+                       },\r
+                       "minItems": 0\r
+               },\r
+               "eventList": {\r
+                       "description": "array of events",\r
+                       "type": "array",\r
+                       "items": {\r
+                               "$ref": "#/definitions/event"\r
+                       }\r
+               },\r
+               "eventThrottlingState": {\r
+                       "description": "reports the throttling in force at the event source",\r
+                       "type": "object",\r
+                       "properties": {\r
+                       "eventThrottlingMode": {\r
+                               "description": "Mode the event manager is in",\r
+                               "type": "string",\r
+                                       "enum": [\r
+                                               "normal",\r
+                                               "throttled"\r
+                                       ]\r
+                       },\r
+                               "eventDomainThrottleSpecificationList": { "$ref": "#/definitions/eventDomainThrottleSpecificationList" }\r
+                       },\r
+                       "required": [ "eventThrottlingMode" ]\r
+               },\r
+               "faultFields": {\r
+                       "description": "fields specific to fault events",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "alarmAdditionalInformation": {\r
+                                       "description": "additional alarm information",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/field"\r
+                                       }\r
+                               },\r
+                               "alarmCondition": {\r
+                                       "description": "alarm condition reported by the device",\r
+                                       "type": "string"\r
+                               },\r
+                               "alarmInterfaceA": {\r
+                                       "description": "card, port, channel or interface name of the device generating the alarm",\r
+                                       "type": "string"\r
+                               },\r
+                               "eventCategory": {\r
+                                       "description": "Event category, for example: license, link, routing, security, signaling",\r
+                                       "type": "string"\r
+                               },\r
+                               "eventSeverity": {\r
+                                       "description": "event severity",\r
+                                       "type": "string",\r
+                                       "enum": [\r
+                                               "CRITICAL",\r
+                                               "MAJOR",\r
+                                               "MINOR",\r
+                                               "WARNING",\r
+                                               "NORMAL"\r
+                                       ]\r
+                               },\r
+                               "eventSourceType": {\r
+                                       "description": "type of event source; examples: card, host, other, port, portThreshold, router, slotThreshold, switch, virtualMachine, virtualNetworkFunction",\r
+                                       "type": "string"\r
+                               },\r
+                               "faultFieldsVersion": {\r
+                                       "description": "version of the faultFields block",\r
+                                       "type": "number"\r
+                               },\r
+                               "specificProblem": {\r
+                                       "description": "short description of the alarm or problem",\r
+                                       "type": "string"\r
+                               },\r
+                               "vfStatus": {\r
+                                       "description": "virtual function status enumeration",\r
+                                       "type": "string",\r
+                                       "enum": [\r
+                                               "Active",\r
+                                               "Idle",\r
+                                               "Preparing to terminate",\r
+                                               "Ready to terminate",\r
+                                               "Requesting termination"\r
+                                       ]\r
+                               }\r
+                       },\r
+                       "required": [ "alarmCondition", "eventSeverity", "eventSourceType",\r
+                                     "faultFieldsVersion", "specificProblem", "vfStatus" ]\r
+               },\r
+               "featuresInUse": {\r
+                       "description": "number of times an identified feature was used over the measurementInterval",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "featureIdentifier": { "type": "string" },\r
+                               "featureUtilization": { "type": "integer" }\r
+                       },\r
+                       "required": [ "featureIdentifier", "featureUtilization" ]\r
+               },\r
+               "field": {\r
+                       "description": "name value pair",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "name":  { "type": "string" },\r
+                               "value": { "type": "string" }\r
+                       },\r
+                       "required": [ "name", "value" ]\r
+               },\r
+               "filesystemUsage": {\r
+                       "description": "disk usage of an identified virtual machine in gigabytes and/or gigabytes per second",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "blockConfigured": { "type": "number" },\r
+                               "blockIops": { "type": "number" },\r
+                               "blockUsed": { "type": "number" },\r
+                               "ephemeralConfigured": { "type": "number" },\r
+                               "ephemeralIops": { "type": "number" },\r
+                               "ephemeralUsed": { "type": "number" },\r
+                               "filesystemName": { "type": "string" }\r
+                       },\r
+                       "required": [ "blockConfigured", "blockIops", "blockUsed", "ephemeralConfigured",\r
+                                     "ephemeralIops", "ephemeralUsed", "filesystemName" ]\r
+               },\r
+               "gtpPerFlowMetrics": {\r
+                       "description": "Mobility GTP Protocol per flow metrics",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "avgBitErrorRate": {\r
+                                       "description": "average bit error rate",\r
+                                       "type": "number"\r
+                               },\r
+                               "avgPacketDelayVariation": {\r
+                                       "description": "Average packet delay variation or jitter in milliseconds for received packets: Average difference between the packet timestamp and time received for all pairs of consecutive packets",\r
+                                       "type": "number"\r
+                               },\r
+                               "avgPacketLatency": {\r
+                                       "description": "average delivery latency",\r
+                                       "type": "number"\r
+                               },\r
+                               "avgReceiveThroughput": {\r
+                                       "description": "average receive throughput",\r
+                                       "type": "number"\r
+                               },\r
+                               "avgTransmitThroughput": {\r
+                                       "description": "average transmit throughput",\r
+                                       "type": "number"\r
+                               },\r
+                               "durConnectionFailedStatus": {\r
+                                       "description": "duration of failed state in milliseconds, computed as the cumulative time between a failed echo request and the next following successful error request, over this reporting interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "durTunnelFailedStatus": {\r
+                                       "description": "Duration of errored state, computed as the cumulative time between a tunnel error indicator and the next following non-errored indicator, over this reporting interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "flowActivatedBy": {\r
+                                       "description": "Endpoint activating the flow",\r
+                                       "type": "string"\r
+                               },\r
+                               "flowActivationEpoch": {\r
+                                       "description": "Time the connection is activated in the flow (connection) being reported on, or transmission time of the first packet if activation time is not available",\r
+                                       "type": "number"\r
+                               },\r
+                               "flowActivationMicrosec": {\r
+                                       "description": "Integer microseconds for the start of the flow connection",\r
+                                       "type": "number"\r
+                               },\r
+                               "flowActivationTime": {\r
+                                       "description": "time the connection is activated in the flow being reported on, or transmission time of the first packet if activation time is not available; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",\r
+                                       "type": "string"\r
+                               },\r
+                               "flowDeactivatedBy": {\r
+                                       "description": "Endpoint deactivating the flow",\r
+                                       "type": "string"\r
+                               },\r
+                               "flowDeactivationEpoch": {\r
+                                       "description": "Time for the start of the flow connection, in integer UTC epoch time aka UNIX time",\r
+                                       "type": "number"\r
+                               },\r
+                               "flowDeactivationMicrosec": {\r
+                                       "description": "Integer microseconds for the start of the flow connection",\r
+                                       "type": "number"\r
+                               },\r
+                               "flowDeactivationTime": {\r
+                                       "description": "Transmission time of the first packet in the flow connection being reported on; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",\r
+                                       "type": "string"\r
+                               },\r
+                               "flowStatus": {\r
+                                       "description": "connection status at reporting time as a working / inactive / failed indicator value",\r
+                                       "type": "string"\r
+                               },\r
+                               "gtpConnectionStatus": {\r
+                                       "description": "Current connection state at reporting time",\r
+                                       "type": "string"\r
+                               },\r
+                               "gtpTunnelStatus": {\r
+                                       "description": "Current tunnel state  at reporting time",\r
+                                       "type": "string"\r
+                               },\r
+                               "ipTosCountList": {\r
+                                       "description": "array of key: value pairs where the keys are drawn from the IP Type-of-Service identifiers which range from '0' to '255', and the values are the count of packets that had those ToS identifiers in the flow",\r
+                    "type": "array",\r
+                    "items": {\r
+                                               "type": "array",\r
+                                               "items": [\r
+                                                       { "type": "string" },\r
+                                                       { "type": "number" }\r
+                                               ]\r
+                                       }\r
+                               },\r
+                               "ipTosList": {\r
+                                       "description": "Array of unique IP Type-of-Service values observed in the flow where values range from '0' to '255'",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "type": "string"\r
+                                       }\r
+                               },\r
+                               "largePacketRtt": {\r
+                                       "description": "large packet round trip time",\r
+                                       "type": "number"\r
+                               },\r
+                               "largePacketThreshold": {\r
+                                       "description": "large packet threshold being applied",\r
+                                       "type": "number"\r
+                               },\r
+                               "maxPacketDelayVariation": {\r
+                                       "description": "Maximum packet delay variation or jitter in milliseconds for received packets: Maximum of the difference between the packet timestamp and time received for all pairs of consecutive packets",\r
+                                       "type": "number"\r
+                               },\r
+                               "maxReceiveBitRate": {\r
+                                       "description": "maximum receive bit rate",\r
+                                       "type": "number"\r
+                               },\r
+                               "maxTransmitBitRate": {\r
+                                       "description": "maximum transmit bit rate",\r
+                                       "type": "number"\r
+                               },\r
+                               "mobileQciCosCountList": {\r
+                                       "description": "array of key: value pairs where the keys are drawn from LTE QCI or UMTS class of service strings, and the values are the count of packets that had those strings in the flow",\r
+                    "type": "array",\r
+                    "items": {\r
+                                               "type": "array",\r
+                                               "items": [\r
+                                                       { "type": "string" },\r
+                                                       { "type": "number" }\r
+                                               ]\r
+                                       }\r
+                               },\r
+                               "mobileQciCosList": {\r
+                                       "description": "Array of unique LTE QCI or UMTS class-of-service values observed in the flow",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "type": "string"\r
+                                       }\r
+                               },\r
+                               "numActivationFailures": {\r
+                                       "description": "Number of failed activation requests, as observed by the reporting node",\r
+                                       "type": "number"\r
+                               },\r
+                               "numBitErrors": {\r
+                                       "description": "number of errored bits",\r
+                                       "type": "number"\r
+                               },\r
+                               "numBytesReceived": {\r
+                                       "description": "number of bytes received, including retransmissions",\r
+                                       "type": "number"\r
+                               },\r
+                               "numBytesTransmitted": {\r
+                                       "description": "number of bytes transmitted, including retransmissions",\r
+                                       "type": "number"\r
+                               },\r
+                               "numDroppedPackets": {\r
+                                       "description": "number of received packets dropped due to errors per virtual interface",\r
+                                       "type": "number"\r
+                               },\r
+                               "numGtpEchoFailures": {\r
+                                       "description": "Number of Echo request path failures where failed paths are defined in 3GPP TS 29.281 sec 7.2.1 and 3GPP TS 29.060 sec. 11.2",\r
+                                       "type": "number"\r
+                               },\r
+                               "numGtpTunnelErrors": {\r
+                                       "description": "Number of tunnel error indications where errors are defined in 3GPP TS 29.281 sec 7.3.1 and 3GPP TS 29.060 sec. 11.1",\r
+                                       "type": "number"\r
+                               },\r
+                               "numHttpErrors": {\r
+                                       "description": "Http error count",\r
+                                       "type": "number"\r
+                               },\r
+                               "numL7BytesReceived": {\r
+                                       "description": "number of tunneled layer 7 bytes received, including retransmissions",\r
+                                       "type": "number"\r
+                               },\r
+                               "numL7BytesTransmitted": {\r
+                                       "description": "number of tunneled layer 7 bytes transmitted, excluding retransmissions",\r
+                                       "type": "number"\r
+                               },\r
+                               "numLostPackets": {\r
+                                       "description": "number of lost packets",\r
+                                       "type": "number"\r
+                               },\r
+                               "numOutOfOrderPackets": {\r
+                                       "description": "number of out-of-order packets",\r
+                                       "type": "number"\r
+                               },\r
+                               "numPacketErrors": {\r
+                                       "description": "number of errored packets",\r
+                                       "type": "number"\r
+                               },\r
+                               "numPacketsReceivedExclRetrans": {\r
+                                       "description": "number of packets received, excluding retransmission",\r
+                                       "type": "number"\r
+                               },\r
+                               "numPacketsReceivedInclRetrans": {\r
+                                       "description": "number of packets received, including retransmission",\r
+                                       "type": "number"\r
+                               },\r
+                               "numPacketsTransmittedInclRetrans": {\r
+                                       "description": "number of packets transmitted, including retransmissions",\r
+                                       "type": "number"\r
+                               },\r
+                               "numRetries": {\r
+                                       "description": "number of packet retries",\r
+                                       "type": "number"\r
+                               },\r
+                               "numTimeouts": {\r
+                                       "description": "number of packet timeouts",\r
+                                       "type": "number"\r
+                               },\r
+                               "numTunneledL7BytesReceived": {\r
+                                       "description": "number of tunneled layer 7 bytes received, excluding retransmissions",\r
+                                       "type": "number"\r
+                               },\r
+                               "roundTripTime": {\r
+                                       "description": "round trip time",\r
+                                       "type": "number"\r
+                               },\r
+                               "tcpFlagCountList": {\r
+                                       "description": "array of key: value pairs where the keys are drawn from TCP Flags and the values are the count of packets that had that TCP Flag in the flow",\r
+                    "type": "array",\r
+                    "items": {\r
+                                               "type": "array",\r
+                                               "items": [\r
+                                                       { "type": "string" },\r
+                                                       { "type": "number" }\r
+                                               ]\r
+                                       }\r
+                               },\r
+                               "tcpFlagList": {\r
+                                       "description": "Array of unique TCP Flags observed in the flow",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "type": "string"\r
+                                       }\r
+                               },\r
+                               "timeToFirstByte": {\r
+                                       "description": "Time in milliseconds between the connection activation and first byte received",\r
+                                       "type": "number"\r
+                               }\r
+                       },\r
+                       "required": [ "avgBitErrorRate", "avgPacketDelayVariation", "avgPacketLatency",\r
+                          "avgReceiveThroughput", "avgTransmitThroughput",\r
+                                                 "flowActivationEpoch", "flowActivationMicrosec",\r
+                                                 "flowDeactivationEpoch", "flowDeactivationMicrosec",\r
+                          "flowDeactivationTime", "flowStatus",\r
+                                                 "maxPacketDelayVariation", "numActivationFailures",\r
+                                                 "numBitErrors", "numBytesReceived", "numBytesTransmitted",\r
+                                                 "numDroppedPackets", "numL7BytesReceived",\r
+                                                 "numL7BytesTransmitted", "numLostPackets",\r
+                                                 "numOutOfOrderPackets", "numPacketErrors",\r
+                                                 "numPacketsReceivedExclRetrans",\r
+                                                 "numPacketsReceivedInclRetrans",\r
+                                                 "numPacketsTransmittedInclRetrans",\r
+                                                 "numRetries", "numTimeouts", "numTunneledL7BytesReceived",\r
+                                                 "roundTripTime", "timeToFirstByte"\r
+                       ]\r
+               },\r
+               "heartbeatFields": {\r
+                       "description": "optional field block for fields specific to heartbeat events",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "additionalFields": {\r
+                                       "description": "additional heartbeat fields if needed",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/field"\r
+                                       }\r
+                               },\r
+                               "heartbeatFieldsVersion": {\r
+                                       "description": "version of the heartbeatFields block",\r
+                                       "type": "number"\r
+                               },\r
+                               "heartbeatInterval": {\r
+                                       "description": "current heartbeat interval in seconds",\r
+                                       "type": "integer"\r
+                               }\r
+                       },\r
+                       "required": [ "heartbeatFieldsVersion", "heartbeatInterval" ]\r
+               },\r
+               "internalHeaderFields": {\r
+                       "description": "enrichment fields for internal VES Event Listener service use only, not supplied by event sources",\r
+                       "type": "object"\r
+               },\r
+               "jsonObject": {\r
+                       "description": "json object schema, name and other meta-information along with one or more object instances",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "objectInstances":  {\r
+                    "description": "one or more instances of the jsonObject", \r
+                    "type": "array",\r
+                    "items": {\r
+                        "$ref": "#/definitions/jsonObjectInstance"     \r
+                    }                                  \r
+                },\r
+                               "objectName":  {\r
+                    "description": "name of the JSON Object", \r
+                    "type": "string" \r
+                },\r
+                               "objectSchema":  {\r
+                    "description": "json schema for the object", \r
+                    "type": "string" \r
+                },\r
+                               "objectSchemaUrl":  {\r
+                    "description": "Url to the json schema for the object", \r
+                    "type": "string" \r
+                },\r
+                               "nfSubscribedObjectName":  {\r
+                    "description": "name of the object associated with the nfSubscriptonId", \r
+                    "type": "string" \r
+                },\r
+                               "nfSubscriptionId":  {\r
+                    "description": "identifies an openConfig telemetry subscription on a network function, which configures the network function to send complex object data associated with the jsonObject", \r
+                    "type": "string" \r
+                }\r
+                       },\r
+                       "required": [ "objectInstances", "objectName" ]\r
+               },\r
+               "jsonObjectInstance": {\r
+                       "description": "meta-information about an instance of a jsonObject along with the actual object instance",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "objectInstance":  {\r
+                    "description": "an instance conforming to the jsonObject schema", \r
+                    "type": "object" \r
+                },\r
+                               "objectInstanceEpochMicrosec":  {\r
+                    "description": "the unix time aka epoch time associated with this objectInstance--as microseconds elapsed since 1 Jan 1970 not including leap seconds", \r
+                    "type": "number" \r
+                },\r
+                               "objectKeys":  {\r
+                    "description": "an ordered set of keys that identifies this particular instance of jsonObject", \r
+                    "type": "array",\r
+                    "items": {\r
+                        "$ref": "#/definitions/key"\r
+                    }                                  \r
+                }\r
+                       },\r
+                       "required": [ "objectInstance" ]\r
+               },\r
+               "key": {\r
+                       "description": "tuple which provides the name of a key along with its value and relative order",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "keyName": { \r
+                    "description": "name of the key", \r
+                                   "type": "string" \r
+                               },\r
+                               "keyOrder": { \r
+                    "description": "relative sequence or order of the key with respect to other keys", \r
+                                   "type": "integer" \r
+                               },\r
+                               "keyValue": { \r
+                    "description": "value of the key", \r
+                                   "type": "string" \r
+                               }\r
+                       },\r
+                       "required": [ "keyName" ]\r
+               },\r
+               "latencyBucketMeasure": {\r
+                       "description": "number of counts falling within a defined latency bucket",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "countsInTheBucket": { "type": "number" },\r
+                               "highEndOfLatencyBucket": { "type": "number" },\r
+                               "lowEndOfLatencyBucket":  { "type": "number" }\r
+                       },\r
+                       "required": [ "countsInTheBucket" ]\r
+               },\r
+               "measurementGroup": {\r
+                       "description": "measurement group",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "name":  { "type": "string" },\r
+                               "measurements": {\r
+                                       "description": "array of name value pair measurements",\r
+                                       "type": "array",\r
+                                       "items": {  \r
+                                               "$ref": "#/definitions/field" \r
+                                       }\r
+                               }\r
+                       },\r
+                       "required": [ "name", "measurements" ]\r
+               },\r
+               "measurementsForVfScalingFields": {\r
+                       "description": "measurementsForVfScaling fields",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "additionalFields": {\r
+                                       "description": "additional name-value-pair fields",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/field"\r
+                                       }\r
+                               },\r
+                               "additionalMeasurements": {\r
+                                       "description": "array of named name-value-pair arrays",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/namedArrayOfFields"\r
+                                       }\r
+                               },\r
+                "additionalObjects": {\r
+                    "description": "array of JSON objects described by name, schema and other meta-information",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                        "$ref": "#/definitions/jsonObject"\r
+                                       }\r
+                },\r
+                               "codecUsageArray": {\r
+                                       "description": "array of codecs in use",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/codecsInUse"\r
+                                       }\r
+                               },\r
+                               "concurrentSessions": {\r
+                                       "description": "peak concurrent sessions for the VM or VNF over the measurementInterval",\r
+                                       "type": "integer"\r
+                               },\r
+                               "configuredEntities": {\r
+                                       "description": "over the measurementInterval, peak total number of: users, subscribers, devices, adjacencies, etc., for the VM, or subscribers, devices, etc., for the VNF",\r
+                                       "type": "integer"\r
+                               },\r
+                               "cpuUsageArray": {\r
+                                       "description": "usage of an array of CPUs",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/cpuUsage"\r
+                                       }\r
+                               },\r
+                "diskUsageArray": {\r
+                                       "description": "usage of an array of disks",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/diskUsage"\r
+                                       }\r
+                               },\r
+                               "featureUsageArray": {\r
+                                       "description": "array of features in use",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/featuresInUse"\r
+                                       }\r
+                               },\r
+                               "filesystemUsageArray": {\r
+                                       "description": "filesystem usage of the VM on which the VNFC reporting the event is running",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/filesystemUsage"\r
+                                       }\r
+                               },\r
+                               "latencyDistribution": {\r
+                                       "description": "array of integers representing counts of requests whose latency in milliseconds falls within per-VNF configured ranges",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/latencyBucketMeasure"\r
+                                       }\r
+                               },\r
+                               "meanRequestLatency": {\r
+                                       "description": "mean seconds required to respond to each request for the VM on which the VNFC reporting the event is running",\r
+                                       "type": "number"\r
+                               },\r
+                               "measurementInterval": {\r
+                                       "description": "interval over which measurements are being reported in seconds",\r
+                                       "type": "number"\r
+                               },\r
+                               "measurementsForVfScalingVersion": {\r
+                                       "description": "version of the measurementsForVfScaling block",\r
+                                       "type": "number"\r
+                               },\r
+                               "memoryUsageArray": {\r
+                                       "description": "memory usage of an array of VMs",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/memoryUsage"\r
+                                       }\r
+                               },\r
+                               "numberOfMediaPortsInUse": {\r
+                                       "description": "number of media ports in use",\r
+                                       "type": "integer"\r
+                               },\r
+                               "requestRate": {\r
+                                       "description": "peak rate of service requests per second to the VNF over the measurementInterval",\r
+                                       "type": "number"\r
+                               },\r
+                               "vnfcScalingMetric": {\r
+                                       "description": "represents busy-ness of the VNF from 0 to 100 as reported by the VNFC",\r
+                                       "type": "integer"\r
+                               },\r
+                               "vNicPerformanceArray": {\r
+                                       "description": "usage of an array of virtual network interface cards",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/vNicPerformance"\r
+                                       }\r
+                               }\r
+                       },\r
+                       "required": [ "measurementInterval", "measurementsForVfScalingVersion" ]\r
+               },\r
+               "memoryUsage": {\r
+                       "description": "memory usage of an identified virtual machine",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "memoryBuffered": { \r
+                    "description": "kilobytes of temporary storage for raw disk blocks", \r
+                    "type": "number" \r
+                },\r
+                               "memoryCached": { \r
+                    "description": "kilobytes of memory used for cache", \r
+                    "type": "number" \r
+                },\r
+                               "memoryConfigured": { \r
+                    "description": "kilobytes of memory configured in the virtual machine on which the VNFC reporting the event is running", \r
+                    "type": "number" \r
+                },\r
+                               "memoryFree": { \r
+                    "description": "kilobytes of physical RAM left unused by the system", \r
+                    "type": "number" \r
+                },\r
+                               "memorySlabRecl": { \r
+                    "description": "the part of the slab that can be reclaimed such as caches measured in kilobytes", \r
+                    "type": "number" \r
+                },\r
+                               "memorySlabUnrecl": { \r
+                    "description": "the part of the slab that cannot be reclaimed even when lacking memory measured in kilobytes", \r
+                    "type": "number" \r
+                },\r
+                               "memoryUsed": { \r
+                    "description": "total memory minus the sum of free, buffered, cached and slab memory measured in kilobytes", \r
+                    "type": "number" \r
+                },\r
+                               "vmIdentifier": { \r
+                    "description": "virtual machine identifier associated with the memory metrics", \r
+                    "type": "string" \r
+                }\r
+                       },\r
+                       "required": [ "memoryFree", "memoryUsed", "vmIdentifier" ]\r
+               },\r
+               "mobileFlowFields": {\r
+                       "description": "mobileFlow fields",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "additionalFields": {\r
+                                       "description": "additional mobileFlow fields if needed",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/field"\r
+                                       }\r
+                               },\r
+                               "applicationType": {\r
+                                       "description": "Application type inferred",\r
+                                       "type": "string"\r
+                               },\r
+                               "appProtocolType": {\r
+                                       "description": "application protocol",\r
+                                       "type": "string"\r
+                               },\r
+                               "appProtocolVersion": {\r
+                                       "description": "application protocol version",\r
+                                       "type": "string"\r
+                               },\r
+                               "cid": {\r
+                                       "description": "cell id",\r
+                                       "type": "string"\r
+                               },\r
+                               "connectionType": {\r
+                                       "description": "Abbreviation referencing a 3GPP reference point e.g., S1-U, S11, etc",\r
+                                       "type": "string"\r
+                               },\r
+                               "ecgi": {\r
+                                       "description": "Evolved Cell Global Id",\r
+                                       "type": "string"\r
+                               },\r
+                               "flowDirection": {\r
+                                       "description": "Flow direction, indicating if the reporting node is the source of the flow or destination for the flow",\r
+                                       "type": "string"\r
+                               },\r
+                               "gtpPerFlowMetrics": { "$ref": "#/definitions/gtpPerFlowMetrics" },\r
+                               "gtpProtocolType": {\r
+                                       "description": "GTP protocol",\r
+                                       "type": "string"\r
+                               },\r
+                               "gtpVersion": {\r
+                                       "description": "GTP protocol version",\r
+                                       "type": "string"\r
+                               },\r
+                               "httpHeader": {\r
+                                       "description": "HTTP request header, if the flow connects to a node referenced by HTTP",\r
+                                       "type": "string"\r
+                               },\r
+                               "imei": {\r
+                                       "description": "IMEI for the subscriber UE used in this flow, if the flow connects to a mobile device",\r
+                                       "type": "string"\r
+                               },\r
+                               "imsi": {\r
+                                       "description": "IMSI for the subscriber UE used in this flow, if the flow connects to a mobile device",\r
+                                       "type": "string"\r
+                               },\r
+                               "ipProtocolType": {\r
+                                       "description": "IP protocol type e.g., TCP, UDP, RTP...",\r
+                                       "type": "string"\r
+                               },\r
+                               "ipVersion": {\r
+                                       "description": "IP protocol version e.g., IPv4, IPv6",\r
+                                       "type": "string"\r
+                               },\r
+                               "lac": {\r
+                                       "description": "location area code",\r
+                                       "type": "string"\r
+                               },\r
+                               "mcc": {\r
+                                       "description": "mobile country code",\r
+                                       "type": "string"\r
+                               },\r
+                               "mnc": {\r
+                                       "description": "mobile network code",\r
+                                       "type": "string"\r
+                               },\r
+                "mobileFlowFieldsVersion": {\r
+                    "description": "version of the mobileFlowFields block",\r
+                    "type": "number"\r
+                },\r
+                               "msisdn": {\r
+                                       "description": "MSISDN for the subscriber UE used in this flow, as an integer, if the flow connects to a mobile device",\r
+                                       "type": "string"\r
+                               },\r
+                               "otherEndpointIpAddress": {\r
+                                       "description": "IP address for the other endpoint, as used for the flow being reported on",\r
+                                       "type": "string"\r
+                               },\r
+                               "otherEndpointPort": {\r
+                                       "description": "IP Port for the reporting entity, as used for the flow being reported on",\r
+                                       "type": "integer"\r
+                               },\r
+                               "otherFunctionalRole": {\r
+                                       "description": "Functional role of the other endpoint for the flow being reported on e.g., MME, S-GW, P-GW, PCRF...",\r
+                                       "type": "string"\r
+                               },\r
+                               "rac": {\r
+                                       "description": "routing area code",\r
+                                       "type": "string"\r
+                               },\r
+                               "radioAccessTechnology": {\r
+                                       "description": "Radio Access Technology e.g., 2G, 3G, LTE",\r
+                                       "type": "string"\r
+                               },\r
+                               "reportingEndpointIpAddr": {\r
+                                       "description": "IP address for the reporting entity, as used for the flow being reported on",\r
+                                       "type": "string"\r
+                               },\r
+                               "reportingEndpointPort": {\r
+                                       "description": "IP port for the reporting entity, as used for the flow being reported on",\r
+                                       "type": "integer"\r
+                               },\r
+                               "sac": {\r
+                                       "description": "service area code",\r
+                                       "type": "string"\r
+                               },\r
+                               "samplingAlgorithm": {\r
+                                       "description": "Integer identifier for the sampling algorithm or rule being applied in calculating the flow metrics if metrics are calculated based on a sample of packets, or 0 if no sampling is applied",\r
+                                       "type": "integer"\r
+                               },\r
+                               "tac": {\r
+                                       "description": "transport area code",\r
+                                       "type": "string"\r
+                               },\r
+                               "tunnelId": {\r
+                                       "description": "tunnel identifier",\r
+                                       "type": "string"\r
+                               },\r
+                               "vlanId": {\r
+                                       "description": "VLAN identifier used by this flow",\r
+                                       "type": "string"\r
+                               }\r
+                       },\r
+                       "required": [ "flowDirection", "gtpPerFlowMetrics", "ipProtocolType", "ipVersion",\r
+                                     "mobileFlowFieldsVersion", "otherEndpointIpAddress", "otherEndpointPort",\r
+                                     "reportingEndpointIpAddr", "reportingEndpointPort" ]\r
+               },\r
+               "namedArrayOfFields": {\r
+                       "description": "an array of name value pairs along with a name for the array",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "name":  { "type": "string" },\r
+                               "arrayOfFields": {\r
+                                       "description": "array of name value pairs",\r
+                                       "type": "array",\r
+                                       "items": {  \r
+                                               "$ref": "#/definitions/field" \r
+                                       }\r
+                               }\r
+                       },\r
+                       "required": [ "name", "measurements" ]\r
+               },\r
+               "otherFields": {\r
+                       "description": "fields for events belonging to the 'other' domain of the commonEventHeader domain enumeration",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "hashOfNameValuePairArrays": {\r
+                                       "description": "array of named name-value-pair arrays",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/namedArrayOfFields"\r
+                                       }\r
+                               },\r
+                "jsonObjects": {\r
+                    "description": "array of JSON objects described by name, schema and other meta-information",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                        "$ref": "#/definitions/jsonObject"\r
+                                       }\r
+                },\r
+                               "nameValuePairs": {\r
+                                       "description": "array of name-value pairs",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/field"\r
+                                       }\r
+                               },                              \r
+                "otherFieldsVersion": {\r
+                    "description": "version of the otherFields block",\r
+                    "type": "number"\r
+                }\r
+            },\r
+            "required": [ "otherFieldsVersion" ]\r
+               },\r
+               "requestError": {\r
+                       "description": "standard request error data structure",\r
+                       "type": "object",\r
+                       "properties": {\r
+                           "messageId": {\r
+                                       "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",\r
+                                       "type": "string"\r
+                               },\r
+                               "text": {\r
+                                       "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",\r
+                                       "type": "string"\r
+                               },\r
+                               "url": {\r
+                                       "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",\r
+                                       "type": "string"\r
+                               },\r
+                               "variables": {\r
+                                       "description": "List of zero or more strings that represent the contents of the variables used by the message text",\r
+                                       "type": "string"\r
+                               }\r
+                       },\r
+                       "required": [ "messageId", "text" ]\r
+               },\r
+        "sipSignalingFields": {\r
+            "description": "sip signaling fields",\r
+            "type": "object",\r
+            "properties": {\r
+                "additionalInformation": {\r
+                                       "description": "additional sip signaling fields if needed",\r
+                                       "type": "array",\r
+                                       "items": {  \r
+                                               "$ref": "#/definitions/field" \r
+                                       }\r
+                },\r
+                "compressedSip": {\r
+                    "description": "the full SIP request/response including headers and bodies",\r
+                    "type": "string"\r
+                },\r
+                "correlator": {\r
+                    "description": "this is the same for all events on this call",\r
+                    "type": "string"\r
+                },\r
+                "localIpAddress": {\r
+                    "description": "IP address on VNF",\r
+                    "type": "string"\r
+                },\r
+                "localPort": {\r
+                    "description": "port on VNF",\r
+                    "type": "string"\r
+                },\r
+                "remoteIpAddress": {\r
+                    "description": "IP address of peer endpoint",\r
+                    "type": "string"\r
+                },\r
+                "remotePort": {\r
+                    "description": "port of peer endpoint",\r
+                    "type": "string"\r
+                },\r
+                "sipSignalingFieldsVersion": {\r
+                    "description": "version of the sipSignalingFields block",\r
+                    "type": "number"\r
+                },\r
+                "summarySip": {\r
+                    "description": "the SIP Method or Response (‘INVITE’, ‘200 OK’, ‘BYE’, etc)",\r
+                    "type": "string"\r
+                },\r
+                "vnfVendorNameFields": {\r
+                    "$ref": "#/definitions/vendorVnfNameFields"\r
+                }\r
+            },\r
+            "required": [ "correlator", "localIpAddress", "localPort", "remoteIpAddress", \r
+                                     "remotePort", "sipSignalingFieldsVersion", "vnfVendorNameFields" ]\r
+        },\r
+               "stateChangeFields": {\r
+                       "description": "stateChange fields",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "additionalFields": {\r
+                                       "description": "additional stateChange fields if needed",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/field"\r
+                                       }\r
+                               },\r
+                               "newState": {\r
+                                       "description": "new state of the entity",\r
+                                       "type": "string",\r
+                                       "enum": [\r
+                                               "inService",\r
+                                               "maintenance",\r
+                                               "outOfService"\r
+                                       ]\r
+                               },\r
+                               "oldState": {\r
+                                       "description": "previous state of the entity",\r
+                                       "type": "string",\r
+                                       "enum": [\r
+                                               "inService",\r
+                                               "maintenance",\r
+                                               "outOfService"\r
+                                       ]\r
+                               },\r
+                               "stateChangeFieldsVersion": {\r
+                                       "description": "version of the stateChangeFields block",\r
+                                       "type": "number"\r
+                               },\r
+                               "stateInterface": {\r
+                                       "description": "card or port name of the entity that changed state",\r
+                                       "type": "string"\r
+                               }\r
+                       },\r
+                       "required": [ "newState", "oldState", "stateChangeFieldsVersion", "stateInterface" ]\r
+               },\r
+               "suppressedNvPairs": {\r
+                       "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "nvPairFieldName": {\r
+                                       "description": "Name of the field within which are the nvpair names to suppress",\r
+                                       "type": "string"\r
+                               },\r
+                               "suppressedNvPairNames": {\r
+                                       "description": "Array of nvpair names to suppress within the nvpairFieldName",\r
+                               "type": "array",\r
+                                       "items": {\r
+                                           "type": "string"\r
+                                       }\r
+                               }\r
+                       },\r
+                       "required": [ "nvPairFieldName", "suppressedNvPairNames" ]\r
+               },\r
+               "syslogFields": {\r
+                       "description": "sysLog fields",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "additionalFields": {\r
+                                       "description": "additional syslog fields if needed provided as name=value delimited by a pipe ‘|’ symbol, for example: 'name1=value1|name2=value2|…'",\r
+                                       "type": "string"\r
+                               },\r
+                               "eventSourceHost": {\r
+                                       "description": "hostname of the device",\r
+                                       "type": "string"\r
+                               },\r
+                               "eventSourceType": {\r
+                                       "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",\r
+                                       "type": "string"\r
+                               },\r
+                               "syslogFacility": {\r
+                                       "description": "numeric code from 0 to 23 for facility--see table in documentation",\r
+                                       "type": "integer"\r
+                               },\r
+                               "syslogFieldsVersion": {\r
+                                       "description": "version of the syslogFields block",\r
+                                       "type": "number"\r
+                               },\r
+                               "syslogMsg": {\r
+                                       "description": "syslog message",\r
+                                       "type": "string"\r
+                               },\r
+                               "syslogPri": {\r
+                                       "description": "0-192 combined severity and facility",\r
+                                       "type": "integer"\r
+                               },\r
+                               "syslogProc": {\r
+                                       "description": "identifies the application that originated the message",\r
+                                       "type": "string"\r
+                               },\r
+                               "syslogProcId": {\r
+                                       "description": "a change in the value of this field indicates a discontinuity in syslog reporting",\r
+                                       "type": "number"\r
+                               },\r
+                               "syslogSData": {\r
+                                       "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",\r
+                                       "type": "string"\r
+                               },\r
+                               "syslogSdId": {\r
+                                       "description": "0-32 char in format name@number for example ourSDID@32473",\r
+                                       "type": "string"\r
+                               },\r
+                               "syslogSev": {\r
+                                       "description": "numerical Code for  severity derived from syslogPri as remaider of syslogPri / 8",\r
+                                       "type": "string",\r
+                                       "enum": [\r
+                                               "Alert",\r
+                                               "Critical",\r
+                                               "Debug",\r
+                                               "Emergency",\r
+                                               "Error",\r
+                                               "Info",\r
+                                               "Notice",\r
+                                               "Warning"\r
+                                       ]\r
+                               },\r
+                               "syslogTag": {\r
+                                       "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",\r
+                                       "type": "string"\r
+                               },\r
+                               "syslogVer": {\r
+                                       "description": "IANA assigned version of the syslog protocol specification - typically 1",\r
+                                       "type": "number"\r
+                               }\r
+                       },\r
+                       "required": [ "eventSourceType", "syslogFieldsVersion", "syslogMsg", "syslogTag" ]\r
+               },\r
+               "thresholdCrossingAlertFields": {\r
+                       "description": "fields specific to threshold crossing alert events",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "additionalFields": {\r
+                                       "description": "additional threshold crossing alert fields if needed",\r
+                                       "type": "array",\r
+                                       "items": {  \r
+                                               "$ref": "#/definitions/field" \r
+                                       }\r
+                               },\r
+                               "additionalParameters": {\r
+                                       "description": "performance counters",\r
+                                       "type": "array",\r
+                                       "items": {\r
+                                               "$ref": "#/definitions/counter"\r
+                                       }\r
+                               },\r
+                               "alertAction": {\r
+                                       "description": "Event action",\r
+                                       "type": "string",\r
+                                       "enum": [\r
+                                               "CLEAR",\r
+                                               "CONT",\r
+                                               "SET"\r
+                                       ]\r
+                               },\r
+                               "alertDescription": {\r
+                                       "description": "Unique short alert description such as IF-SHUB-ERRDROP",\r
+                                       "type": "string"\r
+                               },\r
+                               "alertType": {\r
+                                       "description": "Event type",\r
+                                       "type": "string",\r
+                                       "enum": [\r
+                                               "CARD-ANOMALY",\r
+                                               "ELEMENT-ANOMALY",\r
+                                               "INTERFACE-ANOMALY",\r
+                                               "SERVICE-ANOMALY"\r
+                                       ]\r
+                               },\r
+                               "alertValue": {\r
+                                       "description": "Calculated API value (if applicable)",\r
+                                       "type": "string"\r
+                               },\r
+                               "associatedAlertIdList": {\r
+                                       "description": "List of eventIds associated with the event being reported",\r
+                                       "type": "array",\r
+                                       "items": { "type": "string" }\r
+                               },\r
+                               "collectionTimestamp": {\r
+                                       "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",\r
+                                       "type": "string"\r
+                               },\r
+                               "dataCollector": {\r
+                                       "description": "Specific performance collector instance used",\r
+                                       "type": "string"\r
+                               },\r
+                               "elementType": {\r
+                                       "description": "type of network element - internal ATT field",\r
+                                       "type": "string"\r
+                               },\r
+                               "eventSeverity": {\r
+                                       "description": "event severity or priority",\r
+                                       "type": "string",\r
+                                       "enum": [\r
+                                               "CRITICAL",\r
+                                               "MAJOR",\r
+                                               "MINOR",\r
+                                               "WARNING",\r
+                                               "NORMAL"\r
+                                       ]\r
+                               },\r
+                               "eventStartTimestamp": {\r
+                                       "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",\r
+                                       "type": "string"\r
+                               },\r
+                               "interfaceName": {\r
+                                       "description": "Physical or logical port or card (if applicable)",\r
+                                       "type": "string"\r
+                               },\r
+                               "networkService": {\r
+                                       "description": "network name - internal ATT field",\r
+                                       "type": "string"\r
+                               },\r
+                               "possibleRootCause": {\r
+                                       "description": "Reserved for future use",\r
+                                       "type": "string"\r
+                               },\r
+                               "thresholdCrossingFieldsVersion": {\r
+                                       "description": "version of the thresholdCrossingAlertFields block",\r
+                                       "type": "number"\r
+                               }\r
+                       },\r
+                       "required": [\r
+                               "additionalParameters",\r
+                               "alertAction",\r
+                               "alertDescription",\r
+                               "alertType",\r
+                               "collectionTimestamp",\r
+                               "eventSeverity",\r
+                               "eventStartTimestamp",\r
+                               "thresholdCrossingFieldsVersion"\r
+                       ]\r
+               },\r
+               "vendorVnfNameFields": {\r
+                       "description": "provides vendor, vnf and vfModule identifying information",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "vendorName": {\r
+                                       "description": "VNF vendor name",\r
+                                       "type": "string"\r
+                               },\r
+                               "vfModuleName": {\r
+                                       "description": "ASDC vfModuleName for the vfModule generating the event",\r
+                                       "type": "string"\r
+                               },\r
+                               "vnfName": {\r
+                                       "description": "ASDC modelName for the VNF generating the event",\r
+                                       "type": "string"\r
+                               }\r
+                       },\r
+                       "required": [ "vendorName" ]\r
+               },\r
+               "vNicPerformance": {\r
+                       "description": "describes the performance and errors of an identified virtual network interface card",\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "receivedBroadcastPacketsAccumulated": {\r
+                                       "description": "Cumulative count of broadcast packets received as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedBroadcastPacketsDelta": {\r
+                                       "description": "Count of broadcast packets received within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedDiscardedPacketsAccumulated": {\r
+                                       "description": "Cumulative count of discarded packets received as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedDiscardedPacketsDelta": {\r
+                                       "description": "Count of discarded packets received within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedErrorPacketsAccumulated": {\r
+                                       "description": "Cumulative count of error packets received as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedErrorPacketsDelta": {\r
+                                       "description": "Count of error packets received within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedMulticastPacketsAccumulated": {\r
+                                       "description": "Cumulative count of multicast packets received as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedMulticastPacketsDelta": {\r
+                                       "description": "Count of multicast packets received within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedOctetsAccumulated": {\r
+                                       "description": "Cumulative count of octets received as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedOctetsDelta": {\r
+                                       "description": "Count of octets received within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedTotalPacketsAccumulated": {\r
+                                       "description": "Cumulative count of all packets received as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedTotalPacketsDelta": {\r
+                                       "description": "Count of all packets received within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedUnicastPacketsAccumulated": {\r
+                                       "description": "Cumulative count of unicast packets received as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "receivedUnicastPacketsDelta": {\r
+                                       "description": "Count of unicast packets received within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedBroadcastPacketsAccumulated": {\r
+                                       "description": "Cumulative count of broadcast packets transmitted as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedBroadcastPacketsDelta": {\r
+                                       "description": "Count of broadcast packets transmitted within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedDiscardedPacketsAccumulated": {\r
+                                       "description": "Cumulative count of discarded packets transmitted as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedDiscardedPacketsDelta": {\r
+                                       "description": "Count of discarded packets transmitted within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedErrorPacketsAccumulated": {\r
+                                       "description": "Cumulative count of error packets transmitted as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedErrorPacketsDelta": {\r
+                                       "description": "Count of error packets transmitted within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedMulticastPacketsAccumulated": {\r
+                                       "description": "Cumulative count of multicast packets transmitted as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedMulticastPacketsDelta": {\r
+                                       "description": "Count of multicast packets transmitted within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedOctetsAccumulated": {\r
+                                       "description": "Cumulative count of octets transmitted as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedOctetsDelta": {\r
+                                       "description": "Count of octets transmitted within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedTotalPacketsAccumulated": {\r
+                                       "description": "Cumulative count of all packets transmitted as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedTotalPacketsDelta": {\r
+                                       "description": "Count of all packets transmitted within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedUnicastPacketsAccumulated": {\r
+                                       "description": "Cumulative count of unicast packets transmitted as read at the end of the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "transmittedUnicastPacketsDelta": {\r
+                                       "description": "Count of unicast packets transmitted within the measurement interval",\r
+                                       "type": "number"\r
+                               },\r
+                               "valuesAreSuspect": {\r
+                                       "description": "Indicates whether vNicPerformance values are likely inaccurate due to counter overflow or other condtions",\r
+                                       "type": "string",\r
+                                       "enum": [ "true", "false" ]\r
+                               },\r
+                               "vNicIdentifier": {\r
+                                       "description": "vNic identification",\r
+                                       "type": "string"\r
+                               }\r
+                       },\r
+                       "required": [ "valuesAreSuspect", "vNicIdentifier" ]\r
+               },\r
+        "voiceQualityFields": {\r
+            "description": "provides statistics related to customer facing voice products",\r
+            "type": "object",\r
+            "properties": {\r
+                "additionalInformation": {\r
+                                       "description": "additional voice quality fields if needed",\r
+                                       "type": "array",\r
+                                       "items": {  \r
+                                               "$ref": "#/definitions/field" \r
+                                       }\r
+                },\r
+                "calleeSideCodec": {\r
+                    "description": "callee codec for the call",\r
+                    "type": "string"\r
+                },\r
+                "callerSideCodec": {\r
+                    "description": "caller codec for the call",\r
+                    "type": "string"\r
+                },\r
+                "correlator": {\r
+                    "description": "this is the same for all events on this call",\r
+                    "type": "string"\r
+                },\r
+                "endOfCallVqmSummaries": {\r
+                    "$ref": "#/definitions/endOfCallVqmSummaries"\r
+                },\r
+                "phoneNumber": {\r
+                    "description": "phone number associated with the correlator",\r
+                    "type": "string"\r
+                },\r
+                "midCallRtcp": {\r
+                    "description": "Base64 encoding of the binary RTCP data excluding Eth/IP/UDP headers",\r
+                    "type": "string"\r
+                },\r
+                "vendorVnfNameFields": {\r
+                    "$ref": "#/definitions/vendorVnfNameFields"\r
+                },\r
+                "voiceQualityFieldsVersion": {\r
+                    "description": "version of the voiceQualityFields block",\r
+                    "type": "number"\r
+                }\r
+            },\r
+            "required": [ "calleeSideCodec", "callerSideCodec", "correlator", "midCallRtcp",\r
+                                     "vendorVnfNameFields", "voiceQualityFieldsVersion" ]\r
+        }\r
+       },\r
+       "title": "Event Listener",\r
+       "type": "object",\r
+       "properties": {\r
+        "event": {"$ref": "#/definitions/event"}\r
+    }\r
+}\r
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/test_control_schema.json b/veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/test_control_schema.json
new file mode 100644 (file)
index 0000000..ced0153
--- /dev/null
@@ -0,0 +1,15 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Test Collector Test Control API - commands",
+    "type": "object",
+    "properties": {
+               "commandList": {
+                       "description": "array of commands from an event collector toward an event source",
+                       "type": "array",
+                       "items": {
+                           "$ref": "#/definitions/commandListEntry"
+                       },
+                       "minItems": 0}
+    },
+    "required": ["commandList"]
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/throttle_schema.json b/veslibrary/ves_clibrary/evel/evel-test-collector/docs/att_interface_definition/throttle_schema.json
new file mode 100644 (file)
index 0000000..7763a34
--- /dev/null
@@ -0,0 +1,9 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Vendor Event Listener API - eventThrottlingState",
+    "type": "object",
+    "properties": {
+        "eventThrottlingState": {"$ref": "#/definitions/eventThrottlingState"}
+    },
+    "required": ["eventThrottlingState"]
+}
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/docs/test_collector_user_guide/LICENSE.TXT b/veslibrary/ves_clibrary/evel/evel-test-collector/docs/test_collector_user_guide/LICENSE.TXT
new file mode 100644 (file)
index 0000000..ae12da2
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * ============LICENSE_START==========================================
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ *
+ * ECOMP and OpenECOMP are trademarks 
+ * and service marks of AT&T Intellectual Property.
+ *
+ */
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/docs/test_collector_user_guide/images/architecture.png b/veslibrary/ves_clibrary/evel/evel-test-collector/docs/test_collector_user_guide/images/architecture.png
new file mode 100644 (file)
index 0000000..98adb31
Binary files /dev/null and b/veslibrary/ves_clibrary/evel/evel-test-collector/docs/test_collector_user_guide/images/architecture.png differ
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/docs/test_collector_user_guide/test_collector_user_guide.md b/veslibrary/ves_clibrary/evel/evel-test-collector/docs/test_collector_user_guide/test_collector_user_guide.md
new file mode 100644 (file)
index 0000000..f7a0818
--- /dev/null
@@ -0,0 +1,294 @@
+# AT&T Vendor Event Listener Service - Test Collector - User Guide
+#  ===================================================================
+#  Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+#  ===================================================================
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+# 
+#         http://www.apache.org/licenses/LICENSE-2.0
+# 
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#  ============LICENSE_END============================================
+# 
+#  ECOMP and OpenECOMP are trademarks
+#  and service marks of AT&T Intellectual Property.
+
+
+Introduction
+============
+
+Background
+----------
+
+This document describes how to use the Test Collector application to simulate
+the service API described in "AT&T Service Specification, Service: 
+Vendor Event Listener Revision 2.11, 16-Sep-2016".
+
+Purpose
+-------
+
+This User Guide is intended to enable the reader to understand how
+    the Test Collector can be used to verify the operation of applications
+    supporting the Vendor Event Listener API.
+
+
+Realization
+===========
+
+The realization of the Test Collector is a Python script which acts as a
+server for the Vendor Event Listener API. It uses [jsonschema](https://pypi.python.org/pypi/jsonschema)
+in order to validate the received JSON events against AT&T's published
+schema for the API.
+
+The overall system architecture is shown in Figure 1 and comprises 
+    three key deliverables:
+
+*    The web-application itself.
+
+*    A Backend service.
+
+*    A validating test collector application.
+
+The Test Collector is described in more detail in the
+    following sections.  The other two components are described in a separate 
+    documents:
+
+*    Reference VNF User Guide
+
+*    Reference VNF Application Note
+
+Figure 1: Realization Architecture
+
+![Realization Architecture](images/architecture.png)
+
+Note that items shown in green in the diagram are existing AT&T
+    systems and do not form part of the delivery.
+
+Validating Collector
+--------------------
+
+The validating collector provides a basic test capability for
+    the Reference VNF. The application implements the Vendor Event
+    Listener API providing:
+
+-   Logging of new requests.
+
+-   Validating requests against the published schema.
+
+-   Validating the credentials provided in the request.
+
+-   Responding with a 202 Accepted for valid requests.
+
+-   Test Control endpoint allowing a test harness or user to set a pending
+    commandList, to be sent in response to the next event received.
+
+-   Responding with a 202 Accepted plus a pending commandList.
+
+-   Responding with a 401 Unauthorized error response-code and a JSON
+    exception response for failed authentication.
+
+It is intended to be used in environments where the "real" AT&T
+    Vendor Event Listener service is not available in order to test the
+    Reference VNF or, indeed, any other software which needs to send
+    events to a server.
+
+Using the Validating Collector
+==============================
+
+The test collector can be run manually, either on a Linux platform
+    or a Windows PC. It is invoked with a number of command-line
+    arguments:
+
+```
+  C:> python collector.py --config <file>
+                          --section <section>
+                          --verbose
+```
+
+Where:
+
+  -  **config** defines the path to the config file to be used.
+
+  -  **section** defines the section in the config file to be used.
+
+  -  **verbose** controls the level of logging to be generated.
+
+Wherever you chose to run the Test Collector, note that the
+    configuration of the backend service running on the VM generating
+    the events has to match so that the events generated by the backend
+    service are sent to the correct location and the Test Collector is
+    listening on the correct ports and URLs. The relevant section of the
+    Test Collector config file is:
+    
+```
+    #------------------------------------------------------------------------------
+    # Details of the Vendor Event Listener REST service.
+    #
+    # REST resources are defined with respect to a ServerRoot:
+    # ServerRoot = https://{Domain}:{Port}/{optionalRoutingPath}
+    #
+    # REST resources are of the form:
+    # * {ServerRoot}/eventListener/v{apiVersion}
+    # * {ServerRoot}/eventListener/v{apiVersion}/{topicName}
+    # * {ServerRoot}/eventListener/v{apiVersion}/eventBatch
+    # * {ServerRoot}/eventListener/v{apiVersion}/clientThrottlingState
+    #
+    # The "vel\_topic\_name" parameter is used as the "topicName" element in the path
+    # and may be empty.
+    #
+    # Note that the path, if present, should have no leading "/" but should have a
+    # training "/".
+    #------------------------------------------------------------------------------
+    vel_domain = 127.0.0.1
+    vel_port = 30000
+    vel_path = vendor_event_listener/
+    vel_username = Alice
+    vel_password = This isn't very secure!
+    vel_topic_name = example_vnf
+```
+The equivalent section of the backend service's configuration has to
+    match, or the equivalent parameters injected in the VM by the
+    OpenStack metadata service have to match.
+
+When events are sent from the web application, the results of the
+    validation will be displayed on stdout and be written to the log
+    file specified in the configuration file.
+
+For example: A Fault event failing to validate:
+
+```
+    <machine name>; - - [29/Feb/2016 10:58:28] "POST
+    /vendor_event_listener/eventListener/v1/example_vnf HTTP/1.1" 204  0
+    Event is not valid against schema! 'eventSeverity' is a required
+    property
+    Failed validating 'required' in
+    schema['properties']['event']['properties']['faultFields']:
+        {'description': 'fields specific to fault events',
+        'properties': {'alarmAdditionalInformation': {'description':'additional alarm information',
+                                                      'items': {'$ref': '#/definitions/field'},
+                                                      'type': 'array'},
+                       'alarmCondition': {'description': 'alarm condition reportedby the device',
+                                                      'type': 'string'},
+                       'alarmInterfaceA': {'description': 'card, port, channel or interface name of the device generating the alarm',
+                                                      'type': 'string'},
+                       'eventSeverity': {'description': 'event severity or priority',
+                                         'enum': ['CRITICAL',
+                                                   'MAJOR',
+                                                   'MINOR',
+                                                   'WARNING',
+                                                   'NORMAL'],
+                                         'type': 'string'},  
+                       'eventSourceType': {'description': 'type of event source',
+                                           'enum': ['other(0)',
+                                                     'router(1)',
+                                                     'switch(2)',
+                                                     'host(3)',
+                                                     'card(4)',
+                                                     'port(5)',
+                                                     'slotThreshold(6)',
+                                                     'portThreshold(7)',
+                                                     'virtualMachine(8)'],
+                                           'type': 'string'},
+                       'faultFieldsVersion': {'description': 'version of the faultFields block',
+                                              'type': 'number'},
+                       'specificProblem': {'description': 'short description of the alarm or problem',
+                                              'type': 'string'},
+                       'vfStatus': {'description': 'virtual function status enumeration',
+                                    'enum': ['Active',
+                                              'Idle',
+                                              'Preparing to terminate',
+                                              'Ready to terminate',
+                                              'Requesting termination'],
+                                    'type': 'string'}},
+            'required': ['alarmCondition',
+                          'eventSeverity',
+                          'eventSourceType',
+                          'specificProblem',
+                          'vfStatus'],
+            'type': 'object'}
+    On instance['event']['faultFields']:
+        {'alarmAdditionalInformation': [{'name': 'extra information',
+                                          'value': '2'},
+                                         {'name': 'more information',
+                                          'value': '1'}],
+         'alarmCondition': 'alarm condition 1',
+         'eventSourceType': 'virtualMachine(8)',
+         'faultFieldsVersion': 1,
+         'specificProblem': 'problem 1',
+         'vfStatus': 'Active'}
+    Bad JSON body decoded:
+    {
+        "event": {
+            "commonEventHeader": {
+                "domain": "fault",
+                "eventId": "6",
+                "eventType": "event type 1",
+                "functionalRole": "unknown",
+                "lastEpochMicrosec": 1456743510381000.0,
+                "priority": "Normal",
+                "reportingEntityId": "Not in OpenStack",
+                "reportingEntityName": "Not in OpenStack Environment",
+                "sequence": 0,
+                "sourceId": "Not in OpenStack",
+                "sourceName": "Not in OpenStack Environment",
+                "startEpochMicrosec": 1456743510381000.0,
+                "version": 1
+            },
+            "faultFields": {
+                "alarmAdditionalInformation": [
+                    {
+                        "name": "extra information",
+                        "value": "2"
+                    },
+                    {
+                        "name": "more information",
+                        "value": "1"
+                    }
+               ],
+               "alarmCondition": "alarm condition 1",
+               "eventSourceType": "virtualMachine(8)",
+               "faultFieldsVersion": 1,
+               "specificProblem": "problem 1",
+               "vfStatus": "Active"
+            }
+        }
+    }
+```
+
+Test Control Interface
+----------------------
+
+The test collector will accept any valid commandList on the Test Control interface,
+and will store it until the next event is received at the collector.
+At this point, it will send it to the event sender, and discard the pending commandList.
+
+For example, a POST of the following JSON will result in a measurement interval change
+command being sent to the sender of the next event.
+
+```
+{
+    "commandList": [
+        {
+            "command": {
+                "commandType": "measurementIntervalChange",
+                "measurementInterval": 60
+            }
+        }
+    ]
+}
+```
+
+A python script "test_control.py" provides an example of commandList injection,
+and contains various functions to generate example command lists.
+
+The test control script can be run manually, either on a Linux platform or a Windows PC.
+It is invoked with optional command-line arguments for the fqdn and port number of the 
+test collector to be controlled:
+```
+  C:> python test_control.py --fqdn 127.0.0.1 --port 30000
+```
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/scripts/linux/go-collector.sh b/veslibrary/ves_clibrary/evel/evel-test-collector/scripts/linux/go-collector.sh
new file mode 100644 (file)
index 0000000..31fd8af
--- /dev/null
@@ -0,0 +1,21 @@
+# Run the validating test collector.
+#  ===================================================================
+#  Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+#  ===================================================================
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+# 
+#         http://www.apache.org/licenses/LICENSE-2.0
+# 
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+
+python ../../code/collector/collector.py \
+       --config ../../config/collector.conf \
+       --section windows \
+       --verbose
diff --git a/veslibrary/ves_clibrary/evel/evel-test-collector/scripts/windows/go-collector.bat b/veslibrary/ves_clibrary/evel/evel-test-collector/scripts/windows/go-collector.bat
new file mode 100644 (file)
index 0000000..7241442
--- /dev/null
@@ -0,0 +1,22 @@
+REM  ===================================================================
+REM  Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+REM  ===================================================================
+REM  Licensed under the Apache License, Version 2.0 (the "License");
+REM  you may not use this file except in compliance with the License.
+REM  You may obtain a copy of the License at
+REM 
+REM         http://www.apache.org/licenses/LICENSE-2.0
+REM 
+REM  Unless required by applicable law or agreed to in writing, software
+REM  distributed under the License is distributed on an "AS IS" BASIS,
+REM  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM  See the License for the specific language governing permissions and
+REM  limitations under the License.
+@echo off
+
+REM Run the validating test collector.
+
+python ..\..\code\collector\collector.py ^
+       --config ..\..\config\collector.conf ^
+       --section windows ^
+       --verbose
diff --git a/veslibrary/ves_clibrary/libs/x86_64/README b/veslibrary/ves_clibrary/libs/x86_64/README
new file mode 100644 (file)
index 0000000..760fdc1
--- /dev/null
@@ -0,0 +1 @@
+Generated libraries.
\ No newline at end of file
diff --git a/veslibrary/ves_clibrary/output/x86_64/README b/veslibrary/ves_clibrary/output/x86_64/README
new file mode 100644 (file)
index 0000000..d1c9f1f
--- /dev/null
@@ -0,0 +1 @@
+Generated executables.
\ No newline at end of file
diff --git a/veslibrary/ves_clibrary/readme.md b/veslibrary/ves_clibrary/readme.md
new file mode 100644 (file)
index 0000000..784fade
--- /dev/null
@@ -0,0 +1,30 @@
+# ECOMP Vendor Event Listener Library
+
+“The content of this directory is currently under development and, at this stage, is not intended for demonstration and/or testing.”
+
+This project contains a C library that supports interfacing to AT&T's ECOMP
+Vendor Event Listener. For an overview of ECOMP, see the 
+[ECOMP White Paper](http://att.com/ECOMP).
+
+Developed in 2016 for AT&T by:
+ * Alok Gupta (https://github.com/ag1367)
+ * Paul Potochniak (https://github.com/pp8491)
+ * Gayathri Patrachari(https://github.com/gp2421)
+
+Current Maintainers: 
+ * Alok Gupta (https://github.com/ag1367)
+ * Paul Potochniak (https://github.com/pp8491)
+ * Gayathri Patrachari(https://github.com/gp2421)
+
+# Installation
+
+For installation instructions, clone this repo and load the 
+[installation guide](./docs/source/evel/html/quickstart.html) in your web browser.
+
+Full source-code documentation is included with the code and can be built from 
+the included Makefile. See the [readme file](./code/evel_library/readme.md).
+
+# Use
+
+Clone this repo and load the [user guide](./docs/source/evel/html/index.html)
+in your web browser.
diff --git a/veslibrary/ves_javalibrary/.classpath b/veslibrary/ves_javalibrary/.classpath
new file mode 100644 (file)
index 0000000..fe66f64
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="src" path="src_test"/>\r
+       <classpathentry kind="lib" path="build_time_libs/javassist-3.18.1-GA.jar"/>\r
+       <classpathentry kind="lib" path="build_time_libs/junit-4.8.2.jar"/>\r
+       <classpathentry kind="lib" path="lib/javalite-common-1.4.13.jar"/>\r
+       <classpathentry kind="lib" path="lib/slf4j-api-1.7.6.jar"/>\r
+       <classpathentry kind="lib" path="lib/slf4j-simple-1.7.6.jar"/>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>\r
+       <classpathentry kind="lib" path="C:/Users/gs244f/Downloads/log4j-1.2.17/apache-log4j-1.2.17/log4j-1.2.17.jar"/>\r
+       <classpathentry kind="lib" path="C:/Users/gs244f/workspace/veslibrary/lib/javax.json-1.0.jar"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/veslibrary/ves_javalibrary/.gitignore b/veslibrary/ves_javalibrary/.gitignore
new file mode 100644 (file)
index 0000000..cc6d746
--- /dev/null
@@ -0,0 +1,4 @@
+.idea/
+build/
+dist/
+TEST*
\ No newline at end of file
diff --git a/veslibrary/ves_javalibrary/.project b/veslibrary/ves_javalibrary/.project
new file mode 100644 (file)
index 0000000..9838184
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>evel_javalibrary</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/.classpath b/veslibrary/ves_javalibrary/evel_javalib2/.classpath
new file mode 100644 (file)
index 0000000..c03bc1b
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="src" output="target/classes" path="src">\r
+               <attributes>\r
+                       <attribute name="optional" value="true"/>\r
+                       <attribute name="maven.pomderived" value="true"/>\r
+               </attributes>\r
+       </classpathentry>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">\r
+               <attributes>\r
+                       <attribute name="maven.pomderived" value="true"/>\r
+               </attributes>\r
+       </classpathentry>\r
+       <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">\r
+               <attributes>\r
+                       <attribute name="maven.pomderived" value="true"/>\r
+               </attributes>\r
+       </classpathentry>\r
+       <classpathentry kind="output" path="target/classes"/>\r
+</classpath>\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/.project b/veslibrary/ves_javalibrary/evel_javalib2/.project
new file mode 100644 (file)
index 0000000..bcacf2d
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>evel_javalib2</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.m2e.core.maven2Builder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.m2e.core.maven2Nature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/.settings/org.eclipse.jdt.core.prefs b/veslibrary/ves_javalibrary/evel_javalib2/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..df46a9a
--- /dev/null
@@ -0,0 +1,12 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate\r
+org.eclipse.jdt.core.compiler.debug.localVariable=generate\r
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning\r
+org.eclipse.jdt.core.compiler.source=1.8\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/.settings/org.eclipse.m2e.core.prefs b/veslibrary/ves_javalibrary/evel_javalib2/.settings/org.eclipse.m2e.core.prefs
new file mode 100644 (file)
index 0000000..14b697b
--- /dev/null
@@ -0,0 +1,4 @@
+activeProfiles=\r
+eclipse.preferences.version=1\r
+resolveWorkspaceProjects=true\r
+version=1\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/java/com/javacodegeeks/AppTest.java b/veslibrary/ves_javalibrary/evel_javalib2/java/com/javacodegeeks/AppTest.java
new file mode 100644 (file)
index 0000000..d8e33e3
--- /dev/null
@@ -0,0 +1,16 @@
+package com.javacodegeeks;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+\r
+/**\r
+ * Unit test for simple App.\r
+ */\r
+public class AppTest {\r
+       \r
+       @Test\r
+       public void testApp() {\r
+               App appObject = new App();\r
+               Assert.assertEquals(appObject.reverseString("Test!"), "!tseT");\r
+       }\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/pom.xml b/veslibrary/ves_javalibrary/evel_javalib2/pom.xml
new file mode 100644 (file)
index 0000000..9acaacb
--- /dev/null
@@ -0,0 +1,88 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <groupId>evel_javalib2</groupId>\r
+  <artifactId>evel_javalib2</artifactId>\r
+  <version>0.0.1-SNAPSHOT</version>\r
+  <name>VESJavaLibrary</name>\r
+  \r
+\r
+    <repositories>\r
+        <repository>\r
+            <id>onap-snapshots</id>\r
+            <name>ONAP Snapshot Repository</name>\r
+            <url>http://nexus.onap.org/content/repositories/snapshots</url>\r
+        </repository>\r
+    </repositories>\r
+  \r
+  \r
+  <build>\r
+    <sourceDirectory>src</sourceDirectory>\r
+    <plugins>\r
+      <plugin>\r
+        <artifactId>maven-compiler-plugin</artifactId>\r
+        <version>3.5.1</version>\r
+        <configuration>\r
+          <source>1.8</source>\r
+          <target>1.8</target>\r
+        </configuration>\r
+      </plugin>\r
+      \r
+      <plugin>\r
+                <groupId>org.eclipse.m2e</groupId>\r
+                <artifactId>lifecycle-mapping</artifactId>\r
+                <version>1.0.0</version>\r
+                <configuration>\r
+                    <lifecycleMappingMetadata>\r
+                        <pluginExecutions>\r
+                            <pluginExecution>\r
+                                <pluginExecutionFilter>\r
+                                    <groupId>org.codehaus.mojo</groupId>\r
+                                    <artifactId>aspectj-maven-plugin</artifactId>\r
+                                    <versionRange>[1.0,)</versionRange>\r
+                                    <goals>\r
+                                        <goal>test-compile</goal>\r
+                                        <goal>compile</goal>\r
+                                    </goals>\r
+                                </pluginExecutionFilter>\r
+                                <action>\r
+                                    <execute />\r
+                                </action>\r
+                            </pluginExecution>\r
+                        </pluginExecutions>\r
+                    </lifecycleMappingMetadata>\r
+                </configuration>\r
+            </plugin>\r
+      \r
+    </plugins>\r
+    \r
+    \r
+  </build>\r
+  <dependencies>\r
+       <dependency>\r
+               <groupId>junit</groupId>\r
+               <artifactId>junit</artifactId>\r
+               <version>4.11</version>\r
+               <scope>test</scope>\r
+       </dependency>\r
+       <dependency>\r
+               <groupId>log4j</groupId>\r
+               <artifactId>log4j</artifactId>\r
+               <version>1.2.17</version>\r
+       </dependency>\r
+       <dependency>\r
+               <groupId>javax.json</groupId>\r
+               <artifactId>javax.json-api</artifactId>\r
+               <version>1.1</version>\r
+       </dependency>\r
+       <dependency>\r
+               <groupId>org.slf4j</groupId>\r
+               <artifactId>slf4j-log4j12</artifactId>\r
+               <version>1.7.5</version>\r
+       </dependency>\r
+       <dependency>\r
+               <groupId>org.glassfish</groupId>\r
+               <artifactId>javax.json</artifactId>\r
+               <version>1.0.4</version>\r
+       </dependency>\r
+  </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/AgentMain.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/AgentMain.java
new file mode 100644 (file)
index 0000000..22d5a0a
--- /dev/null
@@ -0,0 +1,322 @@
+
+package evel_javalibrary.att.com;
+
+/**************************************************************************//**
+ * @file
+ * Header for EVEL library
+ *
+ * This file implements the EVEL library which is intended to provide a
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so
+ * that VNFs can use it without worrying about details of the API transport.
+ *
+ * License
+ * -------
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *****************************************************************************/
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.Level;
+
+//import java.io.BufferedReader;
+import java.io.BufferedWriter;
+//import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+//import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+//import java.net.ProtocolException;
+import java.net.URL;
+//import java.nio.charset.StandardCharsets;
+
+
+import javax.net.ssl.HttpsURLConnection;
+
+import org.apache.log4j.BasicConfigurator;
+
+/**
+ * @author Gokul Singaraju
+ */
+
+
+public class AgentMain {
+       
+/**************************************************************************//**
+ * Error codes
+ *
+ * Error codes for EVEL low level interface
+ *****************************************************************************/
+public enum EVEL_ERR_CODES {
+  EVEL_SUCCESS,                   /** The operation was successful.          */
+  EVEL_ERR_GEN_FAIL,              /** Non-specific failure.                  */
+  EVEL_CURL_LIBRARY_FAIL,         /** A cURL library operation failed.       */
+  EVEL_PTHREAD_LIBRARY_FAIL,      /** A Posix threads operation failed.      */
+  EVEL_OUT_OF_MEMORY,             /** A memory allocation failure occurred.  */
+  EVEL_EVENT_BUFFER_FULL,         /** Too many events in the ring-buffer.    */
+  EVEL_EVENT_HANDLER_INACTIVE,    /** Attempt to raise event when inactive.  */
+  EVEL_NO_METADATA,               /** Failed to retrieve OpenStack metadata. */
+  EVEL_BAD_METADATA,              /** OpenStack metadata invalid format.     */
+  EVEL_BAD_JSON_FORMAT,           /** JSON failed to parse correctly.        */
+  EVEL_JSON_KEY_NOT_FOUND,        /** Failed to find the specified JSON key. */
+  EVEL_MAX_ERROR_CODES            /** Maximum number of valid error codes.   */
+}
+       
+       private static final Logger logger = Logger.getLogger(AgentMain.class);
+       
+       private static String url = null;
+       private static URL vesurl = null;
+       private static HttpURLConnection con = null;
+       private static String userpass = null;
+       private static String version = "5";
+       
+       /* RingBuffer to forward messages on sending AgentDispatcher thread */
+       private static RingBuffer ringb = new RingBuffer(100);
+       
+       Thread thr;
+       
+       /* AgentDispatcher loops on messages in RingBuffer and POSTs them
+        * to external Collector
+        */
+    private static class AgentDispatcher  implements Runnable {
+      public void run() {
+      String datatosend=null;  
+      for(;;){
+         if( (datatosend = (String) ringb.take()) != null )
+         {
+                 //process data
+                 
+                 logger.trace(url + "Got an event size "+datatosend.length());
+                 logger.trace(datatosend);
+                 
+                         try {
+                 
+                       //HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
+                       con = (HttpURLConnection) vesurl.openConnection();
+               if (con instanceof HttpsURLConnection) {
+                   HttpsURLConnection httpsConnection = (HttpsURLConnection) con;
+                   //SSLContext sc = SSLContext.getInstance("TLSv1.2");
+                   // Init the SSLContext with a TrustManager[] and SecureRandom()
+                   //sc.init(null, null, new java.security.SecureRandom());
+                   //httpsConnection.setHostnameVerifier(getHostnameVerifier());
+                   //httpsConnection.setSSLSocketFactory(sc.getSocketFactory());
+                   con  = httpsConnection;
+               }
+                       
+                       //add reuqest header
+                       con.setRequestMethod("POST");
+                       //con.setRequestProperty("User-Agent", USER_AGENT);
+                       //con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
+                   // No caching, we want the real thing.
+                   con.setUseCaches (false);
+                   // Specify the content type.
+                   con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
+                   //con.setChunkedStreamingMode(0);
+                   con.setInstanceFollowRedirects( false );
+                   //Basic username password authentication
+                   String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes("UTF-8"));
+                   con.setRequestProperty ("Authorization", basicAuth);
+                   
+               con.setReadTimeout(15000 /* milliseconds */);
+               con.setConnectTimeout(15000 /* milliseconds */);
+                       // Send post request
+                       con.setDoOutput(true);
+                       con.setDoInput(true);
+                 
+                   con.setFixedLengthStreamingMode(datatosend.length());
+               OutputStream os = con.getOutputStream();
+                   BufferedWriter writer = new BufferedWriter(
+                               new OutputStreamWriter(os, "UTF-8"));
+                   //Call writer POST
+                   writer.write(datatosend);
+                   writer.flush();
+                   writer.close();
+                   os.close(); 
+                   //Handle the response code for POST request
+                   int respCode = con.getResponseCode();
+                   logger.trace(url + "Connection HTTP Response code :"+respCode);
+               if(respCode < HttpURLConnection.HTTP_OK ) {
+                       logger.trace(url + " **INFO**");
+               }
+               else if(respCode >= HttpURLConnection.HTTP_OK && respCode < HttpURLConnection.HTTP_MULT_CHOICE )
+               {
+                    logger.trace(url + " **OK**");
+                           }
+                           else if(respCode >= HttpURLConnection.HTTP_MULT_CHOICE  && respCode < HttpURLConnection.HTTP_BAD_REQUEST )
+                           {
+                               logger.warn(url + " **REDIRECTION**");
+                           }
+                           else if(respCode >= HttpURLConnection.HTTP_BAD_REQUEST )
+                           {
+                               logger.warn(url + " **SERVER ERROR**");
+
+                    InputStream es = con.getErrorStream();
+                    if( es != null)
+                    {
+                      int ret = 0;
+                      byte[] buf = null;
+                                     // read the response body
+                      while ((ret = es.read(buf)) > 0) {
+                        logger.info("Resp:"+buf);
+                      }
+                      // close the errorstream
+                      es.close();
+                    }
+                           }
+               
+                               
+                         } catch (IOException e) {
+                                 // TODO Auto-generated catch block
+                                 e.printStackTrace();
+                         }
+                 
+         }
+         else
+         {
+                 logger.trace(url + "Waiting for events");
+                 try {
+                               Thread.sleep(5);
+                         } catch (InterruptedException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                         }
+         }
+      }//end for
+     }//end run
+   }//end AgentDispatcher
+    // Validate URL
+    public static boolean isValidURL(String urlStr) {
+        try {
+          URL url = new URL(urlStr);
+          return true;
+        }
+        catch (MalformedURLException e) {
+            return false;
+        }
+    }
+    
+    /**************************************************************************//**
+     * Library initialization.
+     *
+     * Initialize the EVEL library.
+     *
+     * @note  This function initializes the Java EVEL library interfaces.
+     *        Validates input parameters and starts the AgentDispatcher thread
+     *
+     * @param   event_api_url    The API's URL.
+     * @param   port    The API's port.
+     * @param   path    The optional path (may be NULL).
+     * @param   topic   The optional topic part of the URL (may be NULL).
+     * @param   username  Username for Basic Authentication of requests.
+     * @param   password  Password for Basic Authentication of requests.
+     * @param   Level     Java Log levels.
+     *
+     * @returns Status code
+     * @retval  EVEL_SUCCESS      On success
+     * @retval  ::EVEL_ERR_CODES  On failure.
+     *****************************************************************************/
+    public static EVEL_ERR_CODES evel_initialize(
+               String event_api_url,
+               int port,
+            String path,
+            String topic,
+            String username,
+            String password,
+            Level level) throws IOException
+    {
+         EVEL_ERR_CODES rc = EVEL_ERR_CODES.EVEL_SUCCESS;
+         String throt_api_url = "http://127.0.0.1";
+
+         EVEL_ENTER();
+
+                 BasicConfigurator.configure();
+
+         /***************************************************************************/
+         /* Check assumptions.                                                      */
+         /***************************************************************************/
+         assert(event_api_url != null);
+         assert(port > 1024);
+         assert(throt_api_url != null);
+         assert(username != null);
+         
+         logger.setLevel(level);
+         
+         if( !isValidURL(event_api_url) || !isValidURL(throt_api_url)){
+                 System.out.println("Invalid Event API URL");
+                 rc = EVEL_ERR_CODES.EVEL_ERR_GEN_FAIL;
+                 System.exit(1);
+         }
+         
+         if(path == null){
+                 path = "";
+         } else {
+                 version += "/example_vnf";
+         }
+         
+               url = event_api_url+":"+Integer.toString(port)+path+"/eventListener/v"+version;
+               vesurl = null;
+               try {
+                       vesurl = new URL(url);
+               } catch (MalformedURLException e) {
+                       // TODO Auto-generated catch block
+                       logger.info("Error in url input");
+                       e.printStackTrace();
+                       System.exit(1);
+               }
+           userpass = username + ":" + password;
+
+        logger.info("Starting Agent Dispatcher thread");
+        long startTime = System.currentTimeMillis();
+        Thread t = new Thread(new AgentDispatcher());
+        t.start();
+         
+        EVEL_EXIT();
+       return rc; 
+       
+    }
+    
+    private static void EVEL_EXIT() {
+               // TODO Auto-generated method stub
+               
+       }
+
+       private static void EVEL_ENTER() {
+               // TODO Auto-generated method stub
+               
+       }
+       
+    /**************************************************************************//**
+     * Handle user formatted post message
+     *
+     * @note  This function handles VES 5.x formatted messages from all valid
+     *        Domains and stores them in RingBuffer.
+     *
+     * @param   obj     VES 5.x formatted user messages with common header
+     *                  and optional specialized body
+     *
+     * @retval  boolean    True  On successful acceptance False on failure
+     *****************************************************************************/
+
+       public static boolean evel_post_event(EvelHeader obj )
+    {
+           String data = obj.evel_json_encode_event();
+       boolean ret = ringb.put(data);
+       logger.info("Evel Post event ret:"+ret);
+       return ret;
+    }
+
+       
+
+}
\ No newline at end of file
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelFault.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelFault.java
new file mode 100644 (file)
index 0000000..a252378
--- /dev/null
@@ -0,0 +1,528 @@
+package evel_javalibrary.att.com;\r
+\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Fault Event class extends EvelHeader class\r
+ *\r
+ * This file implements the Evel Fault Event class which is intended to provide a\r
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so\r
+ * that VNFs can use it to send Fault events.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+\r
+import javax.json.Json;\r
+import javax.json.JsonArrayBuilder;\r
+import javax.json.JsonObject;\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.slf4j.helpers.MessageFormatter;\r
+\r
+\r
+public class EvelFault extends EvelHeader {\r
+       //version of EvelFault format revisions\r
+       int major_version = 2;\r
+       int minor_version = 1;\r
+       \r
+       /**************************************************************************//**\r
+        * Fault / Threshold severities.\r
+        * JSON equivalent field: eventSeverity\r
+        *****************************************************************************/\r
+       public enum EVEL_SEVERITIES{\r
+         EVEL_SEVERITY_CRITICAL,\r
+         EVEL_SEVERITY_MAJOR,\r
+         EVEL_SEVERITY_MINOR,\r
+         EVEL_SEVERITY_WARNING,\r
+         EVEL_SEVERITY_NORMAL,\r
+         EVEL_MAX_SEVERITIES\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Fault source types.\r
+        * JSON equivalent field: eventSourceType\r
+        *****************************************************************************/\r
+       public enum EVEL_SOURCE_TYPES{\r
+         EVEL_SOURCE_OTHER,\r
+         EVEL_SOURCE_ROUTER,\r
+         EVEL_SOURCE_SWITCH,\r
+         EVEL_SOURCE_HOST,\r
+         EVEL_SOURCE_CARD,\r
+         EVEL_SOURCE_PORT,\r
+         EVEL_SOURCE_SLOT_THRESHOLD,\r
+         EVEL_SOURCE_PORT_THRESHOLD,\r
+         EVEL_SOURCE_VIRTUAL_MACHINE,\r
+         EVEL_SOURCE_VIRTUAL_NETWORK_FUNCTION,\r
+         /***************************************************************************/\r
+         /* START OF VENDOR-SPECIFIC VALUES                                         */\r
+         /*                                                                         */\r
+         /* Vendor-specific values should be added here, and handled appropriately  */\r
+         /* in evel_event.c.                                                        */\r
+         /***************************************************************************/\r
+\r
+         /***************************************************************************/\r
+         /* END OF VENDOR-SPECIFIC VALUES                                           */\r
+         /***************************************************************************/\r
+         EVEL_MAX_SOURCE_TYPES\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Fault VNF Status.\r
+        * JSON equivalent field: vfStatus\r
+        *****************************************************************************/\r
+       public enum EVEL_VF_STATUSES{\r
+         EVEL_VF_STATUS_ACTIVE,\r
+         EVEL_VF_STATUS_IDLE,\r
+         EVEL_VF_STATUS_PREP_TERMINATE,\r
+         EVEL_VF_STATUS_READY_TERMINATE,\r
+         EVEL_VF_STATUS_REQ_TERMINATE,\r
+         EVEL_MAX_VF_STATUSES\r
+       }\r
+\r
+       \r
+       /***************************************************************************/\r
+       /* Mandatory fields                                                        */\r
+       /***************************************************************************/\r
+         EVEL_SEVERITIES event_severity;\r
+         EVEL_SOURCE_TYPES event_source_type;\r
+         String alarm_condition;\r
+         String specific_problem;\r
+         EVEL_VF_STATUSES vf_status;\r
+\r
+       /***************************************************************************/\r
+       /* Optional fields                                                         */\r
+       /***************************************************************************/\r
+         EvelOptionString category;\r
+         EvelOptionString alarm_interface_a;\r
+         ArrayList<String[]> additional_info;\r
+       \r
+         private static final Logger LOGGER = Logger.getLogger( EvelFault.class.getName() );\r
+\r
+         /**************************************************************************//**\r
+          * Create a new fault event.\r
+          *\r
+          * @note    The mandatory fields on the Fault must be supplied to this factory\r
+          *          function and are immutable once set.  Optional fields have explicit\r
+          *          setter functions, but again values may only be set once so that the\r
+          *          Fault has immutable properties.\r
+          * @param   condition   The condition indicated by the Fault.\r
+          * @param   specproblem  The specific problem triggering the fault.\r
+          * @param   priority    The priority of the event.\r
+          * @param   severity    The severity of the Fault.\r
+          * @param   ev_source_type    Source of Alarm event\r
+          * @param   status      status of Virtual Function\r
+          *****************************************************************************/\r
+       public EvelFault(String evname, String ev_id,\r
+                                String condition, String specproblem,\r
+                     EvelHeader.PRIORITIES priority,\r
+                     EVEL_SEVERITIES severity,\r
+                     EVEL_SOURCE_TYPES ev_source_type,\r
+                     EVEL_VF_STATUSES status)\r
+       {\r
+               //Initializes Evel Header and Domain\r
+               super(evname,ev_id);            \r
+               event_domain = EvelHeader.DOMAINS.EVEL_DOMAIN_FAULT;\r
+               //Validate inputs\r
+               assert( condition != null);\r
+               assert( specific_problem != null);\r
+               assert(EvelHeader.PRIORITIES.EVEL_MAX_PRIORITIES.compareTo(priority) < 0 );\r
+               assert(EVEL_SEVERITIES.EVEL_MAX_SEVERITIES.compareTo(severity) < 0 );\r
+               assert(EVEL_VF_STATUSES.EVEL_MAX_VF_STATUSES.compareTo(status) < 0 );\r
+               //Init mandatory fields\r
+               event_severity = severity;\r
+               event_source_type = ev_source_type;\r
+               alarm_condition = condition;\r
+               specific_problem = specproblem;\r
+               vf_status = status;\r
+               //Init optional fields\r
+               category = new EvelOptionString(false, null);\r
+               alarm_interface_a = new EvelOptionString(false, null);\r
+               additional_info = null;         \r
+       }\r
+       \r
+       /**************************************************************************//**\r
+        * Add an additional value name/value pair to the Fault.\r
+        *\r
+        * The name and value are null delimited ASCII strings.  The library takes\r
+        * a copy so the caller does not have to preserve values after the function\r
+        * returns.\r
+        *\r
+        * @param fault     Pointer to the fault.\r
+        * @param name      ASCIIZ string with the attribute's name.  The caller\r
+        *                  does not need to preserve the value once the function\r
+        *                  returns.\r
+        * @param value     ASCIIZ string with the attribute's value.  The caller\r
+        *                  does not need to preserve the value once the function\r
+        *                  returns.\r
+        *****************************************************************************/\r
+       public void evel_fault_addl_info_add(String name, String value)\r
+       {\r
+         String[] addl_info = null;\r
+         EVEL_ENTER();\r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions.                                                    */\r
+         /***************************************************************************/\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_FAULT);\r
+         assert(name != null);\r
+         assert(value != null);\r
+         \r
+         if( additional_info == null )\r
+         {\r
+                 additional_info = new ArrayList<String[]>();\r
+         }\r
+\r
+         LOGGER.debug(MessageFormat.format("Adding name={0} value={1}", name, value));\r
+         addl_info = new String[2];\r
+         assert(addl_info != null);\r
+         addl_info[0] = name;\r
+         addl_info[1] = value;\r
+\r
+         additional_info.add(addl_info);\r
+\r
+         EVEL_EXIT();\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Set the Fault Category property of the Fault.\r
+        *\r
+        * @note  The property is treated as immutable: it is only valid to call\r
+        *        the setter once.  However, we don't assert if the caller tries to\r
+        *        overwrite, just ignoring the update instead.\r
+        *\r
+        * @param fault      Pointer to the fault.\r
+        * @param category   Category : license, link, routing, security, signaling.\r
+        *                       ASCIIZ string. The caller\r
+        *                   does not need to preserve the value once the function\r
+        *                   returns.\r
+        *****************************************************************************/\r
+       public void evel_fault_category_set( String categ)\r
+       {\r
+         EVEL_ENTER();\r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions.                                                    */\r
+         /***************************************************************************/\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_FAULT);\r
+         assert(categ != null);\r
+         \r
+         category.SetValuePr(categ,"Fault Category set");\r
+\r
+         EVEL_EXIT();\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Set the Alarm Interface A property of the Fault.\r
+        *\r
+        * @note  The property is treated as immutable: it is only valid to call\r
+        *        the setter once.  However, we don't assert if the caller tries to\r
+        *        overwrite, just ignoring the update instead.\r
+        *\r
+        * @param fault      Pointer to the fault.\r
+        * @param interface  The Alarm Interface A to be set. ASCIIZ string. The caller\r
+        *                   does not need to preserve the value once the function\r
+        *                   returns.\r
+        *****************************************************************************/\r
+       public void evel_fault_interface_set(String intf)\r
+       {\r
+         EVEL_ENTER();\r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions.                                                    */\r
+         /***************************************************************************/\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_FAULT);\r
+         assert(intf != null);\r
+\r
+         alarm_interface_a.SetValuePr(intf,"Alarm Interface A");\r
+\r
+         EVEL_EXIT();\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Set the Event Type property of the Fault.\r
+        *\r
+        * @note  The property is treated as immutable: it is only valid to call\r
+        *        the setter once.  However, we don't assert if the caller tries to\r
+        *        overwrite, just ignoring the update instead.\r
+        *\r
+        * @param fault      Pointer to the fault.\r
+        * @param type       The Event Type to be set. ASCIIZ string. The caller\r
+        *                   does not need to preserve the value once the function\r
+        *                   returns.\r
+        *****************************************************************************/\r
+       public void evel_fault_type_set(String type)\r
+       {\r
+         EVEL_ENTER();\r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions and call evel_header_type_set.                      */\r
+         /***************************************************************************/\r
+         assert(type != null);\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_FAULT);\r
+         \r
+         evel_header_type_set(type);\r
+\r
+         EVEL_EXIT();\r
+       }\r
+\r
+       \r
+       /**************************************************************************//**\r
+        * Map an ::EVEL_SOURCE_TYPES enum value to the equivalent string.\r
+        *\r
+        * @param source_type   The source type to convert.\r
+        * @returns The equivalent string.\r
+        *****************************************************************************/\r
+       String evel_source_type(EVEL_SOURCE_TYPES source_type)\r
+       {\r
+         String result;\r
+\r
+         EVEL_ENTER();\r
+\r
+         switch (source_type)\r
+         {\r
+           case EVEL_SOURCE_OTHER:\r
+             result = "other";\r
+             break;\r
+\r
+           case EVEL_SOURCE_ROUTER:\r
+             result = "router";\r
+             break;\r
+\r
+           case EVEL_SOURCE_SWITCH:\r
+             result = "switch";\r
+             break;\r
+\r
+           case EVEL_SOURCE_HOST:\r
+             result = "host";\r
+             break;\r
+\r
+           case EVEL_SOURCE_CARD:\r
+             result = "card";\r
+             break;\r
+\r
+           case EVEL_SOURCE_PORT:\r
+             result = "port";\r
+             break;\r
+\r
+           case EVEL_SOURCE_SLOT_THRESHOLD:\r
+             result = "slotThreshold";\r
+             break;\r
+\r
+           case EVEL_SOURCE_PORT_THRESHOLD:\r
+             result = "portThreshold";\r
+             break;\r
+\r
+           case EVEL_SOURCE_VIRTUAL_MACHINE:\r
+             result = "virtualMachine";\r
+             break;\r
+\r
+           case EVEL_SOURCE_VIRTUAL_NETWORK_FUNCTION:\r
+             result = "virtualNetworkFunction";\r
+             break;\r
+\r
+           default:\r
+             result = null;\r
+             LOGGER.error(MessageFormatter.format("Unexpected Event Source Type {0}", source_type));\r
+             System.exit(1);\r
+         }\r
+\r
+         EVEL_EXIT();\r
+\r
+         return result;\r
+       }\r
+       \r
+       /**************************************************************************//**\r
+        * Map an ::EVEL_SEVERITIES enum value to the equivalent string.\r
+        *\r
+        * @param severity      The severity to convert.\r
+        * @returns The equivalent string.\r
+        *****************************************************************************/\r
+       String evel_severity(EVEL_SEVERITIES severity)\r
+       {\r
+         String result = null;\r
+\r
+         EVEL_ENTER();\r
+\r
+         switch (severity)\r
+         {\r
+           case EVEL_SEVERITY_CRITICAL:\r
+             result = "CRITICAL";\r
+             break;\r
+\r
+           case EVEL_SEVERITY_MAJOR:\r
+             result = "MAJOR";\r
+             break;\r
+\r
+           case EVEL_SEVERITY_MINOR:\r
+             result = "MINOR";\r
+             break;\r
+\r
+           case EVEL_SEVERITY_WARNING:\r
+             result = "WARNING";\r
+             break;\r
+\r
+           case EVEL_SEVERITY_NORMAL:\r
+             result = "NORMAL";\r
+             break;\r
+\r
+           default:\r
+             LOGGER.error("Unexpected event severity "+severity);\r
+             System.exit(1);\r
+         }\r
+\r
+         EVEL_EXIT();\r
+\r
+         return result;\r
+       }\r
+\r
+\r
+       /**************************************************************************//**\r
+        * Map an ::EVEL_VF_STATUSES enum value to the equivalent string.\r
+        *\r
+        * @param vf_status     The vf_status to convert.\r
+        * @returns The equivalent string.\r
+        *****************************************************************************/\r
+       String evel_vf_status(EVEL_VF_STATUSES vf_status)\r
+       {\r
+         String result;\r
+\r
+         EVEL_ENTER();\r
+\r
+         switch (vf_status)\r
+         {\r
+           case EVEL_VF_STATUS_ACTIVE:\r
+             result = "Active";\r
+             break;\r
+\r
+           case EVEL_VF_STATUS_IDLE:\r
+             result = "Idle";\r
+             break;\r
+\r
+           case EVEL_VF_STATUS_PREP_TERMINATE:\r
+             result = "Preparing to terminate";\r
+             break;\r
+\r
+           case EVEL_VF_STATUS_READY_TERMINATE:\r
+             result = "Ready to terminate";\r
+             break;\r
+\r
+           case EVEL_VF_STATUS_REQ_TERMINATE:\r
+             result = "Requesting termination";\r
+             break;\r
+\r
+           default:\r
+             result = null;\r
+             LOGGER.error("Unexpected VF Status "+vf_status);\r
+             System.exit(1);\r
+         }\r
+\r
+         EVEL_EXIT();\r
+\r
+         return result;\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Encode the fault in JSON according to AT&T's schema for the fault type.\r
+        *\r
+        * @retval JsonObjectBuilder of fault body portion of message   \r
+        *****************************************************************************/\r
+        JsonObjectBuilder evelFaultObject()\r
+        {\r
+         String fault_severity;\r
+         String fault_source_type;\r
+         String fault_vf_status;\r
+         double version = major_version+(double)minor_version/10;\r
+\r
+         EVEL_ENTER();\r
+         \r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_FAULT);\r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions.                                                    */\r
+         /***************************************************************************/\r
+\r
+      fault_severity = evel_severity(event_severity);\r
+         fault_source_type = evel_source_type(event_source_type);\r
+         fault_vf_status = evel_vf_status(vf_status);\r
+         \r
+         JsonObjectBuilder evelfault = Json.createObjectBuilder()\r
+                        .add("alarmCondition", alarm_condition);\r
+\r
+         /***************************************************************************/\r
+         /* Optional fields.                                                        */\r
+         /***************************************************************************/\r
+         \r
+         if( category.is_set )\r
+                 evelfault.add("eventCategory", category.GetValue());\r
+         if( alarm_interface_a.is_set )\r
+                 evelfault.add("eventCategory", alarm_interface_a.GetValue());\r
+         \r
+\r
+         /***************************************************************************/\r
+         /* Mandatory fields.                                                       */\r
+         /***************************************************************************/\r
+         evelfault.add( "eventSeverity", fault_severity);\r
+         evelfault.add( "eventSourceType", fault_source_type);\r
+         evelfault.add( "specificProblem", specific_problem);\r
+         evelfault.add( "vfStatus", fault_vf_status);\r
+         evelfault.add( "faultFieldsVersion", version);\r
+\r
+         /***************************************************************************/\r
+         /* Encode additional Name value pairs if any.      */\r
+         /***************************************************************************/\r
+         if( additional_info != null )\r
+         {\r
+           JsonArrayBuilder builder = Json.createArrayBuilder();\r
+           for(int i=0;i<additional_info.size();i++) {\r
+                 String[] addl_info = additional_info.get(i);\r
+                 JsonObject obj = Json.createObjectBuilder()\r
+                            .add("name", addl_info[0])\r
+                            .add("value", addl_info[1]).build();\r
+                 builder.add(obj);\r
+           }\r
+               evelfault.add("alarmAdditionalInformation", builder);\r
+         }\r
+\r
+         EVEL_EXIT();\r
+         \r
+         return evelfault;\r
+       }\r
+       \r
+       \r
+         /**************************************************************************//**\r
+          * Encode the event as a JSON event object according to AT&T's schema.\r
+          * retval : String of JSON event message\r
+          *****************************************************************************/\r
+         String evel_json_encode_event()\r
+         {\r
+               assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_FAULT);\r
+               //encode common event header and body     \r
+           JsonObject obj = Json.createObjectBuilder()\r
+                    .add("event", Json.createObjectBuilder()\r
+                                .add( "commonEventHeader",eventHeaderObject() )\r
+                                .add( "faultFields",evelFaultObject() )\r
+                                ).build();\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return obj.toString();\r
+\r
+         }\r
+       \r
+\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelHeader.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelHeader.java
new file mode 100644 (file)
index 0000000..8b5538b
--- /dev/null
@@ -0,0 +1,664 @@
+package evel_javalibrary.att.com;\r
+\r
+/**************************************************************************//**\r
+ * @file\r
+ * Header for EVEL Header library\r
+ *\r
+ * This file implements the EVEL library which is intended to provide a\r
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so\r
+ * that VNFs can use it without worrying about details of the API transport.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+\r
+import java.text.MessageFormat;\r
+import java.util.Enumeration;\r
+import java.util.logging.Logger;\r
+import java.io.StringWriter;\r
+import java.net.InetAddress;\r
+import java.net.NetworkInterface;\r
+import java.net.SocketException;\r
+import java.net.UnknownHostException;\r
+\r
+import javax.json.Json;\r
+import javax.json.JsonObject;\r
+import javax.json.JsonObjectBuilder;\r
+import javax.json.JsonString;\r
+import javax.json.JsonWriter;\r
+\r
+import org.slf4j.helpers.MessageFormatter;\r
+\r
+\r
+public class EvelHeader {\r
+       \r
+       /**************************************************************************//**\r
+        * Event domains for the various events we support.\r
+        * JSON equivalent field: domain\r
+        *****************************************************************************/\r
+       public enum DOMAINS {\r
+         EVEL_DOMAIN_INTERNAL,       /** Internal event, not for external routing.  */\r
+         EVEL_DOMAIN_FAULT,          /** A Fault event.                             */\r
+         EVEL_DOMAIN_HEARTBEAT,      /** A Heartbeat event (event header only).     */\r
+         EVEL_DOMAIN_MEASUREMENT,    /** A Measurement for VF Scaling event.        */\r
+         EVEL_DOMAIN_MOBILE_FLOW,    /** A Mobile Flow event.                       */\r
+         EVEL_DOMAIN_OTHER,          /** Another event.                             */\r
+         EVEL_DOMAIN_REPORT,         /** A Measurement for VF Reporting event.      */\r
+         EVEL_DOMAIN_SIPSIGNALING,   /** A Signaling event.                         */\r
+         EVEL_DOMAIN_STATE_CHANGE,   /** A State Change event.                      */\r
+         EVEL_DOMAIN_SYSLOG,         /** A Syslog event.                            */\r
+         EVEL_DOMAIN_THRESHOLD_CROSSING,  /** A Threshold crossing alert Event     */\r
+         EVEL_DOMAIN_VOICE_QUALITY,  /** A Voice Quality Event                      */\r
+         EVEL_DOMAIN_HEARTBEAT_FIELD,/** A Heartbeat field event.                   */\r
+         EVEL_MAX_DOMAINS            /** Maximum number of recognized Event types.  */\r
+       }\r
+       \r
+       /**************************************************************************//**\r
+        * Event priorities.\r
+        * JSON equivalent field: priority\r
+        *****************************************************************************/\r
+       public enum PRIORITIES {\r
+         EVEL_PRIORITY_HIGH,\r
+         EVEL_PRIORITY_MEDIUM,\r
+         EVEL_PRIORITY_NORMAL,\r
+         EVEL_PRIORITY_LOW,\r
+         EVEL_MAX_PRIORITIES\r
+       }\r
+       \r
+       final int EVEL_HEADER_MAJOR_VERSION = 1;\r
+       final int EVEL_HEADER_MINOR_VERSION = 1;\r
+         /***************************************************************************/\r
+         /* Version                                                                 */\r
+         /***************************************************************************/\r
+         int major_version;\r
+         int minor_version;\r
+\r
+         /***************************************************************************/\r
+         /* Mandatory fields                                                        */\r
+         /***************************************************************************/\r
+         DOMAINS event_domain;\r
+         String event_id=null;\r
+         String event_name=null;\r
+         String source_name=null;\r
+         String reporting_entity_name=null;\r
+         PRIORITIES priority;\r
+         Long start_epoch_microsec = 0L;\r
+         Long last_epoch_microsec = 0L;\r
+         int sequence;\r
+\r
+         /***************************************************************************/\r
+         /* Optional fields                                                         */\r
+         /***************************************************************************/\r
+         EvelOptionString event_type;\r
+         EvelOptionString source_id;\r
+         EvelOptionString reporting_entity_id;\r
+         EvelOptionIntHeader internal_field;\r
+         EvelOptionString nfcnaming_code;\r
+         EvelOptionString nfnaming_code;\r
+         \r
+         /**************************************************************************//**\r
+          * Unique sequence number for events from this VNF.\r
+          *****************************************************************************/\r
+         static int event_sequence = 1;\r
+         private static final Logger LOGGER = Logger.getLogger( EvelHeader.class.getName() );\r
+\r
+               protected static void EVEL_EXIT() {\r
+                       // TODO Auto-generated method stub\r
+                       \r
+               }\r
+\r
+               protected static void EVEL_ENTER() {\r
+                       // TODO Auto-generated method stub\r
+               }\r
+\r
+         /**************************************************************************//**\r
+          * Set the next event_sequence to use.\r
+          *\r
+          * @param sequence      The next sequence number to use.\r
+          *****************************************************************************/\r
+         void evel_set_next_event_sequence( int sequence)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           LOGGER.info(MessageFormat.format("Setting event sequence to {0}, was {1} ", sequence, event_sequence));\r
+           event_sequence = sequence;\r
+\r
+           EVEL_EXIT();\r
+         }\r
+         \r
+         private final static char[] hexArray = "0123456789ABCDEF".toCharArray();\r
+         private static String bytesToHex(byte[] bytes) {\r
+             char[] hexChars = new char[bytes.length * 2];\r
+             for ( int j = 0; j < bytes.length; j++ ) {\r
+                 int v = bytes[j] & 0xFF;\r
+                 hexChars[j * 2] = hexArray[v >>> 4];\r
+                 hexChars[j * 2 + 1] = hexArray[v & 0x0F];\r
+             }\r
+             return new String(hexChars);\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Initialize a newly created event header.\r
+          *\r
+          * @param header  Pointer to the header being initialized.\r
+          *****************************************************************************/\r
+         public EvelHeader(String eventname,String ev_id)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           assert(eventname != null);\r
+\r
+           /***************************************************************************/\r
+           /* Initialize the header.  Get a new event sequence number.  Note that if  */\r
+           /* any memory allocation fails in here we will fail gracefully because     */\r
+           /* everything downstream can cope with nulls.                              */\r
+           /***************************************************************************/\r
+           this.event_domain = DOMAINS.EVEL_DOMAIN_HEARTBEAT;\r
+           if(ev_id == null){\r
+               event_id = MessageFormat.format("{0}", event_sequence);\r
+               LOGGER.warning("WARNING:not confirming to Common Event Format 28.3 standard");\r
+           } else\r
+               event_id = ev_id;\r
+           event_name = eventname;\r
+           start_epoch_microsec = last_epoch_microsec;\r
+           last_epoch_microsec = System.nanoTime()/1000;\r
+           priority = PRIORITIES.EVEL_PRIORITY_NORMAL;\r
+           \r
+           String hostname = "Unknown";\r
+           String uuid = "Unknown";\r
+\r
+           try\r
+           {\r
+               InetAddress addr;\r
+               addr = InetAddress.getLocalHost();\r
+               hostname = addr.getHostName();\r
+           }\r
+           catch (UnknownHostException ex)\r
+           {\r
+               System.out.println("Hostname can not be resolved");\r
+           }\r
+           \r
+           try{\r
+               \r
+          Enumeration<NetworkInterface> networks =\r
+                NetworkInterface.getNetworkInterfaces();\r
+          while(networks.hasMoreElements()) {\r
+            NetworkInterface network = networks.nextElement();\r
+            byte[] mac = network.getHardwareAddress();\r
+            \r
+            if(hostname.equalsIgnoreCase("unknown"))\r
+            {\r
+                Enumeration inetAddrs = network.getInetAddresses();\r
+                while(inetAddrs.hasMoreElements()){\r
+                InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();\r
+                if (!inetAddr.isLoopbackAddress()) {\r
+                       hostname = inetAddr.getHostAddress();\r
+                       break;\r
+                }\r
+             }\r
+            }\r
+\r
+            if (mac != null) {\r
+                /* System.out.print("Current MAC address : ");\r
+\r
+                StringBuilder sb = new StringBuilder();\r
+                for (int i = 0; i < mac.length; i++) {\r
+                    sb.append(String.format("%02X%s", mac[i],\r
+                                 (i < mac.length - 1) ? "-" : ""));\r
+                } */\r
+                \r
+                uuid = bytesToHex(mac);\r
+            }\r
+          }\r
+        \r
+           } catch (SocketException e) {\r
+                       // TODO Auto-generated catch block\r
+                       e.printStackTrace();\r
+               }\r
+           \r
+           \r
+           reporting_entity_name = hostname;\r
+           source_name = hostname;\r
+           sequence = event_sequence;\r
+\r
+           major_version = EVEL_HEADER_MAJOR_VERSION;\r
+           minor_version = EVEL_HEADER_MINOR_VERSION;\r
+           event_sequence++;\r
+\r
+           /***************************************************************************/\r
+           /* Optional parameters.                                                    */\r
+           /***************************************************************************/\r
+           event_type = new EvelOptionString(false, null);\r
+           nfcnaming_code = new EvelOptionString(false, null);\r
+           nfnaming_code = new EvelOptionString(false, null);\r
+           reporting_entity_id = new EvelOptionString(true, uuid);\r
+           source_id = new EvelOptionString(true, uuid);\r
+           internal_field = new EvelOptionIntHeader(false, null);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         \r
+         /**************************************************************************//**\r
+          * Create a new heartbeat event.\r
+          *\r
+          * @note that the heartbeat is just a "naked" commonEventHeader!\r
+          *\r
+          * @returns pointer to the newly manufactured ::EVENT_HEADER.  \r
+          * @retval  null  Failed to create the event.\r
+          ****************************************************************************/\r
+\r
+\r
+         public static EvelHeader evel_new_heartbeat()\r
+         {\r
+               EvelHeader header = null;\r
+           EVEL_ENTER();\r
+           /***************************************************************************/\r
+           /* Initialize the header.  Get a new event sequence number.  Note that if  */\r
+           /* any memory allocation fails in here we will fail gracefully because     */\r
+           /* everything downstream can cope with nulls.                              */\r
+           /***************************************************************************/\r
+           header = new EvelHeader("Heartbeat",null);\r
+           header.event_type.set_option(true);\r
+           header.event_type.SetValue("HEARTBEAT");\r
+           LOGGER.info(header.event_type.value);\r
+\r
+           EVEL_EXIT();\r
+           return header;\r
+         }\r
+         \r
+         /**************************************************************************//**\r
+          * Create a new heartbeat event.\r
+          *\r
+          * @note that the heartbeat is just a "naked" commonEventHeader!\r
+          *\r
+          * @returns pointer to the newly manufactured ::EVENT_HEADER.  \r
+          * @retval  null  Failed to create the event.\r
+          ****************************************************************************/\r
+\r
+\r
+         public static EvelHeader evel_new_heartbeat(String evname,String evid)\r
+         {\r
+               EvelHeader header = null;\r
+           EVEL_ENTER();\r
+           /***************************************************************************/\r
+           /* Initialize the header.  Get a new event sequence number.  Note that if  */\r
+           /* any memory allocation fails in here we will fail gracefully because     */\r
+           /* everything downstream can cope with nulls.                              */\r
+           /***************************************************************************/\r
+           header = new EvelHeader(evname,evid);\r
+           header.event_type.set_option(true);\r
+           header.event_type.SetValue("HEARTBEAT");;\r
+           LOGGER.info(header.event_type.value);\r
+\r
+           EVEL_EXIT();\r
+           return header;\r
+         }\r
+\r
+\r
+       /**************************************************************************//**\r
+          * Set the Event Type property of the event header.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param header        Pointer to the ::EVENT_HEADER.\r
+          * @param type          The Event Type to be set. ASCIIZ string. The caller\r
+          *                      does not need to preserve the value once the function\r
+          *                      returns.\r
+          *****************************************************************************/\r
+         public void evel_header_type_set(String type)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(type != null);\r
+\r
+           event_type.set_option(true);\r
+           event_type.SetValue(type);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Start Epoch property of the event header.\r
+          *\r
+          * @note The Start Epoch defaults to the time of event creation.\r
+          *\r
+          * @param header        Pointer to the ::EVENT_HEADER.\r
+          * @param start_epoch_microsec\r
+          *                      The start epoch to set, in microseconds.\r
+          *****************************************************************************/\r
+         public void evel_start_epoch_set(Long epoch_microsec)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions and assign the new value.                           */\r
+           /***************************************************************************/\r
+           start_epoch_microsec = epoch_microsec;\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Last Epoch property of the event header.\r
+          *\r
+          * @note The Last Epoch defaults to the time of event creation.\r
+          *\r
+          * @param header        Pointer to the ::EVENT_HEADER.\r
+          * @param last_epoch_microsec\r
+          *                      The last epoch to set, in microseconds.\r
+          *****************************************************************************/\r
+         public void evel_last_epoch_set(Long epoch_microsec)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions and assign the new value.                           */\r
+           /***************************************************************************/\r
+           last_epoch_microsec = epoch_microsec;\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the NFC Naming code property of the event header.\r
+          *\r
+          * @param header        Pointer to the ::EVENT_HEADER.\r
+          * @param nfcnamingcode String\r
+          *****************************************************************************/\r
+         public void evel_nfcnamingcode_set(String nfcnam)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions and assign the new value.                           */\r
+           /***************************************************************************/\r
+           assert(nfcnam != null);\r
+           nfcnaming_code.set_option(true);\r
+           nfcnaming_code.SetValue(nfcnam);\r
+       \r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the NF Naming code property of the event header.\r
+          *\r
+          * @param header        Pointer to the ::EVENT_HEADER.\r
+          * @param nfnamingcode String\r
+          *****************************************************************************/\r
+         public void evel_nfnamingcode_set(String nfnam)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions and assign the new value.                           */\r
+           /***************************************************************************/\r
+           assert(nfnam != null);\r
+           nfnaming_code.set_option(true);\r
+           nfnaming_code.SetValue(nfnam);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the Reporting Entity Name property of the event header.\r
+          *\r
+          * @note The Reporting Entity Name defaults to the OpenStack VM Name.\r
+          *\r
+          * @param header        Pointer to the ::EVENT_HEADER.\r
+          * @param entity_name   The entity name to set.\r
+          *****************************************************************************/\r
+         public void evel_reporting_entity_name_set(String entity_name)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions and assign the new value.                           */\r
+           /***************************************************************************/\r
+           assert(entity_name != null);\r
+\r
+           /***************************************************************************/\r
+           /* Free the previously allocated memory and replace it with a copy of the  */\r
+           /* provided one.                                                           */\r
+           /***************************************************************************/\r
+           reporting_entity_name = entity_name;\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Reporting Entity Id property of the event header.\r
+          *\r
+          * @note The Reporting Entity Id defaults to the OpenStack VM UUID.\r
+          *\r
+          * @param header        Pointer to the ::EVENT_HEADER.\r
+          * @param entity_id     The entity id to set.\r
+          *****************************************************************************/\r
+         public void evel_reporting_entity_id_set(String entity_id)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions and assign the new value.                           */\r
+           /***************************************************************************/\r
+           assert(entity_id != null);\r
+\r
+           /***************************************************************************/\r
+           /* Free the previously allocated memory and replace it with a copy of the  */\r
+           /* provided one.  Note that evel_force_option_string strdups entity_id.    */\r
+           /***************************************************************************/\r
+           reporting_entity_id.set_option(true);\r
+           reporting_entity_id.SetValue(entity_id);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+         \r
+         /**************************************************************************//**\r
+          * Map an ::EVEL_EVENT_DOMAINS enum value to the equivalent string.\r
+          *\r
+          * @param domain        The domain to convert.\r
+          * @returns The equivalent string.\r
+          *****************************************************************************/\r
+         String evel_event_domain(DOMAINS domain)\r
+         {\r
+           String result;\r
+\r
+           EVEL_ENTER();\r
+\r
+           switch (domain)\r
+           {\r
+             case EVEL_DOMAIN_HEARTBEAT:\r
+               result = "heartbeat";\r
+               break;\r
+\r
+             case EVEL_DOMAIN_FAULT:\r
+               result = "fault";\r
+               break;\r
+\r
+             case EVEL_DOMAIN_MEASUREMENT:\r
+               result = "measurementsForVfScaling";\r
+               break;\r
+\r
+             case EVEL_DOMAIN_REPORT:\r
+               result = "measurementsForVfReporting";\r
+               break;\r
+\r
+             case EVEL_DOMAIN_MOBILE_FLOW:\r
+               result = "mobileFlow";\r
+               break;\r
+\r
+             case EVEL_DOMAIN_HEARTBEAT_FIELD:\r
+               result = "heartbeat";\r
+               break;\r
+\r
+             case EVEL_DOMAIN_SIPSIGNALING:\r
+               result = "sipSignaling";\r
+               break;\r
+\r
+             case EVEL_DOMAIN_STATE_CHANGE:\r
+               result = "stateChange";\r
+               break;\r
+\r
+             case EVEL_DOMAIN_SYSLOG:\r
+               result = "syslog";\r
+               break;\r
+\r
+             case EVEL_DOMAIN_OTHER:\r
+               result = "other";\r
+               break;\r
+\r
+             case EVEL_DOMAIN_VOICE_QUALITY:\r
+               result = "voiceQuality";\r
+               break;\r
+\r
+             case EVEL_DOMAIN_THRESHOLD_CROSSING:\r
+                       result = "thresholdCrossingAlert";\r
+                       break;\r
+                       \r
+             default:\r
+               result = null;\r
+               LOGGER.severe(MessageFormat.format("Unexpected domain {0}", domain));\r
+           }\r
+\r
+           EVEL_EXIT();\r
+\r
+           return result;\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Map an ::EVEL_EVENT_PRIORITIES enum value to the equivalent string.\r
+          *\r
+          * @param priority      The priority to convert.\r
+          * @returns The equivalent string.\r
+          *****************************************************************************/\r
+         String evel_event_priority(PRIORITIES priority)\r
+         {\r
+           String result;\r
+\r
+           EVEL_ENTER();\r
+\r
+           switch (priority)\r
+           {\r
+             case EVEL_PRIORITY_HIGH:\r
+               result = "High";\r
+               break;\r
+\r
+             case EVEL_PRIORITY_MEDIUM:\r
+               result = "Medium";\r
+               break;\r
+\r
+             case EVEL_PRIORITY_NORMAL:\r
+               result = "Normal";\r
+               break;\r
+\r
+             case EVEL_PRIORITY_LOW:\r
+               result = "Low";\r
+               break;\r
+\r
+             default:\r
+               result = null;\r
+               LOGGER.severe(MessageFormat.format("Unexpected priority {0}", priority));\r
+           }\r
+\r
+           EVEL_EXIT();\r
+\r
+           return result;\r
+         }\r
+         \r
+         /**************************************************************************//**\r
+          * Encode the CommonEventHeaeder as a JSON event object builder\r
+          * according to AT&T's schema.\r
+          *\r
+          * @retval JsonObjectBuilder of fault body portion of message   \r
+          *****************************************************************************/\r
+         JsonObjectBuilder eventHeaderObject()\r
+         {\r
+           String domain = evel_event_domain(event_domain);\r
+           String prity = evel_event_priority(priority);\r
+           double version = major_version+(double)minor_version/10;\r
+           \r
+           EVEL_ENTER();\r
+           \r
+           /***************************************************************************/\r
+           /* Required fields.                                                        */\r
+           /***************************************************************************/\r
+           \r
+           JsonObjectBuilder commheader = Json.createObjectBuilder()\r
+                        .add("domain", domain)\r
+                        .add("eventId", event_id)\r
+                        .add("eventName", event_name)\r
+                        .add("lastEpochMicrosec", last_epoch_microsec)\r
+                        .add("priority", prity)\r
+                        .add("reportingEntityName", reporting_entity_name)\r
+                        .add("sequence", sequence)\r
+                        .add("sourceName", source_name)\r
+                        .add("startEpochMicrosec", start_epoch_microsec)\r
+                        .add("version", version)\r
+                        .add("reportingEntityId", reporting_entity_id.GetValue())\r
+                        .add("sourceId", source_id.GetValue());\r
+           \r
+           /***************************************************************************/\r
+           /* Optional fields.                                                        */\r
+           /***************************************************************************/\r
+           \r
+           if( event_type.is_set )\r
+               commheader.add("eventType", event_type.GetValue());\r
+           if( source_id.is_set )\r
+               commheader.add("sourceId", source_id.GetValue());\r
+           if( reporting_entity_id.is_set )\r
+               commheader.add("reportingEntityId", reporting_entity_id.GetValue());\r
+           \r
+           if( internal_field.is_set )\r
+               commheader.add("internalField",internal_field.toString());          \r
+           \r
+           if( nfcnaming_code.is_set )\r
+               commheader.add("nfcNamingCode", nfcnaming_code.GetValue());\r
+           if( nfnaming_code.is_set )\r
+               commheader.add("nfNamingCode", nfnaming_code.GetValue());\r
+           \r
+           EVEL_EXIT();\r
+           \r
+           return commheader;\r
+\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Encode the event as a JSON event object according to AT&T's schema.\r
+          * retval : String of JSON event header only message\r
+          *****************************************************************************/\r
+         String evel_json_encode_event()\r
+         {\r
+               \r
+           JsonObject obj = Json.createObjectBuilder()\r
+                    .add("event", Json.createObjectBuilder()\r
+                                .add( "commonEventHeader",eventHeaderObject() )\r
+                                ).build();\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return obj.toString();\r
+\r
+         }\r
+         \r
+         \r
+\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelHeartbeatField.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelHeartbeatField.java
new file mode 100644 (file)
index 0000000..08c6f4f
--- /dev/null
@@ -0,0 +1,214 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Heartbeat field class\r
+ *\r
+ * This file implements the Evel Heartbeat Event class which is intended to provide a\r
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so\r
+ * that VNFs can use it to send Agent status.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+\r
+import javax.json.Json;\r
+import javax.json.JsonArrayBuilder;\r
+import javax.json.JsonObject;\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+\r
+public class EvelHeartbeatField extends EvelHeader {\r
+       \r
+       //version of Heartbeat field format revisions\r
+       int major_version = 1;\r
+       int minor_version = 2;\r
+       \r
+       /**************************************************************************//**\r
+        * Alert types.\r
+        * JSON equivalent fields: newState, oldState\r
+        *****************************************************************************/\r
+       \r
+       /***************************************************************************/\r
+       /* Mandatory fields                                                        */\r
+       /***************************************************************************/\r
+       int    heartbeat_interval;\r
+\r
+\r
+       /***************************************************************************/\r
+       /* Optional fields                                                         */\r
+       /***************************************************************************/\r
+         ArrayList<String[]> additional_info;\r
+       \r
+         private static final Logger LOGGER = Logger.getLogger( EvelHeartbeatField.class.getName() );\r
+\r
+         /**************************************************************************//**\r
+          * Construct Heartbeat field event.\r
+          *\r
+          * @param interval     The Heartbeat interval at which messages are sent.\r
+          * \r
+          *****************************************************************************/\r
+       public EvelHeartbeatField(int interval,String evname,String evid)\r
+       {\r
+               super(evname,evid);\r
+               event_domain = EvelHeader.DOMAINS.EVEL_DOMAIN_HEARTBEAT_FIELD;\r
+               assert( interval > 0 );\r
+               \r
+               heartbeat_interval = interval;\r
+\r
+               additional_info = null;         \r
+       }\r
+       \r
+       /**************************************************************************//**\r
+        * Add an additional value name/value pair to the Fault.\r
+        *\r
+        * The name and value are null delimited ASCII strings.  The library takes\r
+        * a copy so the caller does not have to preserve values after the function\r
+        * returns.\r
+        *\r
+        * @param name      ASCIIZ string with the attribute's name.  The caller\r
+        *                  does not need to preserve the value once the function\r
+        *                  returns.\r
+        * @param value     ASCIIZ string with the attribute's value.  The caller\r
+        *                  does not need to preserve the value once the function\r
+        *                  returns.\r
+        *****************************************************************************/\r
+       public void evel_hrtbt_field_addl_info_add(String name, String value)\r
+       {\r
+         String[] addl_info = null;\r
+         EVEL_ENTER();\r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions.                                                    */\r
+         /***************************************************************************/\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_STATE_CHANGE);\r
+         assert(name != null);\r
+         assert(value != null);\r
+         \r
+         if( additional_info == null )\r
+         {\r
+                 additional_info = new ArrayList<String[]>();\r
+         }\r
+\r
+         LOGGER.debug(MessageFormat.format("Adding name={0} value={1}", name, value));\r
+         addl_info = new String[2];\r
+         assert(addl_info != null);\r
+         addl_info[0] = name;\r
+         addl_info[1] = value;\r
+\r
+         additional_info.add(addl_info);\r
+\r
+         EVEL_EXIT();\r
+       }\r
+       \r
+       /**************************************************************************//**\r
+        * Set the Interval property of the Heartbeat fields event.\r
+        *\r
+        * @note  The property is treated as immutable: it is only valid to call\r
+        *        the setter once.  However, we don't assert if the caller tries to\r
+        *        overwrite, just ignoring the update instead.\r
+        *\r
+        * @param interval      Heartbeat interval.\r
+        *****************************************************************************/\r
+       public void evel_hrtbt_interval_set( int interval)\r
+       {\r
+         EVEL_ENTER();\r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions and call evel_set_option_string.                    */\r
+         /***************************************************************************/\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_HEARTBEAT_FIELD);\r
+         assert(interval > 0);\r
+\r
+         heartbeat_interval = interval;\r
+         EVEL_EXIT();\r
+       }\r
+\r
+\r
+       /**************************************************************************//**\r
+        * Encode the Heartbeat field in JSON according to AT&T's schema.\r
+        *\r
+        * @retval JsonObjectBuilder of Heartbeat field body portion of message   \r
+        *****************************************************************************/\r
+        JsonObjectBuilder evelHeartbeatFieldObject()\r
+        {\r
+         double version = major_version+(double)minor_version/10;\r
+\r
+         EVEL_ENTER();\r
+         \r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions.                                                    */\r
+         /***************************************************************************/\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_HEARTBEAT_FIELD);\r
+\r
+         /***************************************************************************/\r
+         /* Mandatory fields.                                                       */\r
+         /***************************************************************************/\r
+         \r
+         JsonObjectBuilder evelstate = Json.createObjectBuilder()\r
+                        .add("heartbeatInterval", heartbeat_interval);\r
+         \r
+         evelstate.add( "heartbeatFieldsVersion", version);\r
+\r
+         /***************************************************************************/\r
+         /* Checkpoint, so that we can wind back if all fields are suppressed.      */\r
+         /***************************************************************************/\r
+         if( additional_info != null )\r
+         {\r
+           JsonArrayBuilder builder = Json.createArrayBuilder();\r
+           for(int i=0;i<additional_info.size();i++) {\r
+                 String[] addl_info = additional_info.get(i);\r
+                 JsonObject obj = Json.createObjectBuilder()\r
+                            .add("name", addl_info[0])\r
+                            .add("value", addl_info[1]).build();\r
+                 builder.add(obj);\r
+           }\r
+               evelstate.add("additionalFields", builder);\r
+         }\r
+\r
+         EVEL_EXIT();\r
+         \r
+         return evelstate;\r
+       }\r
+       \r
+       \r
+         /**************************************************************************//**\r
+          * Encode the event as a JSON event object according to AT&T's schema.\r
+          * retval : String of JSON event message\r
+          *****************************************************************************/\r
+         String evel_json_encode_event()\r
+         {\r
+               EVEL_ENTER();\r
+               \r
+               assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_HEARTBEAT_FIELD);\r
+           //encode common event header and body    \r
+           JsonObject obj = Json.createObjectBuilder()\r
+                    .add("event", Json.createObjectBuilder()\r
+                                .add( "commonEventHeader",eventHeaderObject() )\r
+                                .add( "heartbeatFields",evelHeartbeatFieldObject() )\r
+                                ).build();\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return obj.toString();\r
+\r
+         }\r
+       \r
+\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelMobileFlow.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelMobileFlow.java
new file mode 100644 (file)
index 0000000..5b2c408
--- /dev/null
@@ -0,0 +1,2064 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Mobile Flow class\r
+ *\r
+ * This file implements the Evel Mobile Flow Event class which is intended to provide a\r
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so\r
+ * that VNFs can use it to send Mobile flow events.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+\r
+import javax.json.Json;\r
+import javax.json.JsonArrayBuilder;\r
+import javax.json.JsonObject;\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+\r
+\r
+public class EvelMobileFlow extends EvelHeader {\r
+       \r
+       int major_version = 1;\r
+       int minor_version = 2;\r
+       \r
+       static int EVEL_TOS_SUPPORTED    =  256;\r
+       /**************************************************************************//**\r
+        * TCP flags.\r
+        * JSON equivalent fields: tcpFlagCountList, tcpFlagList\r
+        *****************************************************************************/\r
+       public enum EVEL_TCP_FLAGS {\r
+         EVEL_TCP_NS,\r
+         EVEL_TCP_CWR,\r
+         EVEL_TCP_ECE,\r
+         EVEL_TCP_URG,\r
+         EVEL_TCP_ACK,\r
+         EVEL_TCP_PSH,\r
+         EVEL_TCP_RST,\r
+         EVEL_TCP_SYN,\r
+         EVEL_TCP_FIN,\r
+         EVEL_MAX_TCP_FLAGS\r
+       }\r
+       static int EVEL_MAX_TCP_FLAGS    =  10;\r
+       /**************************************************************************//**\r
+        * Mobile QCI Classes of Service.\r
+        * JSON equivalent fields: mobileQciCosCountList, mobileQciCosList\r
+        *****************************************************************************/\r
+       public enum EVEL_QCI_COS_TYPES {\r
+\r
+         /***************************************************************************/\r
+         /* UMTS Classes of Service.                                                */\r
+         /***************************************************************************/\r
+         EVEL_QCI_COS_UMTS_CONVERSATIONAL,\r
+         EVEL_QCI_COS_UMTS_STREAMING,\r
+         EVEL_QCI_COS_UMTS_INTERACTIVE,\r
+         EVEL_QCI_COS_UMTS_BACKGROUND,\r
+\r
+         /***************************************************************************/\r
+         /* LTE Classes of Service.                                                 */\r
+         /***************************************************************************/\r
+         EVEL_QCI_COS_LTE_1,\r
+         EVEL_QCI_COS_LTE_2,\r
+         EVEL_QCI_COS_LTE_3,\r
+         EVEL_QCI_COS_LTE_4,\r
+         EVEL_QCI_COS_LTE_65,\r
+         EVEL_QCI_COS_LTE_66,\r
+         EVEL_QCI_COS_LTE_5,\r
+         EVEL_QCI_COS_LTE_6,\r
+         EVEL_QCI_COS_LTE_7,\r
+         EVEL_QCI_COS_LTE_8,\r
+         EVEL_QCI_COS_LTE_9,\r
+         EVEL_QCI_COS_LTE_69,\r
+         EVEL_QCI_COS_LTE_70,\r
+         EVEL_MAX_QCI_COS_TYPES\r
+       }\r
+       static int EVEL_MAX_QCI_COS_TYPES = 18;\r
+       \r
+         private static final Logger LOGGER = Logger.getLogger( EvelMobileFlow.class.getName() );\r
+\r
+         \r
+         /*****************************************************************************/\r
+         /* Array of strings to use when encoding TCP flags.                          */\r
+         /*****************************************************************************/\r
+         static final String[/*EVEL_MAX_TCP_FLAGS*/] evel_tcp_flag_strings = {\r
+           "NS",\r
+           "CWR",\r
+           "ECE",\r
+           "URG",\r
+           "ACK",\r
+           "PSH",\r
+           "RST",\r
+           "SYN",\r
+           "FIN"\r
+         };\r
+\r
+         /*****************************************************************************/\r
+         /* Array of strings to use when encoding QCI COS.                            */\r
+         /*****************************************************************************/\r
+         static final String[/*EVEL_MAX_QCI_COS_TYPES*/] evel_qci_cos_strings = {\r
+           "conversational",\r
+           "streaming",\r
+           "interactive",\r
+           "background",\r
+           "1",\r
+           "2",\r
+           "3",\r
+           "4",\r
+           "65",\r
+           "66",\r
+           "5",\r
+           "6",\r
+           "7",\r
+           "8",\r
+           "9",\r
+           "69",\r
+           "70"\r
+         };\r
+\r
+       \r
+       /**************************************************************************//**\r
+        * Vendor VNF Name fields.\r
+        * JSON equivalent field: vendorVnfNameFields\r
+        *****************************************************************************/\r
+       /**************************************************************************//**\r
+        * Mobile GTP Per Flow Metrics.\r
+        * JSON equivalent field: gtpPerFlowMetrics\r
+        *****************************************************************************/\r
+       public class MOBILE_GTP_PER_FLOW_METRICS {\r
+                 double avg_bit_error_rate;\r
+                 double avg_packet_delay_variation;\r
+                 int avg_packet_latency;\r
+                 int avg_receive_throughput;\r
+                 int avg_transmit_throughput;\r
+                 \r
+                 int flow_activation_epoch;\r
+                 int flow_activation_microsec;\r
+                 \r
+                 int flow_deactivation_epoch;\r
+                 int flow_deactivation_microsec;\r
+                 Date flow_deactivation_time;\r
+                 String flow_status;\r
+                 int max_packet_delay_variation;\r
+                 int num_activation_failures;\r
+                 int num_bit_errors;\r
+                 int num_bytes_received;\r
+                 int num_bytes_transmitted;\r
+                 int num_dropped_packets;\r
+                 int num_l7_bytes_received;\r
+                 int num_l7_bytes_transmitted;\r
+                 int num_lost_packets;\r
+                 int num_out_of_order_packets;\r
+                 int num_packet_errors;\r
+                 int num_packets_received_excl_retrans;\r
+                 int num_packets_received_incl_retrans;\r
+                 int num_packets_transmitted_incl_retrans;\r
+                 int num_retries;\r
+                 int num_timeouts;\r
+                 int num_tunneled_l7_bytes_received;\r
+                 int round_trip_time;\r
+                 int time_to_first_byte;\r
+\r
+                 /***************************************************************************/\r
+                 /* Optional fields                                                         */\r
+                 /***************************************************************************/\r
+                 EvelOptionInt ip_tos_counts[/*EVEL_TOS_SUPPORTED*/];\r
+                 EvelOptionInt tcp_flag_counts[/*EVEL_MAX_TCP_FLAGS*/];\r
+                 EvelOptionInt qci_cos_counts[/*EVEL_MAX_QCI_COS_TYPES*/];\r
+                 \r
+                 EvelOptionInt dur_connection_failed_status;\r
+                 EvelOptionInt dur_tunnel_failed_status;\r
+                 EvelOptionString flow_activated_by;\r
+                 \r
+                 EvelOptionTime flow_activation_time;\r
+                 EvelOptionString flow_deactivated_by;\r
+                 \r
+                 EvelOptionString gtp_connection_status;\r
+                 EvelOptionString gtp_tunnel_status;\r
+                 EvelOptionInt large_packet_rtt;\r
+                 EvelOptionDouble large_packet_threshold;\r
+                 EvelOptionInt max_receive_bit_rate;\r
+                 EvelOptionInt max_transmit_bit_rate;\r
+                 EvelOptionInt num_gtp_echo_failures;\r
+                 EvelOptionInt num_gtp_tunnel_errors;\r
+                 EvelOptionInt num_http_errors;\r
+\r
+         /**************************************************************************//**\r
+          * Create a new Mobile GTP Per Flow Metrics.\r
+          *\r
+          * @note    The mandatory fields on the Mobile GTP Per Flow Metrics must be\r
+          *          supplied to this factory function and are immutable once set.\r
+          *          Optional fields have explicit setter functions, but again values\r
+          *          may only be set once so that the Mobile GTP Per Flow Metrics has\r
+          *          immutable properties.\r
+          *\r
+          * @param   avg_bit_error_rate          Average bit error rate.\r
+          * @param   avg_packet_delay_variation  Average delay or jitter in ms.\r
+          * @param   avg_packet_latency          Average delivery latency.\r
+          * @param   avg_receive_throughput      Average receive throughput.\r
+          * @param   avg_transmit_throughput     Average transmit throughput.\r
+          * @param   flow_activation_epoch       Time the connection is activated.\r
+          * @param   flow_activation_microsec    Microseconds for the start of the flow\r
+          *                                      connection.\r
+          * @param   flow_deactivation_epoch     Time for the end of the connection.\r
+          * @param   flow_deactivation_microsec  Microseconds for the end of the flow\r
+          *                                      connection.\r
+          * @param   flow_deactivation_time      Transmission time of the first packet.\r
+          * @param   flow_status                 Connection status.\r
+          * @param   max_packet_delay_variation  Maximum packet delay or jitter in ms.\r
+          * @param   num_activation_failures     Number of failed activation requests.\r
+          * @param   num_bit_errors              Number of errored bits.\r
+          * @param   num_bytes_received          Number of bytes received.\r
+          * @param   num_bytes_transmitted       Number of bytes transmitted.\r
+          * @param   num_dropped_packets         Number of received packets dropped.\r
+          * @param   num_l7_bytes_received       Number of tunneled Layer 7 bytes\r
+          *                                      received.\r
+          * @param   num_l7_bytes_transmitted    Number of tunneled Layer 7 bytes\r
+          *                                      transmitted.\r
+          * @param   num_lost_packets            Number of lost packets.\r
+          * @param   num_out_of_order_packets    Number of out-of-order packets.\r
+          * @param   num_packet_errors           Number of errored packets.\r
+          * @param   num_packets_received_excl_retrans  Number of packets received,\r
+          *                                             excluding retransmits.\r
+          * @param   num_packets_received_incl_retrans  Number of packets received.\r
+          * @param   num_packets_transmitted_incl_retrans  Number of packets\r
+          *                                                transmitted.\r
+          * @param   num_retries                 Number of packet retries.\r
+          * @param   num_timeouts                Number of packet timeouts.\r
+          * @param   num_tunneled_l7_bytes_received  Number of tunneled Layer 7 bytes\r
+          *                                          received, excluding retransmits.\r
+          * @param   round_trip_time             Round trip time.\r
+          * @param   time_to_first_byte          Time in ms between connection\r
+          *                                      activation and first byte received.\r
+          *\r
+          * @returns pointer to the newly manufactured ::MOBILE_GTP_PER_FLOW_METRICS.\r
+          *          If the structure is not used it must be released using\r
+          *          ::evel_free_mobile_gtp_flow_metrics.\r
+          * @retval  null  Failed to create the event.\r
+          *****************************************************************************/\r
+         public MOBILE_GTP_PER_FLOW_METRICS(\r
+                                               double tavg_bit_error_rate,\r
+                                               double tavg_packet_delay_variation,\r
+                                               int tavg_packet_latency,\r
+                                               int tavg_receive_throughput,\r
+                                               int tavg_transmit_throughput,\r
+                                               int tflow_activation_epoch,\r
+                                               int tflow_activation_microsec,\r
+                                               int tflow_deactivation_epoch,\r
+                                               int tflow_deactivation_microsec,\r
+                                               Date tflow_deactivation_time,\r
+                                               String tflow_status,\r
+                                               int tmax_packet_delay_variation,\r
+                                               int tnum_activation_failures,\r
+                                               int tnum_bit_errors,\r
+                                               int tnum_bytes_received,\r
+                                               int tnum_bytes_transmitted,\r
+                                               int tnum_dropped_packets,\r
+                                               int tnum_l7_bytes_received,\r
+                                               int tnum_l7_bytes_transmitted,\r
+                                               int tnum_lost_packets,\r
+                                               int tnum_out_of_order_packets,\r
+                                               int tnum_packet_errors,\r
+                                               int tnum_packets_received_excl_retrans,\r
+                                               int tnum_packets_received_incl_retrans,\r
+                                               int tnum_packets_transmitted_incl_retrans,\r
+                                               int tnum_retries,\r
+                                               int tnum_timeouts,\r
+                                               int tnum_tunneled_l7_bytes_received,\r
+                                               int tround_trip_time,\r
+                                               int ttime_to_first_byte)\r
+         {\r
+           int ii;\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tavg_bit_error_rate >= 0.0);\r
+           assert(tavg_packet_delay_variation >= 0.0);\r
+           assert(tavg_packet_latency >= 0);\r
+           assert(tavg_receive_throughput >= 0);\r
+           assert(tavg_transmit_throughput >= 0);\r
+           assert(tflow_activation_epoch > 0);\r
+           assert(tflow_activation_microsec >= 0);\r
+           assert(tflow_deactivation_epoch > 0);\r
+           assert(tflow_deactivation_microsec >= 0);\r
+           assert(tflow_status != null);\r
+           assert(tmax_packet_delay_variation >= 0);\r
+           assert(tnum_activation_failures >= 0);\r
+           assert(tnum_bit_errors >= 0);\r
+           assert(tnum_bytes_received >= 0);\r
+           assert(tnum_bytes_transmitted >= 0);\r
+           assert(tnum_dropped_packets >= 0);\r
+           assert(tnum_l7_bytes_received >= 0);\r
+           assert(tnum_l7_bytes_transmitted >= 0);\r
+           assert(tnum_lost_packets >= 0);\r
+           assert(tnum_out_of_order_packets >= 0);\r
+           assert(tnum_packet_errors >= 0);\r
+           assert(tnum_packets_received_excl_retrans >= 0);\r
+           assert(tnum_packets_received_incl_retrans >= 0);\r
+           assert(tnum_packets_transmitted_incl_retrans >= 0);\r
+           assert(tnum_retries >= 0);\r
+           assert(tnum_timeouts >= 0);\r
+           assert(tnum_tunneled_l7_bytes_received >= 0);\r
+           assert(tround_trip_time >= 0);\r
+           assert(ttime_to_first_byte >= 0);\r
+\r
+           /***************************************************************************/\r
+           /* Allocate the Mobile Flow GTP Per Flow Metrics.                          */\r
+           /***************************************************************************/\r
+           LOGGER.debug("New Mobile Flow GTP Per Flow Metrics");\r
+\r
+           /***************************************************************************/\r
+           /* Initialize the Mobile Flow GTP Per Flow Metrics fields.  Optional       */\r
+           /* string values are uninitialized (null).                                 */\r
+           /***************************************************************************/\r
+           avg_bit_error_rate = tavg_bit_error_rate;\r
+           avg_packet_delay_variation = tavg_packet_delay_variation;\r
+           avg_packet_latency = tavg_packet_latency;\r
+           avg_receive_throughput = tavg_receive_throughput;\r
+           avg_transmit_throughput = tavg_transmit_throughput;\r
+           flow_activation_epoch = tflow_activation_epoch;\r
+           flow_activation_microsec = tflow_activation_microsec;\r
+           flow_deactivation_epoch = tflow_deactivation_epoch;\r
+           flow_deactivation_microsec = tflow_deactivation_microsec;\r
+           flow_deactivation_time = tflow_deactivation_time;\r
+           flow_status = tflow_status;\r
+           max_packet_delay_variation = tmax_packet_delay_variation;\r
+           num_activation_failures = tnum_activation_failures;\r
+           num_bit_errors = tnum_bit_errors;\r
+           num_bytes_received = tnum_bytes_received;\r
+           num_bytes_transmitted = tnum_bytes_transmitted;\r
+           num_dropped_packets = tnum_dropped_packets;\r
+           num_l7_bytes_received = tnum_l7_bytes_received;\r
+           num_l7_bytes_transmitted = tnum_l7_bytes_transmitted;\r
+           num_lost_packets = tnum_lost_packets;\r
+           num_out_of_order_packets = tnum_out_of_order_packets;\r
+           num_packet_errors = tnum_packet_errors;\r
+           num_packets_received_excl_retrans =\r
+                                                      tnum_packets_received_excl_retrans;\r
+           num_packets_received_incl_retrans =\r
+                                                      tnum_packets_received_incl_retrans;\r
+           num_packets_transmitted_incl_retrans =\r
+                                                   tnum_packets_transmitted_incl_retrans;\r
+           num_retries = tnum_retries;\r
+           num_timeouts = tnum_timeouts;\r
+           num_tunneled_l7_bytes_received = tnum_tunneled_l7_bytes_received;\r
+           round_trip_time = tround_trip_time;\r
+           time_to_first_byte = ttime_to_first_byte;\r
+           ip_tos_counts = new EvelOptionInt[EVEL_TOS_SUPPORTED];\r
+           for (ii = 0; ii < EVEL_TOS_SUPPORTED; ii++)\r
+           {\r
+             ip_tos_counts[ii] = new EvelOptionInt();\r
+           }\r
+           tcp_flag_counts = new EvelOptionInt[EVEL_MAX_TCP_FLAGS];\r
+           for (ii = 0; ii < EVEL_MAX_TCP_FLAGS; ii++)\r
+           {\r
+             tcp_flag_counts[ii] = new EvelOptionInt();\r
+           }\r
+           qci_cos_counts = new EvelOptionInt[EVEL_MAX_QCI_COS_TYPES];\r
+           for (ii = 0; ii < EVEL_MAX_QCI_COS_TYPES; ii++)\r
+           {\r
+             qci_cos_counts[ii] = new EvelOptionInt();\r
+           }\r
+           dur_connection_failed_status = new EvelOptionInt();\r
+           dur_tunnel_failed_status = new EvelOptionInt();\r
+           flow_activated_by = new EvelOptionString();\r
+           flow_activation_time = new EvelOptionTime();\r
+           flow_deactivated_by = new EvelOptionString();\r
+           gtp_connection_status = new EvelOptionString();\r
+           gtp_tunnel_status = new EvelOptionString();\r
+           large_packet_rtt = new EvelOptionInt();\r
+           large_packet_threshold = new EvelOptionDouble();\r
+           max_receive_bit_rate = new EvelOptionInt();\r
+           max_transmit_bit_rate = new EvelOptionInt();\r
+           num_gtp_echo_failures = new EvelOptionInt();\r
+           num_gtp_tunnel_errors = new EvelOptionInt();\r
+           num_http_errors = new EvelOptionInt();\r
+\r
+           EVEL_EXIT();\r
+         }\r
+       }\r
+       \r
+       /***************************************************************************/\r
+       /* Mandatory fields                                                        */\r
+       /***************************************************************************/     \r
+         String flow_direction;\r
+         public MOBILE_GTP_PER_FLOW_METRICS gtp_per_flow_metrics;\r
+         String ip_protocol_type;\r
+         String ip_version;\r
+         String other_endpoint_ip_address;\r
+         int other_endpoint_port;\r
+         String reporting_endpoint_ip_addr;\r
+         int reporting_endpoint_port;\r
+                 \r
+         /***************************************************************************/\r
+         /* Optional fields                                                         */\r
+         /***************************************************************************/\r
+         ArrayList<String[]> additional_info;\r
+         EvelOptionString application_type;\r
+         EvelOptionString app_protocol_type;\r
+         EvelOptionString app_protocol_version;\r
+         EvelOptionString cid;\r
+         EvelOptionString connection_type;\r
+         EvelOptionString ecgi;\r
+         EvelOptionString gtp_protocol_type;\r
+         EvelOptionString gtp_version;\r
+         EvelOptionString http_header;\r
+         EvelOptionString imei;\r
+         EvelOptionString imsi;\r
+         EvelOptionString lac;\r
+         EvelOptionString mcc;\r
+         EvelOptionString mnc;\r
+         EvelOptionString msisdn;\r
+         EvelOptionString other_functional_role;\r
+         EvelOptionString rac;\r
+         EvelOptionString radio_access_technology;\r
+         EvelOptionString sac;\r
+         EvelOptionInt    sampling_algorithm;\r
+         EvelOptionString tac;\r
+         EvelOptionString tunnel_id;\r
+         EvelOptionString vlan_id;\r
+\r
+       /***************************************************************************/\r
+       /* Optional fields                                                         */\r
+       /***************************************************************************/\r
+\r
+\r
+         /*****************************************************************************/\r
+         /* Local prototypes                                                          */\r
+         /*****************************************************************************/\r
+         \r
+        \r
+         /**************************************************************************//**\r
+          * Create a new Mobile Flow event.\r
+          *\r
+          * @note    The mandatory fields on the Mobile Flow must be supplied to this\r
+          *          factory function and are immutable once set.  Optional fields have\r
+          *          explicit setter functions, but again values may only be set once so\r
+          *          that the Mobile Flow has immutable properties.\r
+          * @param   flow_direction              Flow direction.\r
+          * @param   gtp_per_flow_metrics        GTP per-flow metrics.\r
+          * @param   ip_protocol_type            IP protocol type.\r
+          * @param   ip_version                  IP protocol version.\r
+          * @param   other_endpoint_ip_address   IP address of the other endpoint.\r
+          * @param   other_endpoint_port         IP port of the other endpoint.\r
+          * @param   reporting_endpoint_ip_addr  IP address of the reporting endpoint.\r
+          \r
+          * @param   reporting_endpoint_port     IP port of the reporting endpoint.\r
+          *****************************************************************************/\r
+         public EvelMobileFlow(      String evname, String evid,\r
+                                     String flow_dir,\r
+                                     MOBILE_GTP_PER_FLOW_METRICS gtp_per_flow_metr,\r
+                                     String ip_protocol_typ,\r
+                                     String ip_vers,\r
+                                     String other_endpoint_ip_addr,\r
+                                     int other_endpoint_pt,\r
+                                     String reporting_endpoint_ipaddr,\r
+                                     int reporting_endpoint_pt)\r
+         {\r
+           super(evname,evid);\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(flow_dir != null);\r
+           assert(gtp_per_flow_metr != null);\r
+           assert(ip_protocol_typ != null);\r
+           assert(ip_vers != null);\r
+           assert(other_endpoint_ip_addr != null);\r
+           assert(other_endpoint_pt > 0);\r
+           assert(reporting_endpoint_ipaddr != null);\r
+           assert(reporting_endpoint_pt > 0);\r
+\r
+           /***************************************************************************/\r
+           /* Allocate the Mobile Flow.                                               */\r
+           /***************************************************************************/\r
+           LOGGER.debug("New Mobile Flow created");\r
+\r
+           /***************************************************************************/\r
+           /* Initialize the header & the Mobile Flow fields.  Optional string values */\r
+           /* are uninitialized (null).                                               */\r
+           /***************************************************************************/\r
+           event_domain = EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW;\r
+           flow_direction = flow_dir;\r
+           gtp_per_flow_metrics = gtp_per_flow_metr;\r
+           ip_protocol_type = ip_protocol_typ;\r
+           ip_version = ip_vers;\r
+           other_endpoint_ip_address = other_endpoint_ip_addr;\r
+           other_endpoint_port = other_endpoint_pt;\r
+           reporting_endpoint_ip_addr = reporting_endpoint_ipaddr;\r
+           reporting_endpoint_port = reporting_endpoint_pt;\r
+           \r
+           application_type = new EvelOptionString();\r
+           app_protocol_type = new EvelOptionString();\r
+           app_protocol_version = new EvelOptionString();\r
+           cid = new EvelOptionString();\r
+           connection_type = new EvelOptionString();\r
+           ecgi = new EvelOptionString();\r
+           gtp_protocol_type = new EvelOptionString();\r
+           gtp_version = new EvelOptionString();\r
+           http_header = new EvelOptionString();\r
+           imei = new EvelOptionString();\r
+           imsi = new EvelOptionString();\r
+           lac = new EvelOptionString();\r
+           mcc = new EvelOptionString();\r
+           mnc = new EvelOptionString();\r
+           msisdn = new EvelOptionString();\r
+           other_functional_role = new EvelOptionString();\r
+           rac = new EvelOptionString();\r
+           radio_access_technology = new EvelOptionString();\r
+           sac = new EvelOptionString();\r
+           sampling_algorithm = new EvelOptionInt();\r
+           tac = new EvelOptionString();\r
+           tunnel_id = new EvelOptionString();\r
+           vlan_id = new EvelOptionString();\r
+           additional_info = null;\r
+\r
+           EVEL_EXIT();\r
+\r
+         }\r
+\r
+\r
+\r
+       /**************************************************************************//**\r
+          * Add an additional value name/value pair to the Mobile flow.\r
+          *\r
+          * The name and value are null delimited ASCII strings.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * @param name      ASCIIZ string with the attribute's name.  The caller\r
+          *                  does not need to preserve the value once the function\r
+          *                  returns.\r
+          * @param value     ASCIIZ string with the attribute's value.  The caller\r
+          *                  does not need to preserve the value once the function\r
+          *                  returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_addl_field_add(String name, String value)\r
+               {\r
+                 String[] addl_info = null;\r
+                 EVEL_ENTER();\r
+\r
+                 /***************************************************************************/\r
+                 /* Check preconditions.                                                    */\r
+                 /***************************************************************************/\r
+                 assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+                 assert(name != null);\r
+                 assert(value != null);\r
+                 \r
+                 if( additional_info == null )\r
+                 {\r
+                         additional_info = new ArrayList<String[]>();\r
+                 }\r
+\r
+                 LOGGER.debug(MessageFormat.format("Adding name={0} value={1}", name, value));\r
+                 addl_info = new String[2];\r
+                 assert(addl_info != null);\r
+                 addl_info[0] = name;\r
+                 addl_info[1] = value;\r
+\r
+                 additional_info.add(addl_info);\r
+\r
+                 EVEL_EXIT();\r
+               }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the Event Type property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param type        The Event Type to be set. ASCIIZ string. The caller\r
+          *                    does not need to preserve the value once the function\r
+          *                    returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_type_set(String typ)\r
+         {\r
+                   EVEL_ENTER();\r
+                   assert(typ != null);\r
+\r
+                   /***************************************************************************/\r
+                   /* Check preconditions and call evel_header_type_set.                      */\r
+                   /***************************************************************************/\r
+                   assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+                   evel_header_type_set(typ);\r
+\r
+                   EVEL_EXIT();\r
+         }\r
+         \r
+         /**************************************************************************//**\r
+          * Set the Application Type property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param type        The Application Type to be set. ASCIIZ string. The caller\r
+          *                    does not need to preserve the value once the function\r
+          *                    returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_app_type_set(String type)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           assert(type != null);\r
+\r
+           application_type.SetValuePr(\r
+                                  type,\r
+                                  "Application Type");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Application Protocol Type property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param type        The Application Protocol Type to be set. ASCIIZ string.\r
+          *                    The caller does not need to preserve the value once the\r
+          *                    function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_app_prot_type_set(String type)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           assert(type != null);\r
+\r
+           app_protocol_type.SetValuePr(\r
+                                  type,\r
+                                  "Application Protocol Type");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Application Protocol Version property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param version     The Application Protocol Version to be set. ASCIIZ\r
+          *                    string.  The caller does not need to preserve the value\r
+          *                    once the function returns.\r
+          *****************************************************************************/\r
+         void evel_mobile_flow_app_prot_ver_set(String version)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           assert(version != null);\r
+\r
+           app_protocol_version.SetValuePr(\r
+                                  version,\r
+                                  "Application Protocol Version");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the CID property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param cid         The CID to be set. ASCIIZ string.  The caller does not\r
+          *                    need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_cid_set(String cd)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           assert(cid != null);\r
+\r
+           cid.SetValuePr(\r
+                                  cd,\r
+                                  "CID");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Connection Type property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param type        The Connection Type to be set. ASCIIZ string. The caller\r
+          *                    does not need to preserve the value once the function\r
+          *                    returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_con_type_set(String type)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           assert(type != null);\r
+\r
+           connection_type.SetValuePr(\r
+                                  type,\r
+                                  "Connection Type");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the ECGI property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param ecgi        The ECGI to be set. ASCIIZ string.  The caller does not\r
+          *                    need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_ecgi_set(String ecgit)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           assert(ecgit != null);\r
+\r
+           ecgi.SetValuePr(\r
+                                  ecgit,\r
+                                  "ECGI");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the GTP Protocol Type property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param type        The GTP Protocol Type to be set. ASCIIZ string.  The\r
+          *                    caller does not need to preserve the value once the\r
+          *                    function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_gtp_prot_type_set(String type)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           assert(type != null);\r
+\r
+           gtp_protocol_type.SetValuePr(\r
+                                  type,\r
+                                  "GTP Protocol Type");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the GTP Protocol Version property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param version     The GTP Protocol Version to be set. ASCIIZ string.  The\r
+          *                    caller does not need to preserve the value once the\r
+          *                    function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_gtp_prot_ver_set(String version)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           assert(version != null);\r
+\r
+           gtp_version.SetValuePr(\r
+                                  version,\r
+                                  "GTP Protocol Version");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the HTTP Header property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param header      The HTTP header to be set. ASCIIZ string. The caller does\r
+          *                    not need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_http_header_set(String header)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           \r
+           assert(header != null);\r
+\r
+           http_header.SetValuePr(\r
+                                  header,\r
+                                  "HTTP Header");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the IMEI property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param imei        The IMEI to be set. ASCIIZ string.  The caller does not\r
+          *                    need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_imei_set(String imeit)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           assert(imeit != null);\r
+\r
+           imei.SetValuePr(\r
+                                  imeit,\r
+                                  "IMEI");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the IMSI property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param imsi        The IMSI to be set. ASCIIZ string.  The caller does not\r
+          *                    need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_imsi_set(String imsit)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           assert(imsit != null);\r
+\r
+           imsi.SetValuePr(\r
+                                  imsit,\r
+                                  "IMSI");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the LAC property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param lac         The LAC to be set. ASCIIZ string.  The caller does not\r
+          *                    need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_lac_set(String lact)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           assert(lact != null);\r
+\r
+           lac.SetValuePr(\r
+                                  lact,\r
+                                  "LAC");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the MCC property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param mcc         The MCC to be set. ASCIIZ string.  The caller does not\r
+          *                    need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_mcc_set(String mcct)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           \r
+           assert(mcct != null);\r
+\r
+           mcc.SetValuePr(\r
+                                  mcct,\r
+                                  "MCC");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the MNC property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param mnc         The MNC to be set. ASCIIZ string.  The caller does not\r
+          *                    need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_mnc_set(String mnct)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           \r
+           assert(mnct != null);\r
+\r
+           mnc.SetValuePr(\r
+                                  mnct,\r
+                                  "MNC");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the MSISDN property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param msisdn      The MSISDN to be set. ASCIIZ string.  The caller does not\r
+          *                    need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_msisdn_set(String msisdnt)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           \r
+           assert(msisdnt != null);\r
+\r
+           msisdn.SetValuePr(\r
+                                  msisdnt,\r
+                                  "MSISDN");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Other Functional Role property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param role        The Other Functional Role to be set. ASCIIZ string. The\r
+          *                    caller does not need to preserve the value once the\r
+          *                    function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_other_func_role_set(String role)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           \r
+           assert(role != null);\r
+\r
+           other_functional_role.SetValuePr(\r
+                                  role,\r
+                                  "Other Functional Role");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the RAC property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param rac         The RAC to be set. ASCIIZ string.  The caller does not\r
+          *                    need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_rac_set(String ract)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           \r
+           assert(ract != null);\r
+\r
+           rac.SetValuePr(\r
+                                  ract,\r
+                                  "RAC");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Radio Access Technology property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param tech        The Radio Access Technology to be set. ASCIIZ string. The\r
+          *                    caller does not need to preserve the value once the\r
+          *                    function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_radio_acc_tech_set(String tech)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           \r
+           assert(tech != null);\r
+\r
+           radio_access_technology.SetValuePr(\r
+                                  tech,\r
+                                  "Radio Access Technology");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the SAC property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param sac         The SAC to be set. ASCIIZ string.  The caller does not\r
+          *                    need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_sac_set(String sact)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           \r
+           assert(sact != null);\r
+\r
+           sac.SetValuePr(\r
+                                  sact,\r
+                                  "SAC");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Sampling Algorithm property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param algorithm   The Sampling Algorithm to be set.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_samp_alg_set(\r
+                                            int algorithm)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           \r
+           assert(algorithm >= 0);\r
+\r
+           sampling_algorithm.SetValuePr(\r
+                               algorithm,\r
+                               "Sampling Algorithm");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the TAC property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param tac         The TAC to be set. ASCIIZ string.  The caller does not\r
+          *                    need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_tac_set(String tact)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           \r
+           assert(tact != null);\r
+\r
+           tac.SetValuePr(\r
+                                  tact,\r
+                                  "TAC");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Tunnel ID property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param tunnel_id   The Tunnel ID to be set. ASCIIZ string.  The caller does\r
+          *                    not need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_tunnel_id_set(String tunnel_idt)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           \r
+           assert(tunnel_idt != null);\r
+\r
+           tunnel_id.SetValuePr(\r
+                                  tunnel_idt,\r
+                                  "Tunnel ID");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the VLAN ID property of the Mobile Flow.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+\r
+          * @param vlan_id     The VLAN ID to be set. ASCIIZ string.  The caller does\r
+          *                    not need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_flow_vlan_id_set(String vlan_idt)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+           \r
+           assert(vlan_idt != null);\r
+\r
+           vlan_id.SetValuePr(\r
+                                  vlan_idt,\r
+                                  "VLAN ID");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the Duration of Connection Failed Status property of the Mobile GTP Per\r
+          * Flow Metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param duration    The Duration of Connection Failed Status to be set.\r
+          *****************************************************************************/\r
+         public void evel_mobile_gtp_metrics_dur_con_fail_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS metrics,\r
+                                                  int duration)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(duration >= 0);\r
+\r
+           metrics.dur_connection_failed_status.SetValuePr(\r
+                               duration,\r
+                               "Duration of Connection Failed Status");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Duration of Tunnel Failed Status property of the Mobile GTP Per Flow\r
+          * Metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param duration    The Duration of Tunnel Failed Status to be set.\r
+          *****************************************************************************/\r
+         public void evel_mobile_gtp_metrics_dur_tun_fail_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS metrics,\r
+                                                  int duration)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(duration >= 0);\r
+\r
+           metrics.dur_tunnel_failed_status.SetValuePr(\r
+                               duration,\r
+                               "Duration of Tunnel Failed Status");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Activated By property of the Mobile GTP Per Flow metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param act_by      The Activated By to be set.  ASCIIZ string. The caller\r
+          *                    does not need to preserve the value once the function\r
+          *                    returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_gtp_metrics_act_by_set(MOBILE_GTP_PER_FLOW_METRICS metrics,\r
+                                                 String act_by)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(act_by != null);\r
+\r
+           metrics.flow_activated_by.SetValuePr(\r
+                                  act_by,\r
+                                  "Activated By");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Activation Time property of the Mobile GTP Per Flow metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param act_time    The Activation Time to be set.  ASCIIZ string. The caller\r
+          *                    does not need to preserve the value once the function\r
+          *                    returns.\r
+          *****************************************************************************/\r
+         public  void evel_mobile_gtp_metrics_act_time_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS  metrics,\r
+                                                  Date act_time)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+\r
+           metrics.flow_activation_time.SetValuePr(\r
+                                act_time,\r
+                                "Activation Time");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Deactivated By property of the Mobile GTP Per Flow metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param deact_by    The Deactivated By to be set.  ASCIIZ string. The caller\r
+          *                    does not need to preserve the value once the function\r
+          *                    returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_gtp_metrics_deact_by_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS  metrics,\r
+                                                  String deact_by)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(deact_by != null);\r
+\r
+           metrics.flow_deactivated_by.SetValuePr(\r
+                                  deact_by,\r
+                                  "Deactivated By");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the GTP Connection Status property of the Mobile GTP Per Flow metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param status      The GTP Connection Status to be set.  ASCIIZ string. The\r
+          *                    caller does not need to preserve the value once the\r
+          *                    function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_gtp_metrics_con_status_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS  metrics,\r
+                                                  String status)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(status != null);\r
+\r
+           metrics.gtp_connection_status.SetValuePr(\r
+                                  status,\r
+                                  "GTP Connection Status");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the GTP Tunnel Status property of the Mobile GTP Per Flow metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param status      The GTP Tunnel Status to be set.  ASCIIZ string. The\r
+          *                    caller does not need to preserve the value once the\r
+          *                    function returns.\r
+          *****************************************************************************/\r
+         public void evel_mobile_gtp_metrics_tun_status_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS  metrics,\r
+                                                  String status)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(status != null);\r
+\r
+           metrics.gtp_tunnel_status.SetValuePr(\r
+                                  status,\r
+                                  "GTP Tunnel Status");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set an IP Type-of-Service count property of the Mobile GTP Per Flow metrics.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param index       The index of the IP Type-of-Service.\r
+          * @param count       The count.\r
+          *****************************************************************************/\r
+         public void evel_mobile_gtp_metrics_iptos_set(MOBILE_GTP_PER_FLOW_METRICS metrics,\r
+                                                int index,\r
+                                                int count)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(index >= 0);\r
+           assert(index < EVEL_TOS_SUPPORTED);\r
+           assert(count >= 0);\r
+           assert(count <= 255);\r
+\r
+           LOGGER.debug("IP Type-of-Service "+index);\r
+           metrics.ip_tos_counts[index].SetValuePr(\r
+                               count,\r
+                               "IP Type-of-Service");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Large Packet Round-Trip Time property of the Mobile GTP Per Flow\r
+          * Metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param rtt         The Large Packet Round-Trip Time to be set.\r
+          *****************************************************************************/\r
+         public void evel_mobile_gtp_metrics_large_pkt_rtt_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS  metrics,\r
+                                                  int rtt)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(rtt >= 0);\r
+\r
+           metrics.large_packet_rtt.SetValuePr(\r
+                               rtt,\r
+                               "Large Packet Round-Trip Time");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Large Packet Threshold property of the Mobile GTP Per Flow Metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param threshold   The Large Packet Threshold to be set.\r
+          *****************************************************************************/\r
+         public void evel_mobile_gtp_metrics_large_pkt_thresh_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS metrics,\r
+                                                  double threshold)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(threshold >= 0.0);\r
+\r
+           metrics.large_packet_threshold.SetValuePr(\r
+                                  threshold,\r
+                                  "Large Packet Threshold");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Max Receive Bit Rate property of the Mobile GTP Per Flow Metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param rate        The Max Receive Bit Rate to be set.\r
+          *****************************************************************************/\r
+         public void evel_mobile_gtp_metrics_max_rcv_bit_rate_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS metrics,\r
+                                                  int rate)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(rate >= 0);\r
+\r
+           metrics.max_receive_bit_rate.SetValuePr(\r
+                               rate,\r
+                               "Max Receive Bit Rate");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Max Transmit Bit Rate property of the Mobile GTP Per Flow Metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param rate        The Max Transmit Bit Rate to be set.\r
+          *****************************************************************************/\r
+         public  void evel_mobile_gtp_metrics_max_trx_bit_rate_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS metrics,\r
+                                                  int rate)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(rate >= 0);\r
+\r
+           metrics.max_transmit_bit_rate.SetValuePr(\r
+                               rate,\r
+                               "Max Transmit Bit Rate");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Number of GTP Echo Failures property of the Mobile GTP Per Flow\r
+          * Metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param num         The Number of GTP Echo Failures to be set.\r
+          *****************************************************************************/\r
+         public  void evel_mobile_gtp_metrics_num_echo_fail_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS metrics,\r
+                                                  int num)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(num >= 0);\r
+\r
+           metrics.num_gtp_echo_failures.SetValuePr(\r
+                               num,\r
+                               "Number of GTP Echo Failures");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Number of GTP Tunnel Errors property of the Mobile GTP Per Flow\r
+          * Metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param num         The Number of GTP Tunnel Errors to be set.\r
+          *****************************************************************************/\r
+         public   void evel_mobile_gtp_metrics_num_tun_fail_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS  metrics,\r
+                                                  int num)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(num >= 0);\r
+\r
+           metrics.num_gtp_tunnel_errors.SetValuePr(\r
+                               num,\r
+                               "Number of GTP Tunnel Errors");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Number of HTTP Errors property of the Mobile GTP Per Flow Metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics     Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param num         The Number of HTTP Errors to be set.\r
+          *****************************************************************************/\r
+         public  void evel_mobile_gtp_metrics_num_http_errors_set(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS  metrics,\r
+                                                  int num)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(num >= 0);\r
+\r
+           metrics.num_http_errors.SetValuePr(\r
+                               num,\r
+                               "Number of HTTP Errors");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add a TCP flag count to the metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics       Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param tcp_flag      The TCP flag to be updated.\r
+          * @param count         The associated flag count, which must be nonzero.\r
+          *****************************************************************************/\r
+         public  void evel_mobile_gtp_metrics_tcp_flag_count_add(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS  metrics,\r
+                                                  int tcp_flag,\r
+                                                  int count)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(tcp_flag >= 0 && tcp_flag < EVEL_MAX_TCP_FLAGS);\r
+           assert(count >= 0);\r
+\r
+           LOGGER.debug("TCP Flag: "+tcp_flag);\r
+           metrics.tcp_flag_counts[tcp_flag].SetValuePr(\r
+                               count,\r
+                               "TCP flag");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add a QCI COS count to the metrics.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param metrics       Pointer to the Mobile GTP Per Flow Metrics.\r
+          * @param qci_cos       The QCI COS count to be updated.\r
+          * @param count         The associated QCI COS count.\r
+          *****************************************************************************/\r
+         public  void evel_mobile_gtp_metrics_qci_cos_count_add(\r
+                                                  MOBILE_GTP_PER_FLOW_METRICS  metrics,\r
+                                                  int qci_cos,\r
+                                                  int count)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(metrics != null);\r
+           assert(qci_cos >= 0);\r
+           assert(qci_cos < EVEL_MAX_QCI_COS_TYPES);\r
+           assert(count >= 0);\r
+\r
+           LOGGER.debug("QCI COS: "+ qci_cos);\r
+           metrics.qci_cos_counts[qci_cos].SetValuePr(\r
+                               count,\r
+                               "QCI COS");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+               /**************************************************************************//**\r
+                * Encode the GTP Per Flow Object in JSON according to AT&T's schema.\r
+                *\r
+                * @retval JsonObjectBuilder of GTP Flow body portion of message   \r
+                *****************************************************************************/\r
+         JsonObjectBuilder evelGtpPerFlowObject()\r
+         {\r
+                   int index;\r
+                   boolean found_ip_tos;\r
+                   boolean found_tcp_flag;\r
+                   boolean found_qci_cos;\r
+\r
+                   EVEL_ENTER();\r
+                   \r
+           /***************************************************************************/\r
+           /* Mandatory parameters.                                                   */\r
+           /***************************************************************************/\r
+               MOBILE_GTP_PER_FLOW_METRICS metrics = gtp_per_flow_metrics;\r
+                   \r
+               JsonObjectBuilder obj =  Json.createObjectBuilder()\r
+                                                 .add("avgBitErrorRate", metrics.avg_bit_error_rate)\r
+                                                 .add("avgPacketDelayVariation", metrics.avg_packet_delay_variation)\r
+                                                 .add("avgPacketLatency", metrics.avg_packet_latency)\r
+                                                 .add("avgReceiveThroughput", metrics.avg_receive_throughput)\r
+                                                 .add("avgTransmitThroughput", metrics.avg_transmit_throughput)\r
+                                                 .add("flowActivationEpoch", metrics.flow_activation_epoch)\r
+                                                 .add("flowActivationMicrosec", metrics.flow_activation_microsec)\r
+                                                 .add("flowDeactivationEpoch", metrics.flow_deactivation_epoch)\r
+                                                 .add("flowDeactivationMicrosec", metrics.flow_deactivation_microsec)\r
+                                                 .add("flowDeactivationTime", metrics.flow_deactivation_time.toString())\r
+                                                 .add("flowStatus", metrics.flow_status)\r
+                                                 .add("maxPacketDelayVariation", metrics.max_packet_delay_variation)\r
+                                                 .add("numActivationFailures", metrics.num_activation_failures)\r
+               .add( "numBitErrors", metrics.num_bit_errors)\r
+               .add( "numBytesReceived", metrics.num_bytes_received)\r
+               .add( "numBytesTransmitted", metrics.num_bytes_transmitted)\r
+               .add( "numDroppedPackets", metrics.num_dropped_packets)\r
+               .add( "numL7BytesReceived", metrics.num_l7_bytes_received)\r
+               .add( "numL7BytesTransmitted", metrics.num_l7_bytes_transmitted)\r
+               .add( "numLostPackets", metrics.num_lost_packets)\r
+               .add( "numOutOfOrderPackets", metrics.num_out_of_order_packets)\r
+               .add( "numPacketErrors", metrics.num_packet_errors)\r
+               .add( "numPacketsReceivedExclRetrans",\r
+                                   metrics.num_packets_received_excl_retrans)\r
+               .add(\r
+                                   "numPacketsReceivedInclRetrans",\r
+                                   metrics.num_packets_received_incl_retrans)\r
+               .add(\r
+                                   "numPacketsTransmittedInclRetrans",\r
+                                   metrics.num_packets_transmitted_incl_retrans)\r
+               .add( "numRetries", metrics.num_retries)\r
+               .add( "numTimeouts", metrics.num_timeouts)\r
+               .add(\r
+                                   "numTunneledL7BytesReceived",\r
+                                   metrics.num_tunneled_l7_bytes_received)\r
+               .add( "roundTripTime", metrics.round_trip_time)\r
+               .add( "timeToFirstByte", metrics.time_to_first_byte);\r
+\r
+                   /***************************************************************************/\r
+                   /* Optional parameters.                                                    */\r
+                   /***************************************************************************/\r
+                   found_ip_tos = false;\r
+                   for (index = 0; index < EVEL_TOS_SUPPORTED; index++)\r
+                   {\r
+                     if (metrics.ip_tos_counts[index].is_set)\r
+                     {\r
+                       found_ip_tos = true;\r
+                       break;\r
+                     }\r
+                   }\r
+\r
+                   if (found_ip_tos)\r
+                   {\r
+                     JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                     for (index = 0; index < EVEL_TOS_SUPPORTED; index++)\r
+                     {\r
+                       if (metrics.ip_tos_counts[index].is_set)\r
+                       {\r
+                                 JsonObjectBuilder obj2 = Json.createObjectBuilder()\r
+                                            .add(Integer.toString(index), metrics.ip_tos_counts[index].value);\r
+                                     builder.add(obj2);\r
+                       }\r
+                     }\r
+                     obj.add("ipTosCountList", builder);\r
+                   }\r
+\r
+\r
+                   /***************************************************************************/\r
+                   /* Make some compile-time assertions about EVEL_TCP_FLAGS.  If you update  */\r
+                   /* these, make sure you update evel_tcp_flag_strings to match the enum.    */\r
+                   /***************************************************************************/\r
+\r
+                   found_tcp_flag = false;\r
+                   for (index = 0; index < EVEL_MAX_TCP_FLAGS; index++)\r
+                   {\r
+                     if (metrics.tcp_flag_counts[index].is_set)\r
+                     {\r
+                       found_tcp_flag = true;\r
+                       break;\r
+                     }\r
+                   }\r
+\r
+                   if (found_tcp_flag)\r
+                   {\r
+                     JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                     for (index = 0; index < EVEL_MAX_TCP_FLAGS; index++)\r
+                     {\r
+                       if (metrics.tcp_flag_counts[index].is_set)\r
+                       {\r
+                                 JsonObjectBuilder obj2 = Json.createObjectBuilder()\r
+                                                    .add(Integer.toString(index), evel_tcp_flag_strings[index]);\r
+                                         builder.add(obj2);\r
+                       }\r
+                     }\r
+                     obj.add("tcpFlagList", builder);\r
+                   }\r
+\r
+                   if (found_tcp_flag)\r
+                   {\r
+                     JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                     for (index = 0; index < EVEL_MAX_TCP_FLAGS; index++)\r
+                     {\r
+                       if (metrics.tcp_flag_counts[index].is_set)\r
+                       {\r
+                                  JsonObjectBuilder obj2 = Json.createObjectBuilder()\r
+                                                            .add(evel_tcp_flag_strings[index], metrics.tcp_flag_counts[index].value);\r
+                                          builder.add(obj2);\r
+                       }\r
+                     }\r
+                     obj.add("tcpFlagCountList", builder);\r
+                   }\r
+\r
+                   /***************************************************************************/\r
+                   /* Make some compile-time assertions about EVEL_QCI_COS_TYPES.  If you     */\r
+                   /* update these, make sure you update evel_qci_cos_strings to match the    */\r
+                   /* enum.                                                                   */\r
+                   /***************************************************************************/\r
+\r
+                   found_qci_cos = false;\r
+                   for (index = 0; index < EVEL_MAX_QCI_COS_TYPES; index++)\r
+                   {\r
+                     if (metrics.qci_cos_counts[index].is_set)\r
+                     {\r
+                       found_qci_cos = true;\r
+                       break;\r
+                     }\r
+                   }\r
+\r
+                   if (found_qci_cos)\r
+                   {\r
+                     JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                     for (index = 0; index < EVEL_MAX_QCI_COS_TYPES; index++)\r
+                     {\r
+                       if (metrics.qci_cos_counts[index].is_set)\r
+                       {\r
+                                 JsonObjectBuilder obj2 = Json.createObjectBuilder()\r
+                                                            .add(Integer.toString(index), evel_qci_cos_strings[index]);\r
+                                         builder.add(obj2);\r
+                       }\r
+                     }\r
+                     obj.add("mobileQciCosList", builder);\r
+                   }\r
+\r
+                   if (found_qci_cos)\r
+                   {\r
+                       JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                     for (index = 0; index < EVEL_MAX_QCI_COS_TYPES; index++)\r
+                     {\r
+                       if (metrics.qci_cos_counts[index].is_set)\r
+                       {\r
+                                         JsonObjectBuilder obj2 = Json.createObjectBuilder()\r
+                                                            .add(evel_qci_cos_strings[index], metrics.qci_cos_counts[index].value);\r
+                                             builder.add(obj2);\r
+                       }\r
+                     }\r
+                     obj.add("mobileQciCosCountList", builder);\r
+                   }\r
+\r
+                   metrics.dur_connection_failed_status.encJsonValue(obj, "durConnectionFailedStatus");\r
+                   metrics.dur_tunnel_failed_status.encJsonValue(obj, "durTunnelFailedStatus");\r
+                   metrics.flow_activated_by.encJsonValue(obj, "flowActivatedBy");\r
+                   metrics.flow_activation_time.encJsonValue(obj,"flowActivationTime");\r
+                   metrics.flow_deactivated_by.encJsonValue(obj, "flowDeactivatedBy");\r
+                   metrics.gtp_connection_status.encJsonValue(obj, "gtpConnectionStatus");\r
+                   metrics.gtp_tunnel_status.encJsonValue(obj, "gtpTunnelStatus");\r
+                   metrics.large_packet_rtt.encJsonValue(obj, "largePacketRtt");\r
+                   metrics.large_packet_threshold.encJsonValue(obj, "largePacketThreshold");\r
+                   metrics.max_receive_bit_rate.encJsonValue(obj, "maxReceiveBitRate");\r
+                   metrics.max_transmit_bit_rate.encJsonValue(obj, "maxTransmitBitRate");\r
+                   metrics.num_gtp_echo_failures.encJsonValue(obj, "numGtpEchoFailures");\r
+                   metrics.num_gtp_tunnel_errors.encJsonValue(obj, "numGtpTunnelErrors");\r
+                   metrics.num_http_errors.encJsonValue(obj, "numHttpErrors");\r
+                   \r
+                   return obj;       \r
+                   \r
+         }\r
+         \r
+\r
+         /**************************************************************************//**\r
+          * Encode Mobile Flow Object according to VES schema\r
+          *\r
+          * @retval JSON Object of Mobile Flow event\r
+          *****************************************************************************/\r
+         JsonObjectBuilder evelMobileFlowObject()\r
+         {\r
+\r
+           double version = major_version+(double)minor_version/10;\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MOBILE_FLOW);\r
+\r
+           /***************************************************************************/\r
+           /* Mandatory fields.                                                       */\r
+           /***************************************************************************/\r
+           JsonObjectBuilder evelmf = Json.createObjectBuilder()\r
+                                         .add("flowDirection", flow_direction)\r
+                                         .add("ipProtocolType", ip_protocol_type)\r
+                                         .add("ipVersion", ip_version)\r
+                                  .add("otherEndpointIpAddress", other_endpoint_ip_address)\r
+                                  .add("otherEndpointPort", other_endpoint_port)\r
+                                         .add("reportingEndpointIpAddr", reporting_endpoint_ip_addr)\r
+                                         .add("reportingEndpointPort", reporting_endpoint_port);\r
+           \r
+           //call gtp per flow object encoding function\r
+           if(gtp_per_flow_metrics != null)\r
+                                 evelmf.add("gtpPerFlowMetrics", evelGtpPerFlowObject());\r
+                                  \r
+\r
+\r
+           /***************************************************************************/\r
+           /* Optional fields.                                                        */\r
+           /***************************************************************************/\r
+           // additional fields\r
+                 if( additional_info != null )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<additional_info.size();i++) {\r
+                         String[] addl_info = additional_info.get(i);\r
+                         JsonObject obj = Json.createObjectBuilder()\r
+                                    .add("name", addl_info[0])\r
+                                    .add("value", addl_info[1]).build();\r
+                         builder.add(obj);\r
+                   }\r
+                       evelmf.add("additionalFields", builder);\r
+                 }\r
+                 \r
+\r
+                   /***************************************************************************/\r
+                   /* Optional parameters.                                                    */\r
+                   /***************************************************************************/\r
+                   application_type.encJsonValue(evelmf, "applicationType");\r
+                   app_protocol_type.encJsonValue(evelmf, "appProtocolType");\r
+                   app_protocol_version.encJsonValue(evelmf, "appProtocolVersion");\r
+                   cid.encJsonValue(evelmf,"cid");\r
+                   connection_type.encJsonValue(evelmf, "connectionType");\r
+                   ecgi.encJsonValue(evelmf, "ecgi");\r
+                   gtp_protocol_type.encJsonValue(evelmf, "gtpProtocolType");\r
+                   gtp_version.encJsonValue(evelmf, "gtpVersion");\r
+                   http_header.encJsonValue(evelmf, "httpHeader");\r
+                   imei.encJsonValue(evelmf, "imei");\r
+                   imsi.encJsonValue(evelmf, "imsi");\r
+                   lac.encJsonValue(evelmf, "lac");\r
+                   mcc.encJsonValue(evelmf, "mcc");\r
+                   mnc.encJsonValue(evelmf, "mnc");\r
+                   msisdn.encJsonValue(evelmf, "msisdn");\r
+                   other_functional_role.encJsonValue(evelmf,"otherFunctionalRole");\r
+                   rac.encJsonValue(evelmf, "rac");\r
+                   radio_access_technology.encJsonValue(evelmf, "radioAccessTechnology");\r
+                   sac.encJsonValue(evelmf, "sac");\r
+                   sampling_algorithm.encJsonValue(evelmf, "samplingAlgorithm");\r
+                   tac.encJsonValue(evelmf, "tac");\r
+                   tunnel_id.encJsonValue(evelmf,"tunnelId");\r
+                   vlan_id.encJsonValue(evelmf,"vlanId");\r
+\r
+\r
+           /***************************************************************************/\r
+           /* Although optional, we always generate the version.  Note that this      */\r
+           /* closes the object, too.                                                 */\r
+           /***************************************************************************/\r
+           evelmf.add("mobileFlowFieldsVersion", version);\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return evelmf;\r
+         }\r
+         \r
+         /**************************************************************************//**\r
+          * Encode the event as a JSON event object according to AT&T's schema.\r
+          * retval : String of JSON event message\r
+          *****************************************************************************/\r
+         String evel_json_encode_event()\r
+         {\r
+               EVEL_ENTER();\r
+               \r
+               assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_STATE_CHANGE);\r
+               //encode common event header and mobile flow body    \r
+           JsonObject obj = Json.createObjectBuilder()\r
+                    .add("event", Json.createObjectBuilder()\r
+                                .add( "commonEventHeader",eventHeaderObject() )\r
+                                .add( "mobileFlowFields",evelMobileFlowObject() )\r
+                                ).build();\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return obj.toString();\r
+\r
+         }\r
+\r
+\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOption.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOption.java
new file mode 100644 (file)
index 0000000..f457e85
--- /dev/null
@@ -0,0 +1,43 @@
+package evel_javalibrary.att.com;\r
+/*\r
+ *  * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * \r
+ * \r
+ * Basic Evel Option root class to handle optional message fields\r
+ */\r
+public class EvelOption {\r
+       \r
+       boolean is_set;//optional value setting\r
+       \r
+       public EvelOption()//default constructor\r
+       {\r
+               is_set = false;\r
+       }\r
+       \r
+       public EvelOption(boolean val)\r
+       {\r
+               is_set = val;\r
+       }\r
+       \r
+       public void set_option(boolean tf)//Setter\r
+       {\r
+               is_set = tf;\r
+       }\r
+       \r
+       public boolean get_option(boolean tf)//Getter\r
+       {\r
+               return is_set;\r
+       }\r
+\r
+}\r
+\r
+       \r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionDouble.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionDouble.java
new file mode 100644 (file)
index 0000000..d936ae5
--- /dev/null
@@ -0,0 +1,87 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Option Double class\r
+ *\r
+ * This file implements the Evel Option class to handle optional double fields.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ *  * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+/*\r
+ * Handles Optional Double fields\r
+ */\r
+public class EvelOptionDouble extends EvelOption {\r
+\r
+       /**************************************************************************//**\r
+        * Optional parameter holder for string.\r
+        *****************************************************************************/\r
+     Double value;\r
+     \r
+     private static final Logger LOGGER = Logger.getLogger( EvelOptionDouble.class.getName() );\r
+     \r
+        public EvelOptionDouble()\r
+        {\r
+                super(false);\r
+                value = 0.0;\r
+        }\r
+        \r
+        public EvelOptionDouble(boolean val, Double str)\r
+        {\r
+                super(val);\r
+                value = str;\r
+        }\r
+        \r
+        public void InitValue()\r
+        {\r
+                is_set = false;\r
+                value = 0.0;\r
+        }\r
+        //Sets Double value\r
+        public void SetValue(Double str)\r
+        {\r
+                is_set = true;\r
+                value = str;\r
+        }\r
+        //Sets Double value with debugging message\r
+        public void SetValuePr(Double str, String mstr)\r
+        {\r
+                \r
+                is_set = true;\r
+                value = str;   \r
+                LOGGER.debug("Setting "+mstr+" to "+str);\r
+        }\r
+        //Getter\r
+        public Double GetValue()\r
+        {\r
+                return value;\r
+        }\r
+        /*\r
+         * Encoding JSON function\r
+         * @retval boolean returns option true if object is encoded\r
+         */\r
+        public boolean encJsonValue(JsonObjectBuilder obj, String name)\r
+        {\r
+                //If option is set encodes Double value into JSON object\r
+                // with name tag\r
+                if( is_set ) obj.add(name, value);\r
+                return is_set;\r
+        }\r
+\r
+}\r
+\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionInt.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionInt.java
new file mode 100644 (file)
index 0000000..a6a9900
--- /dev/null
@@ -0,0 +1,88 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Option Int class\r
+ *\r
+ * This file implements the Evel Option class to handle optional ont fields.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+  * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+/*\r
+ * Handles Optional Integer fields\r
+ */\r
+public class EvelOptionInt extends EvelOption {\r
+\r
+       /**************************************************************************//**\r
+        * Optional parameter holder for string.\r
+        *****************************************************************************/\r
+     int value;\r
+     \r
+     private static final Logger LOGGER = Logger.getLogger( EvelOptionInt.class.getName() );\r
+     \r
+        public EvelOptionInt()\r
+        {\r
+                super(false);\r
+                value = 0;\r
+        }\r
+        \r
+        public EvelOptionInt(boolean val, int str)\r
+        {\r
+                super(val);\r
+                value = str;\r
+        }\r
+        \r
+        public void InitValue()\r
+        {\r
+                is_set = false;\r
+                value = 0;\r
+        }\r
+        //Sets int value\r
+        public void SetValue(int str)\r
+        {\r
+                is_set = true;\r
+                value = str;\r
+        }\r
+        //Sets Integer value outputting debugging message\r
+        public void SetValuePr(int str, String mstr)\r
+        {\r
+                \r
+                is_set = true;\r
+                value = str;   \r
+                LOGGER.debug("Setting "+mstr+" to "+str);\r
+        }\r
+        \r
+        public int GetValue()\r
+        {\r
+                return value;\r
+        }\r
+        /*\r
+         * Encoding JSON function\r
+         * @retval boolean returns option true if object is encoded\r
+         * with Integer value\r
+         */     \r
+        public boolean encJsonValue(JsonObjectBuilder obj, String name)\r
+        {\r
+                //If option is set encodes int value into JSON object\r
+                // with name tag\r
+                if( is_set ) obj.add(name, value);\r
+                return is_set;\r
+        }\r
+\r
+}\r
+\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionIntHeader.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionIntHeader.java
new file mode 100644 (file)
index 0000000..3a601a6
--- /dev/null
@@ -0,0 +1,51 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Option Internal Header class\r
+ *\r
+ * This file implements the Evel Option class to handle optional internal header\r
+ *  fields.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import java.util.Date;\r
+\r
+public class EvelOptionIntHeader extends EvelOption {\r
+\r
+       /**************************************************************************//**\r
+        * Optional parameter for any Java object\r
+        *****************************************************************************/\r
+     java.lang.Object value;\r
+     \r
+        public EvelOptionIntHeader(boolean val, java.lang.Object str)\r
+        {\r
+                super(val);\r
+                value = str;\r
+        }\r
+        \r
+        public void SetValue(java.lang.Object str)\r
+        {\r
+                value = str;\r
+        }\r
+        \r
+        public java.lang.Object GetValue()\r
+        {\r
+                return value;\r
+        }\r
+\r
+}\r
+\r
+       \r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionLong.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionLong.java
new file mode 100644 (file)
index 0000000..3758d75
--- /dev/null
@@ -0,0 +1,75 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Option Long class\r
+ *\r
+ * This file implements the Evel Option class to handle optional Long fields.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import org.apache.log4j.Logger;\r
+/*\r
+ * Handles Optional Long Integer fields\r
+ */\r
+public class EvelOptionLong extends EvelOption {\r
+\r
+       /**************************************************************************//**\r
+        * Optional parameter holder for string.\r
+        *****************************************************************************/\r
+     Long value;\r
+     \r
+     private static final Logger LOGGER = Logger.getLogger( EvelOptionLong.class.getName() );\r
+     \r
+        public EvelOptionLong()\r
+        {\r
+                super(false);\r
+                value = 0L;\r
+        }\r
+        \r
+        public EvelOptionLong(boolean val, Long str)\r
+        {\r
+                super(val);\r
+                value = str;\r
+        }\r
+        \r
+        public void InitValue()\r
+        {\r
+                is_set = false;\r
+                value = 0L;\r
+        }\r
+        //Setter\r
+        public void SetValue(Long str)\r
+        {\r
+                is_set = true;\r
+                value = str;\r
+        }\r
+        \r
+       //Sets Long Integer value outputting debugging message\r
+        public void SetValuePr(Long str, String mstr)\r
+        {\r
+                \r
+                is_set = true;\r
+                value = str;   \r
+                LOGGER.debug("Setting "+mstr+" to "+str);\r
+        }\r
+        \r
+        public Long GetValue()\r
+        {\r
+                return value;\r
+        }\r
+\r
+}\r
+\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionString.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionString.java
new file mode 100644 (file)
index 0000000..5cf5e83
--- /dev/null
@@ -0,0 +1,88 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Option String class\r
+ *\r
+ * This file implements the Evel Option class to handle optional String fields.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+  * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+/*\r
+ * Handles Optional String fields\r
+ */\r
+public class EvelOptionString extends EvelOption {\r
+\r
+       /**************************************************************************//**\r
+        * Optional parameter holder for string.\r
+        *****************************************************************************/\r
+     String value;\r
+     \r
+     private static final Logger LOGGER = Logger.getLogger( EvelOptionString.class.getName() );\r
+     \r
+        public EvelOptionString()\r
+        {\r
+                super(false);\r
+                value = null;\r
+        }\r
+        \r
+        public EvelOptionString(boolean val, String str)\r
+        {\r
+                super(val);\r
+                value = str;\r
+        }\r
+        \r
+        public void InitValue()\r
+        {\r
+                is_set = false;\r
+                value = null;\r
+        }\r
+        //Setter\r
+        public void SetValue(String str)\r
+        {\r
+                is_set = true;\r
+                value = str;\r
+        }\r
+        \r
+       //Sets String value outputting debugging message\r
+        public void SetValuePr(String str, String mstr)\r
+        {\r
+                \r
+                is_set = true;\r
+                value = str;   \r
+                LOGGER.debug("Setting "+mstr+" to "+str);\r
+        }\r
+        //Getter\r
+        public String GetValue()\r
+        {\r
+                return value;\r
+        }\r
+        /*\r
+         * Encoding JSON function\r
+         * @retval boolean returns option true if object is encoded\r
+         * with String value\r
+         */\r
+        public boolean encJsonValue(JsonObjectBuilder obj, String name)\r
+        {\r
+                if( is_set ) obj.add(name, value);\r
+                return is_set;\r
+        }\r
+\r
+}\r
+\r
+       \r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionTime.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOptionTime.java
new file mode 100644 (file)
index 0000000..66109c1
--- /dev/null
@@ -0,0 +1,91 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Option Time class\r
+ *\r
+ * This file implements the Evel Option Time class to handle optional time fields.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import java.util.Date;\r
+\r
+import javax.json.JsonObjectBuilder;\r
+import javax.json.JsonValue;\r
+\r
+import org.apache.log4j.Logger;\r
+/*\r
+ * Handles Optional Date/Time fields\r
+ */\r
+public class EvelOptionTime extends EvelOption {\r
+\r
+       /**************************************************************************//**\r
+        * Optional parameter holder for string.\r
+        *****************************************************************************/\r
+     Date value;\r
+     \r
+     private static final Logger LOGGER = Logger.getLogger( EvelOptionTime.class.getName() );\r
+     \r
+        public EvelOptionTime()\r
+        {\r
+                super(false);\r
+                value = null;\r
+        }\r
+     \r
+        public EvelOptionTime(boolean val, Date str)\r
+        {\r
+                super(val);\r
+                value = str;\r
+        }\r
+        \r
+        public void InitValue()\r
+        {\r
+                is_set = false;\r
+                value = null;\r
+        }\r
+        //Setter\r
+        public void SetValue(Date str)\r
+        {\r
+                is_set = true;\r
+                value = str;\r
+        }\r
+        \r
+       //Sets Date value outputting debugging message\r
+        public void SetValuePr(Date str, String mstr)\r
+        {\r
+                \r
+                is_set = true;\r
+                value = str;   \r
+                LOGGER.debug("Setting "+mstr+" to "+str);\r
+        }\r
+        \r
+        public Date GetValue()\r
+        {\r
+                return value;\r
+        }\r
+        /*\r
+         * Encoding JSON function\r
+         * @retval boolean returns option true if object is encoded\r
+         * with Date value\r
+         */     \r
+        public boolean encJsonValue(JsonObjectBuilder obj, String name)\r
+        {\r
+                if( is_set ) obj.add(name, (JsonValue) value);\r
+                return is_set;\r
+        }\r
+\r
+}\r
+\r
+       \r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOther.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelOther.java
new file mode 100644 (file)
index 0000000..3778767
--- /dev/null
@@ -0,0 +1,347 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Other class\r
+ *\r
+ * This file implements the Evel Other class to handle Other domain events.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import javax.json.Json;\r
+import javax.json.JsonArrayBuilder;\r
+import javax.json.JsonObject;\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.slf4j.helpers.MessageFormatter;\r
+\r
+/*\r
+ * Handles Optional Other fields\r
+ */\r
+public class EvelOther extends EvelHeader {\r
+\r
+         int major_version = 1;\r
+         int minor_version = 1;\r
+\r
+         /***************************************************************************/\r
+         /* Mandatory fields                                                        */\r
+         /***************************************************************************/\r
+         ArrayList<javax.json.JsonObject> additional_objects;\r
+         \r
+         /***************************************************************************/\r
+         /* Optional fields                                                         */\r
+         /***************************************************************************/\r
+         Map<String,String> additional_info;\r
+         HashMap<String,Map<String,String>> evelmap;\r
+         \r
+\r
+         private static final Logger LOGGER = Logger.getLogger( EvelOther.class.getName() );\r
+\r
+         /**************************************************************************//**\r
+          * Create a new Other event.\r
+          *\r
+          *****************************************************************************/\r
+         public EvelOther(String evname,String evid)\r
+         {\r
+                 //Init header and domain\r
+        super(evname,evid);\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+\r
+           /***************************************************************************/\r
+           /* Allocate the measurement.                                               */\r
+           /***************************************************************************/\r
+           LOGGER.debug("New Evel Other Object");\r
+           \r
+           /***************************************************************************/\r
+           /* Initialize the header & the measurement fields.                         */\r
+           /***************************************************************************/\r
+           event_domain = EvelHeader.DOMAINS.EVEL_DOMAIN_OTHER;\r
+\r
+           /***************************************************************************/\r
+           /* Optional fields.                                                    */\r
+           /***************************************************************************/\r
+           additional_info = null;\r
+           additional_objects = null;\r
+           evelmap = null;\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Event Type property of the Measurement.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param type        The Event Type to be set. ASCIIZ string. The caller\r
+          *                    does not need to preserve the value once the function\r
+          *                    returns.\r
+          *****************************************************************************/\r
+         public void evel_other_type_set(String typ)\r
+         {\r
+           EVEL_ENTER();\r
+           assert(typ != null);\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions and call evel_header_type_set.                      */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_OTHER);\r
+           evel_header_type_set(typ);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         \r
+         \r
+         \r
+         /**************************************************************************//**\r
+          * Adds name value pair under hash key\r
+          *\r
+          *\r
+          * @param hashname String         Hash name.\r
+          * @param name String             Name.\r
+          * @param value String            Value.\r
+          *****************************************************************************/\r
+         public void evel_other_field_add_namedarray(String hashname,  String name, String value)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_OTHER);\r
+           assert(hashname != null);\r
+           assert(name != null);\r
+           assert(value != null);\r
+           \r
+           if( evelmap == null)\r
+              evelmap = new HashMap<String,Map<String,String>>();\r
+               \r
+           LOGGER.debug("Adding hash : "+hashname+" name="+name+"value= "+value);\r
+           \r
+           Map<String,String> mymap = null;\r
+           try{\r
+            mymap = evelmap.get(hashname);\r
+           } catch( Exception e)\r
+           {\r
+               e.printStackTrace();\r
+           }\r
+           \r
+           if(mymap == null)\r
+               mymap = new HashMap<String,String>();\r
+           try{\r
+           if( mymap.put(name, value) == null)\r
+               LOGGER.debug("Unable to add map hash : "+hashname+" name="+name+"value= "+value);;\r
+           \r
+           if( evelmap.put(hashname, mymap) == null)\r
+               LOGGER.debug("Unable to add hash entry : "+hashname+" name="+name+"value= "+value);;\r
+           } catch( Exception e)\r
+           {\r
+               e.printStackTrace();\r
+           }\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Add a json object to optional jsonObject list.\r
+          *\r
+          * @param jsonobj   Pointer to json object\r
+          *****************************************************************************/\r
+         public void evel_other_field_add_jsonobj(javax.json.JsonObject  jsonobj)\r
+         {\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_OTHER);\r
+           assert(jsonobj != null);\r
+\r
+           LOGGER.debug("Adding jsonObject");\r
+           \r
+           if( additional_objects == null )\r
+               additional_objects = new ArrayList<javax.json.JsonObject>();\r
+           \r
+           additional_objects.add(jsonobj);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add a field name/value pair to the Other.\r
+          *\r
+          * The name and value are null delimited ASCII strings.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          * @param name      ASCIIZ string with the field's name.  The caller does not\r
+          *                  need to preserve the value once the function returns.\r
+          * @param value     ASCIIZ string with the field's value.  The caller does not\r
+          *                  need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_other_field_add(String name, String value)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_OTHER);\r
+           assert(name != null);\r
+           assert(value != null);\r
+\r
+           LOGGER.debug("Adding name="+name+" value="+value);\r
+           \r
+           if(additional_info == null)\r
+               additional_info = new HashMap<String,String>();\r
+           \r
+           if( additional_info.put(name, value) == null)\r
+               LOGGER.debug("Unable to add map : name="+name+"value= "+value);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Encode Other Object according to VES schema\r
+          *\r
+          * @retval JSON Object of Other event\r
+          *****************************************************************************/\r
+         JsonObjectBuilder evelOtherObject()\r
+         {\r
+\r
+           double version = major_version+(double)minor_version/10;\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_OTHER);\r
+\r
+           /***************************************************************************/\r
+           /* Mandatory fields.                                                       */\r
+           /***************************************************************************/\r
+           \r
+           /***************************************************************************/\r
+           /* Additional Objects.                                                 */\r
+           /***************************************************************************/\r
+           \r
+           JsonObjectBuilder eveloth = Json.createObjectBuilder();\r
+           \r
+           /***************************************************************************/\r
+           /* Optional fields.                                                        */\r
+           /***************************************************************************/\r
+           // additional fields\r
+                 if( additional_info != null )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+           for(Map.Entry<String, String> entry : additional_info.entrySet()){\r
+              LOGGER.debug(MessageFormat.format("Key : {0} and Value: {1}", entry.getKey(), entry.getValue()));\r
+                         JsonObject obj = Json.createObjectBuilder()\r
+                                    .add("name", entry.getKey())\r
+                                    .add("value", entry.getValue()).build();\r
+                         builder.add(obj);\r
+                   }\r
+                       eveloth.add("nameValuePairs", builder);\r
+                 }\r
+                       \r
+        if( additional_objects != null && additional_objects.size() > 0 )\r
+           {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<additional_objects.size();i++) {\r
+                         JsonObject jobj = additional_objects.get(i);\r
+                         builder.add(jobj);\r
+                   }\r
+                       eveloth.add("jsonObjects",builder);\r
+           } \r
+        \r
+                  if( evelmap != null && evelmap.size() > 0)\r
+                  {\r
+                           JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                       for(Map.Entry<String, Map<String,String>> entry : evelmap.entrySet()){\r
+                             LOGGER.debug(MessageFormat.format("Key : {0} and Value: {1}", entry.getKey(), entry.getValue()));\r
+                             Map<String,String> item = entry.getValue();   \r
+                             JsonArrayBuilder builder2 = Json.createArrayBuilder();              \r
+                             for(Map.Entry<String, String> entry2 : item.entrySet()){\r
+                                 LOGGER.debug(MessageFormat.format("Key : {0} and Value: {1}", entry2.getKey(), entry2.getValue()));\r
+                                         JsonObject obj = Json.createObjectBuilder()\r
+                                                    .add("name", entry2.getKey())\r
+                                                    .add("value", entry2.getValue()).build();\r
+                                         builder2.add(obj);\r
+                                  }\r
+                             \r
+                             \r
+                                         JsonObjectBuilder obj = Json.createObjectBuilder()\r
+                                                    .add(entry.getKey(),builder2);\r
+                                         \r
+                                         builder.add(obj);\r
+                               }\r
+                               eveloth.add("hashOfNameValuePairArrays", builder);\r
+                  }\r
+\r
+                 \r
+           \r
+\r
+           /***************************************************************************/\r
+           /* Although optional, we always generate the version.  Note that this      */\r
+           /* closes the object, too.                                                 */\r
+           /***************************************************************************/\r
+           eveloth.add("otherFieldsVersion", version);\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return eveloth;\r
+         }\r
+         \r
+         /**************************************************************************//**\r
+          * Encode the event as a JSON event object according to AT&T's schema.\r
+          * retval : String of JSON event message\r
+          *****************************************************************************/\r
+         String evel_json_encode_event()\r
+         {\r
+               EVEL_ENTER();\r
+               \r
+               assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_OTHER);\r
+               //encode common event header and body for other     \r
+           JsonObject obj = Json.createObjectBuilder()\r
+                    .add("event", Json.createObjectBuilder()\r
+                                .add( "commonEventHeader",eventHeaderObject() )\r
+                                .add( "otherFields",evelOtherObject() )\r
+                                ).build();\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return obj.toString();\r
+\r
+         }\r
+\r
+\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelScalingMeasurement.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelScalingMeasurement.java
new file mode 100644 (file)
index 0000000..392de48
--- /dev/null
@@ -0,0 +1,3677 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Scaling Measurement class\r
+ *\r
+  * This file implements the Evel Scaling Measurement Event class which is intended to provide a\r
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so\r
+ * that VNFs can use it to send CPU, Memory, Disk Measurements to Collector.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+\r
+import javax.json.Json;\r
+import javax.json.JsonArrayBuilder;\r
+import javax.json.JsonObject;\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.slf4j.helpers.MessageFormatter;\r
+\r
+\r
+public class EvelScalingMeasurement extends EvelHeader {\r
+       \r
+       int major_version = 2;\r
+       int minor_version = 1;\r
+       \r
+       /**************************************************************************//**\r
+        * CPU Usage.\r
+        * JSON equivalent field: cpuUsage\r
+        *****************************************************************************/\r
+       public class MEASUREMENT_CPU_USE {\r
+         String id;\r
+         double usage;\r
+         public EvelOptionDouble idle;\r
+         public EvelOptionDouble intrpt;\r
+         public EvelOptionDouble nice;\r
+         public EvelOptionDouble softirq;\r
+         public EvelOptionDouble steal;\r
+         public EvelOptionDouble sys;\r
+         public EvelOptionDouble user;\r
+         public EvelOptionDouble wait;\r
+       }\r
+\r
+\r
+       /**************************************************************************//**\r
+        * Disk Usage.\r
+        * JSON equivalent field: diskUsage\r
+        *****************************************************************************/\r
+       public class MEASUREMENT_DISK_USE {\r
+         String id;\r
+         public EvelOptionDouble iotimeavg;\r
+         public EvelOptionDouble iotimelast;\r
+         public EvelOptionDouble iotimemax;\r
+         public EvelOptionDouble iotimemin;\r
+         public EvelOptionDouble mergereadavg;\r
+         public EvelOptionDouble mergereadlast;\r
+         public EvelOptionDouble mergereadmax;\r
+         public EvelOptionDouble mergereadmin;\r
+         public EvelOptionDouble mergewriteavg;\r
+         public EvelOptionDouble mergewritelast;\r
+         public EvelOptionDouble mergewritemax;\r
+         public EvelOptionDouble mergewritemin;\r
+         public EvelOptionDouble octetsreadavg;\r
+         public EvelOptionDouble octetsreadlast;\r
+         public EvelOptionDouble octetsreadmax;\r
+         public EvelOptionDouble octetsreadmin;\r
+         public EvelOptionDouble octetswriteavg;\r
+         public EvelOptionDouble octetswritelast;\r
+         public EvelOptionDouble octetswritemax;\r
+         public EvelOptionDouble octetswritemin;\r
+         public EvelOptionDouble opsreadavg;\r
+         public EvelOptionDouble opsreadlast;\r
+         public EvelOptionDouble opsreadmax;\r
+         public EvelOptionDouble opsreadmin;\r
+         public EvelOptionDouble opswriteavg;\r
+         public EvelOptionDouble opswritelast;\r
+         public EvelOptionDouble opswritemax;\r
+         public EvelOptionDouble opswritemin;\r
+         public EvelOptionDouble pendingopsavg;\r
+         public EvelOptionDouble pendingopslast;\r
+         public EvelOptionDouble pendingopsmax;\r
+         public EvelOptionDouble pendingopsmin;\r
+         public EvelOptionDouble timereadavg;\r
+         public EvelOptionDouble timereadlast;\r
+         public EvelOptionDouble timereadmax;\r
+         public EvelOptionDouble timereadmin;\r
+         public EvelOptionDouble timewriteavg;\r
+         public EvelOptionDouble timewritelast;\r
+         public EvelOptionDouble timewritemax;\r
+         public EvelOptionDouble timewritemin;\r
+\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Filesystem Usage.\r
+        * JSON equivalent field: filesystemUsage\r
+        *****************************************************************************/\r
+       public class MEASUREMENT_FSYS_USE {\r
+         String filesystem_name;\r
+         double block_configured;\r
+         double block_iops;\r
+         double block_used;\r
+         double ephemeral_configured;\r
+         double ephemeral_iops;\r
+         double ephemeral_used;\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Memory Usage.\r
+        * JSON equivalent field: memoryUsage\r
+        *****************************************************************************/\r
+       public class MEASUREMENT_MEM_USE {\r
+         String id;\r
+         String vmid;\r
+         double membuffsz;\r
+         public EvelOptionDouble memcache;\r
+         public EvelOptionDouble memconfig;\r
+         public EvelOptionDouble memfree;\r
+         public EvelOptionDouble slabrecl;\r
+         public EvelOptionDouble slabunrecl;\r
+         public EvelOptionDouble memused;\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * myerrors.\r
+        * JSON equivalent field: myerrors\r
+        *****************************************************************************/\r
+       public class MEASUREMENT_ERRORS {\r
+         int receive_discards;\r
+         int receive_myerrors;\r
+         int transmit_discards;\r
+         int transmit_myerrors;\r
+       }\r
+       \r
+       /**************************************************************************//**\r
+        * Latency Bucket.\r
+        * JSON equivalent field: latencyBucketMeasure\r
+        *****************************************************************************/\r
+       public class MEASUREMENT_LATENCY_BUCKET {\r
+         int count;\r
+\r
+         /***************************************************************************/\r
+         /* Optional fields                                                         */\r
+         /***************************************************************************/\r
+         public EvelOptionDouble high_end;\r
+         public EvelOptionDouble low_end;\r
+\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Virtual NIC usage.\r
+        * JSON equivalent field: vNicUsage\r
+        *****************************************************************************/\r
+       public class MEASUREMENT_VNIC_PERFORMANCE {\r
+       String vnic_id;\r
+       String valuesaresuspect;\r
+         /***************************************************************************/\r
+         /* Optional fields                                                         */\r
+         /***************************************************************************/\r
+         /*Cumulative count of broadcast packets received as read at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble recvd_bcast_packets_acc;\r
+         /*Count of broadcast packets received within the measurement interval*/\r
+         public EvelOptionDouble recvd_bcast_packets_delta;\r
+         /*Cumulative count of discarded packets received as read at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble recvd_discarded_packets_acc;\r
+         /*Count of discarded packets received within the measurement interval*/\r
+         public EvelOptionDouble recvd_discarded_packets_delta;\r
+         /*Cumulative count of error packets received as read at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble recvd_error_packets_acc;\r
+         /*Count of error packets received within the measurement interval*/\r
+         public EvelOptionDouble recvd_error_packets_delta;\r
+         /*Cumulative count of multicast packets received as read at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble recvd_mcast_packets_acc;\r
+         /*Count of mcast packets received within the measurement interval*/\r
+         public EvelOptionDouble recvd_mcast_packets_delta;\r
+         /*Cumulative count of octets received as read at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble recvd_octets_acc;\r
+         /*Count of octets received within the measurement interval*/\r
+         public EvelOptionDouble recvd_octets_delta;\r
+         /*Cumulative count of all packets received as read at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble recvd_total_packets_acc;\r
+         /*Count of all packets received within the measurement interval*/\r
+         public EvelOptionDouble recvd_total_packets_delta;\r
+         /*Cumulative count of unicast packets received as read at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble recvd_ucast_packets_acc;\r
+         /*Count of unicast packets received within the measurement interval*/\r
+         public EvelOptionDouble recvd_ucast_packets_delta;\r
+         /*Cumulative count of transmitted broadcast packets at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble tx_bcast_packets_acc;\r
+         /*Count of transmitted broadcast packets within the measurement interval*/\r
+         public EvelOptionDouble tx_bcast_packets_delta;\r
+         /*Cumulative count of transmit discarded packets at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble tx_discarded_packets_acc;\r
+         /*Count of transmit discarded packets within the measurement interval*/\r
+         public EvelOptionDouble tx_discarded_packets_delta;\r
+         /*Cumulative count of transmit error packets at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble tx_error_packets_acc;\r
+         /*Count of transmit error packets within the measurement interval*/\r
+         public EvelOptionDouble tx_error_packets_delta;\r
+         /*Cumulative count of transmit multicast packets at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble tx_mcast_packets_acc;\r
+         /*Count of transmit multicast packets within the measurement interval*/\r
+         public EvelOptionDouble tx_mcast_packets_delta;\r
+         /*Cumulative count of transmit octets at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble tx_octets_acc;\r
+         /*Count of transmit octets received within the measurement interval*/\r
+         public EvelOptionDouble tx_octets_delta;\r
+         /*Cumulative count of all transmit packets at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble tx_total_packets_acc;\r
+         /*Count of transmit packets within the measurement interval*/\r
+         public EvelOptionDouble tx_total_packets_delta;\r
+         /*Cumulative count of all transmit unicast packets at the end of\r
+          the measurement interval*/\r
+         public EvelOptionDouble tx_ucast_packets_acc;\r
+         /*Count of transmit unicast packets within the measurement interval*/\r
+         public EvelOptionDouble tx_ucast_packets_delta;\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Codec Usage.\r
+        * JSON equivalent field: codecsInUse\r
+        *****************************************************************************/\r
+       public class MEASUREMENT_CODEC_USE {\r
+         String codec_id;\r
+         int number_in_use;\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Feature Usage.\r
+        * JSON equivalent field: featuresInUse\r
+        *****************************************************************************/\r
+       public class MEASUREMENT_FEATURE_USE {\r
+         String feature_id;\r
+         int feature_utilization;\r
+       }\r
+\r
+\r
+       /**************************************************************************//**\r
+        * Custom Defined Measurement.\r
+        * JSON equivalent field: measurements\r
+        *****************************************************************************/\r
+       public class CUSTOM_MEASUREMENT {\r
+         String name;\r
+         String value;\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Measurement Group.\r
+        * JSON equivalent field: additionalMeasurements\r
+        *****************************************************************************/\r
+       public class MEASUREMENT_GROUP {\r
+         String name;\r
+         ArrayList<CUSTOM_MEASUREMENT> measurements;\r
+       }\r
+\r
+       \r
+       /***************************************************************************/\r
+         /* Mandatory fields                                                        */\r
+         /***************************************************************************/\r
+         double measurement_interval;\r
+\r
+         /***************************************************************************/\r
+         /* Optional fields                                                         */\r
+         /***************************************************************************/\r
+         ArrayList<String[]> additional_info;\r
+         ArrayList<MEASUREMENT_GROUP> additional_measurements;\r
+         ArrayList<javax.json.JsonObject> additional_objects;\r
+         ArrayList<MEASUREMENT_CODEC_USE> codec_usage;\r
+         EvelOptionInt concurrent_sessions;\r
+         EvelOptionInt configured_entities;\r
+         ArrayList<MEASUREMENT_CPU_USE> cpu_usage;\r
+         ArrayList<MEASUREMENT_DISK_USE> disk_usage;\r
+         boolean errstat;\r
+         MEASUREMENT_ERRORS myerrors;\r
+         ArrayList<MEASUREMENT_FEATURE_USE> feature_usage;\r
+         ArrayList<MEASUREMENT_FSYS_USE> filesystem_usage;\r
+         ArrayList<MEASUREMENT_LATENCY_BUCKET> latency_distribution;\r
+         EvelOptionDouble mean_request_latency;\r
+         ArrayList<MEASUREMENT_MEM_USE> mem_usage;\r
+         EvelOptionInt media_ports_in_use;\r
+         EvelOptionInt request_rate;\r
+         EvelOptionInt vnfc_scaling_metric;\r
+         ArrayList<MEASUREMENT_VNIC_PERFORMANCE> vnic_usage;\r
+\r
+\r
+       /***************************************************************************/\r
+       /* Optional fields                                                         */\r
+       /***************************************************************************/\r
+\r
+         private static final Logger LOGGER = Logger.getLogger( EvelScalingMeasurement.class.getName() );\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Constructs a new Measurement event.\r
+          *\r
+          * @note    The mandatory fields on the Measurement must be supplied to this\r
+          *          factory function and are immutable once set.  Optional fields have\r
+          *          explicit setter functions, but again values may only be set once so\r
+          *          that the Measurement has immutable properties.\r
+          *\r
+          * @param   measurement_interval\r
+          *\r
+          *****************************************************************************/\r
+         public EvelScalingMeasurement(double meas_interval,String evname,String evid)\r
+         { //Init header\r
+        super(evname,evid);\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(meas_interval >= 0.0);\r
+\r
+           LOGGER.debug("New measurement is at "+meas_interval);\r
+\r
+           /***************************************************************************/\r
+           /* Initialize the header & the measurement fields.                         */\r
+           /***************************************************************************/\r
+           event_domain = EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT;\r
+        //initialize optional fields\r
+           measurement_interval = meas_interval;\r
+           additional_info = null;\r
+           additional_measurements = null;\r
+           additional_objects = null;\r
+           cpu_usage = null;\r
+           disk_usage = null;\r
+           mem_usage = null;\r
+           filesystem_usage = null;\r
+           latency_distribution = null;\r
+           vnic_usage = null;\r
+           codec_usage = null;\r
+           feature_usage = null;\r
+           errstat = false;\r
+           \r
+           mean_request_latency = new EvelOptionDouble(false, 0.0);\r
+           vnfc_scaling_metric = new EvelOptionInt(false, 0);\r
+           concurrent_sessions = new EvelOptionInt(false, 0);\r
+           configured_entities = new EvelOptionInt(false, 0);\r
+           media_ports_in_use = new EvelOptionInt(false, 0);\r
+           request_rate = new EvelOptionInt(false, 0);\r
+           errstat = false;\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Event Type property of the Measurement.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          \r
+          * @param type        The Event Type to be set. ASCIIZ string. The caller\r
+          *                    does not need to preserve the value once the function\r
+          *                    returns.\r
+          *****************************************************************************/\r
+         public void evel_measurement_type_set(String typ)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions and call evel_header_type_set.                      */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           evel_header_type_set(typ);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add an additional value name/value pair to the Measurement.\r
+          *\r
+          * The name and value are null delimited ASCII strings.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * @param name      ASCIIZ string with the attribute's name.  The caller\r
+          *                  does not need to preserve the value once the function\r
+          *                  returns.\r
+          * @param value     ASCIIZ string with the attribute's value.  The caller\r
+          *                  does not need to preserve the value once the function\r
+          *                  returns.\r
+          *****************************************************************************/\r
+         public void evel_measurement_addl_info_add(String name, String value)\r
+               {\r
+                 String[] addl_info = null;\r
+                 EVEL_ENTER();\r
+\r
+                 /***************************************************************************/\r
+                 /* Check preconditions.                                                    */\r
+                 /***************************************************************************/\r
+                 assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+                 assert(name != null);\r
+                 assert(value != null);\r
+                 \r
+                 if( additional_info == null )\r
+                 {\r
+                         additional_info = new ArrayList<String[]>();\r
+                 }\r
+\r
+                 LOGGER.debug(MessageFormat.format("Adding name={0} value={1}", name, value));\r
+                 addl_info = new String[2];\r
+                 assert(addl_info != null);\r
+                 addl_info[0] = name;\r
+                 addl_info[1] = value;\r
+\r
+                 additional_info.add(addl_info);\r
+\r
+                 EVEL_EXIT();\r
+               }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Concurrent Sessions property of the Measurement.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          \r
+          * @param concurrent_sessions The Concurrent Sessions to be set.\r
+          *****************************************************************************/\r
+         public void evel_measurement_conc_sess_set(int conc_sessions)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(conc_sessions >= 0);\r
+\r
+               concurrent_sessions.SetValuePr(conc_sessions,"Concurrent Sessions");\r
+                 \r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Configured Entities property of the Measurement.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          \r
+          * @param configured_entities The Configured Entities to be set.\r
+          *****************************************************************************/\r
+         public void evel_measurement_cfg_ents_set(EvelScalingMeasurement measurement,\r
+                                            int config_entities)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(config_entities >= 0);\r
+\r
+           configured_entities.SetValuePr(config_entities,"Configured Entities");\r
+               \r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add an additional set of myerrors to the Measurement.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param measurement       Pointer to the measurement.\r
+          * @param receive_discard  The number of receive discards.\r
+          * @param receive_error    The number of receive myerrors.\r
+          * @param transmit_discard The number of transmit discards.\r
+          * @param transmit_error   The number of transmit myerrors.\r
+          *****************************************************************************/\r
+         public void evel_measurement_myerrors_set( \r
+                                          int receive_discard,\r
+                                          int receive_error,\r
+                                          int transmit_discard,\r
+                                          int transmit_error)\r
+         {\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                      */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(receive_discard >= 0);\r
+           assert(receive_error >= 0);\r
+           assert(transmit_discard >= 0);\r
+           assert(transmit_error >= 0);\r
+\r
+           if (errstat == false)\r
+           {\r
+             errstat = true;\r
+             LOGGER.debug(MessageFormat.format("Adding myerrors: {0}, {1}, {2}, {3}",\r
+                        receive_discard,\r
+                        receive_error,\r
+                        transmit_discard,\r
+                        transmit_error));\r
+             if( myerrors == null )myerrors = new MEASUREMENT_ERRORS();\r
+             myerrors.receive_discards = receive_discard;\r
+             myerrors.receive_myerrors = receive_error;\r
+             myerrors.transmit_discards = transmit_discard;\r
+             myerrors.transmit_myerrors = transmit_error;\r
+           }\r
+           else\r
+           {\r
+             LOGGER.debug(MessageFormat.format("Adding myerrors: {0}, {1}; {2}, {3} myerrors already set: {4}, {5}; {6}, {7}",\r
+                        receive_discard,\r
+                        receive_error,\r
+                        transmit_discard,\r
+                        transmit_error,\r
+                        myerrors.receive_discards,\r
+                        myerrors.receive_myerrors,\r
+                        myerrors.transmit_discards,\r
+                        myerrors.transmit_myerrors));\r
+           }\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Mean Request Latency property of the Measurement.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          \r
+          * @param mean_request_latency The Mean Request Latency to be set.\r
+          *****************************************************************************/\r
+         public void evel_measurement_mean_req_lat_set(\r
+                                                double mean_req_latency)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(mean_req_latency >= 0.0);\r
+\r
+           mean_request_latency.SetValuePr(mean_req_latency,"Mean Request Latency");\r
+           \r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the Request Rate property of the Measurement.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          \r
+          * @param request_rate The Request Rate to be set.\r
+          *****************************************************************************/\r
+         public void evel_measurement_request_rate_set(int req_rate)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(req_rate >= 0);\r
+\r
+           request_rate.SetValuePr(req_rate,"Request Rate");\r
+           \r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add an additional CPU usage value name/value pair to the Measurement.\r
+          *\r
+          * The name and value are null delimited ASCII strings.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * \r
+          * @param id            ASCIIZ string with the CPU's identifier.\r
+          * @param usage         CPU utilization.\r
+          *****************************************************************************/\r
+         public MEASUREMENT_CPU_USE evel_measurement_new_cpu_use_add(String id, double usage)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check assumptions.                                                      */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(id != null);\r
+           assert(usage >= 0.0);\r
+\r
+           /***************************************************************************/\r
+           /* Allocate a container for the value and push onto the list.              */\r
+           /***************************************************************************/\r
+           LOGGER.debug(MessageFormatter.format("Adding id={0} usage={1}", id, usage));\r
+           MEASUREMENT_CPU_USE cpu_use = new MEASUREMENT_CPU_USE();\r
+           assert(cpu_use != null);\r
+           cpu_use.id    = id;\r
+           cpu_use.usage = usage;\r
+           cpu_use.idle = new EvelOptionDouble();\r
+           cpu_use.intrpt = new EvelOptionDouble();\r
+           cpu_use.nice = new EvelOptionDouble();\r
+           cpu_use.softirq = new EvelOptionDouble();\r
+           cpu_use.steal = new EvelOptionDouble();\r
+           cpu_use.sys = new EvelOptionDouble();\r
+           cpu_use.user = new EvelOptionDouble();\r
+           cpu_use.wait = new EvelOptionDouble();\r
+           \r
+           if( cpu_usage == null ){\r
+               cpu_usage = new ArrayList<MEASUREMENT_CPU_USE>();\r
+               if( cpu_usage == null)LOGGER.error("Unable to allocate new cpu usage");\r
+           }\r
+\r
+           cpu_usage.add(cpu_use);\r
+\r
+           EVEL_EXIT();\r
+           return cpu_use;\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the CPU Idle value in measurement interval\r
+          *   percentage of CPU time spent in the idle task\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param cpu_use      Pointer to the CPU Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_cpu_use_idle_set(MEASUREMENT_CPU_USE cpu_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           cpu_use.idle.SetValuePr(val,"CPU idle time");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the percentage of time spent servicing interrupts\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param cpu_use      Pointer to the CPU Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_cpu_use_interrupt_set(MEASUREMENT_CPU_USE cpu_use,\r
+                                                     double val)\r
+         {\r
+           EVEL_ENTER();\r
+           cpu_use.intrpt.SetValuePr(val,"CPU interrupt value");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the percentage of time spent running user space processes that have been niced\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param cpu_use      Pointer to the CPU Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_cpu_use_nice_set(MEASUREMENT_CPU_USE cpu_use,\r
+                                                double val)\r
+         {\r
+           EVEL_ENTER();\r
+           cpu_use.nice.SetValuePr(val, "CPU nice value");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the percentage of time spent handling soft irq interrupts\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param cpu_use      Pointer to the CPU Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_cpu_use_softirq_set(MEASUREMENT_CPU_USE cpu_use,\r
+                                                   double val)\r
+         {\r
+           EVEL_ENTER();\r
+           cpu_use.softirq.SetValuePr(val, "CPU Soft IRQ value");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the percentage of time spent in involuntary wait\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param cpu_use      Pointer to the CPU Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_cpu_use_steal_set(MEASUREMENT_CPU_USE cpu_use,\r
+                                                 double val)\r
+         {\r
+           EVEL_ENTER();\r
+           cpu_use.steal.SetValuePr(val,"CPU involuntary wait");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the percentage of time spent on system tasks running the kernel\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param cpu_use      Pointer to the CPU Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_cpu_use_system_set(MEASUREMENT_CPU_USE cpu_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           cpu_use.sys.SetValuePr(val,"CPU System load");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the percentage of time spent running un-niced user space processes\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param cpu_use      Pointer to the CPU Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_cpu_use_usageuser_set(MEASUREMENT_CPU_USE cpu_use,\r
+                                                     double val)\r
+         {\r
+           EVEL_ENTER();\r
+           cpu_use.user.SetValuePr(val,"CPU User load value");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the percentage of CPU time spent waiting for I/O operations to complete\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param cpu_use      Pointer to the CPU Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_cpu_use_wait_set(MEASUREMENT_CPU_USE cpu_use,\r
+                                                double val)\r
+         {\r
+           EVEL_ENTER();\r
+           cpu_use.wait.SetValuePr(val, "CPU Wait IO value");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Add an additional Memory usage value name/value pair to the Measurement.\r
+          *\r
+          * The name and value are null delimited ASCII strings.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * \r
+          * @param id            ASCIIZ string with the Memory identifier.\r
+          * @param vmidentifier  ASCIIZ string with the VM's identifier.\r
+          * @param membuffsz     Memory Size.\r
+          *\r
+          * @return  Returns pointer to memory use structure in measurements\r
+          *****************************************************************************/\r
+         public MEASUREMENT_MEM_USE evel_measurement_new_mem_use_add(\r
+                                          String id,  String vmidentifier,  double membuffsz)\r
+         {\r
+           MEASUREMENT_MEM_USE mem_use = null;\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check assumptions.                                                      */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(id != null);\r
+           assert(membuffsz >= 0.0);\r
+\r
+           /***************************************************************************/\r
+           /* Allocate a container for the value and push onto the list.              */\r
+           /***************************************************************************/\r
+           LOGGER.debug(MessageFormatter.format("Adding id={0} buffer size={1}", id, membuffsz));\r
+           mem_use = new MEASUREMENT_MEM_USE();\r
+           assert(mem_use != null);\r
+           mem_use.id    = id;\r
+           mem_use.vmid  = vmidentifier;\r
+           mem_use.membuffsz = membuffsz;\r
+           mem_use.memcache = new EvelOptionDouble();\r
+           mem_use.memconfig= new EvelOptionDouble();\r
+           mem_use.memfree= new EvelOptionDouble();\r
+           mem_use.slabrecl= new EvelOptionDouble();\r
+           mem_use.slabunrecl= new EvelOptionDouble();\r
+           mem_use.memused= new EvelOptionDouble();\r
+\r
+           assert(mem_use.id != null);\r
+           \r
+           if( mem_usage == null ){\r
+               mem_usage = new ArrayList<MEASUREMENT_MEM_USE>();\r
+               if( mem_usage == null )LOGGER.error("Unable to allocate new memory usage");\r
+           }\r
+\r
+\r
+           mem_usage.add(mem_use);\r
+\r
+           EVEL_EXIT();\r
+           return mem_use;\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set kilobytes of memory used for cache\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param mem_use      Pointer to the Memory Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_mem_use_memcache_set(MEASUREMENT_MEM_USE mem_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           mem_use.memcache.SetValuePr(val,"Memory cache value");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set kilobytes of memory configured in the virtual machine on which the VNFC reporting\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param mem_use      Pointer to the Memory Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_mem_use_memconfig_set(MEASUREMENT_MEM_USE mem_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           mem_use.memconfig.SetValuePr(val, "Memory configured value");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set kilobytes of physical RAM left unused by the system\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param mem_use      Pointer to the Memory Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_mem_use_memfree_set(MEASUREMENT_MEM_USE mem_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           mem_use.memfree.SetValuePr(val, "Memory freely available value");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the part of the slab that can be reclaimed such as caches measured in kilobytes\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param mem_use      Pointer to the Memory Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_mem_use_slab_reclaimed_set(MEASUREMENT_MEM_USE mem_use,\r
+                                              double val)\r
+         {\r
+           EVEL_ENTER();\r
+           mem_use.slabrecl.SetValuePr(val, "Memory reclaimable slab set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the part of the slab that cannot be reclaimed such as caches measured in kilobytes\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param mem_use      Pointer to the Memory Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_mem_use_slab_unreclaimable_set(MEASUREMENT_MEM_USE  mem_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           mem_use.slabunrecl.SetValuePr(val, "Memory unreclaimable slab set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the total memory minus the sum of free, buffered, cached and slab memory in kilobytes\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param mem_use      Pointer to the Memory Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_mem_use_usedup_set(MEASUREMENT_MEM_USE mem_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           mem_use.memused.SetValuePr(val, "Memory usedup total set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add an additional Disk usage value name/value pair to the Measurement.\r
+          *\r
+          * The name and value are null delimited ASCII strings.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * \r
+          * @param id            ASCIIZ string with the CPU's identifier.\r
+          * @param usage         Disk utilization.\r
+          *****************************************************************************/\r
+         public MEASUREMENT_DISK_USE evel_measurement_new_disk_use_add(String id)\r
+         {\r
+           MEASUREMENT_DISK_USE disk_use = null;\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check assumptions.                                                      */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(id != null);\r
+\r
+           /***************************************************************************/\r
+           /* Allocate a container for the value and push onto the list.              */\r
+           /***************************************************************************/\r
+           LOGGER.debug(MessageFormatter.format("Adding id={0} disk usage", id));\r
+           disk_use = new MEASUREMENT_DISK_USE();\r
+           assert(disk_use != null);\r
+           disk_use.id    = id;\r
+           assert(disk_use.id != null);\r
+\r
+           disk_use.iotimeavg= new EvelOptionDouble();\r
+           disk_use.iotimelast= new EvelOptionDouble();\r
+           disk_use.iotimemax= new EvelOptionDouble();\r
+           disk_use.iotimemin= new EvelOptionDouble();\r
+           disk_use.mergereadavg= new EvelOptionDouble();\r
+           disk_use.mergereadlast= new EvelOptionDouble();\r
+           disk_use.mergereadmax= new EvelOptionDouble();\r
+           disk_use.mergereadmin= new EvelOptionDouble();\r
+           disk_use.mergewriteavg= new EvelOptionDouble();\r
+           disk_use.mergewritelast= new EvelOptionDouble();\r
+           disk_use.mergewritemax= new EvelOptionDouble();\r
+           disk_use.mergewritemin= new EvelOptionDouble();\r
+           disk_use.octetsreadavg= new EvelOptionDouble();\r
+           disk_use.octetsreadlast= new EvelOptionDouble();\r
+           disk_use.octetsreadmax= new EvelOptionDouble();\r
+           disk_use.octetsreadmin= new EvelOptionDouble();\r
+           disk_use.octetswriteavg= new EvelOptionDouble();\r
+           disk_use.octetswritelast= new EvelOptionDouble();\r
+           disk_use.octetswritemax= new EvelOptionDouble();\r
+           disk_use.octetswritemin= new EvelOptionDouble();\r
+           disk_use.opsreadavg= new EvelOptionDouble();\r
+           disk_use.opsreadlast= new EvelOptionDouble();\r
+           disk_use.opsreadmax= new EvelOptionDouble();\r
+           disk_use.opsreadmin= new EvelOptionDouble();\r
+           disk_use.opswriteavg= new EvelOptionDouble();\r
+           disk_use.opswritelast= new EvelOptionDouble();\r
+           disk_use.opswritemax= new EvelOptionDouble();\r
+           disk_use.opswritemin= new EvelOptionDouble();\r
+           disk_use.pendingopsavg= new EvelOptionDouble();\r
+           disk_use.pendingopslast= new EvelOptionDouble();\r
+           disk_use.pendingopsmax= new EvelOptionDouble();\r
+           disk_use.pendingopsmin= new EvelOptionDouble();\r
+           disk_use.timereadavg= new EvelOptionDouble();\r
+           disk_use.timereadlast= new EvelOptionDouble();\r
+           disk_use.timereadmax= new EvelOptionDouble();\r
+           disk_use.timereadmin= new EvelOptionDouble();\r
+           disk_use.timewriteavg= new EvelOptionDouble();\r
+           disk_use.timewritelast= new EvelOptionDouble();\r
+           disk_use.timewritemax= new EvelOptionDouble();\r
+           disk_use.timewritemin= new EvelOptionDouble();\r
+           \r
+           if( disk_usage == null ){\r
+               disk_usage = new ArrayList<MEASUREMENT_DISK_USE>();\r
+               if( disk_usage == null ) LOGGER.error("Unable to allocate new disk usage");\r
+           }\r
+\r
+           \r
+           disk_usage.add(disk_use);\r
+\r
+\r
+           EVEL_EXIT();\r
+           return disk_use;\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set milliseconds spent doing input/output operations over 1 sec; treat\r
+          * this metric as a device load percentage where 1000ms  matches 100% load;\r
+          * provide the average over the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_iotimeavg_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val) \r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.iotimeavg.SetValuePr(val,"Disk ioload set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set milliseconds spent doing input/output operations over 1 sec; treat\r
+          * this metric as a device load percentage where 1000ms  matches 100% load;\r
+          * provide the last value within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_iotimelast_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.iotimelast.SetValuePr(val, "Disk ioloadlast set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set milliseconds spent doing input/output operations over 1 sec; treat\r
+          * this metric as a device load percentage where 1000ms  matches 100% load;\r
+          * provide the maximum value within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_iotimemax_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.iotimemax.SetValuePr(val, "Disk ioloadmax set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set milliseconds spent doing input/output operations over 1 sec; treat\r
+          * this metric as a device load percentage where 1000ms  matches 100% load;\r
+          * provide the minimum value within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_iotimemin_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.iotimemin.SetValuePr(val, "Disk ioloadmin set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set number of logical read operations that were merged into physical read\r
+          * operations, e.g., two logical reads were served by one physical disk access;\r
+          * provide the average measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_mergereadavg_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.mergereadavg.SetValuePr(val, "Disk Merged read average set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of logical read operations that were merged into physical read\r
+          * operations, e.g., two logical reads were served by one physical disk access;\r
+          * provide the last measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_mergereadlast_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.mergereadlast.SetValuePr(val, "Disk mergedload last set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of logical read operations that were merged into physical read\r
+          * operations, e.g., two logical reads were served by one physical disk access;\r
+          * provide the maximum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_mergereadmax_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.mergereadmax.SetValuePr(val, "Disk merged loadmax set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set number of logical read operations that were merged into physical read\r
+          * operations, e.g., two logical reads were served by one physical disk access;\r
+          * provide the minimum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_mergereadmin_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.mergereadmin.SetValuePr(val, "Disk merged loadmin set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of logical write operations that were merged into physical read\r
+          * operations, e.g., two logical writes were served by one physical disk access;\r
+          * provide the last measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_mergewritelast_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.mergewritelast.SetValuePr(val, "Disk merged writelast set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of logical write operations that were merged into physical read\r
+          * operations, e.g., two logical writes were served by one physical disk access;\r
+          * provide the maximum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_mergewritemax_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.mergewritemax.SetValuePr(val, "Disk writemax set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of logical write operations that were merged into physical read\r
+          * operations, e.g., two logical writes were served by one physical disk access;\r
+          * provide the maximum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_mergewritemin_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.mergewritemin.SetValuePr(val, "Disk writemin set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set number of octets per second read from a disk or partition;\r
+          * provide the average measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_octetsreadavg_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.octetsreadavg.SetValuePr(val, "Octets readavg set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set number of octets per second read from a disk or partition;\r
+          * provide the last measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_octetsreadlast_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.octetsreadlast.SetValuePr(val, "Octets readlast set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set number of octets per second read from a disk or partition;\r
+          * provide the maximum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_octetsreadmax_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.octetsreadmax.SetValuePr(val, "Octets readmax set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of octets per second read from a disk or partition;\r
+          * provide the minimum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_octetsreadmin_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.octetsreadmin.SetValuePr(val, "Octets readmin set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of octets per second written to a disk or partition;\r
+          * provide the average measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_octetswriteavg_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.octetswriteavg.SetValuePr(val, "Octets writeavg set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of octets per second written to a disk or partition;\r
+          * provide the last measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_octetswritelast_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.octetswritelast.SetValuePr(val, "Octets writelast set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of octets per second written to a disk or partition;\r
+          * provide the maximum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_octetswritemax_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.octetswritemax.SetValuePr(val, "Octets writemax set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of octets per second written to a disk or partition;\r
+          * provide the minimum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_octetswritemin_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.octetswritemin.SetValuePr(val, "Octets writemin set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set number of read operations per second issued to the disk;\r
+          * provide the average measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_opsreadavg_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.opsreadavg.SetValuePr(val, "Disk read operation average set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of read operations per second issued to the disk;\r
+          * provide the last measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_opsreadlast_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.opsreadlast.SetValuePr(val, "Disk read operation last set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of read operations per second issued to the disk;\r
+          * provide the maximum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_opsreadmax_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.opsreadmax.SetValuePr(val, "Disk read operation maximum set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of read operations per second issued to the disk;\r
+          * provide the minimum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_opsreadmin_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.opsreadmin.SetValuePr(val, "Disk read operation minimum set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of write operations per second issued to the disk;\r
+          * provide the average measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_opswriteavg_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.opswriteavg.SetValuePr(val, "Disk write operation average set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of write operations per second issued to the disk;\r
+          * provide the last measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_opswritelast_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.opswritelast.SetValuePr(val, "Disk write operation last set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set number of write operations per second issued to the disk;\r
+          * provide the maximum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_opswritemax_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.opswritemax.SetValuePr(val, "Disk write operation maximum set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set number of write operations per second issued to the disk;\r
+          * provide the average measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_opswritemin_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.opswritemin.SetValuePr(val, "Disk write operation minimum set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set queue size of pending I/O operations per second;\r
+          * provide the average measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_pendingopsavg_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.pendingopsavg.SetValuePr(val, "Disk pending operation average set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set queue size of pending I/O operations per second;\r
+          * provide the last measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_pendingopslast_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.pendingopslast.SetValuePr(val, "Disk pending operation last set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set queue size of pending I/O operations per second;\r
+          * provide the maximum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_pendingopsmax_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.pendingopsmax.SetValuePr(val, "Disk pending operation maximum set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set queue size of pending I/O operations per second;\r
+          * provide the minimum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_pendingopsmin_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.pendingopsmin.SetValuePr(val, "Disk pending operation min set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set milliseconds a read operation took to complete;\r
+          * provide the average measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_timereadavg_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.timereadavg.SetValuePr(val, "Disk read time average set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set milliseconds a read operation took to complete;\r
+          * provide the last measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_timereadlast_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.timereadlast.SetValuePr(val, "Disk read time last set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set milliseconds a read operation took to complete;\r
+          * provide the maximum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_timereadmax_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.timereadmax.SetValuePr(val, "Disk read time maximum set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set milliseconds a read operation took to complete;\r
+          * provide the minimum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_timereadmin_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.timereadmin.SetValuePr(val, "Disk read time minimum set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set milliseconds a write operation took to complete;\r
+          * provide the average measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_timewriteavg_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.timewriteavg.SetValuePr(val, "Disk write time average set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set milliseconds a write operation took to complete;\r
+          * provide the last measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_timewritelast_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.timewritelast.SetValuePr(val, "Disk write time last set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set milliseconds a write operation took to complete;\r
+          * provide the maximum measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_timewritemax_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.timewritemax.SetValuePr(val, "Disk write time max set");\r
+           EVEL_EXIT();\r
+         }\r
+         /**************************************************************************//**\r
+          * Set milliseconds a write operation took to complete;\r
+          * provide the average measurement within the measurement interval\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param disk_use     Pointer to the Disk Use.\r
+          * @param val          double\r
+          *****************************************************************************/\r
+         public void evel_measurement_disk_use_timewritemin_set(MEASUREMENT_DISK_USE  disk_use,\r
+                                             double val)\r
+         {\r
+           EVEL_ENTER();\r
+           disk_use.timewritemin.SetValuePr(val, "Disk write time min set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add an additional File System usage value name/value pair to the\r
+          * Measurement.\r
+          *\r
+          * The filesystem_name is null delimited ASCII string.  The library takes a\r
+          * copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * \r
+          * @param filesystem_name   ASCIIZ string with the file-system's UUID.\r
+          * @param block_configured  Block storage configured.\r
+          * @param block_used        Block storage in use.\r
+          * @param block_iops        Block storage IOPS.\r
+          * @param ephemeral_configured  Ephemeral storage configured.\r
+          * @param ephemeral_used        Ephemeral storage in use.\r
+          * @param ephemeral_iops        Ephemeral storage IOPS.\r
+          *****************************************************************************/\r
+         public void evel_measurement_fsys_use_add(\r
+                                            String filesystem_name,\r
+                                            double block_configured,\r
+                                            double block_used,\r
+                                            double block_iops,\r
+                                            double ephemeral_configured,\r
+                                            double ephemeral_used,\r
+                                            double ephemeral_iops)\r
+         {\r
+           MEASUREMENT_FSYS_USE fsys_use = null;\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check assumptions.                                                      */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(filesystem_name != null);\r
+           assert(block_configured >= 0.0);\r
+           assert(block_used >= 0.0);\r
+           assert(block_iops >= 0.0);\r
+           assert(ephemeral_configured >= 0.0);\r
+           assert(ephemeral_used >= 0.0);\r
+           assert(ephemeral_iops >= 0.0);\r
+\r
+           /***************************************************************************/\r
+           /* Allocate a container for the value and push onto the list.              */\r
+           /***************************************************************************/\r
+           LOGGER.debug("Adding filesystem_name="+filesystem_name);\r
+           fsys_use = new MEASUREMENT_FSYS_USE();\r
+           assert(fsys_use != null);\r
+           fsys_use.filesystem_name = filesystem_name;\r
+           fsys_use.block_configured = block_configured;\r
+           fsys_use.block_used = block_used;\r
+           fsys_use.block_iops = block_iops;\r
+           fsys_use.ephemeral_configured = ephemeral_configured;\r
+           fsys_use.ephemeral_used = ephemeral_used;\r
+           fsys_use.ephemeral_iops = ephemeral_iops;\r
+           \r
+           if( filesystem_usage == null ){\r
+               filesystem_usage = new ArrayList<MEASUREMENT_FSYS_USE>();\r
+               if( filesystem_usage == null )LOGGER.error("Unable to allocate new file system usage");\r
+           }\r
+\r
+           filesystem_usage.add(fsys_use);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add a Feature usage value name/value pair to the Measurement.\r
+          *\r
+          * The name is null delimited ASCII string.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * \r
+          * @param feature         ASCIIZ string with the feature's name.\r
+          * @param utilization     Utilization of the feature.\r
+          *****************************************************************************/\r
+         public void evel_measurement_feature_use_add(\r
+                                               String feature,\r
+                                               int utilization)\r
+         {\r
+           MEASUREMENT_FEATURE_USE feature_use = null;\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check assumptions.                                                      */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(feature != null);\r
+           assert(utilization >= 0);\r
+\r
+           /***************************************************************************/\r
+           /* Allocate a container for the value and push onto the list.              */\r
+           /***************************************************************************/\r
+           LOGGER.debug(MessageFormatter.format("Adding Feature={0} Use={1}", feature, utilization));\r
+           feature_use = new MEASUREMENT_FEATURE_USE();\r
+           assert(feature_use != null);\r
+           feature_use.feature_id = feature;\r
+           assert(feature_use.feature_id != null);\r
+           feature_use.feature_utilization = utilization;\r
+           \r
+           if( feature_usage == null ){\r
+               feature_usage = new ArrayList<MEASUREMENT_FEATURE_USE>();\r
+               if( feature_usage == null )LOGGER.error("Unable to allocate new feature usage");\r
+           }\r
+\r
+           feature_usage.add(feature_use);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add a Additional Measurement value name/value pair to the Report.\r
+          *\r
+          * The name is null delimited ASCII string.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * @param measurement   Pointer to the Measaurement.\r
+          * @param group    ASCIIZ string with the measurement group's name.\r
+          * @param name     ASCIIZ string containing the measurement's name.\r
+          * @param value    ASCIIZ string containing the measurement's value.\r
+          *****************************************************************************/\r
+         public void evel_measurement_custom_measurement_add(\r
+                                                      String  group,\r
+                                                      String  name,\r
+                                                      String  value)\r
+         {\r
+           MEASUREMENT_GROUP measurement_group = null;\r
+           CUSTOM_MEASUREMENT custom_measurement = null;\r
+           MEASUREMENT_GROUP item = null;\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check assumptions.                                                      */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(group != null);\r
+           assert(name != null);\r
+           assert(value != null);\r
+\r
+           /***************************************************************************/\r
+           /* Allocate a container for the name/value pair.                           */\r
+           /***************************************************************************/\r
+           LOGGER.debug(MessageFormat.format("Adding Measurement Group={0} Name={1} Value={2}",\r
+                       group, name, value));\r
+           custom_measurement = new CUSTOM_MEASUREMENT();\r
+           assert(custom_measurement != null);\r
+           custom_measurement.name = name;\r
+           assert(custom_measurement.name != null);\r
+           custom_measurement.value = value;\r
+           assert(custom_measurement.value != null);\r
+\r
+           /***************************************************************************/\r
+           /* See if we have that group already.                                      */\r
+           /***************************************************************************/\r
+           if (additional_measurements != null && additional_measurements.size()>0)\r
+           {\r
+             for(int i=0;i<additional_measurements.size();i++)\r
+             {\r
+                 item = additional_measurements.get(i);\r
+                 if( item.name.equals(name))\r
+                 {\r
+                         LOGGER.debug("Found existing Measurement Group");\r
+                         measurement_group = item;\r
+                         break;\r
+                 }\r
+            }\r
+           }\r
+\r
+           /***************************************************************************/\r
+           /* If we didn't have the group already, create it.                         */\r
+           /***************************************************************************/\r
+           if (measurement_group == null)\r
+           {\r
+             LOGGER.debug("Creating new Measurement Group");\r
+             measurement_group = new MEASUREMENT_GROUP();\r
+             assert(measurement_group != null);\r
+             measurement_group.name = group;\r
+             assert(measurement_group.name != null);\r
+             if( additional_measurements == null){\r
+                 additional_measurements = new ArrayList<MEASUREMENT_GROUP>();\r
+                 if( additional_measurements == null ){\r
+                         LOGGER.error("Unable to allocate additional measurements ");\r
+                 }\r
+             }\r
+             additional_measurements.add(measurement_group);\r
+           }\r
+\r
+           /***************************************************************************/\r
+           /* If we didn't have the group already, create it.                         */\r
+           /***************************************************************************/\r
+           measurement_group.measurements.add(custom_measurement);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add a Codec usage value name/value pair to the Measurement.\r
+          *\r
+          * The name is null delimited ASCII string.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * \r
+          * @param codec           ASCIIZ string with the codec's name.\r
+          * @param utilization     Number of codecs in use.\r
+          *****************************************************************************/\r
+         public void evel_measurement_codec_use_add( String codec,\r
+                                              int utilization )\r
+         {\r
+           MEASUREMENT_CODEC_USE codec_use = null;\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check assumptions.                                                      */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(codec != null);\r
+           assert(utilization >= 0.0);\r
+\r
+           /***************************************************************************/\r
+           /* Allocate a container for the value and push onto the list.              */\r
+           /***************************************************************************/\r
+           LOGGER.debug(MessageFormatter.format("Adding Codec={0} Use={1}", codec, utilization));\r
+           codec_use = new MEASUREMENT_CODEC_USE();\r
+           assert(codec_use != null);\r
+           codec_use.codec_id = codec;\r
+           codec_use.number_in_use = utilization;\r
+           \r
+           if( codec_usage == null ){\r
+               codec_usage = new ArrayList<MEASUREMENT_CODEC_USE>();\r
+               if( codec_usage == null )LOGGER.error("Unable to allocate new codec usage");\r
+           }\r
+\r
+           codec_usage.add(codec_use);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the Media Ports in Use property of the Measurement.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          \r
+          * @param media_ports_in_use  The media port usage to set.\r
+          *****************************************************************************/\r
+         public void evel_measurement_media_port_use_set(\r
+                                                  int media_portsuse)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(media_portsuse >= 0);\r
+\r
+           media_ports_in_use.SetValuePr(\r
+                               media_portsuse,\r
+                               "Media Ports In Use");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the VNFC Scaling Metric property of the Measurement.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param scaling_metric  The scaling metric to set.\r
+          *****************************************************************************/\r
+         public void evel_measurement_vnfc_scaling_metric_set(EvelScalingMeasurement measurement,\r
+                                                       int scaling_metric)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(measurement != null);\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(scaling_metric >= 0.0);\r
+\r
+           vnfc_scaling_metric.SetValuePr(\r
+                                  scaling_metric,\r
+                                  "VNFC Scaling Metric");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Create a new Latency Bucket to be added to a Measurement event.\r
+          *\r
+          * @note    The mandatory fields on the ::MEASUREMENT_LATENCY_BUCKET must be\r
+          *          supplied to this factory function and are immutable once set.\r
+          *          Optional fields have explicit setter functions, but again values\r
+          *          may only be set once so that the ::MEASUREMENT_LATENCY_BUCKET has\r
+          *          immutable properties.\r
+          *\r
+          * @param count         Count of events in this bucket.\r
+          *\r
+          * @returns pointer to the newly manufactured ::MEASUREMENT_LATENCY_BUCKET.\r
+          *          If the structure is not used it must be released using free.\r
+          * @retval  null  Failed to create the Latency Bucket.\r
+          *****************************************************************************/\r
+         public MEASUREMENT_LATENCY_BUCKET evel_new_meas_latency_bucket(int count)\r
+         {\r
+           MEASUREMENT_LATENCY_BUCKET bucket=null;\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(count >= 0);\r
+\r
+           /***************************************************************************/\r
+           /* Allocate, then set Mandatory Parameters.                                */\r
+           /***************************************************************************/\r
+           LOGGER.debug("Creating bucket, count = "+count);\r
+           bucket = new MEASUREMENT_LATENCY_BUCKET();\r
+           assert(bucket != null);\r
+\r
+           /***************************************************************************/\r
+           /* Set Mandatory Parameters.                                               */\r
+           /***************************************************************************/\r
+           bucket.count = count;\r
+           \r
+           /***************************************************************************/\r
+           /* Initialize Optional Parameters.                                         */\r
+           /***************************************************************************/\r
+        bucket.low_end = new EvelOptionDouble();\r
+        bucket.high_end = new EvelOptionDouble();\r
+        \r
+           EVEL_EXIT();\r
+\r
+           return bucket;\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the High End property of the Measurement Latency Bucket.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param bucket        Pointer to the Measurement Latency Bucket.\r
+          * @param high_end      High end of the bucket's range.\r
+          *****************************************************************************/\r
+         public void evel_meas_latency_bucket_high_end_set(\r
+                                              MEASUREMENT_LATENCY_BUCKET  bucket,\r
+                                              double high_end)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(high_end >= 0.0);\r
+           bucket.high_end.SetValuePr(high_end, "High End");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Low End property of the Measurement Latency Bucket.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param bucket        Pointer to the Measurement Latency Bucket.\r
+          * @param low_end       Low end of the bucket's range.\r
+          *****************************************************************************/\r
+         public void evel_meas_latency_bucket_low_end_set(\r
+                                              MEASUREMENT_LATENCY_BUCKET  bucket,\r
+                                              double low_end)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(low_end >= 0.0);\r
+           bucket.low_end.SetValuePr(low_end, "Low End");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add an additional Measurement Latency Bucket to the specified event.\r
+          *\r
+          * @param measurement   Pointer to the Measurement event.\r
+          * @param bucket        Pointer to the Measurement Latency Bucket to add.\r
+          *****************************************************************************/\r
+         public void evel_meas_latency_bucket_add(MEASUREMENT_LATENCY_BUCKET  bucket)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(bucket != null);\r
+           \r
+           if( latency_distribution == null ){\r
+               latency_distribution = new ArrayList<MEASUREMENT_LATENCY_BUCKET>();\r
+               if( latency_distribution == null )LOGGER.error("Unable to allocate new file system usage");\r
+           }\r
+           latency_distribution.add(bucket);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add an additional Latency Distribution bucket to the Measurement.\r
+          *\r
+          * This function implements the previous API, purely for convenience.\r
+          *\r
+          * \r
+          * @param low_end       Low end of the bucket's range.\r
+          * @param high_end      High end of the bucket's range.\r
+          * @param count         Count of events in this bucket.\r
+          *****************************************************************************/\r
+         public void evel_measurement_latency_add(\r
+                                           double low_end,\r
+                                           double high_end,\r
+                                           int count)\r
+         {\r
+           MEASUREMENT_LATENCY_BUCKET bucket = null;\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Trust the assertions in the underlying methods.                         */\r
+           /***************************************************************************/\r
+           bucket = evel_new_meas_latency_bucket(count);\r
+           bucket.low_end.SetValue(low_end);\r
+           bucket.high_end.SetValue(high_end);\r
+           evel_meas_latency_bucket_add(bucket);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Create a new vNIC Use to be added to a Measurement event.\r
+          *\r
+          * @note    The mandatory fields on the ::MEASUREMENT_VNIC_PERFORMANCE must be supplied\r
+          *          to this factory function and are immutable once set. Optional\r
+          *          fields have explicit setter functions, but again values may only be\r
+          *          set once so that the ::MEASUREMENT_VNIC_PERFORMANCE has immutable\r
+          *          properties.\r
+          *\r
+          * @param vnic_id               ASCIIZ string with the vNIC's ID.\r
+          * @param val_suspect           True or false confidence in data.\r
+          *\r
+          * @returns pointer to the newly manufactured ::MEASUREMENT_VNIC_PERFORMANCE.\r
+          *          If the structure is not used it must be released using\r
+          *          ::evel_measurement_free_vnic_performance.\r
+          * @retval  null  Failed to create the vNIC Use.\r
+          *****************************************************************************/\r
+         public MEASUREMENT_VNIC_PERFORMANCE evel_measurement_new_vnic_performance(String vnic_id,\r
+                                                              String  val_suspect)\r
+         {\r
+           MEASUREMENT_VNIC_PERFORMANCE vnic_perf=null;\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(vnic_id != null);\r
+           assert(val_suspect.equals("true") || val_suspect.equals("false"));\r
+\r
+           /***************************************************************************/\r
+           /* Allocate, then set Mandatory Parameters.                                */\r
+           /***************************************************************************/\r
+\r
+           vnic_perf = new MEASUREMENT_VNIC_PERFORMANCE();\r
+           assert(vnic_perf != null);\r
+           vnic_perf.vnic_id = vnic_id;\r
+           vnic_perf.valuesaresuspect = val_suspect;\r
+           \r
+           vnic_perf.recvd_bcast_packets_acc= new EvelOptionDouble();\r
+           vnic_perf.recvd_bcast_packets_delta= new EvelOptionDouble();\r
+\r
+           vnic_perf.recvd_discarded_packets_acc= new EvelOptionDouble();\r
+           vnic_perf.recvd_discarded_packets_delta= new EvelOptionDouble();\r
+           vnic_perf.recvd_error_packets_acc= new EvelOptionDouble();\r
+           vnic_perf.recvd_error_packets_delta= new EvelOptionDouble();\r
+           vnic_perf.recvd_mcast_packets_acc= new EvelOptionDouble();\r
+           vnic_perf.recvd_mcast_packets_delta= new EvelOptionDouble();\r
+           vnic_perf.recvd_octets_acc= new EvelOptionDouble();\r
+           vnic_perf.recvd_octets_delta= new EvelOptionDouble();\r
+           vnic_perf.recvd_total_packets_acc= new EvelOptionDouble();\r
+           vnic_perf.recvd_total_packets_delta= new EvelOptionDouble();\r
+           vnic_perf.recvd_ucast_packets_acc= new EvelOptionDouble();\r
+           vnic_perf.recvd_ucast_packets_delta= new EvelOptionDouble();\r
+           vnic_perf.tx_bcast_packets_acc= new EvelOptionDouble();\r
+           vnic_perf.tx_bcast_packets_delta= new EvelOptionDouble();\r
+           vnic_perf.tx_discarded_packets_acc= new EvelOptionDouble();\r
+           vnic_perf.tx_discarded_packets_delta= new EvelOptionDouble();\r
+           vnic_perf.tx_error_packets_acc= new EvelOptionDouble();\r
+           vnic_perf.tx_error_packets_delta= new EvelOptionDouble();\r
+           vnic_perf.tx_mcast_packets_acc= new EvelOptionDouble();\r
+           vnic_perf.tx_mcast_packets_delta= new EvelOptionDouble();\r
+           vnic_perf.tx_octets_acc= new EvelOptionDouble();\r
+           vnic_perf.tx_octets_delta= new EvelOptionDouble();\r
+           vnic_perf.tx_total_packets_acc= new EvelOptionDouble();\r
+           vnic_perf.tx_total_packets_delta= new EvelOptionDouble();\r
+           vnic_perf.tx_ucast_packets_acc= new EvelOptionDouble();\r
+           vnic_perf.tx_ucast_packets_delta= new EvelOptionDouble();\r
+           \r
+           LOGGER.debug("Adding "+vnic_perf+"VNIC ID="+ vnic_perf.vnic_id+"Value="+vnic_perf.valuesaresuspect);\r
+\r
+           /***************************************************************************/\r
+           /* Initialize Optional Parameters.                                         */\r
+           /***************************************************************************/\r
+           EVEL_EXIT();\r
+\r
+           return vnic_perf;\r
+         }\r
+\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the Accumulated Broadcast Packets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_bcast_packets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_bcast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_bcast_packets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_bcast_packets_acc >= 0.0);\r
+\r
+           vnic_performance.recvd_bcast_packets_acc.SetValuePr(\r
+                               recvd_bcast_packets_acc,\r
+                               "Broadcast Packets accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Broadcast Packets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_bcast_packets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_bcast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_bcast_packets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_bcast_packets_delta >= 0.0);\r
+\r
+           vnic_performance.recvd_bcast_packets_delta.SetValuePr(\r
+                               recvd_bcast_packets_delta,\r
+                               "Delta Broadcast Packets recieved");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the Discarded Packets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_discard_packets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_discard_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_discard_packets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_discard_packets_acc >= 0.0);\r
+\r
+           vnic_performance.recvd_discarded_packets_acc.SetValuePr(\r
+                               recvd_discard_packets_acc,\r
+                               "Discarded Packets accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Discarded Packets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_discard_packets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_discard_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_discard_packets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_discard_packets_delta >= 0.0);\r
+\r
+           vnic_performance.recvd_discarded_packets_delta.SetValuePr(\r
+                               recvd_discard_packets_delta,\r
+                               "Delta Discarded Packets recieved");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the Error Packets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_error_packets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_error_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_error_packets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_error_packets_acc >= 0.0);\r
+\r
+           vnic_performance.recvd_error_packets_acc.SetValuePr(\r
+                               recvd_error_packets_acc,\r
+                               "Error Packets received accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Error Packets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_error_packets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_error_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_error_packets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_error_packets_delta >= 0.0);\r
+\r
+           vnic_performance.recvd_error_packets_delta.SetValuePr(\r
+                               recvd_error_packets_delta,\r
+                               "Delta Error Packets recieved");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Accumulated Multicast Packets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_mcast_packets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_mcast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_mcast_packets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_mcast_packets_acc >= 0.0);\r
+\r
+           vnic_performance.recvd_mcast_packets_acc.SetValuePr(\r
+                               recvd_mcast_packets_acc,\r
+                               "Multicast Packets accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Multicast Packets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_mcast_packets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_mcast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_mcast_packets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_mcast_packets_delta >= 0.0);\r
+\r
+           vnic_performance.recvd_mcast_packets_delta.SetValuePr(\r
+                               recvd_mcast_packets_delta,\r
+                               "Delta Multicast Packets recieved");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Accumulated Octets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_octets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_octets_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_octets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_octets_acc >= 0.0);\r
+\r
+           vnic_performance.recvd_octets_acc.SetValuePr(\r
+                               recvd_octets_acc,\r
+                               "Octets received accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Octets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_octets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_octets_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_octets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_octets_delta >= 0.0);\r
+\r
+           vnic_performance.recvd_octets_delta.SetValuePr(\r
+                               recvd_octets_delta,\r
+                               "Delta Octets recieved");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Accumulated Total Packets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_total_packets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_total_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_total_packets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_total_packets_acc >= 0.0);\r
+\r
+           vnic_performance.recvd_total_packets_acc.SetValuePr(\r
+                               recvd_total_packets_acc,\r
+                               "Total Packets accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Total Packets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_total_packets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_total_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_total_packets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_total_packets_delta >= 0.0);\r
+\r
+           vnic_performance.recvd_total_packets_delta.SetValuePr(\r
+                               recvd_total_packets_delta,\r
+                               "Delta Total Packets recieved");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Accumulated Unicast Packets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_ucast_packets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_ucast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_ucast_packets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_ucast_packets_acc >= 0.0);\r
+\r
+           vnic_performance.recvd_ucast_packets_acc.SetValuePr(\r
+                               recvd_ucast_packets_acc,\r
+                               "Unicast Packets received accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Unicast packets Received in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param recvd_ucast_packets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_rx_ucast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double recvd_ucast_packets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(recvd_ucast_packets_delta >= 0.0);\r
+\r
+           vnic_performance.recvd_ucast_packets_delta.SetValuePr(\r
+                               recvd_ucast_packets_delta,\r
+                               "Delta Unicast packets recieved");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Transmitted Broadcast Packets in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_bcast_packets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_bcast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_bcast_packets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_bcast_packets_acc >= 0.0);\r
+\r
+           vnic_performance.tx_bcast_packets_acc.SetValuePr(\r
+                               tx_bcast_packets_acc,\r
+                               "Transmitted Broadcast Packets accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Broadcast packets Transmitted in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_bcast_packets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_bcast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_bcast_packets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_bcast_packets_delta >= 0.0);\r
+\r
+           vnic_performance.tx_bcast_packets_delta.SetValuePr(\r
+                               tx_bcast_packets_delta,\r
+                               "Delta Transmitted Broadcast packets ");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Transmitted Discarded Packets in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_discarded_packets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_discarded_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_discarded_packets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_discarded_packets_acc >= 0.0);\r
+\r
+           vnic_performance.tx_discarded_packets_acc.SetValuePr(\r
+                               tx_discarded_packets_acc,\r
+                               "Transmitted Discarded Packets accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Discarded packets Transmitted in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_discarded_packets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_discarded_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_discarded_packets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_discarded_packets_delta >= 0.0);\r
+\r
+           vnic_performance.tx_discarded_packets_delta.SetValuePr(\r
+                               tx_discarded_packets_delta,\r
+                               "Delta Transmitted Discarded packets ");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Transmitted Errored Packets in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_error_packets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_error_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_error_packets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_error_packets_acc >= 0.0);\r
+\r
+           vnic_performance.tx_error_packets_acc.SetValuePr(\r
+                               tx_error_packets_acc,\r
+                               "Transmitted Error Packets accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Errored packets Transmitted in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_error_packets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_error_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_error_packets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_error_packets_delta >= 0.0);\r
+\r
+           vnic_performance.tx_error_packets_delta.SetValuePr(\r
+                               tx_error_packets_delta,\r
+                               "Delta Transmitted Error packets ");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Transmitted Multicast Packets in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_mcast_packets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_mcast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_mcast_packets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_mcast_packets_acc >= 0.0);\r
+\r
+           vnic_performance.tx_mcast_packets_acc.SetValuePr(\r
+                               tx_mcast_packets_acc,\r
+                               "Transmitted Multicast Packets accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Multicast packets Transmitted in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_mcast_packets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_mcast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_mcast_packets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_mcast_packets_delta >= 0.0);\r
+\r
+           vnic_performance.tx_mcast_packets_delta.SetValuePr(\r
+                               tx_mcast_packets_delta,\r
+                               "Delta Transmitted Multicast packets ");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Transmitted Octets in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_octets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_octets_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_octets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_octets_acc >= 0.0);\r
+\r
+           vnic_performance.tx_octets_acc.SetValuePr(\r
+                               tx_octets_acc,\r
+                               "Transmitted Octets accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Octets Transmitted in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_octets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_octets_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_octets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_octets_delta >= 0.0);\r
+\r
+           vnic_performance.tx_octets_delta.SetValuePr(\r
+                               tx_octets_delta,\r
+                               "Delta Transmitted Octets ");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the Transmitted Total Packets in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_total_packets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_total_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_total_packets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_total_packets_acc >= 0.0);\r
+\r
+           vnic_performance.tx_total_packets_acc.SetValuePr(\r
+                               tx_total_packets_acc,\r
+                               "Transmitted Total Packets accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Total Packets Transmitted in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_total_packets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_total_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_total_packets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_total_packets_delta >= 0.0);\r
+\r
+           vnic_performance.tx_total_packets_delta.SetValuePr(\r
+                               tx_total_packets_delta,\r
+                               "Delta Transmitted Total Packets ");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Set the Transmitted Unicast Packets in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_ucast_packets_acc\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_ucast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_ucast_packets_acc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_ucast_packets_acc >= 0.0);\r
+\r
+           vnic_performance.tx_ucast_packets_acc.SetValuePr(\r
+                               tx_ucast_packets_acc,\r
+                               "Transmitted Unicast Packets accumulated");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Delta Octets Transmitted in measurement interval\r
+          * property of the vNIC performance.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param vnic_performance      Pointer to the vNIC Use.\r
+          * @param tx_ucast_packets_delta\r
+          *****************************************************************************/\r
+         public void evel_vnic_performance_tx_ucast_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE  vnic_performance,\r
+                                             double tx_ucast_packets_delta)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(tx_ucast_packets_delta >= 0.0);\r
+\r
+           vnic_performance.tx_ucast_packets_delta.SetValuePr(\r
+                               tx_ucast_packets_delta,\r
+                               "Delta Transmitted Unicast Packets ");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Add an additional vNIC Use to the specified Measurement event.\r
+          *\r
+          * \r
+          * @param vnic_performance      Pointer to the vNIC Use to add.\r
+          *****************************************************************************/\r
+         public void evel_meas_vnic_performance_add(\r
+                                     MEASUREMENT_VNIC_PERFORMANCE  vnic_performance)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(vnic_performance != null);\r
+           \r
+           if( vnic_usage == null ){\r
+               vnic_usage = new ArrayList<MEASUREMENT_VNIC_PERFORMANCE>();\r
+               if( vnic_usage == null )LOGGER.error("Unable to allocate new file system usage");\r
+           }\r
+\r
+           vnic_usage.add(vnic_performance);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add an additional vNIC usage record Measurement.\r
+          *\r
+          * This function implements the previous API, purely for convenience.\r
+          *\r
+          * The ID is null delimited ASCII string.  The library takes a copy so the\r
+          * caller does not have to preserve values after the function returns.\r
+          *\r
+          * @param measurement           Pointer to the measurement.\r
+          * @param vnic_id               ASCIIZ string with the vNIC's ID.\r
+          * @param valset                true or false confidence level\r
+          * @param recvd_bcast_packets_acc         Recieved broadcast packets\r
+          * @param recvd_bcast_packets_delta       Received delta broadcast packets\r
+          * @param recvd_discarded_packets_acc     Recieved discarded packets\r
+          * @param recvd_discarded_packets_delta   Received discarded delta packets\r
+          * @param recvd_error_packets_acc         Received error packets\r
+          * @param recvd_error_packets_delta,      Received delta error packets\r
+          * @param recvd_mcast_packets_acc         Received multicast packets\r
+          * @param recvd_mcast_packets_delta       Received delta multicast packets\r
+          * @param recvd_octets_acc                Received octets\r
+          * @param recvd_octets_delta              Received delta octets\r
+          * @param recvd_total_packets_acc         Received total packets\r
+          * @param recvd_total_packets_delta       Received delta total packets\r
+          * @param recvd_ucast_packets_acc         Received Unicast packets\r
+          * @param recvd_ucast_packets_delta       Received delta unicast packets\r
+          * @param tx_bcast_packets_acc            Transmitted broadcast packets\r
+          * @param tx_bcast_packets_delta          Transmitted delta broadcast packets\r
+          * @param tx_discarded_packets_acc        Transmitted packets discarded\r
+          * @param tx_discarded_packets_delta      Transmitted delta discarded packets\r
+          * @param tx_error_packets_acc            Transmitted error packets\r
+          * @param tx_error_packets_delta          Transmitted delta error packets\r
+          * @param tx_mcast_packets_acc            Transmitted multicast packets accumulated\r
+          * @param tx_mcast_packets_delta          Transmitted delta multicast packets\r
+          * @param tx_octets_acc                   Transmitted octets\r
+          * @param tx_octets_delta                 Transmitted delta octets\r
+          * @param tx_total_packets_acc            Transmitted total packets\r
+          * @param tx_total_packets_delta          Transmitted delta total packets\r
+          * @param tx_ucast_packets_acc            Transmitted Unicast packets\r
+          * @param tx_ucast_packets_delta          Transmitted delta Unicast packets\r
+          *****************************************************************************/\r
+         public void evel_measurement_vnic_performance_add(\r
+                                        String  vnic_id,\r
+                                        String valset,\r
+                                        double recvd_bcast_packets_acc,\r
+                                        double recvd_bcast_packets_delta,\r
+                                        double recvd_discarded_packets_acc,\r
+                                        double recvd_discarded_packets_delta,\r
+                                        double recvd_error_packets_acc,\r
+                                        double recvd_error_packets_delta,\r
+                                        double recvd_mcast_packets_acc,\r
+                                        double recvd_mcast_packets_delta,\r
+                                        double recvd_octets_acc,\r
+                                        double recvd_octets_delta,\r
+                                        double recvd_total_packets_acc,\r
+                                        double recvd_total_packets_delta,\r
+                                        double recvd_ucast_packets_acc,\r
+                                        double recvd_ucast_packets_delta,\r
+                                        double tx_bcast_packets_acc,\r
+                                        double tx_bcast_packets_delta,\r
+                                        double tx_discarded_packets_acc,\r
+                                        double tx_discarded_packets_delta,\r
+                                        double tx_error_packets_acc,\r
+                                        double tx_error_packets_delta,\r
+                                        double tx_mcast_packets_acc,\r
+                                        double tx_mcast_packets_delta,\r
+                                        double tx_octets_acc,\r
+                                        double tx_octets_delta,\r
+                                        double tx_total_packets_acc,\r
+                                        double tx_total_packets_delta,\r
+                                        double tx_ucast_packets_acc,\r
+                                        double tx_ucast_packets_delta)\r
+         {\r
+           MEASUREMENT_VNIC_PERFORMANCE vnic_performance = null;\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Trust the assertions in the underlying methods.                         */\r
+           /***************************************************************************/\r
+           vnic_performance = evel_measurement_new_vnic_performance(vnic_id, valset);\r
+                                                    \r
+           evel_vnic_performance_rx_bcast_pkt_acc_set(vnic_performance, recvd_bcast_packets_acc);\r
+           evel_vnic_performance_rx_bcast_pkt_delta_set(vnic_performance, recvd_bcast_packets_delta);\r
+           evel_vnic_performance_rx_discard_pkt_acc_set(vnic_performance, recvd_discarded_packets_acc);\r
+           evel_vnic_performance_rx_discard_pkt_delta_set(vnic_performance, recvd_discarded_packets_delta);\r
+           evel_vnic_performance_rx_error_pkt_acc_set(vnic_performance, recvd_error_packets_acc);\r
+           evel_vnic_performance_rx_error_pkt_delta_set(vnic_performance, recvd_error_packets_delta);\r
+           evel_vnic_performance_rx_mcast_pkt_acc_set(vnic_performance, recvd_mcast_packets_acc);\r
+           evel_vnic_performance_rx_mcast_pkt_delta_set(vnic_performance, recvd_mcast_packets_delta);\r
+           evel_vnic_performance_rx_octets_acc_set(vnic_performance, recvd_octets_acc);\r
+           evel_vnic_performance_rx_octets_delta_set(vnic_performance, recvd_octets_delta);\r
+           evel_vnic_performance_rx_total_pkt_acc_set(vnic_performance, recvd_total_packets_acc);\r
+           evel_vnic_performance_rx_total_pkt_delta_set(vnic_performance, recvd_total_packets_delta);\r
+           evel_vnic_performance_rx_ucast_pkt_acc_set(vnic_performance, recvd_ucast_packets_acc);\r
+           evel_vnic_performance_rx_ucast_pkt_delta_set(vnic_performance, recvd_ucast_packets_delta);\r
+           evel_vnic_performance_tx_bcast_pkt_acc_set(vnic_performance, tx_bcast_packets_acc);\r
+           evel_vnic_performance_tx_bcast_pkt_delta_set(vnic_performance, tx_bcast_packets_delta);\r
+           evel_vnic_performance_tx_discarded_pkt_acc_set(vnic_performance, tx_discarded_packets_acc);\r
+           evel_vnic_performance_tx_discarded_pkt_delta_set(vnic_performance, tx_discarded_packets_delta);\r
+           evel_vnic_performance_tx_error_pkt_acc_set(vnic_performance, tx_error_packets_acc);\r
+           evel_vnic_performance_tx_error_pkt_delta_set(vnic_performance, tx_error_packets_delta);\r
+           evel_vnic_performance_tx_mcast_pkt_acc_set(vnic_performance, tx_mcast_packets_acc);\r
+           evel_vnic_performance_tx_mcast_pkt_delta_set(vnic_performance, tx_mcast_packets_delta);\r
+           evel_vnic_performance_tx_octets_acc_set(vnic_performance, tx_octets_acc);\r
+           evel_vnic_performance_tx_octets_delta_set(vnic_performance, tx_octets_delta);\r
+           evel_vnic_performance_tx_total_pkt_acc_set(vnic_performance, tx_total_packets_acc);\r
+           evel_vnic_performance_tx_total_pkt_delta_set(vnic_performance, tx_total_packets_delta);\r
+           evel_vnic_performance_tx_ucast_pkt_acc_set(vnic_performance, tx_ucast_packets_acc);\r
+           evel_vnic_performance_tx_ucast_pkt_delta_set(vnic_performance, tx_ucast_packets_delta);\r
+           \r
+           if( vnic_usage == null ){\r
+               vnic_usage = new ArrayList<MEASUREMENT_VNIC_PERFORMANCE>();\r
+               if( vnic_usage == null )LOGGER.error("Unable to allocate new file system usage");\r
+           }\r
+           \r
+           vnic_usage.add(vnic_performance);\r
+         }\r
+         \r
+         /**************************************************************************//**\r
+          * Add a json object to jsonObject list.\r
+          *\r
+          * The name and value are null delimited ASCII strings.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * @param jsonobj   Pointer to json object\r
+          *****************************************************************************/\r
+         public  void evel_measurement_add_jsonobj(javax.json.JsonObject  jsonobj)\r
+         {\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+           assert(jsonobj != null);\r
+\r
+           LOGGER.debug("Adding jsonObject");\r
+           \r
+           if( additional_objects == null )\r
+               additional_objects = new ArrayList<javax.json.JsonObject>();\r
+           \r
+           additional_objects.add(jsonobj);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Encode Scaling Measurement Object according to VES schema\r
+          *\r
+          * @retval JSON Object of Scaling Measurement event\r
+          *****************************************************************************/\r
+       JsonObjectBuilder evelScalingMeasurementObject()\r
+         {\r
+           MEASUREMENT_CPU_USE cpu_use = null;\r
+           MEASUREMENT_MEM_USE mem_use = null;\r
+           MEASUREMENT_DISK_USE disk_use = null;\r
+           MEASUREMENT_FSYS_USE fsys_use = null;\r
+           MEASUREMENT_LATENCY_BUCKET bucket = null;\r
+           MEASUREMENT_VNIC_PERFORMANCE vnic_use = null;\r
+           MEASUREMENT_FEATURE_USE feature_use = null;\r
+           MEASUREMENT_CODEC_USE codec_use = null;\r
+           MEASUREMENT_GROUP meas_group = null;\r
+           CUSTOM_MEASUREMENT custom_meas = null;\r
+           //DLIST_ITEM item = null;\r
+           //DLIST_ITEM nested_item = null;\r
+           //DLIST_ITEM addl_info_item = null;\r
+           //OTHER_FIELD addl_info = null;\r
+           double version = major_version+(double)minor_version/10;\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_MEASUREMENT);\r
+\r
+           /***************************************************************************/\r
+           /* Mandatory fields.                                                       */\r
+           /***************************************************************************/\r
+           JsonObjectBuilder evelmeasmt = Json.createObjectBuilder()\r
+                                         .add("measurementInterval", measurement_interval);\r
+\r
+           /***************************************************************************/\r
+           /* Optional fields.                                                        */\r
+           /***************************************************************************/\r
+           // additional fields\r
+                 if( additional_info != null )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<additional_info.size();i++) {\r
+                         String[] addl_info = additional_info.get(i);\r
+                         JsonObject obj = Json.createObjectBuilder()\r
+                                    .add("name", addl_info[0])\r
+                                    .add("value", addl_info[1]).build();\r
+                         builder.add(obj);\r
+                   }\r
+                       evelmeasmt.add("additionalFields", builder);\r
+                 }\r
+           \r
+\r
+           // TBD additional json objects\r
+               if( concurrent_sessions.is_set )\r
+                       evelmeasmt.add("concurrentSessions", concurrent_sessions.GetValue());\r
+               if( configured_entities.is_set )\r
+                       evelmeasmt.add("configuredEntities", configured_entities.GetValue());\r
+\r
+           /***************************************************************************/\r
+           /* CPU Use list.                                                           */\r
+           /***************************************************************************/\r
+                 if( cpu_usage != null && cpu_usage.size() > 0 )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<cpu_usage.size();i++) {\r
+                         cpu_use = cpu_usage.get(i);\r
+                         JsonObjectBuilder obj = Json.createObjectBuilder()\r
+                                             .add( "cpuIdentifier", cpu_use.id)\r
+                                             .add( "percentUsage",cpu_use.usage);\r
+                         \r
+                         cpu_use.idle.encJsonValue(obj,"cpuIdle");\r
+                         cpu_use.intrpt.encJsonValue(obj,"cpuUsageInterrupt");\r
+                         cpu_use.nice.encJsonValue(obj,"cpuUsageNice");\r
+                         cpu_use.softirq.encJsonValue(obj,"cpuUsageSoftIrq");\r
+                         cpu_use.steal.encJsonValue(obj,"cpuUsageSteal");\r
+                         cpu_use.sys.encJsonValue(obj,"cpuUsageSystem");\r
+                         cpu_use.user.encJsonValue(obj,"cpuUsageUser");\r
+                         cpu_use.wait.encJsonValue(obj,"cpuWait");                                       \r
+                                         \r
+                         builder.add(obj.build());\r
+                   }\r
+                       evelmeasmt.add("cpuUsageArray", builder);\r
+                 }\r
+               \r
+\r
+\r
+           /***************************************************************************/\r
+           /* Disk Use list.                                                           */\r
+           /***************************************************************************/\r
+                 if( disk_usage != null && disk_usage.size() > 0 )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<disk_usage.size();i++) {\r
+                         disk_use = disk_usage.get(i);\r
+                         JsonObjectBuilder obj = Json.createObjectBuilder()\r
+                                             .add( "diskIdentifier", disk_use.id);\r
+                         \r
+                          disk_use.iotimeavg.encJsonValue(obj,"diskIoTimeAvg");\r
+                          disk_use.iotimelast.encJsonValue(obj,"diskIoTimeLast");\r
+                          disk_use.iotimemax.encJsonValue(obj,"diskIoTimeMax");\r
+                          disk_use.iotimemin.encJsonValue(obj,"diskIoTimeMin");\r
+                          disk_use.mergereadavg.encJsonValue(obj,"diskMergedReadAvg");\r
+                          disk_use.mergereadlast.encJsonValue(obj,"diskMergedReadLast");\r
+                          disk_use.mergereadmax.encJsonValue(obj,"diskMergedReadMax");\r
+                          disk_use.mergereadmin.encJsonValue(obj,"diskMergedReadMin");\r
+                          disk_use.mergewriteavg.encJsonValue(obj,"diskMergedWriteAvg");\r
+                          disk_use.mergewritelast.encJsonValue(obj,"diskMergedWriteLast");\r
+                          disk_use.mergewritemax.encJsonValue(obj,"diskMergedWriteMax");\r
+                          disk_use.mergewritemin.encJsonValue(obj,"diskMergedWriteMin");\r
+                          disk_use.octetsreadavg.encJsonValue(obj,"diskOctetsReadAvg");\r
+                          disk_use.octetsreadlast.encJsonValue(obj,"diskOctetsReadLast");\r
+                          disk_use.octetsreadmax.encJsonValue(obj,"diskOctetsReadMax");\r
+                          disk_use.octetsreadmin.encJsonValue(obj,"diskOctetsReadMin");\r
+                          disk_use.octetswriteavg.encJsonValue(obj,"diskOctetsWriteAvg");\r
+                          disk_use.octetswritelast.encJsonValue(obj,"diskOctetsWriteLast");\r
+                          disk_use.octetswritemax.encJsonValue(obj,"diskOctetsWriteMax");\r
+                          disk_use.octetswritemin.encJsonValue(obj,"diskOctetsWriteMin");\r
+                          disk_use.opsreadavg.encJsonValue(obj,"diskOpsReadAvg");\r
+                          disk_use.opsreadlast.encJsonValue(obj,"diskOpsReadLast");\r
+                          disk_use.opsreadmax.encJsonValue(obj,"diskOpsReadMax");\r
+                          disk_use.opsreadmin.encJsonValue(obj,"diskOpsReadMin");\r
+                          disk_use.opswriteavg.encJsonValue(obj,"diskOpsWriteAvg");\r
+                          disk_use.opswritelast.encJsonValue(obj,"diskOpsWriteLast");\r
+                          disk_use.opswritemax.encJsonValue(obj,"diskOpsWriteMax");\r
+                          disk_use.opswritemin.encJsonValue(obj,"diskOpsWriteMin");\r
+                          disk_use.pendingopsavg.encJsonValue(obj,"diskPendingOperationsAvg");\r
+                          disk_use.pendingopslast.encJsonValue(obj,"diskPendingOperationsLast");\r
+                          disk_use.pendingopsmax.encJsonValue(obj,"diskPendingOperationsMax");\r
+                          disk_use.pendingopsmin.encJsonValue(obj,"diskPendingOperationsMin");\r
+                          disk_use.timereadavg.encJsonValue(obj,"diskTimeReadAvg");\r
+                          disk_use.timereadlast.encJsonValue(obj,"diskTimeReadLast");\r
+                          disk_use.timereadmax.encJsonValue(obj,"diskTimeReadMax");\r
+                          disk_use.timereadmin.encJsonValue(obj,"diskTimeReadMin");\r
+                          disk_use.timewriteavg.encJsonValue(obj,"diskTimeWriteAvg");\r
+                          disk_use.timewritelast.encJsonValue(obj,"diskTimeWriteLast");\r
+                          disk_use.timewritemax.encJsonValue(obj,"diskTimeWriteMax");\r
+                          disk_use.timewritemin.encJsonValue(obj,"diskTimeWriteMin");\r
+                        \r
+                         builder.add(obj.build());\r
+                   }\r
+                       evelmeasmt.add("diskUsageArray", builder);\r
+                 }\r
+\r
+\r
+           /***************************************************************************/\r
+           /* Filesystem Usage list.                                                  */\r
+           /***************************************************************************/\r
+                 if( filesystem_usage != null &&  filesystem_usage.size() > 0 )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<filesystem_usage.size();i++) {\r
+                         fsys_use = filesystem_usage.get(i);\r
+                         JsonObject obj = Json.createObjectBuilder()\r
+                                    .add("blockConfigured", fsys_use.block_configured)\r
+                                    .add("blockIops", fsys_use.block_iops)\r
+                                        .add("blockUsed", fsys_use.block_used)\r
+                                        .add("ephemeralConfigured", fsys_use.ephemeral_configured)\r
+                                        .add("ephemeralIops", fsys_use.ephemeral_iops)\r
+                                        .add("ephemeralUsed", fsys_use.ephemeral_used)\r
+                                        .add("filesystemName", fsys_use.filesystem_name)                                    \r
+                                    .build();\r
+                         builder.add(obj);\r
+                   }\r
+                       evelmeasmt.add("filesystemUsageArray", builder);\r
+                 }\r
+\r
+           /***************************************************************************/\r
+           /* Latency distribution.                                                   */\r
+           /***************************************************************************/ \r
+                 if( latency_distribution != null && latency_distribution.size() > 0 )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<latency_distribution.size();i++) {\r
+                         bucket = latency_distribution.get(i);\r
+                         JsonObjectBuilder obj = Json.createObjectBuilder()\r
+                                             .add( "countsInTheBucket", bucket.count);\r
+                         \r
+                         bucket.low_end.encJsonValue(obj,"lowEndOfLatencyBucket");\r
+                         bucket.high_end.encJsonValue(obj,"highEndOfLatencyBucket");                             \r
+                                         \r
+                         builder.add(obj.build());\r
+                   }\r
+                       evelmeasmt.add("latencyDistribution", builder);\r
+                 }\r
+                 \r
+                 mean_request_latency.encJsonValue(evelmeasmt, "meanRequestLatency");\r
+                 request_rate.encJsonValue(evelmeasmt, "requestRate");\r
+\r
+           /***************************************************************************/\r
+           /* vNIC Usage TBD Performance array                          */\r
+           /***************************************************************************/\r
+                 if( vnic_usage!= null && vnic_usage.size() > 0 )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<vnic_usage.size();i++) {\r
+                         vnic_use = vnic_usage.get(i);\r
+                         JsonObjectBuilder obj = Json.createObjectBuilder()\r
+                                             .add( "vNicIdentifier", vnic_use.vnic_id)\r
+                                             .add( "valuesAreSuspect",vnic_use.valuesaresuspect);\r
+                         \r
+                         \r
+                 /*********************************************************************/\r
+                 /* Optional fields.                                                  */\r
+                 /*********************************************************************/                         \r
+                         vnic_use.recvd_bcast_packets_acc.encJsonValue(obj,"receivedBroadcastPacketsAccumulated");\r
+                         vnic_use.recvd_bcast_packets_delta.encJsonValue(obj,"receivedBroadcastPacketsDelta");\r
+                         vnic_use.recvd_discarded_packets_acc.encJsonValue(obj,"receivedDiscardedPacketsAccumulated");\r
+                         vnic_use.recvd_discarded_packets_delta.encJsonValue(obj,"receivedDiscardedPacketsDelta");\r
+                         vnic_use.recvd_error_packets_acc.encJsonValue(obj,"receivedErrorPacketsAccumulated");\r
+                         vnic_use.recvd_error_packets_delta.encJsonValue(obj,"receivedErrorPacketsDelta");\r
+                         \r
+                         vnic_use.recvd_mcast_packets_acc.encJsonValue(obj,"receivedMulticastPacketsAccumulated");\r
+                         vnic_use.recvd_mcast_packets_delta.encJsonValue(obj,"receivedMulticastPacketsDelta");\r
+                         vnic_use.recvd_octets_acc.encJsonValue(obj,"receivedOctetsAccumulated");\r
+                         vnic_use.recvd_octets_delta.encJsonValue(obj,"receivedOctetsDelta");\r
+                         \r
+                         vnic_use.recvd_total_packets_acc.encJsonValue(obj,"receivedTotalPacketsAccumulated");\r
+                         vnic_use.recvd_total_packets_delta.encJsonValue(obj,"receivedTotalPacketsDelta");\r
+                         vnic_use.recvd_ucast_packets_acc.encJsonValue(obj,"receivedUnicastPacketsAccumulated");\r
+                         vnic_use.recvd_ucast_packets_delta.encJsonValue(obj,"receivedUnicastPacketsDelta");\r
+                         \r
+                         vnic_use.tx_bcast_packets_acc.encJsonValue(obj,"transmittedBroadcastPacketsAccumulated");\r
+                         vnic_use.tx_bcast_packets_delta.encJsonValue(obj,"transmittedBroadcastPacketsDelta");\r
+                         vnic_use.tx_discarded_packets_acc.encJsonValue(obj,"transmittedDiscardedPacketsAccumulated");\r
+                         vnic_use.tx_discarded_packets_delta.encJsonValue(obj,"transmittedDiscardedPacketsDelta");                       \r
+\r
+                         vnic_use.tx_error_packets_acc.encJsonValue(obj,"transmittedErrorPacketsAccumulated");\r
+                         vnic_use.tx_error_packets_delta.encJsonValue(obj,"transmittedErrorPacketsDelta");\r
+                         vnic_use.tx_mcast_packets_acc.encJsonValue(obj,"transmittedMulticastPacketsAccumulated");\r
+                         vnic_use.tx_mcast_packets_delta.encJsonValue(obj,"transmittedMulticastPacketsDelta");\r
+                         \r
+                         vnic_use.tx_octets_acc.encJsonValue(obj,"transmittedOctetsAccumulated");\r
+                         vnic_use.tx_octets_delta.encJsonValue(obj,"transmittedOctetsDelta");\r
+                         vnic_use.tx_total_packets_acc.encJsonValue(obj,"transmittedTotalPacketsAccumulated");\r
+                         vnic_use.tx_total_packets_delta.encJsonValue(obj,"transmittedTotalPacketsDelta");\r
+                         vnic_use.tx_ucast_packets_acc.encJsonValue(obj,"transmittedUnicastPacketsAccumulated");\r
+                         vnic_use.tx_ucast_packets_delta.encJsonValue(obj,"transmittedUnicastPacketsDelta");\r
+                                         \r
+                         builder.add(obj.build());\r
+                   }\r
+                       evelmeasmt.add("vNicUsageArray", builder);\r
+                 }  \r
+                 \r
+\r
+\r
+           /***************************************************************************/\r
+           /* Memory Use list.                                                           */\r
+           /***************************************************************************/ \r
+                 if( mem_usage != null && mem_usage.size() > 0 )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<mem_usage.size();i++) {\r
+                         mem_use = mem_usage.get(i);\r
+                         JsonObjectBuilder obj = Json.createObjectBuilder()\r
+                                             .add( "memIdentifier", mem_use.id)\r
+                                             .add( "vmIdentifier", mem_use.vmid)\r
+                                             .add( "percentUsage",mem_use.membuffsz);\r
+                         \r
+                         mem_use.memcache.encJsonValue(obj,"memoryCached");\r
+                         mem_use.memconfig.encJsonValue(obj,"memoryConfigured");\r
+                         mem_use.memfree.encJsonValue(obj,"memoryFree");\r
+                         mem_use.slabrecl.encJsonValue(obj,"memorySlabRecl");\r
+                         mem_use.slabunrecl.encJsonValue(obj,"memorySlabUnrecl");\r
+                         mem_use.memused.encJsonValue(obj,"memoryUsed");                                 \r
+                                         \r
+                         builder.add(obj.build());\r
+                   }\r
+                       evelmeasmt.add("memUsageArray", builder);\r
+                 }\r
+                 \r
+                 media_ports_in_use.encJsonValue(evelmeasmt, "numberOfMediaPortsInUse");\r
+                 vnfc_scaling_metric.encJsonValue(evelmeasmt, "vnfcScalingMetric");\r
+                 \r
+\r
+           /***************************************************************************/\r
+           /* myerrors list.                                                            */\r
+           /***************************************************************************/\r
+           if (errstat == true && myerrors != null) \r
+           {\r
+               evelmeasmt.add("receiveDiscards", myerrors.receive_discards);\r
+               evelmeasmt.add("receivemyerrors", myerrors.receive_myerrors);\r
+               evelmeasmt.add("transmitDiscards", myerrors.transmit_discards);\r
+               evelmeasmt.add("transmitmyerrors", myerrors.transmit_myerrors);\r
+           }\r
+\r
+           /***************************************************************************/\r
+           /* Feature Utilization list.                                               */\r
+           /***************************************************************************/\r
+                 if( feature_usage != null && feature_usage.size() > 0 )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<feature_usage.size();i++) {\r
+                         feature_use = feature_usage.get(i);\r
+                         JsonObjectBuilder obj = Json.createObjectBuilder()\r
+                                             .add( "featureIdentifier", feature_use.feature_id)\r
+                                             .add( "featureUtilization", feature_use.feature_utilization);                       \r
+                                         \r
+                         builder.add(obj.build());\r
+                   }\r
+                       evelmeasmt.add("featureUsageArray", builder);\r
+                 }\r
+\r
+\r
+           /***************************************************************************/\r
+           /* Codec Utilization list.                                                 */\r
+           /***************************************************************************/\r
+                 if( codec_usage != null && codec_usage.size() > 0 )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<codec_usage.size();i++) {\r
+                         codec_use = codec_usage.get(i);\r
+                         JsonObjectBuilder obj = Json.createObjectBuilder()\r
+                                             .add( "codecIdentifier", codec_use.codec_id)\r
+                                             .add( "numberInUse", codec_use.number_in_use);                      \r
+                                         \r
+                         builder.add(obj.build());\r
+                   }\r
+                       evelmeasmt.add("codecUsageArray", builder);\r
+                 }\r
+                 \r
+\r
+           /***************************************************************************/\r
+           /* Additional Measurement Groups list.                                     */\r
+           /***************************************************************************/\r
+                 if( additional_measurements != null && additional_measurements.size() > 0 )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<additional_measurements.size();i++) {\r
+                         meas_group = additional_measurements.get(i);\r
+                         JsonObjectBuilder obj = Json.createObjectBuilder()\r
+                                             .add( "name", meas_group.name);\r
+                         JsonArrayBuilder builder2 = Json.createArrayBuilder();\r
+                         for(int j=0;j<meas_group.measurements.size();j++) {\r
+                                 custom_meas = meas_group.measurements.get(j);\r
+                                 JsonObjectBuilder obj2 = Json.createObjectBuilder()\r
+                                                                   .add("name", custom_meas.name)\r
+                                                                   .add("value",custom_meas.value);\r
+                                 builder2.add(obj2.build());     \r
+                         }\r
+                         obj.add("measurements", builder2);\r
+                         builder.add(obj.build());\r
+                   }\r
+                       evelmeasmt.add("additionalMeasurements", builder);\r
+                 }\r
+                 \r
+                   /***************************************************************************/\r
+                   /* Additional Objects.                                                 */\r
+                   /***************************************************************************/\r
+             if( additional_objects != null && additional_objects.size() > 0 )\r
+                 {\r
+                           JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                           for(int i=0;i<additional_objects.size();i++) {\r
+                                 JsonObject jobj = additional_objects.get(i);\r
+                                 builder.add(jobj);\r
+                           }\r
+                               evelmeasmt.add("additionalObjects",builder);\r
+                 }\r
+\r
+           /***************************************************************************/\r
+           /* Although optional, we always generate the version.  Note that this      */\r
+           /* closes the object, too.                                                 */\r
+           /***************************************************************************/\r
+           evelmeasmt.add("measurementsForVfScalingVersion", version);\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return evelmeasmt;\r
+         }\r
+         \r
+         /**************************************************************************//**\r
+          * Encode the event as a JSON event object according to AT&T's schema.\r
+          *\r
+          * retval : String of JSON event message\r
+          *****************************************************************************/\r
+         String evel_json_encode_event()\r
+         {\r
+               EVEL_ENTER();\r
+               \r
+               assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_STATE_CHANGE);\r
+               //encode common event header and measurement body    \r
+           JsonObject obj = Json.createObjectBuilder()\r
+                    .add("event", Json.createObjectBuilder()\r
+                                .add( "commonEventHeader",eventHeaderObject() )\r
+                                .add( "measurementsForVfScalingFields",evelScalingMeasurementObject() )\r
+                                ).build();\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return obj.toString();\r
+\r
+         }\r
+\r
+\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelSipSignaling.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelSipSignaling.java
new file mode 100644 (file)
index 0000000..0dcab34
--- /dev/null
@@ -0,0 +1,558 @@
+package evel_javalibrary.att.com;\r
+\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel SIP Signalling class\r
+ *\r
+  * This file implements the Evel SIP Signaling Event class which is intended to provide a\r
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so\r
+ * that VNFs can use it to send SIP events.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+\r
+import javax.json.Json;\r
+import javax.json.JsonArrayBuilder;\r
+import javax.json.JsonObject;\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.slf4j.helpers.MessageFormatter;\r
+\r
+\r
+public class EvelSipSignaling extends EvelHeader {\r
+       \r
+       int major_version = 2;\r
+       int minor_version = 1;\r
+       \r
+       /**************************************************************************//**\r
+        * Vendor VNF Name fields.\r
+        * JSON equivalent field: vendorVnfNameFields\r
+        *****************************************************************************/\r
+       public class VENDOR_VNFNAME_FIELD {\r
+         String vendorname;\r
+         EvelOptionString vfmodule;\r
+         EvelOptionString vnfname;\r
+       }\r
+       \r
+       /***************************************************************************/\r
+       /* Mandatory fields                                                        */\r
+       /***************************************************************************/\r
+         VENDOR_VNFNAME_FIELD vnfname_field;\r
+         String correlator;                         /* JSON: correlator */\r
+         String local_ip_address;               /* JSON: localIpAddress */\r
+         String local_port;                          /* JSON: localPort */\r
+         String remote_ip_address;             /* JSON: remoteIpAddress */\r
+         String remote_port;                        /* JSON: remotePort */\r
+                 \r
+         /***************************************************************************/\r
+         /* Optional fields                                                         */\r
+         /***************************************************************************/\r
+         ArrayList<String[]> additional_info;\r
+         EvelOptionString compressed_sip;                  /* JSON: compressedSip */\r
+         EvelOptionString summary_sip;                        /* JSON: summarySip */\r
+\r
+\r
+       /***************************************************************************/\r
+       /* Optional fields                                                         */\r
+       /***************************************************************************/\r
+\r
+         private static final Logger LOGGER = Logger.getLogger( EvelSipSignaling.class.getName() );\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Create a new SIP Signaling event.\r
+          * @param corlator  Correlator value\r
+          * @param locip_address  Local IP address\r
+          * @param loc_port       Local Port\r
+          * @param remip_address   Remote IP address\r
+          * @param rem_port        Remote Port\r
+          *\r
+          *****************************************************************************/\r
+         public EvelSipSignaling(String evname,String evid,\r
+                         String vendr_name,\r
+              String corlator,\r
+              String locip_address,\r
+              String loc_port,\r
+              String remip_address,\r
+              String rem_port)\r
+         {//Init header\r
+        super(evname,evid);\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(vendr_name != null);\r
+           assert(corlator != null);\r
+           assert(locip_address != null);\r
+           assert(loc_port != null);\r
+           \r
+           assert(remip_address != null);\r
+           assert(rem_port != null);\r
+\r
+           LOGGER.debug("New SipSignaling vendor "+vendr_name+" correlator"+corlator+"local_ip_address"+locip_address+"local port"+loc_port+"remote ip address"+remip_address+"remote port"+rem_port);\r
+\r
+           /***************************************************************************/\r
+           /* Initialize the header & the Domain                        */\r
+           /***************************************************************************/\r
+           event_domain = EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING;\r
+           /***************************************************************************/\r
+           /* Initialize mandatory fields                       */\r
+           /***************************************************************************/\r
+           \r
+           correlator = corlator;\r
+               local_ip_address = locip_address;\r
+               local_port = loc_port;\r
+               remote_ip_address = remip_address;\r
+               remote_port = rem_port;\r
+               \r
+           /***************************************************************************/\r
+           /* Optional fields.                                                    */\r
+           /***************************************************************************/\r
+               \r
+               vnfname_field = new VENDOR_VNFNAME_FIELD();\r
+               vnfname_field.vendorname = vendr_name;\r
+               vnfname_field.vfmodule = new EvelOptionString();\r
+               vnfname_field.vnfname = new EvelOptionString();\r
+\r
+           additional_info = null;\r
+           compressed_sip = new EvelOptionString();\r
+           summary_sip = new EvelOptionString();\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Event Type property of the SIP signaling.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+       * @param type        The Event Type to be set. ASCIIZ string. The caller\r
+          *                    does not need to preserve the value once the function\r
+          *                    returns.\r
+          *****************************************************************************/\r
+          public void evel_signaling_type_set(String typ)\r
+         {\r
+           EVEL_ENTER();\r
+           assert(typ != null);\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions and call evel_header_type_set.                      */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+           evel_header_type_set(typ);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Local Ip Address property of the Signaling event.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param local_ip_address\r
+          *                      The Local Ip Address to be set. ASCIIZ string. The\r
+          *                      caller does not need to preserve the value once the\r
+          *                      function returns.\r
+          *****************************************************************************/\r
+         public  void evel_signaling_local_ip_address_set(\r
+                                                  String loc_ip_address)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(loc_ip_address != null);\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+           LOGGER.debug("Setting SipSignaling Local IP "+loc_ip_address);\r
+\r
+           local_ip_address = loc_ip_address;\r
+\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Local Port property of the Signaling event.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param local_port    The Local Port to be set. ASCIIZ string. The caller\r
+          *                      does not need to preserve the value once the function\r
+          *                      returns.\r
+          *****************************************************************************/\r
+         public  void evel_signaling_local_port_set(String loc_port)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(loc_port != null);\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+           LOGGER.debug("Setting SipSignaling Local Port "+loc_port);\r
+\r
+           local_port = loc_port;\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Remote Ip Address property of the Signaling event.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param remote_ip_address\r
+          *                      The Remote Ip Address to be set. ASCIIZ string. The\r
+          *                      caller does not need to preserve the value once the\r
+          *                      function returns.\r
+          *****************************************************************************/\r
+         public  void evel_signaling_remote_ip_address_set(String remip_address)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(remip_address != null);\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+           LOGGER.debug("Setting SipSignaling Remote IP Address "+remip_address);\r
+\r
+           remote_ip_address = remip_address;\r
+           \r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Remote Port property of the Signaling event.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param remote_port   The Remote Port to be set. ASCIIZ string. The caller\r
+          *                      does not need to preserve the value once the function\r
+          *                      returns.\r
+          *****************************************************************************/\r
+         public  void evel_signaling_remote_port_set(String rem_port)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(rem_port != null);\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+           LOGGER.debug("Setting SipSignaling Remote Port "+rem_port);\r
+\r
+           remote_port = rem_port;\r
+           \r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Vendor module property of the Signaling event.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param modulename    The module name to be set. ASCIIZ string. The caller\r
+          *                      does not need to preserve the value once the function\r
+          *                      returns.\r
+          *****************************************************************************/\r
+         public  void evel_signaling_vnfmodule_name_set(String module_name)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(module_name != null);\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+           LOGGER.debug("Setting SipSignaling Module Name "+module_name);\r
+           \r
+           vnfname_field.vfmodule.SetValue(module_name);\r
+           \r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Vendor module property of the Signaling event.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param vnfname       The Virtual Network function to be set. ASCIIZ string.\r
+          *                      The caller does not need to preserve the value once\r
+          *                    the function returns.\r
+          *****************************************************************************/\r
+         public void evel_signaling_vnfname_set(String vnfname)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(vnfname != null);\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+           LOGGER.debug("Setting SipSignaling VNF Name "+vnfname);\r
+           \r
+           vnfname_field.vnfname.SetValue(vnfname);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Compressed SIP property of the Signaling event.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param compressed_sip\r
+          *                      The Compressed SIP to be set. ASCIIZ string. The caller\r
+          *                      does not need to preserve the value once the function\r
+          *                      returns.\r
+          *****************************************************************************/\r
+         public  void evel_signaling_compressed_sip_set(String compr_sip)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(compr_sip != null);\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+           LOGGER.debug("Setting SipSignaling Compressed SIP "+compr_sip);\r
+           \r
+           compressed_sip.SetValue(compr_sip);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Summary SIP property of the Signaling event.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param summary_sip   The Summary SIP to be set. ASCIIZ string. The caller\r
+          *                      does not need to preserve the value once the function\r
+          *                      returns.\r
+          *****************************************************************************/\r
+         public void evel_signaling_summary_sip_set(String summ_sip)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(summ_sip != null);\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+           LOGGER.debug("Setting SipSignaling Summary SIP "+summ_sip);\r
+           \r
+           summary_sip.SetValue(summ_sip);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Correlator property of the Signaling event.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param correlator    The correlator to be set. ASCIIZ string. The caller\r
+          *                      does not need to preserve the value once the function\r
+          *                      returns.\r
+          *****************************************************************************/\r
+         public void evel_signaling_correlator_set(String corlator)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions and call evel_header_type_set.                      */\r
+           /***************************************************************************/\r
+           assert(corlator != null);\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+           LOGGER.debug("Setting Correlator "+corlator);\r
+           \r
+           correlator = corlator;\r
+           \r
+           EVEL_EXIT();\r
+         }\r
+         \r
+         /**************************************************************************//**\r
+          * Add an additional value name/value pair to the Signaling.\r
+          *\r
+          * The name and value are null delimited ASCII strings.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * @param name      ASCIIZ string with the attribute's name.  The caller\r
+          *                  does not need to preserve the value once the function\r
+          *                  returns.\r
+          * @param value     ASCIIZ string with the attribute's value.  The caller\r
+          *                  does not need to preserve the value once the function\r
+          *                  returns.\r
+          *****************************************************************************/\r
+         public void evel_signaling_addl_info_add(String name, String value)\r
+               {\r
+                 String[] addl_info = null;\r
+                 EVEL_ENTER();\r
+\r
+                 /***************************************************************************/\r
+                 /* Check preconditions.                                                    */\r
+                 /***************************************************************************/\r
+                 assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+                 assert(name != null);\r
+                 assert(value != null);\r
+                 \r
+                 if( additional_info == null )\r
+                 {\r
+                         additional_info = new ArrayList<String[]>();\r
+                 }\r
+\r
+                 LOGGER.debug(MessageFormat.format("Adding name={0} value={1}", name, value));\r
+                 addl_info = new String[2];\r
+                 assert(addl_info != null);\r
+                 addl_info[0] = name;\r
+                 addl_info[1] = value;\r
+\r
+                 additional_info.add(addl_info);\r
+\r
+                 EVEL_EXIT();\r
+               }\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Encode SIP Signaling Object according to VES schema\r
+          *\r
+          * @retval JSON Object of SIP event\r
+          *****************************************************************************/\r
+         JsonObjectBuilder evelSipSignalingObject()\r
+         {\r
+\r
+           double version = major_version+(double)minor_version/10;\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+\r
+           /***************************************************************************/\r
+           /* Mandatory fields.                                                       */\r
+           /***************************************************************************/\r
+           \r
+        JsonObjectBuilder vnfnamedobj =  Json.createObjectBuilder()\r
+                .add( "vendorName",vnfname_field.vendorname);\r
+            vnfname_field.vfmodule.encJsonValue(vnfnamedobj,"vfModuleName");\r
+            vnfname_field.vfmodule.encJsonValue(vnfnamedobj,"vnfName");\r
+           \r
+           JsonObjectBuilder evelsip = Json.createObjectBuilder()\r
+                                         .add("correlator", correlator)\r
+                                         .add("localIpAddress", local_ip_address)\r
+                                         .add("localPort", local_port)\r
+                                  .add("remoteIpAddress", remote_ip_address)\r
+                                  .add("remotePort", remote_port)\r
+                                  .add("vendorVnfNamedFields", vnfnamedobj);\r
+                                    \r
+           \r
+           /***************************************************************************/\r
+           /* Optional fields.                                                        */\r
+           /***************************************************************************/\r
+           compressed_sip.encJsonValue(evelsip, "compressedSip");\r
+           summary_sip.encJsonValue(evelsip, "summarySip");\r
+           \r
+           \r
+           // additional fields\r
+                 if( additional_info != null )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<additional_info.size();i++) {\r
+                         String[] addl_info = additional_info.get(i);\r
+                         JsonObject obj = Json.createObjectBuilder()\r
+                                    .add("name", addl_info[0])\r
+                                    .add("value", addl_info[1]).build();\r
+                         builder.add(obj);\r
+                   }\r
+                       evelsip.add("additionalFields", builder);\r
+                 }\r
+           \r
+\r
+           /***************************************************************************/\r
+           /* Although optional, we always generate the version.  Note that this      */\r
+           /* closes the object, too.                                                 */\r
+           /***************************************************************************/\r
+           evelsip.add("signalingFieldsVersion", version);\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return evelsip;\r
+         }\r
+         \r
+         /**************************************************************************//**\r
+          * Encode the event as a JSON event object according to AT&T's schema.\r
+          *\r
+          * retval : String of JSON event message\r
+          *****************************************************************************/\r
+         String evel_json_encode_event()\r
+         {\r
+               EVEL_ENTER();\r
+               \r
+               assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SIPSIGNALING);\r
+           //encode commonheader and sip signaling body fields    \r
+           JsonObject obj = Json.createObjectBuilder()\r
+                    .add("event", Json.createObjectBuilder()\r
+                                .add( "commonEventHeader",eventHeaderObject() )\r
+                                .add( "signalingFields",evelSipSignalingObject() )\r
+                                ).build();\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return obj.toString();\r
+\r
+         }\r
+\r
+\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelStateChange.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelStateChange.java
new file mode 100644 (file)
index 0000000..817b283
--- /dev/null
@@ -0,0 +1,258 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel State Change class\r
+ *\r
+  * This file implements the Evel State Change Event class which is intended to provide a\r
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so\r
+ * that VNFs can use it to send Agent State change events.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+\r
+import javax.json.Json;\r
+import javax.json.JsonArrayBuilder;\r
+import javax.json.JsonObject;\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.slf4j.helpers.MessageFormatter;\r
+\r
+import evel_javalibrary.att.com.EvelFault.EVEL_SEVERITIES;\r
+\r
+\r
+public class EvelStateChange extends EvelHeader {\r
+       \r
+       int major_version = 1;\r
+       int minor_version = 2;\r
+       \r
+       /**************************************************************************//**\r
+        * Alert types.\r
+        * JSON equivalent fields: newState, oldState\r
+        *****************************************************************************/\r
+       public enum EVEL_ENTITY_STATE{\r
+         EVEL_ENTITY_STATE_IN_SERVICE,\r
+         EVEL_ENTITY_STATE_MAINTENANCE,\r
+         EVEL_ENTITY_STATE_OUT_OF_SERVICE,\r
+         EVEL_MAX_ENTITY_STATES\r
+       }\r
+       \r
+       /***************************************************************************/\r
+       /* Mandatory fields                                                        */\r
+       /***************************************************************************/\r
+         EVEL_ENTITY_STATE new_state;\r
+         EVEL_ENTITY_STATE old_state;\r
+         String state_interface;\r
+\r
+       /***************************************************************************/\r
+       /* Optional fields                                                         */\r
+       /***************************************************************************/\r
+         ArrayList<String[]> additional_info;\r
+       \r
+         private static final Logger LOGGER = Logger.getLogger( EvelStateChange.class.getName() );\r
+\r
+         /**************************************************************************//**\r
+          * Create a new State Change event.\r
+          *\r
+          * @note    The mandatory fields on the State Change must be supplied to this\r
+          *          factory function and are immutable once set.  Optional fields have\r
+          *          explicit setter functions, but again values may only be set once\r
+          *          so that the State Change has immutable properties.\r
+          *\r
+          * @param new_state     The new state of the reporting entity.\r
+          * @param old_state     The old state of the reporting entity.\r
+          * @param interface     The card or port name of the reporting entity.\r
+          *\r
+          *****************************************************************************/\r
+       public EvelStateChange(String evname, String evid,\r
+                                      EVEL_ENTITY_STATE newstate,\r
+                           EVEL_ENTITY_STATE oldstate,\r
+                           String interfce)\r
+       {\r
+               super(evname,evid);\r
+               event_domain = EvelHeader.DOMAINS.EVEL_DOMAIN_STATE_CHANGE;\r
+               assert(EVEL_ENTITY_STATE.EVEL_MAX_ENTITY_STATES.compareTo(newstate) < 0 );\r
+               assert(EVEL_ENTITY_STATE.EVEL_MAX_ENTITY_STATES.compareTo(oldstate) < 0 );\r
+               assert( interfce != null);\r
+               \r
+               new_state = newstate;\r
+               old_state = oldstate;\r
+               state_interface = interfce;\r
+\r
+               additional_info = null;         \r
+       }\r
+       \r
+       /**************************************************************************//**\r
+        * Add an additional value name/value pair to the Fault.\r
+        *\r
+        * The name and value are null delimited ASCII strings.  The library takes\r
+        * a copy so the caller does not have to preserve values after the function\r
+        * returns.\r
+        *\r
+        * @param name      ASCIIZ string with the attribute's name.  The caller\r
+        *                  does not need to preserve the value once the function\r
+        *                  returns.\r
+        * @param value     ASCIIZ string with the attribute's value.  The caller\r
+        *                  does not need to preserve the value once the function\r
+        *                  returns.\r
+        *****************************************************************************/\r
+       public void evel_statechange_addl_info_add(String name, String value)\r
+       {\r
+         String[] addl_info = null;\r
+         EVEL_ENTER();\r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions.                                                    */\r
+         /***************************************************************************/\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_STATE_CHANGE);\r
+         assert(name != null);\r
+         assert(value != null);\r
+         \r
+         if( additional_info == null )\r
+         {\r
+                 additional_info = new ArrayList<String[]>();\r
+         }\r
+\r
+         LOGGER.debug(MessageFormat.format("Adding name={0} value={1}", name, value));\r
+         addl_info = new String[2];\r
+         assert(addl_info != null);\r
+         addl_info[0] = name;\r
+         addl_info[1] = value;\r
+\r
+         additional_info.add(addl_info);\r
+\r
+         EVEL_EXIT();\r
+       }\r
+       \r
+       /**************************************************************************//**\r
+        * Convert a ::EVEL_ENTITY_STATE to it's string form for JSON encoding.\r
+        *\r
+        * @param state         The entity state to encode.\r
+        *\r
+        * @returns the corresponding string\r
+        *****************************************************************************/\r
+       String evel_entity_state(EVEL_ENTITY_STATE state)\r
+       {\r
+         String result=null;\r
+\r
+         EVEL_ENTER();\r
+\r
+         switch (state)\r
+         {\r
+           case EVEL_ENTITY_STATE_IN_SERVICE:\r
+             result = "inService";\r
+             break;\r
+\r
+           case EVEL_ENTITY_STATE_MAINTENANCE:\r
+             result = "maintenance";\r
+             break;\r
+\r
+           case EVEL_ENTITY_STATE_OUT_OF_SERVICE:\r
+             result = "outOfService";\r
+             break;\r
+\r
+           default:\r
+             LOGGER.error("Unexpected entity state "+state);\r
+             System.exit(1);\r
+         }\r
+\r
+         EVEL_EXIT();\r
+\r
+         return result;\r
+       }\r
+\r
+\r
+       /**************************************************************************//**\r
+        * Encode the State Change in JSON according to AT&T's schema.\r
+        *\r
+        *****************************************************************************/\r
+        JsonObjectBuilder evelStateChangeObject()\r
+        {\r
+         String nstate;\r
+         String ostate;\r
+         double version = major_version+(double)minor_version/10;\r
+\r
+         EVEL_ENTER();\r
+         \r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions.                                                    */\r
+         /***************************************************************************/\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_STATE_CHANGE);\r
+\r
+\r
+\r
+         /***************************************************************************/\r
+         /* Mandatory fields.                                                       */\r
+         /***************************************************************************/\r
+      nstate = evel_entity_state(new_state);\r
+      ostate = evel_entity_state(old_state);\r
+         \r
+         JsonObjectBuilder evelstate = Json.createObjectBuilder()\r
+                        .add("newState", nstate)\r
+                        .add("oldState", ostate)\r
+                        .add("stateInterface", state_interface);\r
+         \r
+         evelstate.add( "stateChangeFieldsVersion", version);\r
+\r
+         /***************************************************************************/\r
+         /* Optional additional information      */\r
+         /***************************************************************************/\r
+         if( additional_info != null )\r
+         {\r
+           JsonArrayBuilder builder = Json.createArrayBuilder();\r
+           for(int i=0;i<additional_info.size();i++) {\r
+                 String[] addl_info = additional_info.get(i);\r
+                 JsonObject obj = Json.createObjectBuilder()\r
+                            .add("name", addl_info[0])\r
+                            .add("value", addl_info[1]).build();\r
+                 builder.add(obj);\r
+           }\r
+               evelstate.add("additionalFields", builder);\r
+         }\r
+\r
+         EVEL_EXIT();\r
+         \r
+         return evelstate;\r
+       }\r
+       \r
+       \r
+         /**************************************************************************//**\r
+          * Encode the event as a JSON event object according to AT&T's schema.\r
+          * retval : String of JSON state change event message\r
+          *****************************************************************************/\r
+         String evel_json_encode_event()\r
+         {\r
+               EVEL_ENTER();\r
+               \r
+               assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_STATE_CHANGE);\r
+           //encode header and state change fields    \r
+           JsonObject obj = Json.createObjectBuilder()\r
+                    .add("event", Json.createObjectBuilder()\r
+                                .add( "commonEventHeader",eventHeaderObject() )\r
+                                .add( "stateChangeFields",evelStateChangeObject() )\r
+                                ).build();\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return obj.toString();\r
+\r
+         }\r
+       \r
+\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelSyslog.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelSyslog.java
new file mode 100644 (file)
index 0000000..272ff3a
--- /dev/null
@@ -0,0 +1,486 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Syslog class\r
+ *\r
+  * This file implements the Evel Syslog Event class which is intended to provide a\r
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so\r
+ * that VNFs can use it to send Syslog events.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+\r
+import javax.json.Json;\r
+import javax.json.JsonArrayBuilder;\r
+import javax.json.JsonObject;\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.slf4j.helpers.MessageFormatter;\r
+\r
+import evel_javalibrary.att.com.EvelFault.EVEL_SEVERITIES;\r
+\r
+\r
+public class EvelSyslog extends EvelHeader {\r
+       \r
+       int major_version = 1;\r
+       int minor_version = 2;\r
+       \r
+       /**************************************************************************//**\r
+        * Alert types.\r
+        * JSON equivalent fields: newState, oldState\r
+        *****************************************************************************/\r
+       /**************************************************************************//**\r
+        * Syslog facilities.\r
+        * JSON equivalent field: syslogFacility\r
+        *****************************************************************************/\r
+       public enum EVEL_SYSLOG_FACILITIES{\r
+         EVEL_SYSLOG_FACILITY_KERNEL,\r
+         EVEL_SYSLOG_FACILITY_USER,\r
+         EVEL_SYSLOG_FACILITY_MAIL,\r
+         EVEL_SYSLOG_FACILITY_SYSTEM_DAEMON,\r
+         EVEL_SYSLOG_FACILITY_SECURITY_AUTH,\r
+         EVEL_SYSLOG_FACILITY_INTERNAL,\r
+         EVEL_SYSLOG_FACILITY_LINE_PRINTER,\r
+         EVEL_SYSLOG_FACILITY_NETWORK_NEWS,\r
+         EVEL_SYSLOG_FACILITY_UUCP,\r
+         EVEL_SYSLOG_FACILITY_CLOCK_DAEMON,\r
+         EVEL_SYSLOG_FACILITY_SECURITY_AUTH2,\r
+         EVEL_SYSLOG_FACILITY_FTP_DAEMON,\r
+         EVEL_SYSLOG_FACILITY_NTP,\r
+         EVEL_SYSLOG_FACILITY_LOG_AUDIT,\r
+         EVEL_SYSLOG_FACILITY_LOG_ALERT,\r
+         EVEL_SYSLOG_FACILITY_CLOCK_DAEMON2,\r
+         EVEL_SYSLOG_FACILITY_LOCAL0,\r
+         EVEL_SYSLOG_FACILITY_LOCAL1,\r
+         EVEL_SYSLOG_FACILITY_LOCAL2,\r
+         EVEL_SYSLOG_FACILITY_LOCAL3,\r
+         EVEL_SYSLOG_FACILITY_LOCAL4,\r
+         EVEL_SYSLOG_FACILITY_LOCAL5,\r
+         EVEL_SYSLOG_FACILITY_LOCAL6,\r
+         EVEL_SYSLOG_FACILITY_LOCAL7,\r
+         EVEL_MAX_SYSLOG_FACILITIES\r
+       }\r
+\r
+\r
+       \r
+       /***************************************************************************/\r
+       /* Mandatory fields                                                        */\r
+       /***************************************************************************/\r
+         EvelFault.EVEL_SOURCE_TYPES event_source_type;\r
+         String syslog_msg;\r
+         String syslog_tag;\r
+\r
+       /***************************************************************************/\r
+       /* Optional fields                                                         */\r
+       /***************************************************************************/\r
+         EvelOptionString additional_filters;\r
+         EvelOptionString event_source_host;\r
+         EvelOptionInt syslog_facility;\r
+         EvelOptionInt syslog_priority;\r
+         EvelOptionString syslog_proc;\r
+         EvelOptionInt syslog_proc_id;\r
+         EvelOptionString syslog_s_data;\r
+         EvelOptionString syslog_sdid;\r
+         EvelOptionString syslog_severity;\r
+         double syslog_fver;\r
+         EvelOptionInt syslog_ver;\r
+\r
+       \r
+         private static final Logger LOGGER = Logger.getLogger( EvelSyslog.class.getName() );\r
+\r
+         /**************************************************************************//**\r
+          * Create a new Syslog event.\r
+          *\r
+          *\r
+          * @param syslg_msg     The Syslog message string.\r
+          * @param syslg_tag     The Syslog tag string.\r
+          * @param interface     The card or port name of the reporting entity.\r
+          *\r
+          *****************************************************************************/\r
+       public EvelSyslog(String evname, String evid,\r
+                                 EvelFault.EVEL_SOURCE_TYPES evt_source_type,\r
+                      String syslg_msg,\r
+                      String syslg_tag)\r
+       {\r
+               super(evname,evid);\r
+               event_domain = EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG;\r
+           assert(EvelFault.EVEL_SOURCE_TYPES.EVEL_MAX_SOURCE_TYPES.compareTo(event_source_type) < 0);\r
+           assert(syslog_msg != null);\r
+           assert(syslog_tag != null);\r
+\r
+           event_source_type = evt_source_type;\r
+           syslog_msg = syslg_msg;\r
+           syslog_tag = syslg_tag;\r
+           syslog_facility = new EvelOptionInt();\r
+           syslog_priority = new EvelOptionInt();\r
+           syslog_proc_id = new EvelOptionInt();\r
+           syslog_ver = new EvelOptionInt();\r
+           additional_filters = new EvelOptionString();\r
+           event_source_host = new EvelOptionString();\r
+           syslog_proc = new EvelOptionString();\r
+           syslog_s_data = new EvelOptionString();\r
+           syslog_sdid = new EvelOptionString();\r
+           syslog_severity = new EvelOptionString();   \r
+       }         \r
+         \r
+         /**************************************************************************//**\r
+          * Set the Event Type property of the Syslog.\r
+          *\r
+          * @param type        The Event Type to be set. ASCIIZ string. The caller\r
+          *                    does not need to preserve the value once the function\r
+          *                    returns.\r
+          *****************************************************************************/\r
+         public void evel_syslog_type_set(String typ)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions and call evel_header_type_set.                      */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG);\r
+           evel_header_type_set(typ);\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add an additional value name/value pair to the Syslog.\r
+          *\r
+          * The name and value are null delimited ASCII strings.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * \r
+          * @param name      ASCIIZ string with the attribute's name.  The caller\r
+          *                  does not need to preserve the value once the function\r
+          *                  returns.\r
+          * @param value     ASCIIZ string with the attribute's value.  The caller\r
+          *                  does not need to preserve the value once the function\r
+          *                  returns.\r
+          *****************************************************************************/\r
+         public void evel_syslog_addl_filter_set(String filter)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG);\r
+           assert(filter != null);\r
+\r
+           additional_filters.SetValuePr(\r
+                                  filter,\r
+                                  "Syslog filter string");\r
+\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Event Source Host property of the Syslog.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param host       The Event Source Host to be set. ASCIIZ string. The caller\r
+          *                   does not need to preserve the value once the function\r
+          *                   returns.\r
+          *****************************************************************************/\r
+         public void evel_syslog_event_source_host_set(String host)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG);\r
+           assert(host != null);\r
+\r
+           event_source_host.SetValuePr(\r
+                                  host,\r
+                                  "Event Source Host");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Facility property of the Syslog.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * @param syslog      Pointer to the Syslog.\r
+          * @param facility    The Syslog Facility to be set.  ASCIIZ string. The caller\r
+          *                    does not need to preserve the value once the function\r
+          *                    returns.\r
+          *****************************************************************************/\r
+         public void evel_syslog_facility_set(\r
+                                       EVEL_SYSLOG_FACILITIES facility)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG);\r
+           assert(facility.compareTo(EVEL_SYSLOG_FACILITIES.EVEL_MAX_SYSLOG_FACILITIES) < 0);\r
+           int num = facility.compareTo(EVEL_SYSLOG_FACILITIES.EVEL_SYSLOG_FACILITY_KERNEL);\r
+\r
+           syslog_facility.SetValuePr(\r
+                               num,\r
+                               "Facility");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Process property of the Syslog.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param proc       The Process to be set. ASCIIZ string. The caller does not\r
+          *                   need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_syslog_proc_set(String proc)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG);\r
+           assert(proc != null);\r
+\r
+           syslog_proc.SetValuePr(proc, "Process");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Process ID property of the Syslog.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param proc_id    The Process ID to be set. ASCIIZ string. The caller does\r
+          *                   not need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_syslog_proc_id_set(int proc_id)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG);\r
+           assert(proc_id > 0);\r
+\r
+           syslog_proc_id.SetValuePr(\r
+                               proc_id,\r
+                               "Process ID");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Version property of the Syslog.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param version    The Version to be set. ASCIIZ string. The caller does not\r
+          *                   need to preserve the value once the function returns.\r
+          *****************************************************************************/\r
+         public void evel_syslog_version_set(int version)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG);\r
+           assert(version >= 0);\r
+\r
+           syslog_ver.SetValuePr(\r
+                               version,\r
+                               "Version");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Structured Data property of the Syslog.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param s_data     The Structured Data to be set. ASCIIZ string. The caller\r
+          *                   does not need to preserve the value once the function\r
+          *                   returns.\r
+          *****************************************************************************/\r
+         public void evel_syslog_s_data_set(String s_data)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG);\r
+           assert(s_data != null);\r
+\r
+           syslog_s_data.SetValuePr(\r
+                                  s_data,\r
+                                  "Structured Data");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Structured SDID property of the Syslog.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param sdid     The Structured Data to be set. ASCIIZ string. name@number\r
+          *                 Caller does not need to preserve the value once the function\r
+          *                   returns.\r
+          *****************************************************************************/\r
+         public void evel_syslog_sdid_set(String sdid)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG);\r
+           assert(sdid != null);\r
+\r
+           syslog_sdid.SetValuePr(\r
+                                  sdid,\r
+                                  "SdId set");\r
+           EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Structured Severity property of the Syslog.\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param sdid     The Structured Data to be set. ASCIIZ string. \r
+          *                 Caller does not need to preserve the value once the function\r
+          *                   returns.\r
+          *****************************************************************************/\r
+         public void evel_syslog_severity_set(String severty)\r
+         {\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG);\r
+           assert(severty != null);\r
+\r
+           if( severty.equals("Alert") || severty.equals("Critical") || severty.equals("Debug") ||\r
+                       severty.equals("Emergency") || severty.equals("Error") || severty.equals("Info") ||\r
+                       severty.equals("Notice") || severty.equals("Warning") )\r
+           {\r
+              syslog_severity.SetValuePr(\r
+                                  severty,\r
+                                  "Severity set");\r
+           }\r
+           EVEL_EXIT();\r
+         }\r
+       \r
+         \r
+               /**************************************************************************//**\r
+                * Encode the Syslog in JSON according to AT&T's schema.\r
+                *\r
+                *****************************************************************************/\r
+                JsonObjectBuilder evelSyslogObject()\r
+                {\r
+                 String evt_source_type;\r
+                 double version = major_version+(double)minor_version/10;\r
+\r
+                 EVEL_ENTER();\r
+                 \r
+                 assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG);\r
+                 \r
+                 /***************************************************************************/\r
+                 /* Mandatory fields                                                        */\r
+                 /***************************************************************************/\r
+                 JsonObjectBuilder obj = Json.createObjectBuilder()\r
+                                .add("eventSourceType", event_source_type.toString())\r
+                                .add("syslogMsg", syslog_msg)\r
+                                .add("syslogTag", syslog_tag)\r
+                                .add("syslogFieldsVersion",version);\r
+\r
+                 /***************************************************************************/\r
+                 /* Optional fields                                                         */\r
+                 /***************************************************************************/\r
+                 event_source_host.encJsonValue(obj, "eventSourceHost");\r
+                 syslog_facility.encJsonValue(obj,"syslogFacility");\r
+                 syslog_priority.encJsonValue(obj,"syslogPri");\r
+                 syslog_proc.encJsonValue(obj, "syslogProc");\r
+                 syslog_proc_id.encJsonValue(obj, "syslogProcId");\r
+                 syslog_s_data.encJsonValue(obj, "syslogSData");\r
+                 syslog_sdid.encJsonValue(obj, "syslogSdId");\r
+                 syslog_severity.encJsonValue(obj, "syslogSev");\r
+                 syslog_ver.encJsonValue(obj, "syslogVer");\r
+\r
+                 EVEL_EXIT();\r
+                 \r
+                 return obj;\r
+               }       \r
+       \r
+       /**************************************************************************//**\r
+     * Encode the event as a JSON event object according to AT&T's schema.\r
+     * retval : String of JSON syslog event message\r
+     *****************************************************************************/\r
+         String evel_json_encode_event()\r
+         {\r
+               EVEL_ENTER();\r
+               \r
+               assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_SYSLOG);\r
+               \r
+           JsonObject obj = Json.createObjectBuilder()\r
+                    .add("event", Json.createObjectBuilder()\r
+                                .add( "commonEventHeader",eventHeaderObject() )\r
+                                .add( "syslogFields",evelSyslogObject() )\r
+                                ).build();\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return obj.toString();\r
+\r
+         }\r
+         \r
+         \r
+       \r
+\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelThresholdCross.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelThresholdCross.java
new file mode 100644 (file)
index 0000000..1a1b1f0
--- /dev/null
@@ -0,0 +1,502 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Threshold Crossing event class\r
+ *\r
+  * This file implements the Evel Threshold Crossing event class which is intended to provide a\r
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so\r
+ * that VNFs can use it to send Threshold Crossing Alert events.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+\r
+import javax.json.Json;\r
+import javax.json.JsonArrayBuilder;\r
+import javax.json.JsonObject;\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+import evel_javalibrary.att.com.EvelMobileFlow.MOBILE_GTP_PER_FLOW_METRICS;\r
+\r
+\r
+public class EvelThresholdCross extends EvelHeader {\r
+       \r
+       \r
+       int major_version = 1;\r
+       int minor_version = 1;\r
+       \r
+       /**************************************************************************//**\r
+        * Alert types.\r
+        * JSON equivalent fields: newState, oldState\r
+        *****************************************************************************/\r
+       public enum EVEL_EVENT_ACTION {\r
+                 EVEL_EVENT_ACTION_CLEAR,\r
+                 EVEL_EVENT_ACTION_CONTINUE,\r
+                 EVEL_EVENT_ACTION_SET,\r
+                 EVEL_MAX_EVENT_ACTION\r
+       }\r
+       \r
+       public enum EVEL_ALERT_TYPE {\r
+                        EVEL_CARD_ANOMALY, \r
+                    EVEL_ELEMENT_ANOMALY, \r
+                    EVEL_INTERFACE_ANOMALY, \r
+                        EVEL_SERVICE_ANOMALY,\r
+                 EVEL_MAX_ANOMALY\r
+       }\r
+       \r
+       public enum EVEL_SEVERITIES{\r
+                 EVEL_SEVERITY_CRITICAL,\r
+                 EVEL_SEVERITY_MAJOR,\r
+                 EVEL_SEVERITY_MINOR,\r
+                 EVEL_SEVERITY_WARNING,\r
+                 EVEL_SEVERITY_NORMAL,\r
+                 EVEL_MAX_SEVERITIES\r
+               }\r
+\r
+       \r
+       /***************************************************************************/\r
+       /* Mandatory fields                                                        */\r
+       /***************************************************************************/\r
+\r
+       public class PERF_COUNTER {\r
+               String criticality;\r
+               String name;\r
+               String thresholdCrossed;\r
+               String value;\r
+       }\r
+       \r
+       PERF_COUNTER       additionalParameters;\r
+       EVEL_EVENT_ACTION  alertAction;\r
+    String             alertDescription; \r
+    EVEL_ALERT_TYPE    alertType;\r
+    Date               collectionTimestamp; \r
+    EVEL_SEVERITIES    eventSeverity;\r
+    Date               eventStartTimestamp;\r
+\r
+\r
+       /***************************************************************************/\r
+       /* Optional fields                                                         */\r
+       /***************************************************************************/\r
+    ArrayList<String[]> additional_info;\r
+    EvelOptionString    alertValue;\r
+    ArrayList<String>   alertidList;\r
+    EvelOptionString    dataCollector;\r
+    EvelOptionString    elementType;\r
+    EvelOptionString    interfaceName;\r
+    EvelOptionString    networkService;\r
+    EvelOptionString    possibleRootCause;\r
+\r
+       \r
+       private static final Logger LOGGER = Logger.getLogger( EvelThresholdCross.class.getName() );\r
+\r
+         /**************************************************************************//**\r
+          * Create a new Threshold Crossing event.\r
+          *\r
+          *\r
+          * @param String tcriticality   Counter Criticality MAJ MIN,\r
+          * @param String tname          Counter Threshold name\r
+          * @param String tthresholdCrossed  Counter Threshold crossed value\r
+          * @param String tvalue             Counter actual value\r
+          * @param EVEL_EVENT_ACTION talertAction   Alert set continue or clear\r
+          * @param String  talertDescription\r
+          * @param EVEL_ALERT_TYPE    talertType    Kind of anamoly\r
+          * @param Date               tcollectionTimestamp time at which alert was collected\r
+          * @param EVEL_SEVERITIES    teventSeverity  Severity of Alert\r
+          * @param Date               teventStartTimestamp Time when this alert started\r
+          *****************************************************************************/\r
+       public EvelThresholdCross( String evname,String evid,\r
+                                          String tcriticality,\r
+                                  String tname,\r
+                                  String tthresholdCrossed,\r
+                                  String tvalue,\r
+                               EVEL_EVENT_ACTION  talertAction,\r
+                               String             talertDescription, \r
+                               EVEL_ALERT_TYPE    talertType,\r
+                               Date               tcollectionTimestamp, \r
+                               EVEL_SEVERITIES    teventSeverity,\r
+                               Date               teventStartTimestamp)\r
+       {\r
+               super(evname,evid);\r
+               event_domain = EvelHeader.DOMAINS.EVEL_DOMAIN_THRESHOLD_CROSSING;\r
+               assert( tcriticality!= null );\r
+               assert( tname!= null );\r
+               assert( tthresholdCrossed!= null );\r
+               assert( tvalue!= null );\r
+               assert( talertAction!= null );\r
+               \r
+               additionalParameters = new PERF_COUNTER();\r
+               assert( additionalParameters != null);\r
+               \r
+               additionalParameters.criticality = tcriticality;\r
+               additionalParameters.name = tname;\r
+               additionalParameters.thresholdCrossed = tthresholdCrossed;\r
+               additionalParameters.value = tvalue;\r
+        alertAction      =  talertAction;\r
+        alertDescription = talertDescription; \r
+        alertType        = talertType;\r
+        collectionTimestamp =   tcollectionTimestamp; \r
+        eventSeverity       =    teventSeverity;\r
+        eventStartTimestamp =    teventStartTimestamp;\r
+               \r
+        additional_info = null;\r
+        alertValue = new EvelOptionString();\r
+        alertidList = null;\r
+        dataCollector = new EvelOptionString();\r
+        elementType = new EvelOptionString();\r
+        interfaceName = new EvelOptionString();\r
+        networkService = new EvelOptionString();\r
+        possibleRootCause = new EvelOptionString();\r
+       }\r
+       \r
+       \r
+       /**************************************************************************//**\r
+        * Set the Event Type property of the TC Alert.\r
+        *\r
+        * @note  The property is treated as immutable: it is only valid to call\r
+        *        the setter once.  However, we don't assert if the caller tries to\r
+        *        overwrite, just ignoring the update instead.\r
+        *\r
+        * @param type        The Event Type to be set. ASCIIZ string. The caller\r
+        *                    does not need to preserve the value once the function\r
+        *                    returns.\r
+        *****************************************************************************/\r
+       public void evel_thresholdcross_type_set(String type)\r
+       {\r
+         EVEL_ENTER();\r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions and call evel_header_type_set.                      */\r
+         /***************************************************************************/\r
+         assert(type!=null);\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_THRESHOLD_CROSSING);\r
+         evel_header_type_set(type);\r
+\r
+         EVEL_EXIT();\r
+       }\r
+\r
+       /**************************************************************************//**\r
+        * Add an optional additional alertid value to Alert.\r
+        *\r
+        *****************************************************************************/\r
+       public void evel_thresholdcross_alertid_add(String alertid)\r
+       {\r
+         EVEL_ENTER();\r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions.                                                    */\r
+         /***************************************************************************/\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_THRESHOLD_CROSSING);\r
+         assert(alertid != null);\r
+         \r
+         if( alertidList == null )\r
+         {\r
+                 alertidList = new ArrayList<String>();\r
+         }\r
+\r
+         LOGGER.debug(MessageFormat.format("Adding alertid={0}", alertid));\r
+\r
+         alertidList.add(new String(alertid));\r
+\r
+         EVEL_EXIT();\r
+       }\r
+       \r
+       /**************************************************************************//**\r
+        * Add an optional additional value name/value pair to the Alert.\r
+        *\r
+        * The name and value are null delimited ASCII strings.  The library takes\r
+        * a copy so the caller does not have to preserve values after the function\r
+        * returns.\r
+        * @param name      ASCIIZ string with the attribute's name.  The caller\r
+        *                  does not need to preserve the value once the function\r
+        *                  returns.\r
+        * @param value     ASCIIZ string with the attribute's value.  The caller\r
+        *                  does not need to preserve the value once the function\r
+        *                  returns.\r
+        *****************************************************************************/\r
+       public void evel_thresholdcross_addl_info_add(String name, String value)\r
+       {\r
+         String[] addl_info = null;\r
+         EVEL_ENTER();\r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions.                                                    */\r
+         /***************************************************************************/\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_THRESHOLD_CROSSING);\r
+         assert(name != null);\r
+         assert(value != null);\r
+         \r
+         if( additional_info == null )\r
+         {\r
+                 additional_info = new ArrayList<String[]>();\r
+         }\r
+\r
+         LOGGER.debug(MessageFormat.format("Adding name={0} value={1}", name, value));\r
+         addl_info = new String[2];\r
+         assert(addl_info != null);\r
+         addl_info[0] = name;\r
+         addl_info[1] = value;\r
+\r
+         additional_info.add(addl_info);\r
+\r
+         EVEL_EXIT();\r
+       }\r
+       \r
+\r
+         /**************************************************************************//**\r
+          * Set the TCA probable Root cause.\r
+          *\r
+          * @param sheader     Possible root cause to Threshold\r
+          *****************************************************************************/\r
+         public void evel_threshold_cross_possible_rootcause_set(String sheader)\r
+         {\r
+                   EVEL_ENTER();\r
+\r
+                   /***************************************************************************/\r
+                   /* Check preconditions.                                                    */\r
+                   /***************************************************************************/\r
+                   assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_THRESHOLD_CROSSING);\r
+                   \r
+                   assert(sheader != null);\r
+\r
+                   possibleRootCause.SetValuePr(\r
+                                          sheader,\r
+                                          "Rootcause value");\r
+                   EVEL_EXIT();\r
+         }\r
+    \r
+         /**************************************************************************//**\r
+          * Set the TCA networking cause.\r
+          *\r
+          * @param sheader     Possible networking service value to Threshold\r
+          *****************************************************************************/\r
+         public void evel_threshold_cross_networkservice_set(String sheader)\r
+         {\r
+                   EVEL_ENTER();\r
+\r
+                   /***************************************************************************/\r
+                   /* Check preconditions.                                                    */\r
+                   /***************************************************************************/\r
+                   assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_THRESHOLD_CROSSING);\r
+                   \r
+                   assert(sheader != null);\r
+\r
+                   networkService.SetValuePr(\r
+                                          sheader,\r
+                                          "Networking service value");\r
+                   EVEL_EXIT();\r
+         }\r
+    \r
+         /**************************************************************************//**\r
+          * Set the TCA Interface name.\r
+          *\r
+          * @param sheader     Interface name to threshold\r
+          *****************************************************************************/\r
+         public void evel_threshold_cross_interfacename_set(String sheader)\r
+         {\r
+                   EVEL_ENTER();\r
+\r
+                   /***************************************************************************/\r
+                   /* Check preconditions.                                                    */\r
+                   /***************************************************************************/\r
+                   assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_THRESHOLD_CROSSING);\r
+                   \r
+                   assert(sheader != null);\r
+\r
+                   interfaceName.SetValuePr(\r
+                                          sheader,\r
+                                          "TCA Interface name");\r
+                   EVEL_EXIT();\r
+         }\r
+    \r
+         /**************************************************************************//**\r
+          * Set the TCA Data element type.\r
+          *\r
+          * @param sheader     element type of Threshold\r
+          *****************************************************************************/\r
+         public void evel_threshold_cross_data_elementtype_set(String sheader)\r
+         {\r
+                   EVEL_ENTER();\r
+\r
+                   /***************************************************************************/\r
+                   /* Check preconditions.                                                    */\r
+                   /***************************************************************************/\r
+                   assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_THRESHOLD_CROSSING);\r
+                   \r
+                   assert(sheader != null);\r
+\r
+                   elementType.SetValuePr(\r
+                                          sheader,\r
+                                          "TCA Element type value");\r
+                   EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the TCA Data collector value.\r
+          *\r
+          * @param sheader     Data collector value\r
+          *****************************************************************************/\r
+         public void evel_threshold_cross_data_collector_set(String sheader)\r
+         {\r
+                   EVEL_ENTER();\r
+\r
+                   /***************************************************************************/\r
+                   /* Check preconditions.                                                    */\r
+                   /***************************************************************************/\r
+                   assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_THRESHOLD_CROSSING);\r
+                   \r
+                   assert(sheader != null);\r
+\r
+                   dataCollector.SetValuePr(\r
+                                          sheader,\r
+                                          "Datacollector value");\r
+                   EVEL_EXIT();\r
+         }\r
+    \r
+    \r
+    \r
+         /**************************************************************************//**\r
+          * Set the TCA alert value.\r
+          *\r
+          * @param sheader     Possible alert value\r
+          *****************************************************************************/\r
+         public void evel_threshold_cross_alertvalue_set(String sheader)\r
+         {\r
+                   EVEL_ENTER();\r
+\r
+                   /***************************************************************************/\r
+                   /* Check preconditions.                                                    */\r
+                   /***************************************************************************/\r
+                   assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_THRESHOLD_CROSSING);\r
+                   \r
+                   assert(sheader != null);\r
+\r
+                   alertValue.SetValuePr(\r
+                                          sheader,\r
+                                          "Alert value");\r
+                   EVEL_EXIT();\r
+         }\r
+\r
+       \r
+       /**************************************************************************//**\r
+        * Encode the fault in JSON according to AT&T's schema for the TC ALert type.\r
+        *\r
+        * @retvalue       JSON object of TC Alert encoding\r
+        *****************************************************************************/\r
+        JsonObjectBuilder evelThresholdCrossingObject()\r
+        {\r
+           double version = major_version+(double)minor_version/10;\r
+\r
+           EVEL_ENTER();\r
+         \r
+\r
+         /***************************************************************************/\r
+         /* Check preconditions.                                                    */\r
+         /***************************************************************************/\r
+         assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_THRESHOLD_CROSSING);\r
+\r
+         /***************************************************************************/\r
+         /* Mandatory fields.                                                       */\r
+         /***************************************************************************/\r
+         //encode counter\r
+      JsonObjectBuilder counterobj =  Json.createObjectBuilder()\r
+              .add( "criticality",additionalParameters.criticality)\r
+              .add( "name", additionalParameters.name)\r
+              .add( "thresholdCrossed",additionalParameters.thresholdCrossed)\r
+              .add( "value", additionalParameters.value);\r
+\r
+           \r
+         JsonObjectBuilder evelrep = Json.createObjectBuilder()\r
+                                      .add("additionalParameters", counterobj)\r
+                                      .add("alertAction", alertAction.toString())\r
+                                      .add("alertDescription", alertDescription)\r
+                               .add("alertType", alertType.toString())\r
+                               .add("collectionTimestamp", collectionTimestamp.toString())\r
+                               .add("eventSeverity",eventSeverity.toString())\r
+                               .add("eventStartTimestamp",eventStartTimestamp.toString());\r
+\r
+           /***************************************************************************/\r
+           /* Optional fields.                                                        */\r
+           /***************************************************************************/\r
+           alertValue.encJsonValue(evelrep, "alertValue");\r
+           if( alertidList != null && alertidList.size() > 0)\r
+           {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<alertidList.size();i++) {\r
+                         String addl_info = alertidList.get(i);\r
+                         JsonObject obj = Json.createObjectBuilder()\r
+                                    .add("item",addl_info).build();\r
+                         builder.add(obj);\r
+                   }\r
+                       evelrep.add("associatedAlertIdList", builder);\r
+           }\r
+\r
+           dataCollector.encJsonValue(evelrep, "dataCollector");\r
+           elementType.encJsonValue(evelrep, "elementType");\r
+           interfaceName.encJsonValue(evelrep, "interfaceName");\r
+           networkService.encJsonValue(evelrep, "networkService");\r
+           possibleRootCause.encJsonValue(evelrep, "possibleRootCause");\r
+\r
+         \r
+         evelrep.add( "thresholdCrossingFieldsVersion", version);\r
+\r
+         if( additional_info != null )\r
+         {\r
+           JsonArrayBuilder builder = Json.createArrayBuilder();\r
+           for(int i=0;i<additional_info.size();i++) {\r
+                 String[] addl_info = additional_info.get(i);\r
+                 JsonObject obj = Json.createObjectBuilder()\r
+                            .add("name", addl_info[0])\r
+                            .add("value", addl_info[1]).build();\r
+                 builder.add(obj);\r
+           }\r
+               evelrep.add("additionalFields", builder);\r
+         }\r
+\r
+\r
+         EVEL_EXIT();\r
+         \r
+         return evelrep;\r
+       }\r
+       \r
+       \r
+               /**************************************************************************//**\r
+            * Encode the event as a JSON event object according to AT&T's schema.\r
+            * retval : String of JSON TCA event message\r
+            *****************************************************************************/\r
+         String evel_json_encode_event()\r
+         {\r
+               EVEL_ENTER();\r
+               \r
+               assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_THRESHOLD_CROSSING);\r
+               \r
+           JsonObject obj = Json.createObjectBuilder()\r
+                    .add("event", Json.createObjectBuilder()\r
+                                .add( "commonEventHeader",eventHeaderObject() )\r
+                                .add( "thresholdCrossingAlert",evelThresholdCrossingObject() )\r
+                                ).build();\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return obj.toString();\r
+\r
+         }\r
+       \r
+\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelVoiceQuality.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/EvelVoiceQuality.java
new file mode 100644 (file)
index 0000000..409b9b4
--- /dev/null
@@ -0,0 +1,671 @@
+package evel_javalibrary.att.com;\r
+\r
+/**************************************************************************//**\r
+ * @file\r
+ * Evel Voice Quality event class\r
+ *\r
+  * This file implements the Evel TVoice Quality event event class which is intended to provide a\r
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so\r
+ * that VNFs can use it to send Voice Quality event reports.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+\r
+import javax.json.Json;\r
+import javax.json.JsonArrayBuilder;\r
+import javax.json.JsonObject;\r
+import javax.json.JsonObjectBuilder;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.slf4j.helpers.MessageFormatter;\r
+\r
+\r
+\r
+public class EvelVoiceQuality extends EvelHeader {\r
+       \r
+       int major_version = 1;\r
+       int minor_version = 1;\r
+\r
+       /**************************************************************************//**\r
+        * Vendor VNF Name fields.\r
+        * JSON equivalent field: vendorVnfNameFields\r
+        *****************************************************************************/\r
+       public class VENDOR_VNFNAME_FIELD {\r
+         String vendorname;\r
+         EvelOptionString vfmodule;\r
+         EvelOptionString vnfname;\r
+       }\r
+       \r
+       /**************************************************************************//**\r
+        * Service Event endpoint description\r
+        * JSON equivalent field: endpointDesc\r
+        *****************************************************************************/\r
+       public enum EVEL_SERVICE_ENDPOINT_DESC {\r
+         EVEL_SERVICE_ENDPOINT_CALLEE,\r
+         EVEL_SERVICE_ENDPOINT_CALLER,\r
+         EVEL_MAX_SERVICE_ENDPOINT_DESC\r
+       }\r
+       \r
+       /**************************************************************************//**\r
+        * End of Call Voice Quality Metrices\r
+        * JSON equivalent field: endOfCallVqmSummaries\r
+        *****************************************************************************/\r
+       public class END_OF_CALL_VOICE_QUALITY_METRICS {\r
+               /***************************************************************************/\r
+               /* Mandatory fields                                                        */\r
+               /***************************************************************************/\r
+               String adjacencyName;\r
+               String endpointDescription;\r
+\r
+               /***************************************************************************/\r
+               /* Optional fields                                                         */\r
+               /***************************************************************************/\r
+               EvelOptionDouble endpointJitter;\r
+               EvelOptionDouble endpointRtpOctetsDiscarded;\r
+               EvelOptionDouble endpointRtpOctetsReceived;\r
+               EvelOptionDouble endpointRtpOctetsSent;\r
+               EvelOptionDouble endpointRtpPacketsDiscarded;\r
+               EvelOptionDouble endpointRtpPacketsReceived;\r
+               EvelOptionDouble endpointRtpPacketsSent;\r
+               EvelOptionDouble localJitter;\r
+               EvelOptionDouble localRtpOctetsDiscarded;\r
+               EvelOptionDouble localRtpOctetsReceived;\r
+               EvelOptionDouble localRtpOctetsSent;\r
+               EvelOptionDouble localRtpPacketsDiscarded;\r
+               EvelOptionDouble localRtpPacketsReceived;\r
+               EvelOptionDouble localRtpPacketsSent;\r
+               EvelOptionDouble mosCqe;\r
+               EvelOptionDouble packetsLost;\r
+               EvelOptionDouble packetLossPercent;\r
+               EvelOptionDouble rFactor;\r
+               EvelOptionDouble roundTripDelay;\r
+       }\r
+\r
+       /***************************************************************************/\r
+         /* Mandatory fields                                                        */\r
+         /***************************************************************************/\r
+         VENDOR_VNFNAME_FIELD vnfname_field;\r
+         String calleeSideCodec;\r
+         String callerSideCodec;\r
+         String correlator;\r
+         String midCallRtcp;\r
+\r
+         /***************************************************************************/\r
+         /* Optional fields                                                         */\r
+         /***************************************************************************/\r
+         ArrayList<String[]> additional_info;\r
+         END_OF_CALL_VOICE_QUALITY_METRICS endOfCallVqmSummaries;\r
+         EvelOptionString evphoneNumber;\r
+\r
+       /***************************************************************************/\r
+       /* Optional fields                                                         */\r
+       /***************************************************************************/\r
+\r
+         private static final Logger LOGGER = Logger.getLogger( EvelVoiceQuality.class.getName() );\r
+\r
+\r
+         /**************************************************************************//**\r
+          * Create a new Voice Quality event.\r
+          *\r
+          * @note    The mandatory fields on the Voice Quality must be supplied to this\r
+          *          factory function and are immutable once set.  Optional fields have\r
+          *          explicit setter functions, but again values may only be set once so\r
+          *          that the event has immutable properties.\r
+          *\r
+          * @param   calleeSideCodec    callee codec for voice call\r
+          * @param   callerSideCodec    caller codec\r
+          * @param   corlator           Correlator\r
+          * @param   midCallRtcp        Midcall RTCP value\r
+          * @param   vendr_name         Vendor name\r
+          *\r
+          * @returns pointer to the newly manufactured ::EVENT_MEASUREMENT.  If the\r
+          *          event is not used (i.e. posted) it must be released using\r
+          *          ::evel_free_event.\r
+          * @retval  null  Failed to create the event.\r
+          *****************************************************************************/\r
+         public EvelVoiceQuality(String evname, String evid,\r
+                           String calleeSideCodc,\r
+                           String callerSideCodc, String corlator,\r
+                           String midCllRtcp, String vendr_name)\r
+         {\r
+        super(evname,evid);\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(vendr_name != null);\r
+           assert(calleeSideCodc != null);\r
+           assert(callerSideCodc != null);\r
+           assert(midCllRtcp != null);\r
+           assert(corlator != null);\r
+        \r
+\r
+           /***************************************************************************/\r
+           /* Allocate the measurement.                                               */\r
+           /***************************************************************************/\r
+           LOGGER.debug("New Voice Quality vendor "+vendr_name+" correlator"+corlator+"calleeSideCodec"+calleeSideCodc+"callerSideCodec"+callerSideCodc+"midCallRtcp"+midCllRtcp);\r
+\r
+           /***************************************************************************/\r
+           /* Initialize the header & the measurement fields.                         */\r
+           /***************************************************************************/\r
+           event_domain = EvelHeader.DOMAINS.EVEL_DOMAIN_VOICE_QUALITY;\r
+           correlator = corlator;\r
+               calleeSideCodec = calleeSideCodc;\r
+               callerSideCodec = callerSideCodc;\r
+               midCallRtcp = midCllRtcp;\r
+               \r
+               vnfname_field = new VENDOR_VNFNAME_FIELD();\r
+               vnfname_field.vendorname = vendr_name;\r
+               vnfname_field.vfmodule = new EvelOptionString();\r
+               vnfname_field.vnfname = new EvelOptionString();\r
+\r
+           /***************************************************************************/\r
+           /* Optional fields.                                                    */\r
+           /***************************************************************************/\r
+           additional_info = null;\r
+           endOfCallVqmSummaries = null;\r
+           evphoneNumber = new EvelOptionString();\r
+\r
+           EVEL_EXIT();\r
+         }\r
+         \r
+         /**************************************************************************//**\r
+          * Add an additional value name/value pair to the Voice Quality.\r
+          *\r
+          * The name and value are null delimited ASCII strings.  The library takes\r
+          * a copy so the caller does not have to preserve values after the function\r
+          * returns.\r
+          *\r
+          * @param name      ASCIIZ string with the attribute's name.  The caller\r
+          *                  does not need to preserve the value once the function\r
+          *                  returns.\r
+          * @param value     ASCIIZ string with the attribute's value.  The caller\r
+          *                  does not need to preserve the value once the function\r
+          *                  returns.\r
+          *****************************************************************************/\r
+         public void evel_voice_quality_addl_info_add(String name, String value)\r
+               {\r
+                 String[] addl_info = null;\r
+                 EVEL_ENTER();\r
+\r
+                 /***************************************************************************/\r
+                 /* Check preconditions.                                                    */\r
+                 /***************************************************************************/\r
+                 assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_VOICE_QUALITY);\r
+                 assert(name != null);\r
+                 assert(value != null);\r
+                 \r
+                 if( additional_info == null )\r
+                 {\r
+                         additional_info = new ArrayList<String[]>();\r
+                 }\r
+\r
+                 LOGGER.debug(MessageFormat.format("Adding name={0} value={1}", name, value));\r
+                 addl_info = new String[2];\r
+                 assert(addl_info != null);\r
+                 addl_info[0] = name;\r
+                 addl_info[1] = value;\r
+\r
+                 additional_info.add(addl_info);\r
+\r
+                 EVEL_EXIT();\r
+               }\r
+         \r
+         \r
+         /**************************************************************************//**\r
+          * Set the Callee side codec for Call for domain Voice Quality\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param calleeCodecForCall        The Callee Side Codec to be set.  ASCIIZ \r
+          *                                  string. The caller does not need to \r
+          *                                  preserve the value once the function\r
+          *                                  returns.\r
+          *****************************************************************************/\r
+         public void evel_voice_quality_callee_codec_set(String calleeCodecForCall) {\r
+             EVEL_ENTER();\r
+\r
+             /***************************************************************************/\r
+             /* Check preconditions.                                                    */\r
+             /***************************************************************************/\r
+                 assert(calleeCodecForCall != null);\r
+                 assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_VOICE_QUALITY);\r
+                 LOGGER.debug("Setting Correlator "+calleeCodecForCall);\r
+\r
+             calleeSideCodec = calleeCodecForCall;\r
+\r
+             EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Caller side codec for Call for domain Voice Quality\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param callerCodecForCall        The Caller Side Codec to be set.  ASCIIZ \r
+          *                                  string. The caller does not need to \r
+          *                                  preserve the value once the function\r
+          *                                  returns.\r
+          *****************************************************************************/\r
+         public void evel_voice_quality_caller_codec_set(String callerCodecForCall) {\r
+             EVEL_ENTER();\r
+\r
+             /***************************************************************************/\r
+             /* Check preconditions.                                                    */\r
+             /***************************************************************************/\r
+             assert(callerCodecForCall != null);\r
+                 assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_VOICE_QUALITY);\r
+                 LOGGER.debug("Setting CallerCodecForCall "+callerCodecForCall);\r
+\r
+             callerSideCodec = callerCodecForCall;\r
+\r
+             EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the correlator for domain Voice Quality\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param correlator                The correlator value to be set.  ASCIIZ \r
+          *                                  string. The caller does not need to \r
+          *                                  preserve the value once the function\r
+          *                                  returns.\r
+          *****************************************************************************/\r
+         public void evel_voice_quality_correlator_set(String vCorrelator) {\r
+             EVEL_ENTER();\r
+\r
+             /***************************************************************************/\r
+             /* Check preconditions.                                                    */\r
+             /***************************************************************************/\r
+             assert(vCorrelator != null);\r
+                 assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_VOICE_QUALITY);\r
+                 LOGGER.debug("Setting Correlator "+vCorrelator);\r
+                 \r
+             correlator = vCorrelator;\r
+\r
+             EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the RTCP Call Data for domain Voice Quality\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param rtcpCallData              The RTCP Call Data to be set.  ASCIIZ \r
+          *                                  string. The caller does not need to \r
+          *                                  preserve the value once the function\r
+          *                                  returns.\r
+          *****************************************************************************/\r
+         public void evel_voice_quality_rtcp_data_set(String rtcpCallData) {\r
+             EVEL_ENTER();\r
+\r
+             /***************************************************************************/\r
+             /* Check preconditions.                                                    */\r
+             /***************************************************************************/\r
+             assert(rtcpCallData != null);\r
+                 assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_VOICE_QUALITY);\r
+                 LOGGER.debug("Setting RTCP Data "+rtcpCallData);\r
+\r
+             midCallRtcp = rtcpCallData;\r
+\r
+             EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Vendor VNF Name fields for domain Voice Quality\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param modulename                The Vendor, VNF and VfModule names to be set.   \r
+          *                                  ASCIIZ string. The caller does not need to \r
+          *                                  preserve the value once the function\r
+          *                                  returns.\r
+          *****************************************************************************/\r
+         public void evel_voice_quality_vnfmodule_name_set(String module_name) {\r
+             EVEL_ENTER();\r
+\r
+             /***************************************************************************/\r
+             /* Check preconditions.                                                    */\r
+             /***************************************************************************/\r
+                 assert(module_name != null);\r
+                 assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_VOICE_QUALITY);\r
+                 LOGGER.debug("Setting VoiceQuality Module Name "+module_name);\r
+                   \r
+                 vnfname_field.vfmodule.SetValue(module_name);\r
+\r
+             EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Set the Vendor VNF Name fields for domain Voice Quality\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param modulename                The Vendor, VNF and VfModule names to be set.   \r
+          *                                  ASCIIZ string. The caller does not need to \r
+          *                                  preserve the value once the function\r
+          *                                  returns.\r
+          *****************************************************************************/\r
+         public void evel_voice_quality_vnfname_set(String vnfname) {\r
+             EVEL_ENTER();\r
+\r
+             /***************************************************************************/\r
+             /* Check preconditions.                                                    */\r
+             /***************************************************************************/\r
+                 assert(vnfname != null);\r
+                 assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_VOICE_QUALITY);\r
+                 LOGGER.debug("Setting VoiceQuality VNF Name "+vnfname);\r
+                   \r
+                 vnfname_field.vnfname.SetValue(vnfname);\r
+                 \r
+             EVEL_EXIT();\r
+         }\r
+         \r
+\r
+         /**************************************************************************//**\r
+          * Set the Phone Number associated with the Correlator for domain Voice Quality\r
+          *\r
+          * @note  The property is treated as immutable: it is only valid to call\r
+          *        the setter once.  However, we don't assert if the caller tries to\r
+          *        overwrite, just ignoring the update instead.\r
+          *\r
+          * \r
+          * @param calleeCodecForCall        The Phone Number to be set.  ASCIIZ \r
+          *                                  string. The caller does not need to \r
+          *                                  preserve the value once the function\r
+          *                                  returns.\r
+          *****************************************************************************/\r
+         public void evel_voice_quality_phone_number_set(String phoneNumber) {\r
+             EVEL_ENTER();\r
+\r
+             /***************************************************************************/\r
+             /* Check preconditions.                                                    */\r
+             /***************************************************************************/\r
+             assert(phoneNumber != null);\r
+                 assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_VOICE_QUALITY);\r
+                 \r
+                 evphoneNumber.SetValuePr(phoneNumber,"Phone_Number");\r
+                 \r
+             EVEL_EXIT();\r
+         }\r
+\r
+         /**************************************************************************//**\r
+          * Add an End of Call Voice Quality Metrices\r
+\r
+          * The adjacencyName and endpointDescription is null delimited ASCII string.  \r
+          * The library takes a copy so the caller does not have to preserve values\r
+          * after the function returns.\r
+          *\r
+          * @param voiceQuality     Pointer to the measurement.\r
+          * @param adjacencyName                     Adjacency name\r
+          * @param endpointDescription               Enumeration: ‘Caller’, ‘Callee’.\r
+          * @param endpointJitter                    Endpoint jitter\r
+          * @param endpointRtpOctetsDiscarded        Endpoint RTP octets discarded.\r
+          * @param endpointRtpOctetsReceived         Endpoint RTP octets received.\r
+          * @param endpointRtpOctetsSent             Endpoint RTP octets sent\r
+          * @param endpointRtpPacketsDiscarded       Endpoint RTP packets discarded.\r
+          * @param endpointRtpPacketsReceived        Endpoint RTP packets received.\r
+          * @param endpointRtpPacketsSent            Endpoint RTP packets sent.\r
+          * @param localJitter                       Local jitter.\r
+          * @param localRtpOctetsDiscarded           Local RTP octets discarded.\r
+          * @param localRtpOctetsReceived            Local RTP octets received.\r
+          * @param localRtpOctetsSent                Local RTP octets sent.\r
+          * @param localRtpPacketsDiscarded          Local RTP packets discarded.\r
+          * @param localRtpPacketsReceived           Local RTP packets received.\r
+          * @param localRtpPacketsSent               Local RTP packets sent.\r
+          * @param mosCqe                            Decimal range from 1 to 5\r
+          *                                          (1 decimal place)\r
+          * @param packetsLost                       No  Packets lost\r
+          * @param packetLossPercent                 Calculated percentage packet loss \r
+          * @param rFactor                           rFactor from 0 to 100\r
+          * @param roundTripDelay                    Round trip delay in milliseconds\r
+          *****************************************************************************/\r
+         public void evel_voice_quality_end_metrics_set(\r
+             String adjacencyName, String endpointDescr,\r
+             double endpointJitter,\r
+             double endpointRtpOctetsDiscarded,\r
+             double endpointRtpOctetsReceived,\r
+             double endpointRtpOctetsSent,\r
+             double endpointRtpPacketsDiscarded,\r
+             double endpointRtpPacketsReceived,\r
+             double endpointRtpPacketsSent,\r
+             double localJitter,\r
+             double localRtpOctetsDiscarded,\r
+             double localRtpOctetsReceived,\r
+             double localRtpOctetsSent,\r
+             double localRtpPacketsDiscarded,\r
+             double localRtpPacketsReceived,\r
+             double localRtpPacketsSent,\r
+             double mosCqe,\r
+             double packetsLost,\r
+             double packetLossPercent,\r
+             double rFactor,\r
+             double roundTripDelay) {\r
+             \r
+             END_OF_CALL_VOICE_QUALITY_METRICS vQMetrices = null;\r
+             EVEL_ENTER();\r
+\r
+             /***************************************************************************/\r
+             /* Check assumptions.                                                      */\r
+             /***************************************************************************/\r
+             assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_VOICE_QUALITY);\r
+             assert(adjacencyName != null);\r
+             assert(mosCqe >= 1 && mosCqe <= 5);\r
+             assert(rFactor >= 0 && rFactor <= 100);\r
+             assert(endpointDescr != null && (endpointDescr.equals("Caller")||endpointDescr.equals("Callee")) );\r
+             \r
+             /***************************************************************************/\r
+             /* Allocate a container for the value and push onto the list.              */\r
+             /***************************************************************************/\r
+             LOGGER.debug(MessageFormat.format("Adding adjacencyName={0} endpointDescription={1}", adjacencyName, endpointDescr));\r
+             vQMetrices = new END_OF_CALL_VOICE_QUALITY_METRICS();\r
+             assert(vQMetrices != null);\r
+\r
+             vQMetrices.adjacencyName = adjacencyName;\r
+             vQMetrices.endpointDescription = endpointDescr;\r
+             \r
+             vQMetrices.endpointJitter = new EvelOptionDouble();\r
+             vQMetrices.endpointRtpOctetsDiscarded= new EvelOptionDouble();\r
+             vQMetrices.endpointRtpOctetsReceived= new EvelOptionDouble();\r
+             vQMetrices.endpointRtpOctetsSent= new EvelOptionDouble();\r
+             vQMetrices.endpointRtpPacketsDiscarded= new EvelOptionDouble();\r
+             vQMetrices.endpointRtpPacketsReceived= new EvelOptionDouble();\r
+             vQMetrices.endpointRtpPacketsSent= new EvelOptionDouble();\r
+             vQMetrices.localJitter= new EvelOptionDouble();\r
+             vQMetrices.localRtpOctetsDiscarded= new EvelOptionDouble();\r
+             vQMetrices.localRtpOctetsReceived= new EvelOptionDouble();\r
+             vQMetrices.localRtpOctetsSent= new EvelOptionDouble();\r
+             vQMetrices.localRtpPacketsDiscarded= new EvelOptionDouble();\r
+             vQMetrices.localRtpPacketsReceived= new EvelOptionDouble();\r
+             vQMetrices.localRtpPacketsSent= new EvelOptionDouble();\r
+             vQMetrices.mosCqe= new EvelOptionDouble();\r
+             vQMetrices.packetsLost= new EvelOptionDouble();\r
+             vQMetrices.packetLossPercent= new EvelOptionDouble();\r
+             vQMetrices.rFactor= new EvelOptionDouble();\r
+             vQMetrices.roundTripDelay= new EvelOptionDouble();\r
+\r
+             vQMetrices.endpointJitter.SetValuePr(endpointJitter, "Endpoint jitter");\r
+             vQMetrices.endpointRtpOctetsDiscarded.SetValuePr(endpointRtpOctetsDiscarded, "Endpoint RTP octets discarded");\r
+             vQMetrices.endpointRtpOctetsReceived.SetValuePr(endpointRtpOctetsReceived, "Endpoint RTP octets received");\r
+             vQMetrices.endpointRtpOctetsSent.SetValuePr(endpointRtpOctetsSent, "Endpoint RTP octets sent");\r
+             vQMetrices.endpointRtpPacketsDiscarded.SetValuePr(endpointRtpPacketsDiscarded, "Endpoint RTP packets discarded");\r
+             vQMetrices.endpointRtpPacketsReceived.SetValuePr(endpointRtpPacketsReceived, "Endpoint RTP packets received");\r
+             vQMetrices.endpointRtpPacketsSent.SetValuePr(endpointRtpPacketsSent, "Endpoint RTP packets sent");\r
+             vQMetrices.localJitter.SetValuePr( localJitter, "Local jitter");\r
+             vQMetrices.localRtpOctetsDiscarded.SetValuePr(localRtpOctetsDiscarded, "Local RTP octets discarded");\r
+             vQMetrices.localRtpOctetsReceived.SetValuePr(localRtpOctetsReceived, "Local RTP octets received");\r
+             vQMetrices.localRtpOctetsSent.SetValuePr(localRtpOctetsSent, "Local RTP octets sent");\r
+             vQMetrices.localRtpPacketsDiscarded.SetValuePr(localRtpPacketsDiscarded, "Local RTP packets discarded");\r
+             vQMetrices.localRtpPacketsReceived.SetValuePr(localRtpPacketsReceived, "Local RTP packets received");\r
+             vQMetrices.localRtpPacketsSent.SetValuePr(localRtpPacketsSent, "Local RTP packets sent");\r
+             vQMetrices.mosCqe.SetValuePr(mosCqe, "Decimal range from 1 to 5 (1 decimal place)");\r
+             vQMetrices.packetsLost.SetValuePr(packetsLost, "Packets lost");\r
+             vQMetrices.packetLossPercent.SetValuePr(packetLossPercent, "Calculated percentage packet loss");\r
+             vQMetrices.rFactor.SetValuePr(rFactor, "rFactor ");\r
+             vQMetrices.roundTripDelay.SetValuePr(roundTripDelay, "Round trip delay in milliseconds ");\r
+\r
+             endOfCallVqmSummaries = vQMetrices;\r
+\r
+             EVEL_EXIT();\r
+         }\r
+\r
+               /**************************************************************************//**\r
+                * Encode the Voice Quality in JSON according to AT&T's schema\r
+                *\r
+                * @retvalue       JSON object of VoiceQuality body encoding\r
+                *****************************************************************************/\r
+         JsonObjectBuilder evelVoiceQualityObject()\r
+         {\r
+\r
+           double version = major_version+(double)minor_version/10;\r
+\r
+           EVEL_ENTER();\r
+\r
+           /***************************************************************************/\r
+           /* Check preconditions.                                                    */\r
+           /***************************************************************************/\r
+           assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_VOICE_QUALITY);\r
+\r
+           /***************************************************************************/\r
+           /* Mandatory fields.                                                       */\r
+           /***************************************************************************/\r
+           \r
+        JsonObjectBuilder vnfnamedobj =  Json.createObjectBuilder()\r
+                .add( "vendorName",vnfname_field.vendorname);\r
+            vnfname_field.vfmodule.encJsonValue(vnfnamedobj,"vfModuleName");\r
+            vnfname_field.vfmodule.encJsonValue(vnfnamedobj,"vnfName");\r
+           \r
+           JsonObjectBuilder evelvq = Json.createObjectBuilder()\r
+                                         .add("correlator", correlator)\r
+                                         .add("calleeSideCodec", calleeSideCodec)\r
+                                         .add("callerSideCodec", callerSideCodec)\r
+                                  .add("midCallRtcp", midCallRtcp)\r
+                                  .add("voiceQualityFieldsVersion", version)\r
+                                  .add("vendorVnfNameFields", vnfnamedobj);\r
+           \r
+           /***************************************************************************/\r
+           /* Optional fields.                                                        */\r
+           /***************************************************************************/\r
+           evphoneNumber.encJsonValue(evelvq, "phoneNumber");\r
+           \r
+           \r
+           // additional fields\r
+                 if( additional_info != null )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+                   for(int i=0;i<additional_info.size();i++) {\r
+                         String[] addl_info = additional_info.get(i);\r
+                         JsonObject obj = Json.createObjectBuilder()\r
+                                    .add("name", addl_info[0])\r
+                                    .add("value", addl_info[1]).build();\r
+                         builder.add(obj);\r
+                   }\r
+                       evelvq.add("additionalFields", builder);\r
+                 }\r
+                 \r
+                 \r
+                 if( endOfCallVqmSummaries != null )\r
+                 {\r
+                   JsonArrayBuilder builder = Json.createArrayBuilder();\r
+\r
+                         END_OF_CALL_VOICE_QUALITY_METRICS vQMetrics = endOfCallVqmSummaries;\r
+                         \r
+                         JsonObjectBuilder obj = Json.createObjectBuilder()\r
+                                         .add("adjacencyName", vQMetrics.adjacencyName)\r
+                                         .add("endpointDescription", vQMetrics.endpointDescription);\r
+                                         \r
+                         vQMetrics.endpointJitter.encJsonValue(obj,"endpointJitter");\r
+                         vQMetrics.endpointRtpOctetsDiscarded.encJsonValue(obj,"endpointRtpOctetsDiscarded");\r
+                         vQMetrics.endpointRtpOctetsReceived.encJsonValue(obj,"endpointRtpOctetsReceived");\r
+                         vQMetrics.endpointRtpOctetsSent.encJsonValue(obj,"endpointRtpOctetsSent");\r
+                         vQMetrics.endpointRtpPacketsDiscarded.encJsonValue(obj,"endpointRtpPacketsDiscarded");                          \r
+                         vQMetrics.endpointRtpPacketsReceived.encJsonValue(obj,"endpointRtpPacketsReceived");\r
+                         vQMetrics.endpointRtpPacketsSent.encJsonValue(obj,"endpointRtpPacketsSent");\r
+                         vQMetrics.localJitter.encJsonValue(obj,"localJitter");\r
+                         vQMetrics.localRtpOctetsDiscarded.encJsonValue(obj,"localRtpOctetsDiscarded");\r
+                         vQMetrics.localRtpOctetsReceived.encJsonValue(obj,"localRtpOctetsReceived");\r
+                         vQMetrics.localRtpOctetsSent.encJsonValue(obj,"localRtpOctetsSent");\r
+                         vQMetrics.localRtpPacketsDiscarded.encJsonValue(obj,"localRtpPacketsDiscarded");                        \r
+                         vQMetrics.localRtpPacketsReceived.encJsonValue(obj,"localRtpPacketsReceived");\r
+                         vQMetrics.localRtpPacketsSent.encJsonValue(obj,"localRtpPacketsSent");\r
+                         vQMetrics.mosCqe.encJsonValue(obj,"mosCqe");\r
+                         vQMetrics.packetsLost.encJsonValue(obj,"packetsLost");\r
+                         vQMetrics.packetLossPercent.encJsonValue(obj,"packetLossPercent");\r
+                         vQMetrics.rFactor.encJsonValue(obj,"rFactor");\r
+                         vQMetrics.roundTripDelay.encJsonValue(obj,"roundTripDelay");\r
+\r
+                         evelvq.add("endOfCallVqmSummaries", obj);\r
+                 }\r
+           \r
+\r
+           /***************************************************************************/\r
+           /* Although optional, we always generate the version.  Note that this      */\r
+           /* closes the object, too.                                                 */\r
+           /***************************************************************************/\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return evelvq;\r
+         }\r
+         \r
+               /**************************************************************************//**\r
+            * Encode the event as a JSON event object according to AT&T's schema.\r
+            * retval : String of JSON Voice Quality event message\r
+            *****************************************************************************/\r
+         String evel_json_encode_event()\r
+         {\r
+               EVEL_ENTER();\r
+               \r
+               assert(event_domain == EvelHeader.DOMAINS.EVEL_DOMAIN_VOICE_QUALITY);\r
+               \r
+           JsonObject obj = Json.createObjectBuilder()\r
+                    .add("event", Json.createObjectBuilder()\r
+                                .add( "commonEventHeader",eventHeaderObject() )\r
+                                .add( "voiceQualityFields",evelVoiceQualityObject() )\r
+                                ).build();\r
+\r
+           EVEL_EXIT();\r
+           \r
+           return obj.toString();\r
+\r
+         }\r
+\r
+\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/RingBuffer.java b/veslibrary/ves_javalibrary/evel_javalib2/src/evel_javalibrary/att/com/RingBuffer.java
new file mode 100644 (file)
index 0000000..28b309a
--- /dev/null
@@ -0,0 +1,276 @@
+package evel_javalibrary.att.com;\r
+/**************************************************************************//**\r
+ * @file\r
+ * RingBuffer class\r
+ *\r
+  * This file implements internal Ringbuffer for storing and\r
+  *  forwarding events to Collector.\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+import java.util.concurrent.Semaphore;\r
+/*\r
+ * Ringbuffer to store and Forward http(s) POST requests\r
+ */\r
+public class RingBuffer {\r
+\r
+           // message count semaphore\r
+           public static Semaphore countsem;\r
+           // space semaphore\r
+           public static Semaphore spacesem;\r
+           // lock semaphore\r
+           public static Semaphore lock;\r
+\r
+           public Object[] elements = null;\r
+\r
+           public int capacity  = 0;\r
+           public int writePos  = 0;\r
+           public int available = 0;\r
+\r
+           /*\r
+            * Constructs Ringbuffer of specified capacity\r
+            */\r
+           public RingBuffer(int capacity) {\r
+               this.capacity = capacity;\r
+               this.elements = new Object[capacity];\r
+               countsem = new Semaphore(1);\r
+               spacesem = new Semaphore(capacity);\r
+               lock = new Semaphore(1);\r
+           }\r
+\r
+           //resets the positions\r
+           public void reset() {\r
+               this.writePos = 0;\r
+               this.available = 0;\r
+           }\r
+\r
+           //returns available capacity\r
+           public int remainingCapacity() {\r
+               return this.capacity - this.available;\r
+           }\r
+\r
+\r
+\r
+           //Puts Java object into ringbuffer\r
+           public boolean put(Object element){\r
+               \r
+               boolean ret = false;\r
+               //acquire locks\r
+               try {\r
+                               spacesem.acquire();\r
+                               lock.acquire();\r
+                       } catch (InterruptedException e) {\r
+                               // TODO Auto-generated catch block\r
+                               e.printStackTrace();\r
+                       }\r
+               \r
+\r
+               //store object\r
+               if(available < capacity){\r
+                   if(writePos >= capacity){\r
+                       writePos = 0;\r
+                   }\r
+                   elements[writePos] = element;\r
+                   writePos++;\r
+                   available++;\r
+                   ret = true;\r
+               }\r
+               \r
+               //release Locks\r
+                   lock.release();\r
+                       countsem.release();\r
+\r
+\r
+               return ret;\r
+           }\r
+\r
+           public int put(Object[] newElements){\r
+               return put(newElements, newElements.length);\r
+           }\r
+\r
+           public int put(Object[] newElements, int length){\r
+               //Acquire locks\r
+               try {\r
+                               spacesem.acquire();\r
+                               lock.acquire();\r
+                       } catch (InterruptedException e) {\r
+                               // TODO Auto-generated catch block\r
+                               e.printStackTrace();\r
+                       }\r
+               \r
+               int readPos = 0;\r
+               if(this.writePos > this.available){\r
+                   //space above writePos is all empty\r
+\r
+                   if(length <= this.capacity - this.writePos){\r
+                       //space above writePos is sufficient to insert batch\r
+\r
+                       for(;  readPos < length; readPos++){\r
+                           this.elements[this.writePos++] = newElements[readPos];\r
+                       }\r
+                       this.available += readPos;\r
+                       //release\r
+                           lock.release();\r
+                               countsem.release();\r
+                       return length;\r
+\r
+                   } else {\r
+                       //both space above writePos and below writePos is necessary to use\r
+                       //to insert batch.\r
+\r
+                       int lastEmptyPos = writePos - available;\r
+\r
+                       for(; this.writePos < this.capacity; this.writePos++){\r
+                           this.elements[this.writePos] = newElements[readPos++];\r
+                       }\r
+\r
+                       //fill into bottom of array too.\r
+                       this.writePos = 0;\r
+\r
+                       int endPos = Math.min(length - readPos, capacity - available - readPos);\r
+                       for(;this.writePos < endPos; this.writePos++){\r
+                           this.elements[this.writePos] = newElements[readPos++];\r
+                       }\r
+                       this.available += readPos;\r
+                       //release\r
+                           lock.release();\r
+                               countsem.release();\r
+                       return readPos;\r
+                   }\r
+               } else {\r
+                   int endPos = this.capacity - this.available + this.writePos;\r
+\r
+                   for(; this.writePos < endPos; this.writePos++){\r
+                       this.elements[this.writePos] = newElements[readPos++];\r
+                   }\r
+                   this.available += readPos;\r
+                   //release\r
+                           lock.release();\r
+                               countsem.release();\r
+\r
+                   return readPos;\r
+               }\r
+\r
+           }\r
+\r
+           /*\r
+            * Takes a stored object in Ringbuffer and releases the space\r
+            */\r
+\r
+           public Object take() {\r
+               \r
+               Object nextObj;\r
+               //acquire lock\r
+               try {\r
+                               countsem.acquire();\r
+                               lock.acquire();\r
+                       } catch (InterruptedException e) {\r
+                               // TODO Auto-generated catch block\r
+                               e.printStackTrace();\r
+                       }\r
+               \r
+               if(available == 0){\r
+                   nextObj = null;\r
+               }\r
+               else {\r
+                 int nextSlot = writePos - available;\r
+                 if(nextSlot < 0){\r
+                   nextSlot += capacity;\r
+                 }\r
+                 nextObj = elements[nextSlot];\r
+                 available--;\r
+               }\r
+               //releases object\r
+                   lock.release();\r
+                       spacesem.release();\r
+               \r
+               return nextObj;\r
+           }\r
+\r
+\r
+           public int take(Object[] into){\r
+               return take(into, into.length);\r
+           }\r
+\r
+\r
+           public int take(Object[] into, int length){\r
+               int intoPos = 0;\r
+               \r
+               //acquire lock\r
+               try {\r
+                               countsem.acquire();\r
+                               lock.acquire();\r
+                       } catch (InterruptedException e) {\r
+                               // TODO Auto-generated catch block\r
+                               e.printStackTrace();\r
+                       }\r
+\r
+               if(available <= writePos){\r
+                   int nextPos= writePos - available;\r
+                   int endPos   = nextPos + Math.min(available, length);\r
+\r
+                   for(;nextPos < endPos; nextPos++){\r
+                       into[intoPos++] = this.elements[nextPos];\r
+                   }\r
+                   this.available -= intoPos;\r
+                   \r
+                   //release\r
+                           lock.release();\r
+                               countsem.release();\r
+                               \r
+                   return intoPos;\r
+               } else {\r
+                   int nextPos = writePos - available + capacity;\r
+\r
+                   int leftInTop = capacity - nextPos;\r
+                   if(length <= leftInTop){\r
+                       //copy directly\r
+                       for(; intoPos < length; intoPos++){\r
+                           into[intoPos] = this.elements[nextPos++];\r
+                       }\r
+                       this.available -= length;\r
+                           //release\r
+                                   lock.release();\r
+                                       countsem.release();\r
+                       return length;\r
+\r
+                   } else {\r
+                       //copy top\r
+                       for(; nextPos < capacity; nextPos++){\r
+                           into[intoPos++] = this.elements[nextPos];\r
+                       }\r
+\r
+                       //copy bottom - from 0 to writePos\r
+                       nextPos = 0;\r
+                       int leftToCopy = length - intoPos;\r
+                       int endPos = Math.min(writePos, leftToCopy);\r
+\r
+                       for(;nextPos < endPos; nextPos++){\r
+                           into[intoPos++] = this.elements[nextPos];\r
+                       }\r
+\r
+                       this.available -= intoPos;\r
+                       \r
+                           //release\r
+                                   lock.release();\r
+                                       countsem.release();\r
+\r
+                       return intoPos;\r
+                   }\r
+               }\r
+           }\r
+       \r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/src_test/maindir/Main.java b/veslibrary/ves_javalibrary/evel_javalib2/src_test/maindir/Main.java
new file mode 100644 (file)
index 0000000..756bac0
--- /dev/null
@@ -0,0 +1,249 @@
+package evel_javalibrary.att.com.maindir;\r
+\r
+/**************************************************************************//**\r
+ * @file\r
+ * Sample Test Agent for EVEL library\r
+ *\r
+ * This file implements the Sample Agent which is intended to provide a\r
+ * simple wrapper around the complexity of AT&T's Vendor Event Listener API so\r
+ * that VNFs can use it without worrying about details of the API transport.\r
+ * It also shows how events can be formatted with data for POST\r
+ *\r
+ * License\r
+ * -------\r
+ *\r
+  * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *****************************************************************************/\r
+\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+import evel_javalibrary.att.com.*;\r
+import evel_javalibrary.att.com.AgentMain.EVEL_ERR_CODES;\r
+import evel_javalibrary.att.com.EvelFault.EVEL_SEVERITIES;\r
+import evel_javalibrary.att.com.EvelFault.EVEL_SOURCE_TYPES;\r
+import evel_javalibrary.att.com.EvelFault.EVEL_VF_STATUSES;\r
+import evel_javalibrary.att.com.EvelHeader.PRIORITIES;\r
+import evel_javalibrary.att.com.EvelMobileFlow.MOBILE_GTP_PER_FLOW_METRICS;\r
+import evel_javalibrary.att.com.EvelScalingMeasurement.MEASUREMENT_CPU_USE;\r
+import evel_javalibrary.att.com.EvelScalingMeasurement.MEASUREMENT_VNIC_PERFORMANCE;\r
+import evel_javalibrary.att.com.EvelStateChange.EVEL_ENTITY_STATE;\r
+import evel_javalibrary.att.com.EvelThresholdCross.EVEL_ALERT_TYPE;\r
+import evel_javalibrary.att.com.EvelThresholdCross.EVEL_EVENT_ACTION;\r
+\r
+import org.apache.log4j.Level;\r
+\r
+import java.io.*;\r
+import java.text.SimpleDateFormat;\r
+import java.time.LocalDateTime;\r
+import java.util.Date;\r
+\r
+public class Main\r
+{\r
+\r
+        public static void main(String[] args)\r
+        {\r
+\r
+       try{\r
+\r
+        AgentMain.evel_initialize("http://127.0.0.1", 30000,\r
+                              "/vendor_event_listener","/example_vnf",\r
+                "pill",\r
+                "will",\r
+                Level.DEBUG);\r
+       } catch( Exception e )\r
+       {\r
+           e.printStackTrace();\r
+       }\r
+\r
+        for(int i= 0; i < 20; i++)\r
+        {\r
+              EvelHeader header  = EvelHeader.evel_new_heartbeat("Hearbeat_vAFX","vmname_ip");\r
+              header.evel_nfnamingcode_set("vVNF");\r
+              header.evel_nfcnamingcode_set("vVNF");\r
+              AgentMain.evel_post_event(header);\r
+              try {\r
+                Thread.sleep(1);\r
+              } catch( Exception e )\r
+              {\r
+                 e.printStackTrace();\r
+              }\r
+\r
+              EvelFault flt  = new EvelFault("Fault_vVNF", "vmname_ip",\r
+                         "NIC error", "Hardware failed",\r
+                  EvelHeader.PRIORITIES.EVEL_PRIORITY_HIGH,\r
+                  EVEL_SEVERITIES.EVEL_SEVERITY_MAJOR,\r
+                  EVEL_SOURCE_TYPES.EVEL_SOURCE_CARD,\r
+                  EVEL_VF_STATUSES.EVEL_VF_STATUS_ACTIVE);\r
+              flt.evel_fault_addl_info_add("nichw", "fail");\r
+              flt.evel_fault_addl_info_add("nicsw", "fail");\r
+              AgentMain.evel_post_event(flt);\r
+\r
+              EvelStateChange stc  = new EvelStateChange("StateChange_vVNF", "vmname_ip",\r
+                             EvelStateChange.EVEL_ENTITY_STATE.EVEL_ENTITY_STATE_IN_SERVICE,\r
+                          EvelStateChange.EVEL_ENTITY_STATE.EVEL_ENTITY_STATE_OUT_OF_SERVICE,"bgp");\r
+              stc.evel_statechange_addl_info_add("bgpa", "fail");\r
+              stc.evel_statechange_addl_info_add("bgpb", "fail");\r
+\r
+              AgentMain.evel_post_event(stc);\r
+\r
+              EvelScalingMeasurement sm  = new EvelScalingMeasurement(10.0,"Measurements_vVNF", "vmname_ip");\r
+              sm.evel_nfnamingcode_set("vVNF");\r
+              sm.evel_nfcnamingcode_set("vVNF");\r
+              sm.evel_measurement_myerrors_set(10,20,30,40);\r
+              MEASUREMENT_CPU_USE my1 = sm.evel_measurement_new_cpu_use_add("cpu1", 100.0);\r
+              my1.idle.SetValue(20.0);\r
+              my1.sys.SetValue(21.0);\r
+              MEASUREMENT_CPU_USE my2 = sm.evel_measurement_new_cpu_use_add("cpu2", 10.0);\r
+              my2.steal.SetValue(34.0);\r
+              my2.user.SetValue(32.0);\r
+\r
+\r
+              MEASUREMENT_VNIC_PERFORMANCE vnic_p = sm.evel_measurement_new_vnic_performance("vnic1","true");\r
+              vnic_p.recvd_bcast_packets_acc.SetValue(2400000.0);\r
+              vnic_p.recvd_mcast_packets_delta.SetValue(5677888.0);\r
+              vnic_p.recvd_mcast_packets_acc.SetValue(5677888.0);\r
+              vnic_p.tx_ucast_packets_acc.SetValue(547856576.0);\r
+              vnic_p.tx_ucast_packets_delta.SetValue(540000.0);\r
+              sm.evel_meas_vnic_performance_add(vnic_p);\r
+\r
+              AgentMain.evel_post_event(sm);\r
+              \r
+              EvelSyslog sysl = new EvelSyslog("Syslog_vVNF", "vmname_ip",\r
+                                           EvelFault.EVEL_SOURCE_TYPES.EVEL_SOURCE_ROUTER,\r
+                                          "Router failed","JUNIPER");\r
+              sysl.evel_nfnamingcode_set("vVNF");\r
+              sysl.evel_nfcnamingcode_set("vVNF");\r
+              sysl.evel_syslog_proc_id_set(456);\r
+              sysl.evel_syslog_proc_set("routed");\r
+              AgentMain.evel_post_event(sysl);\r
+              \r
+              EvelHeartbeatField hfld = new EvelHeartbeatField(123,"HeartbeatField_vVNF", "vmname_ip");\r
+              hfld.evel_hrtbt_interval_set(23);\r
+              AgentMain.evel_post_event(hfld);\r
+              \r
+              \r
+              EvelSipSignaling sip = new EvelSipSignaling("SipSignaling_vVNF", "vmname_ip","aricent","corlator","127.0.0.1","5647","10.1.1.124","5678");\r
+              sip.evel_nfnamingcode_set("vVNF");\r
+              sip.evel_nfcnamingcode_set("vVNF");\r
+              AgentMain.evel_post_event(sip);\r
+              \r
+              EvelVoiceQuality vq = new EvelVoiceQuality("VoiceQuality_vVNF", "vmname_ip",\r
+                         "calleeSideCodc",\r
+                           "callerSideCodc", "corlator",\r
+                           "midCllRtcp", "juniper");\r
+              vq.evel_nfnamingcode_set("vVNF");\r
+              vq.evel_nfcnamingcode_set("vVNF");\r
+              vq.evel_voice_quality_end_metrics_set("adjname", "Caller", 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 15.1, 160.12, 170, 180, 190);\r
+              AgentMain.evel_post_event(vq);\r
+              \r
+              EvelOther ev = new EvelOther("MyCustomEvent_vVNF", "vmname_ip");\r
+              ev.evel_other_field_add("a1", "b1");\r
+              ev.evel_other_field_add("a1", "b2");\r
+              \r
+              /*ev.evel_other_field_add_namedarray("a1", "b1", "c1");\r
+              ev.evel_other_field_add_namedarray("a1", "b2", "c2");\r
+              ev.evel_other_field_add_namedarray("a2", "b1", "c1");\r
+              ev.evel_other_field_add_namedarray("a2", "b1", "c1");*/\r
+              AgentMain.evel_post_event(ev);\r
+              \r
+              \r
+\r
+               String dateStart = "01/14/2012 09:29:58";\r
+               String dateStop = "01/15/2012 10:31:48";\r
+\r
+               //HH converts hour in 24 hours format (0-23), day calculation\r
+               SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");\r
+\r
+               Date d1 = null;\r
+               Date d2 = null;\r
+\r
+               try {\r
+                       d1 = format.parse(dateStart);\r
+                       d2 = format.parse(dateStop);\r
+               }catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+              \r
+              \r
+              EvelThresholdCross tca = new EvelThresholdCross("ThresholdCross_vVNF", "vmname_ip",\r
+              "CRIT",\r
+              "mcast Limit reached",\r
+              "mcastRxPackets",\r
+              "1250000000",\r
+              EvelThresholdCross.EVEL_EVENT_ACTION.EVEL_EVENT_ACTION_SET,\r
+              "Mcast Rx breached", \r
+              EvelThresholdCross.EVEL_ALERT_TYPE.EVEL_ELEMENT_ANOMALY,\r
+              d1, \r
+              EvelThresholdCross.EVEL_SEVERITIES.EVEL_SEVERITY_CRITICAL,\r
+              d2);\r
+              tca.evel_nfnamingcode_set("vVNF");\r
+              tca.evel_nfcnamingcode_set("vVNF");\r
+              tca.evel_threshold_cross_interfacename_set("ns345");\r
+              tca.evel_thresholdcross_addl_info_add("n1", "v1");\r
+              tca.evel_thresholdcross_addl_info_add("n2", "v2");\r
+              tca.evel_thresholdcross_alertid_add("alert1");\r
+              tca.evel_thresholdcross_alertid_add("alert2");\r
+              \r
+              AgentMain.evel_post_event(tca);\r
+              \r
+\r
+              EvelMobileFlow mf = new EvelMobileFlow("MobileFlow_vVNF", "vmname_ip",\r
+                         "In",\r
+                      null,\r
+                      "GTP",\r
+                       "v2.3",\r
+                      "1.2.3.4",\r
+                      345556,\r
+                      "5.6.7.8",\r
+                      334344);\r
+              MOBILE_GTP_PER_FLOW_METRICS mygtp = mf.new MOBILE_GTP_PER_FLOW_METRICS(\r
+                      1.01,\r
+                      2.02,\r
+                      3,\r
+                      4,\r
+                      5,\r
+                      6,\r
+                      7,\r
+                      8,\r
+                      9,\r
+                      d1,\r
+                      "ACTIVE",\r
+                      10,\r
+                      11,\r
+                      12,\r
+                      13,\r
+                      14,\r
+                      15,\r
+                      16,\r
+                      17,\r
+                      18,\r
+                      19,\r
+                      20,\r
+                      21,\r
+                      22,\r
+                      23,\r
+                      24,\r
+                      25,\r
+                      26,\r
+                      27,\r
+                      28);\r
+              mf.gtp_per_flow_metrics = mygtp;\r
+              mf.evel_nfnamingcode_set("vVNF");\r
+              mf.evel_nfcnamingcode_set("vVNF");\r
+              AgentMain.evel_post_event(mf);\r
+\r
+\r
+    }\r
+\r
+  }\r
+}\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/target/maven-archiver/pom.properties b/veslibrary/ves_javalibrary/evel_javalib2/target/maven-archiver/pom.properties
new file mode 100644 (file)
index 0000000..dcf099e
--- /dev/null
@@ -0,0 +1,5 @@
+#Generated by Maven\r
+#Wed Sep 20 23:50:43 EDT 2017\r
+version=0.0.1-SNAPSHOT\r
+groupId=evel_javalib2\r
+artifactId=evel_javalib2\r
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/veslibrary/ves_javalibrary/evel_javalib2/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644 (file)
index 0000000..352f685
--- /dev/null
@@ -0,0 +1,55 @@
+evel_javalibrary\att\com\EvelScalingMeasurement$MEASUREMENT_MEM_USE.class
+evel_javalibrary\att\com\EvelFault$EVEL_SEVERITIES.class
+evel_javalibrary\att\com\EvelMobileFlow.class
+evel_javalibrary\att\com\EvelSyslog$EVEL_SYSLOG_FACILITIES.class
+evel_javalibrary\att\com\EvelScalingMeasurement$CUSTOM_MEASUREMENT.class
+evel_javalibrary\att\com\EvelThresholdCross$PERF_COUNTER.class
+evel_javalibrary\att\com\EvelFault$EVEL_VF_STATUSES.class
+evel_javalibrary\att\com\EvelScalingMeasurement$MEASUREMENT_ERRORS.class
+evel_javalibrary\att\com\EvelScalingMeasurement.class
+evel_javalibrary\att\com\EvelMobileFlow$EVEL_TCP_FLAGS.class
+evel_javalibrary\att\com\EvelOptionTime.class
+evel_javalibrary\att\com\EvelScalingMeasurement$MEASUREMENT_CPU_USE.class
+evel_javalibrary\att\com\EvelScalingMeasurement$MEASUREMENT_CODEC_USE.class
+evel_javalibrary\att\com\RingBuffer.class
+evel_javalibrary\att\com\EvelMobileFlow$MOBILE_GTP_PER_FLOW_METRICS.class
+evel_javalibrary\att\com\EvelFault.class
+evel_javalibrary\att\com\EvelStateChange$EVEL_ENTITY_STATE.class
+evel_javalibrary\att\com\EvelHeader$1.class
+evel_javalibrary\att\com\EvelOther.class
+evel_javalibrary\att\com\AgentMain$EVEL_ERR_CODES.class
+evel_javalibrary\att\com\EvelVoiceQuality$END_OF_CALL_VOICE_QUALITY_METRICS.class
+evel_javalibrary\att\com\EvelScalingMeasurement$MEASUREMENT_GROUP.class
+evel_javalibrary\att\com\EvelVoiceQuality$VENDOR_VNFNAME_FIELD.class
+evel_javalibrary\att\com\EvelScalingMeasurement$MEASUREMENT_FEATURE_USE.class
+evel_javalibrary\att\com\EvelThresholdCross.class
+evel_javalibrary\att\com\EvelOptionString.class
+evel_javalibrary\att\com\AgentMain$1.class
+evel_javalibrary\att\com\EvelOption.class
+evel_javalibrary\att\com\EvelVoiceQuality.class
+evel_javalibrary\att\com\EvelThresholdCross$EVEL_ALERT_TYPE.class
+evel_javalibrary\att\com\EvelHeartbeatField.class
+evel_javalibrary\att\com\EvelHeader$PRIORITIES.class
+evel_javalibrary\att\com\EvelHeader.class
+evel_javalibrary\att\com\EvelThresholdCross$EVEL_SEVERITIES.class
+evel_javalibrary\att\com\EvelSyslog.class
+evel_javalibrary\att\com\EvelStateChange.class
+evel_javalibrary\att\com\EvelOptionIntHeader.class
+evel_javalibrary\att\com\EvelSipSignaling.class
+evel_javalibrary\att\com\EvelHeader$DOMAINS.class
+evel_javalibrary\att\com\EvelScalingMeasurement$MEASUREMENT_DISK_USE.class
+evel_javalibrary\att\com\EvelFault$EVEL_SOURCE_TYPES.class
+evel_javalibrary\att\com\EvelMobileFlow$EVEL_QCI_COS_TYPES.class
+evel_javalibrary\att\com\AgentMain$AgentDispatcher.class
+evel_javalibrary\att\com\EvelSipSignaling$VENDOR_VNFNAME_FIELD.class
+evel_javalibrary\att\com\EvelOptionDouble.class
+evel_javalibrary\att\com\EvelScalingMeasurement$MEASUREMENT_LATENCY_BUCKET.class
+evel_javalibrary\att\com\EvelScalingMeasurement$MEASUREMENT_VNIC_PERFORMANCE.class
+evel_javalibrary\att\com\AgentMain.class
+evel_javalibrary\att\com\EvelThresholdCross$EVEL_EVENT_ACTION.class
+evel_javalibrary\att\com\EvelStateChange$1.class
+evel_javalibrary\att\com\EvelVoiceQuality$EVEL_SERVICE_ENDPOINT_DESC.class
+evel_javalibrary\att\com\EvelScalingMeasurement$MEASUREMENT_FSYS_USE.class
+evel_javalibrary\att\com\EvelOptionInt.class
+evel_javalibrary\att\com\EvelOptionLong.class
+evel_javalibrary\att\com\EvelFault$1.class
diff --git a/veslibrary/ves_javalibrary/evel_javalib2/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/veslibrary/ves_javalibrary/evel_javalib2/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644 (file)
index 0000000..ebc3671
--- /dev/null
@@ -0,0 +1,20 @@
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelOptionDouble.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelOther.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelOption.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelStateChange.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelOptionString.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelHeartbeatField.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\AgentMain.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelSyslog.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelThresholdCross.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelHeader.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelMobileFlow.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelVoiceQuality.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelFault.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelSipSignaling.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelOptionInt.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelScalingMeasurement.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelOptionLong.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\RingBuffer.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelOptionIntHeader.java
+C:\Users\gs244f\workspace\evel_javalib2\src\evel_javalibrary\att\com\EvelOptionTime.java