Version 3.02 07/1807/1
authoraa7133@att.com <aa7133@att.com>
Wed, 27 Nov 2019 09:56:09 +0000 (11:56 +0200)
committeraa7133@att.com <aa7133@att.com>
Wed, 27 Nov 2019 10:09:22 +0000 (12:09 +0200)
Change cli to dsupport configuration file as property file that will allow the K8s to use configmap files
add support for stop start logging data collection
Add local address and port to TERM_INIT message with retry to set it if no messages from any xAPP

Change-Id: I20dad37904765a7ba98e514bb6f63fee5ca76b7a
Signed-off-by: aa7133@att.com <aa7133@att.com>
15 files changed:
.gitignore
.gitreview
RIC-E2-TERMINATION/CMakeLists.txt
RIC-E2-TERMINATION/Dockerfile
RIC-E2-TERMINATION/ReadConfigFile.h [new file with mode: 0644]
RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.cpp [new file with mode: 0644]
RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.h [new file with mode: 0644]
RIC-E2-TERMINATION/TEST/ConfigurationFileTest/testConfigFile.cpp [new file with mode: 0644]
RIC-E2-TERMINATION/TEST/e2sm.c
RIC-E2-TERMINATION/TEST/e2sm.h
RIC-E2-TERMINATION/TEST/e2smTest/Dockerfile [new file with mode: 0644]
RIC-E2-TERMINATION/config/config.conf [new file with mode: 0644]
RIC-E2-TERMINATION/container-tag.yaml
RIC-E2-TERMINATION/sctpThread.cpp
RIC-E2-TERMINATION/sctpThread.h

index 8fefad8..c71895f 100644 (file)
@@ -36,3 +36,7 @@ RIC-E2-TERMINATION/tracelibcpp/CMakeLists.txt
 RIC-E2-TERMINATION/nlohmann/
 RIC-E2-TERMINATION/concurrentqueue/
 /RIC-E2-TERMINATION/base64/
+/RIC-E2-TERMINATION/3rdparty/cxxopts/
+/RIC-E2-TERMINATION/3rdparty/cgreen_1.2.0_amd64.deb
+/testConfigFile
+/config/config.conf
index 351d6b6..303642c 100644 (file)
@@ -2,4 +2,4 @@
 host=gerrit.o-ran-sc.org
 port=29418
 project=ric-plt/e2
-defaultbranch=master
+defaultbranch=PI3
index 30e4f4f..ca55d24 100644 (file)
@@ -23,12 +23,13 @@ set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEV_PKG=1")
 
 #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DASN_DISABLE_OER_SUPPORT -DASN_PDU_COLLECTION -L. -LRIC-E2-TERMINATION/tracelibcpp/build -ggdb3 -Wall -W -Wpedantic")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DASN_DISABLE_OER_SUPPORT -DASN_PDU_COLLECTION -L. -LRIC-E2-TERMINATION/base64/lib -O3 -Wall -Wpedantic")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DASN_DISABLE_OER_SUPPORT -DASN_PDU_COLLECTION -L. -O3 -L/usr/lib -Wall -Wpedantic")
 #only c code with -O3
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DASN_DISABLE_OER_SUPPORT -DASN_PDU_COLLECTION -L. -LRIC-E2-TERMINATION/base64/lib -O3 -Wall -W -Wpedantic")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DASN_DISABLE_OER_SUPPORT -DASN_PDU_COLLECTION -L. -O3 -L/usr/lib -Wall -W -Wpedantic")
 
-include_directories(RIC-E2-TERMINATION)
-include_directories(RIC-E2-TERMINATION/asn1cFiles)
+include_directories(RIC-E2-TERMINATION
+        RIC-E2-TERMINATION/asn1cFiles
+        RIC-E2-TERMINATION/3rdparty)
 
 file(GLOB ASN_MODULE_SRCS "RIC-E2-TERMINATION/asn1cFiles/*.c")
 file(GLOB ASN_MODULE_HDRS "RIC-E2-TERMINATION/asn1cFiles/*.h")
@@ -58,9 +59,29 @@ add_library(e2sm
         RIC-E2-TERMINATION/TEST/e2sm.c
         RIC-E2-TERMINATION/TEST/e2sm.h
         ${ASN_MODULE_HDRS})
+
 add_definitions(-DBOOST_LOG_DYN_LINK)
 
-link_libraries(nsl sctp c m dl mdclog rmr_nng nng e2sm asn1codec boost_system boost_log_setup boost_log boost_date_time boost_thread rt boost_filesystem  pthread)
+link_libraries(nsl
+        sctp
+        c
+        m
+        dl
+        mdclog
+        rmr_nng
+        nng
+        e2sm
+        asn1codec
+        boost_system
+        boost_log_setup
+        boost_log
+        boost_date_time
+        boost_thread
+        boost_system
+        rt
+        boost_filesystem
+        cgreen
+        pthread)
 
 add_executable(e2 RIC-E2-TERMINATION/sctpThread.cpp
         RIC-E2-TERMINATION/sctpThread.h
@@ -68,7 +89,12 @@ add_executable(e2 RIC-E2-TERMINATION/sctpThread.cpp
         RIC-E2-TERMINATION/mapWrapper.h
         RIC-E2-TERMINATION/base64.h
         RIC-E2-TERMINATION/base64.cpp
+        RIC-E2-TERMINATION/ReadConfigFile.h
         )
 
 add_executable(e2smtest
         RIC-E2-TERMINATION/TEST/e2smTest/e2smtest.cpp)
+
+add_executable(testConfigFile
+        RIC-E2-TERMINATION/ReadConfigFile.h
+        RIC-E2-TERMINATION/TEST/ConfigurationFileTest/testConfigFile.cpp)
index 5860e37..a0cd909 100644 (file)
@@ -16,7 +16,7 @@
 #
 ##############################################################################
 
-FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu16-c-go:2-u16.04-nng as ubuntu
+FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu16-c-go:1-u16.04-nng1.1.1 as ubuntu
 
 WORKDIR /opt/e2/
 
@@ -26,15 +26,20 @@ RUN mkdir -p /opt/e2/RIC-E2-TERMINATION/ \
 COPY . /opt/e2/RIC-E2-TERMINATION/
 RUN mv /opt/e2/RIC-E2-TERMINATION/CMakeLists.txt /opt/e2/
 
-RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_1.10.0_amd64.deb/download.deb
-RUN dpkg -i rmr_1.10.0_amd64.deb
-RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_1.10.0_amd64.deb/download.deb
-RUN dpkg -i rmr-dev_1.10.0_amd64.deb
+RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_1.12.0_amd64.deb/download.deb
+RUN dpkg -i rmr_1.12.0_amd64.deb
+RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_1.12.0_amd64.deb/download.deb
+RUN dpkg -i rmr-dev_1.12.0_amd64.deb
 
 RUN apt-get install -y autoconf gawk libtool automake pkg-config autoconf-archive \
     && git clone http://gerrit.o-ran-sc.org/r/com/log \
     && cd log \
     && ./autogen.sh && ./configure && make && make install && ldconfig \
+    && cd /opt/e2/RIC-E2-TERMINATION/3rdparty && git clone https://github.com/jarro2783/cxxopts.git \
+    && cd cxxopts && mkdir build && cd build && cmake .. && make install && ldconfig \
+    && cd /opt/e2/RIC-E2-TERMINATION/3rdparty \
+    && wget --content-disposition https://github.com/cgreen-devs/cgreen/releases/download/1.2.0/cgreen_1.2.0_amd64.deb \
+    && dpkg -i cgreen_1.2.0_amd64.deb
     && cd /opt/e2/ && /usr/local/bin/cmake . && make
 
 #    && git clone http://gerrit.o-ran-sc.org/r/ric-plt/tracelibcpp \
@@ -48,10 +53,11 @@ RUN apt-get install -y autoconf gawk libtool automake pkg-config autoconf-archiv
 #    && find / -type f -name "libopentracing.a" -exec cp {} libopentracing.a \; && cd /opt/e2/RIC-E2-TERMINATION && ls nlohmann  \
 
 FROM ubuntu:16.04
-RUN apt-get update && apt-get install -y net-tools iputils-ping curl tcpdump
+RUN apt-get update && apt-get install -y net-tools iputils-ping curl tcpdump && mkdir /opt/e2/config
 
 COPY --from=ubuntu /opt/e2/e2 /opt/e2/e2
 COPY --from=ubuntu /opt/e2/RIC-E2-TERMINATION/dockerRouter.txt /opt/e2/dockerRouter.txt
+COPY --from=ubuntu /opt/e2/RIC-E2-TERMINATION/config/config.conf /opt/e2/config/config.conf
 #COPY --from=ubuntu /opt/e2/RIC-E2-TERMINATION/tracelibcpp/build/libtracelibcpp.so /usr/local/lib/libtracelibcpp.so
 #COPY --from=ubuntu /opt/e2/RIC-E2-TERMINATION/tracelibcpp/build/libtracelibcpp.so.0 /usr/local/lib/libtracelibcpp.so.0
 #COPY --from=ubuntu /opt/e2/RIC-E2-TERMINATION/tracelibcpp/build/libtracelibcpp.so.0.0.2 /usr/local/lib/libtracelibcpp.so.0.0.2
@@ -62,6 +68,10 @@ COPY --from=ubuntu /usr/local/lib/librmr_nng.so.1.10.0 /usr/local/lib/librmr_nng
 COPY --from=ubuntu /usr/local/lib/libnng.so.1 /usr/local/lib/libnng.so.1
 COPY --from=ubuntu /usr/local/lib/libmdclog.so.0 /usr/local/lib/libmdclog.so.0
 
+COPY --from=ubuntu /usr/local/lib/libcgreen.so.1.2.0 /usr/local/lib/libcgreen.so.1.2.0
+COPY --from=ubuntu /usr/local/lib/libcgreen.so.1 /usr/local/lib/libcgreen.so.1
+COPY --from=ubuntu /usr/local/lib/libcgreen.so /usr/local/lib/libcgreen.so
+
 COPY --from=ubuntu /usr/lib/libboost_log_setup.so /usr/lib/libboost_log_setup.so
 COPY --from=ubuntu /usr/lib/libboost_log_setup.so.1.69.0 /usr/lib/libboost_log_setup.so.1.69.0
 
@@ -93,8 +103,5 @@ COPY --from=ubuntu /usr/lib/x86_64-linux-gnu/libicudata.so.55.1 /usr/lib/x86_64-
 WORKDIR /opt/e2/
 ENV LD_LIBRARY_PATH=/usr/local/lib
 ENV RMR_SEED_RT=dockerRouter.txt
-ENV nano=38000
-ENV loglevel=info
-ENV volume="."
 EXPOSE 38000
-CMD ["sh", "-c", "./e2 nano $nano loglevel $loglevel volume $volume"]
+CMD ["sh", "-c", "./e2 -p config -f config.conf"]
diff --git a/RIC-E2-TERMINATION/ReadConfigFile.h b/RIC-E2-TERMINATION/ReadConfigFile.h
new file mode 100644 (file)
index 0000000..941be6e
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2019 AT&T Intellectual Property
+ * Copyright 2019 Nokia
+ *
+ * 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.
+ */
+
+//
+// Created by adi ENZEL on 11/19/19.
+//
+
+#ifndef E2_READCONFIGFILE_H
+#define E2_READCONFIGFILE_H
+
+#include <string>
+#include <unordered_map>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <cstdlib>
+
+#include <boost/algorithm/string.hpp>
+
+using namespace std;
+
+class ReadConfigFile {
+public:
+
+    explicit ReadConfigFile() = default;
+
+    int openConfigFile(std::string const& configFile) {
+        std::ifstream file(configFile.c_str());
+        if (!file) {  // file not found
+            //perror(configFile.c_str());
+            //mdclog_write(MDCLOG_ERR, "File: %s, failed to open", configFile.c_str());
+            return -1;
+        }
+        std::string line;
+
+        while (std::getline(file,line)) {
+            if (!line.length()) {  //line empty
+                continue;
+            } else if (line[0] == '#') {
+                continue;
+            } else if (line[0] == ';') {
+                continue;
+            }
+
+            auto leftHand = line.find('=');
+            auto name = line.substr(0,leftHand);
+            trim(name);
+            auto value = line.substr(leftHand+1);
+            trim(value);
+            //cout << "entry = " << name << " value = " << value  << endl;
+            entries[name] = value;
+        }
+        return 0;
+    }
+
+    /**
+     * @param key the key we are looking
+     * @return string value of the entry and "" if not exists
+     */
+    string getStringValue(std::string const& key) const {
+        auto entry = entries.find(key);
+        if (entry == entries.end()) {
+            return "";
+        }
+        return entry->second;
+    }
+
+    /**
+     * @param key the key we are looking
+     * @return int value of the entry and -1 if not exists
+     */
+    int getIntValue(std::string const& key) const {
+        auto entry = entries.find(key);
+        if (entry == entries.end()) {
+             return -1;
+        }
+        char *dummy;
+        int ret = (int)std::strtol(entry->second.c_str(), &dummy, 10);
+        //cout << "entry = " << key << " value = " << entry->second  << " int value = " << ret << endl;
+        return ret;
+    }
+
+    /**
+    * @param key the key we are looking
+    * @return double value of the entry and -1.0 if not exists
+    */
+    double getDoubleValue(std::string const& key) const {
+        auto entry = entries.find(key);
+        if (entry == entries.end()) {
+            return -1.0;
+        }
+        char *dummy;
+        return std::strtod(entry->second.c_str(), &dummy);
+    }
+
+private:
+    std::unordered_map<string, string> entries;
+
+
+    inline static std::string& ltrim(std::string& str, const std::string& chars = "\t\n\v\f\r ") {
+        str.erase(0, str.find_first_not_of(chars));
+        return str;
+    }
+
+    inline static std::string& rtrim(std::string& str, const std::string& chars = "\t\n\v\f\r ") {
+        str.erase(str.find_last_not_of(chars) + 1);
+        return str;
+    }
+
+    inline static std::string& trim(std::string& str, const std::string& chars = "\t\n\v\f\r ") {
+        return ltrim(rtrim(str, chars), chars);
+    }
+};
+
+
+#endif //E2_READCONFIGFILE_H
diff --git a/RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.cpp b/RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.cpp
new file mode 100644 (file)
index 0000000..c367d5e
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2019 AT&T Intellectual Property
+ * Copyright 2019 Nokia
+ *
+ * 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.
+ */
+
+//
+// Created by adi ENZEL on 11/26/19.
+//
+
+#include "LogTest.h"
+
diff --git a/RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.h b/RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.h
new file mode 100644 (file)
index 0000000..b18f395
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2019 AT&T Intellectual Property
+ * Copyright 2019 Nokia
+ *
+ * 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.
+ */
+
+//
+// Created by adi ENZEL on 11/26/19.
+//
+
+#ifndef E2_LOGTEST_H
+#define E2_LOGTEST_H
+#include <algorithm>
+
+#include <cstdio>
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+#include <random>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/sctp.h>
+#include <thread>
+#include <atomic>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <ctime>
+#include <netdb.h>
+#include <sys/epoll.h>
+#include <mutex>
+#include <shared_mutex>
+#include <iterator>
+#include <map>
+
+using namespace std;
+
+class LogTest {
+public:
+    LogTest() = default;
+
+    openFile(string const& configFile);
+
+};
+
+
+#endif //E2_LOGTEST_H
diff --git a/RIC-E2-TERMINATION/TEST/ConfigurationFileTest/testConfigFile.cpp b/RIC-E2-TERMINATION/TEST/ConfigurationFileTest/testConfigFile.cpp
new file mode 100644 (file)
index 0000000..da8fb5d
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2019 AT&T Intellectual Property
+ * Copyright 2019 Nokia
+ *
+ * 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.
+ */
+
+//
+// Created by adi ENZEL on 11/19/19.
+//
+
+#include "ReadConfigFile.h"
+#include <mdclog/mdclog.h>
+#include <cgreen/cgreen.h>
+
+Describe(Cgreen);
+BeforeEach(Cgreen) {}
+AfterEach(Cgreen) {}
+
+using namespace cgreen;
+
+void init_log() {
+    mdclog_attr_t *attr;
+    mdclog_attr_init(&attr);
+    mdclog_attr_set_ident(attr, "TestConfiguration");
+    mdclog_init(attr);
+    mdclog_attr_destroy(attr);
+}
+
+Ensure(Cgreen, fileNotExist) {
+    ReadConfigFile  conf {};
+    assert_that( conf.openConfigFile("kuku") == -1);
+}
+
+Ensure(Cgreen, fileExists) {
+    ReadConfigFile  conf {};
+    assert_that(conf.openConfigFile("config") == 0);
+}
+
+Ensure(Cgreen, goodparams) {
+    ReadConfigFile  conf {};
+    assert_that(conf.openConfigFile("config") == 0);
+    assert_that(conf.getIntValue("nano") == 38002);
+    assert_that(conf.getStringValue("loglevel") == "info");
+    assert_that(conf.getStringValue("volume") == ".");
+
+}
+
+Ensure(Cgreen, badParams) {
+    ReadConfigFile  conf {};
+    assert_that(conf.openConfigFile("config") == 0);
+    assert_that(conf.getIntValue("nano") != 38000);
+    assert_that(conf.getStringValue("loglevel") != "");
+    assert_that(conf.getStringValue("volume") != "bob");
+    assert_that(conf.getStringValue("volum") != "bob");
+}
+
+Ensure(Cgreen, wrongType) {
+    ReadConfigFile  conf {};
+    assert_that(conf.openConfigFile("config") == 0);
+    assert_that(conf.getStringValue("nano") != "debug");
+    assert_that(conf.getIntValue("loglevel") != 3);
+    assert_that(conf.getDoubleValue("loglevel") != 3.0);
+}
+
+
+int main(const int argc, char **argv) {
+    mdclog_severity_t loglevel = MDCLOG_INFO;
+    init_log();
+    mdclog_level_set(loglevel);
+
+    //TestSuite *suite = create_test_suite();
+    TestSuite *suite = create_named_test_suite_(__FUNCTION__, __FILE__, __LINE__);
+
+    add_test_with_context(suite, Cgreen, fileNotExist);
+    add_test_with_context(suite, Cgreen, fileExists);
+    add_test_with_context(suite, Cgreen, goodparams);
+    add_test_with_context(suite, Cgreen, badParams);
+    add_test_with_context(suite, Cgreen, wrongType);
+
+    return cgreen::run_test_suite(suite, create_text_reporter());
+
+}
\ No newline at end of file
index 077be9b..5fff9e3 100644 (file)
@@ -50,7 +50,7 @@ static size_t encodebuff(int codingType,
     clock_gettime(CLOCK_MONOTONIC, &end);
     if (er.encoded == -1) {
         mdclog_write(MDCLOG_ERR, "encoding of %s failed, %s", asn_DEF_E2SM_gNB_X2_eventTriggerDefinition.name, strerror(errno));
-    } else if (er.encoded > buffer_size) {
+    } else if (er.encoded > (ssize_t)buffer_size) {
         mdclog_write(MDCLOG_ERR, "Buffer of size %d is to small for %s", (int) buffer_size,
                      typeDescriptor->name);
     } else if (mdclog_level_get() >= MDCLOG_DEBUG) {
@@ -76,7 +76,7 @@ static size_t encodebuff(int codingType,
 }
 
 PLMN_Identity_t *createPLMN_ID(const unsigned char *data) {
-    printEntry("PLMN_Identity_t", __func__);
+    printEntry("PLMN_Identity_t", __func__)
     PLMN_Identity_t *plmnId = calloc(1, sizeof(PLMN_Identity_t));
     ASN_STRUCT_RESET(asn_DEF_PLMN_Identity, plmnId);
     plmnId->size = 3;
@@ -91,7 +91,7 @@ PLMN_Identity_t *createPLMN_ID(const unsigned char *data) {
 }
 
 ENB_ID_t *createENB_ID(ENB_ID_PR enbType, unsigned char *data) {
-    printEntry("ENB_ID_t", __func__);
+    printEntry("ENB_ID_t", __func__)
     ENB_ID_t *enb = calloc(1, sizeof(ENB_ID_t));
     ASN_STRUCT_RESET(asn_DEF_ENB_ID, enb);
     switch (enbType) {
@@ -154,7 +154,7 @@ ENB_ID_t *createENB_ID(ENB_ID_PR enbType, unsigned char *data) {
 }
 
 GNB_ID_t *createGnb_id(const unsigned char *data, int numOfBits) {
-    printEntry("GNB_ID_t", __func__);
+    printEntry("GNB_ID_t", __func__)
     if (numOfBits < 22 || numOfBits > 32) {
         mdclog_write(MDCLOG_ERR, "GNB_ID_t number of bits = %d, needs to be 22 .. 32", numOfBits);
         return NULL;
@@ -164,7 +164,7 @@ GNB_ID_t *createGnb_id(const unsigned char *data, int numOfBits) {
 
     gnb->present = GNB_ID_PR_gNB_ID;
     gnb->choice.gNB_ID.size = numOfBits % 8 == 0 ? (unsigned int)(numOfBits / 8) : (unsigned int)(numOfBits / 8 + 1);
-    gnb->choice.gNB_ID.bits_unused = gnb->choice.gNB_ID.size * 8 - numOfBits;
+    gnb->choice.gNB_ID.bits_unused = (int)gnb->choice.gNB_ID.size * 8 - numOfBits;
     gnb->choice.gNB_ID.buf = calloc(1, gnb->choice.gNB_ID.size);
     memcpy(gnb->choice.gNB_ID.buf, data, gnb->choice.gNB_ID.size);
     gnb->choice.gNB_ID.buf[gnb->choice.gNB_ID.size - 1] =
@@ -180,7 +180,7 @@ GNB_ID_t *createGnb_id(const unsigned char *data, int numOfBits) {
 }
 
 GlobalENB_ID_t *createGlobalENB_ID(PLMN_Identity_t *plmnIdentity, ENB_ID_t *enbId) {
-    printEntry("GlobalENB_ID_t", __func__);
+    printEntry("GlobalENB_ID_t", __func__)
     GlobalENB_ID_t *genbId = calloc(1, sizeof(GlobalENB_ID_t));
     ASN_STRUCT_RESET(asn_DEF_GlobalENB_ID, genbId);
     memcpy(&genbId->pLMN_Identity, plmnIdentity, sizeof(PLMN_Identity_t));
@@ -193,7 +193,7 @@ GlobalENB_ID_t *createGlobalENB_ID(PLMN_Identity_t *plmnIdentity, ENB_ID_t *enbI
 }
 
 GlobalGNB_ID_t *createGlobalGNB_ID(PLMN_Identity_t *plmnIdentity, GNB_ID_t *gnb) {
-    printEntry("GlobalGNB_ID_t", __func__);
+    printEntry("GlobalGNB_ID_t", __func__)
     GlobalGNB_ID_t *ggnbId = calloc(1, sizeof(GlobalGNB_ID_t));
     ASN_STRUCT_RESET(asn_DEF_GlobalGNB_ID, ggnbId);
 
@@ -209,7 +209,7 @@ GlobalGNB_ID_t *createGlobalGNB_ID(PLMN_Identity_t *plmnIdentity, GNB_ID_t *gnb)
 
 
 Interface_ID_t *createInterfaceIDForGnb(GlobalGNB_ID_t *gnb) {
-    printEntry("Interface_ID_t", __func__);
+    printEntry("Interface_ID_t", __func__)
     Interface_ID_t *interfaceId = calloc(1, sizeof(Interface_ID_t));
     ASN_STRUCT_RESET(asn_DEF_Interface_ID, interfaceId);
 
@@ -225,7 +225,7 @@ Interface_ID_t *createInterfaceIDForGnb(GlobalGNB_ID_t *gnb) {
 }
 
 Interface_ID_t *createInterfaceIDForEnb(GlobalENB_ID_t *enb) {
-    printEntry("Interface_ID_t", __func__);
+    printEntry("Interface_ID_t", __func__)
     Interface_ID_t *interfaceId = calloc(1, sizeof(Interface_ID_t));
     ASN_STRUCT_RESET(asn_DEF_Interface_ID, interfaceId);
 
@@ -243,7 +243,7 @@ Interface_ID_t *createInterfaceIDForEnb(GlobalENB_ID_t *enb) {
 
 
 InterfaceMessageType_t *createInterfaceMessageInitiating(long procedureCode) {
-    printEntry("InterfaceMessageType_t", __func__);
+    printEntry("InterfaceMessageType_t", __func__)
     InterfaceMessageType_t *intMsgT = calloc(1, sizeof(InterfaceMessageType_t));
     ASN_STRUCT_RESET(asn_DEF_InterfaceMessageType, intMsgT);
 
@@ -258,7 +258,7 @@ InterfaceMessageType_t *createInterfaceMessageInitiating(long procedureCode) {
 }
 
 InterfaceMessageType_t *createInterfaceMessageSuccsesful(long procedureCode) {
-    printEntry("InterfaceMessageType_t", __func__);
+    printEntry("InterfaceMessageType_t", __func__)
     InterfaceMessageType_t *intMsgT = calloc(1, sizeof(InterfaceMessageType_t));
     ASN_STRUCT_RESET(asn_DEF_InterfaceMessageType, intMsgT);
 
@@ -273,7 +273,7 @@ InterfaceMessageType_t *createInterfaceMessageSuccsesful(long procedureCode) {
 }
 
 InterfaceMessageType_t *createInterfaceMessageUnsuccessful(long procedureCode) {
-    printEntry("InterfaceMessageType_t", __func__);
+    printEntry("InterfaceMessageType_t", __func__)
     InterfaceMessageType_t *intMsgT = calloc(1, sizeof(InterfaceMessageType_t));
     ASN_STRUCT_RESET(asn_DEF_InterfaceMessageType, intMsgT);
 
@@ -288,7 +288,7 @@ InterfaceMessageType_t *createInterfaceMessageUnsuccessful(long procedureCode) {
 }
 
 InterfaceProtocolIE_Value_t *createInterfaceProtocolValueInt(long number) {
-    printEntry("InterfaceProtocolIE_Value_t", __func__);
+    printEntry("InterfaceProtocolIE_Value_t", __func__)
     InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t));
     ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value);
 
@@ -303,7 +303,7 @@ InterfaceProtocolIE_Value_t *createInterfaceProtocolValueInt(long number) {
 }
 
 InterfaceProtocolIE_Value_t *createInterfaceProtocolValueEnum(long number) {
-    printEntry("InterfaceProtocolIE_Value_t", __func__);
+    printEntry("InterfaceProtocolIE_Value_t", __func__)
     InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t));
     ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value);
 
@@ -318,7 +318,7 @@ InterfaceProtocolIE_Value_t *createInterfaceProtocolValueEnum(long number) {
 }
 
 InterfaceProtocolIE_Value_t *createInterfaceProtocolValueBool(int val) {
-    printEntry("InterfaceProtocolIE_Value_t", __func__);
+    printEntry("InterfaceProtocolIE_Value_t", __func__)
     InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t));
     ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value);
 
@@ -334,7 +334,7 @@ InterfaceProtocolIE_Value_t *createInterfaceProtocolValueBool(int val) {
 
 
 InterfaceProtocolIE_Value_t *createInterfaceProtocolValueBitString(unsigned char *buf, int numOfBits) {
-    printEntry("InterfaceProtocolIE_Value_t", __func__);
+    printEntry("InterfaceProtocolIE_Value_t", __func__)
     size_t size = numOfBits % 8 == 0 ? (unsigned int)(numOfBits / 8) : (unsigned int)(numOfBits / 8 + 1);
     if (strlen((const char *)buf) < size) {
         mdclog_write(MDCLOG_ERR, "size of buffer is small : %d needs to be %d in %s", (int)strlen((const char *)buf), (int)size, __func__);
@@ -345,7 +345,7 @@ InterfaceProtocolIE_Value_t *createInterfaceProtocolValueBitString(unsigned char
     value->present = InterfaceProtocolIE_Value_PR_valueBitS;
     value->choice.valueBitS.size = numOfBits % 8 == 0 ? (unsigned int)(numOfBits / 8) : (unsigned int)(numOfBits / 8 + 1);
     value->choice.valueBitS.buf = calloc(1, value->choice.valueBitS.size);
-    int bits_unused = value->choice.valueBitS.size * 8 - numOfBits;
+    int bits_unused = (int)value->choice.valueBitS.size * 8 - numOfBits;
     value->choice.valueBitS.bits_unused = bits_unused;
 
     memcpy(value->choice.valueBitS.buf, buf, value->choice.valueBitS.size);
@@ -360,7 +360,7 @@ InterfaceProtocolIE_Value_t *createInterfaceProtocolValueBitString(unsigned char
 
 
 InterfaceProtocolIE_Value_t *createInterfaceProtocolValueOCTETS(uint8_t *buf) {
-    printEntry("InterfaceProtocolIE_Value_t", __func__);
+    printEntry("InterfaceProtocolIE_Value_t", __func__)
     size_t size = strlen((const char *)buf);
     InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t));
     ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value);
@@ -379,7 +379,7 @@ InterfaceProtocolIE_Value_t *createInterfaceProtocolValueOCTETS(uint8_t *buf) {
 
 
 InterfaceProtocolIE_Item_t *createInterfaceProtocolIE_Item(long id, long test, InterfaceProtocolIE_Value_t *value) {
-    printEntry("InterfaceProtocolIE_Item_t", __func__);
+    printEntry("InterfaceProtocolIE_Item_t", __func__)
     if (test < InterfaceProtocolIE_Test_equal || test > InterfaceProtocolIE_Test_present) {
         mdclog_write(MDCLOG_ERR, "InterfaceProtocolIE_Item_t test value is %ld,  out of scope %d .. %d ",
                 test, InterfaceProtocolIE_Test_equal, InterfaceProtocolIE_Test_present);
@@ -406,7 +406,7 @@ InterfaceProtocolIE_Item_t *createInterfaceProtocolIE_Item(long id, long test, I
 
 
 ActionParameter_Value_t *createActionParameterValue_Int(long number) {
-    printEntry("ActionParameter_Value_t", __func__);
+    printEntry("ActionParameter_Value_t", __func__)
     ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t));
     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value);
 
@@ -421,7 +421,7 @@ ActionParameter_Value_t *createActionParameterValue_Int(long number) {
 }
 
 ActionParameter_Value_t *createActionParameterValue_Enum(long number) {
-    printEntry("ActionParameter_Value_t", __func__);
+    printEntry("ActionParameter_Value_t", __func__)
     ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t));
     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value);
 
@@ -436,7 +436,7 @@ ActionParameter_Value_t *createActionParameterValue_Enum(long number) {
 }
 
 ActionParameter_Value_t *createActionParameterValue_Bool(int val) {
-    printEntry("ActionParameter_Value_t", __func__);
+    printEntry("ActionParameter_Value_t", __func__)
     ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t));
     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value);
 
@@ -452,12 +452,12 @@ ActionParameter_Value_t *createActionParameterValue_Bool(int val) {
 
 
 ActionParameter_Value_t *createActionParameterValue_Bit_String(unsigned char *buf, int numOfBits) {
-    printEntry("ActionParameter_Value_t", __func__);
+    printEntry("ActionParameter_Value_t", __func__)
     size_t size = numOfBits % 8 == 0 ? (unsigned int)(numOfBits / 8) : (unsigned int)(numOfBits / 8 + 1);
     if (strlen((const char *)buf) < size) {
         mdclog_write(MDCLOG_ERR, "size of buffer is small : %d needs to be %d in %s", (int)strlen((const char *)buf), (int)size, __func__);
     }
-    int bits_unused = size * 8 - numOfBits;
+    int bits_unused = (int)size * 8 - numOfBits;
 
     ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t));
     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value);
@@ -479,7 +479,7 @@ ActionParameter_Value_t *createActionParameterValue_Bit_String(unsigned char *bu
 
 
 ActionParameter_Value_t *createActionParameterValue_OCTETS(uint8_t *buf) {
-    printEntry("ActionParameter_Value_t", __func__);
+    printEntry("ActionParameter_Value_t", __func__)
     size_t size = strlen((const char *)buf);
     ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t));
     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value);
@@ -502,7 +502,7 @@ ActionParameter_Value_t *createActionParameterValue_OCTETS(uint8_t *buf) {
  * @return ActionParameter_Value_t *
  */
 ActionParameter_Value_t *createActionParameterValue_PRINTS(char *buf) {
-    printEntry("ActionParameter_Value_t", __func__);
+    printEntry("ActionParameter_Value_t", __func__)
     size_t size = strlen((const char *)buf);
     ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t));
     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value);
@@ -520,7 +520,7 @@ ActionParameter_Value_t *createActionParameterValue_PRINTS(char *buf) {
 }
 
 ActionParameter_Item_t *creatActionParameter_Item(long id, ActionParameter_Value_t *val) {
-    printEntry("ActionParameter_Item_t", __func__);
+    printEntry("ActionParameter_Item_t", __func__)
     if (id < 0 || id > 255) {
         mdclog_write(MDCLOG_ERR, "ActionParameter_Item_t id = %ld, values are 0 .. 255", id);
         return NULL;
@@ -555,7 +555,7 @@ size_t createEventTrigger(Interface_ID_t *interfaceId, long direction,
                           int listSize,
                           uint8_t *buffer,
                           size_t buffer_size) {
-    printEntry("E2SM_gNB_X2_eventTriggerDefinition_t", __func__);
+    printEntry("E2SM_gNB_X2_eventTriggerDefinition_t", __func__)
     if (direction < InterfaceDirection_incoming || direction > InterfaceDirection_outgoing) {
         mdclog_write(MDCLOG_ERR, "E2SM_gNB_X2_eventTriggerDefinition_t direction = %ld, values are %d .. %d",
                      direction, InterfaceDirection_incoming, InterfaceDirection_outgoing);
@@ -586,7 +586,7 @@ size_t createEventTrigger(Interface_ID_t *interfaceId, long direction,
 
     if (mdclog_level_get() >= MDCLOG_INFO) {
         uint8_t buf1[4096];
-        asn_enc_rval_t er1;
+        //asn_enc_rval_t er1;
         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_eventTriggerDefinition,
                                  eventTrigger,
                                  buf1,
@@ -601,7 +601,7 @@ size_t createEventTrigger(Interface_ID_t *interfaceId, long direction,
 size_t createActionDefinition(long styleId, ActionParameter_Item_t actionParamList[], int listSize,
                                                        uint8_t *buffer,
                                                        size_t buffer_size) {
-    printEntry("E2SM_gNB_X2_actionDefinition_t", __func__);
+    printEntry("E2SM_gNB_X2_actionDefinition_t", __func__)
     E2SM_gNB_X2_actionDefinition_t *actDef = calloc(1, sizeof(E2SM_gNB_X2_actionDefinition_t));
     ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_actionDefinition, actDef);
 
@@ -622,7 +622,7 @@ size_t createActionDefinition(long styleId, ActionParameter_Item_t actionParamLi
 
     if (mdclog_level_get() >= MDCLOG_INFO) {
         uint8_t buf1[4096];
-        asn_enc_rval_t er1;
+        //asn_enc_rval_t er1;
         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_actionDefinition,
                    actDef,
                    buf1,
@@ -639,7 +639,7 @@ size_t createE2SM_gNB_X2_indicationHeader(long direction,
                                           int size,
                                           uint8_t *buffer,
                                           size_t buffer_size) {
-    printEntry("E2SM_gNB_X2_indicationHeader_t", __func__);
+    printEntry("E2SM_gNB_X2_indicationHeader_t", __func__)
     if (direction < InterfaceDirection_incoming || direction > InterfaceDirection_outgoing) {
         mdclog_write(MDCLOG_ERR, "E2SM_gNB_X2_indicationHeader_t direction = %ld, values are %d .. %d",
                      direction, InterfaceDirection_incoming, InterfaceDirection_outgoing);
@@ -668,7 +668,7 @@ size_t createE2SM_gNB_X2_indicationHeader(long direction,
 
     if (mdclog_level_get() >= MDCLOG_INFO) {
         uint8_t buf1[4096];
-        asn_enc_rval_t er1;
+        //asn_enc_rval_t er1;
         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_indicationHeader,
                    indiHead,
                    buf1,
@@ -682,7 +682,7 @@ size_t createE2SM_gNB_X2_indicationHeader(long direction,
 size_t createE2SM_gNB_X2_indicationMessage(uint8_t *message, uint msgSize,
                                                                      uint8_t *buffer,
                                                                      size_t buffer_size) {
-    printEntry("E2SM_gNB_X2_indicationMessage_t", __func__);
+    printEntry("E2SM_gNB_X2_indicationMessage_t", __func__)
     if (msgSize <= 0) {
         mdclog_write(MDCLOG_ERR, "E2SM_gNB_X2_indicationMessage_t failed messsage size =  %d", msgSize);
         return -1;
@@ -707,7 +707,7 @@ size_t createE2SM_gNB_X2_indicationMessage(uint8_t *message, uint msgSize,
 
     if (mdclog_level_get() >= MDCLOG_INFO) {
         uint8_t buf1[4096];
-        asn_enc_rval_t er1;
+        //asn_enc_rval_t er1;
         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_indicationMessage,
                    indicationMessage,
                    buf1,
@@ -722,7 +722,7 @@ size_t createE2SM_gNB_X2_indicationMessage(uint8_t *message, uint msgSize,
 size_t createE2SM_gNB_X2_callProcessID(long callProcess_Id,
                                                              uint8_t *buffer,
                                                              size_t buffer_size) {
-    printEntry("E2SM_gNB_X2_callProcessID_t", __func__);
+    printEntry("E2SM_gNB_X2_callProcessID_t", __func__)
     E2SM_gNB_X2_callProcessID_t *callProcessId = calloc(1, sizeof(E2SM_gNB_X2_callProcessID_t));
     ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_callProcessID, callProcessId);
 
@@ -740,7 +740,7 @@ size_t createE2SM_gNB_X2_callProcessID(long callProcess_Id,
 
     if (mdclog_level_get() >= MDCLOG_INFO) {
         uint8_t buf1[4096];
-        asn_enc_rval_t er1;
+        //asn_enc_rval_t er1;
         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_callProcessID,
                    callProcessId,
                    buf1,
@@ -754,7 +754,7 @@ size_t createE2SM_gNB_X2_callProcessID(long callProcess_Id,
 size_t createE2SM_gNB_X2_controlHeader(Interface_ID_t *interfaceId, long direction,
                                                              uint8_t *buffer,
                                                              size_t buffer_size) {
-    printEntry("E2SM_gNB_X2_controlHeader_t", __func__);
+    printEntry("E2SM_gNB_X2_controlHeader_t", __func__)
     if (direction < InterfaceDirection_incoming || direction > InterfaceDirection_outgoing) {
         mdclog_write(MDCLOG_ERR, "E2SM_gNB_X2_controlHeader_t direction = %ld, values are %d .. %d",
                      direction, InterfaceDirection_incoming, InterfaceDirection_outgoing);
@@ -778,7 +778,7 @@ size_t createE2SM_gNB_X2_controlHeader(Interface_ID_t *interfaceId, long directi
 
     if (mdclog_level_get() >= MDCLOG_INFO) {
         uint8_t buf1[4096];
-        asn_enc_rval_t er1;
+        //asn_enc_rval_t er1;
         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_controlHeader,
                    controlHeader,
                    buf1,
@@ -793,7 +793,7 @@ size_t createE2SM_gNB_X2_controlHeader(Interface_ID_t *interfaceId, long directi
 size_t createE2SM_gNB_X2_controlMessage(uint8_t *message, uint msgSize,
                                                                uint8_t *buffer,
                                                                size_t buffer_size) {
-    printEntry("E2SM_gNB_X2_controlMessage_t", __func__);
+    printEntry("E2SM_gNB_X2_controlMessage_t", __func__)
     E2SM_gNB_X2_controlMessage_t *controlMsg = calloc(1, sizeof(E2SM_gNB_X2_controlMessage_t));
     ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_controlMessage, controlMsg);
 
@@ -813,7 +813,7 @@ size_t createE2SM_gNB_X2_controlMessage(uint8_t *message, uint msgSize,
 
     if (mdclog_level_get() >= MDCLOG_INFO) {
         uint8_t buf1[4096];
-        asn_enc_rval_t er1;
+        //asn_enc_rval_t er1;
         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_controlMessage,
                    controlMsg,
                    buf1,
@@ -822,4 +822,4 @@ size_t createE2SM_gNB_X2_controlMessage(uint8_t *message, uint msgSize,
     }
 
     return len;
-}
\ No newline at end of file
+}
index a4e432f..56e6e18 100644 (file)
@@ -43,26 +43,26 @@ extern "C"
 #include <math.h>
 
 
-#include "../asn1cFiles/ENB-ID.h"
-
-#include "../asn1cFiles/E2SM-gNB-X2-actionDefinition.h"
-
-#include "../asn1cFiles/E2SM-gNB-X2-callProcessID.h"
-#include "../asn1cFiles/E2SM-gNB-X2-controlHeader.h"
-#include "../asn1cFiles/E2SM-gNB-X2-controlMessage.h"
-#include "../asn1cFiles/E2SM-gNB-X2-indicationHeader.h"
-#include "../asn1cFiles/E2SM-gNB-X2-indicationMessage.h"
-#include "../asn1cFiles/E2SM-gNB-X2-eventTriggerDefinition.h"
-
-
-#include "../asn1cFiles/ActionParameter-Item.h"
-#include "../asn1cFiles/ActionParameter-Value.h"
-#include "../asn1cFiles/PLMN-Identity.h"
-#include "../asn1cFiles/GlobalENB-ID.h"
-#include "../asn1cFiles/GlobalGNB-ID.h"
-#include "../asn1cFiles/Interface-ID.h"
-#include "../asn1cFiles/InterfaceMessageType.h"
-#include "../asn1cFiles/InterfaceProtocolIE-Item.h"
+#include "asn1cFiles/ENB-ID.h"
+
+#include "asn1cFiles/E2SM-gNB-X2-actionDefinition.h"
+
+#include "asn1cFiles/E2SM-gNB-X2-callProcessID.h"
+#include "asn1cFiles/E2SM-gNB-X2-controlHeader.h"
+#include "asn1cFiles/E2SM-gNB-X2-controlMessage.h"
+#include "asn1cFiles/E2SM-gNB-X2-indicationHeader.h"
+#include "asn1cFiles/E2SM-gNB-X2-indicationMessage.h"
+#include "asn1cFiles/E2SM-gNB-X2-eventTriggerDefinition.h"
+
+
+#include "asn1cFiles/ActionParameter-Item.h"
+#include "asn1cFiles/ActionParameter-Value.h"
+#include "asn1cFiles/PLMN-Identity.h"
+#include "asn1cFiles/GlobalENB-ID.h"
+#include "asn1cFiles/GlobalGNB-ID.h"
+#include "asn1cFiles/Interface-ID.h"
+#include "asn1cFiles/InterfaceMessageType.h"
+#include "asn1cFiles/InterfaceProtocolIE-Item.h"
 
 /**
  *
diff --git a/RIC-E2-TERMINATION/TEST/e2smTest/Dockerfile b/RIC-E2-TERMINATION/TEST/e2smTest/Dockerfile
new file mode 100644 (file)
index 0000000..9b614c8
--- /dev/null
@@ -0,0 +1,67 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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 snapshot.docker.ranco-dev-tools.eastus.cloudapp.azure.com:10001/e2_base:1.0.0 as ubuntu
+
+WORKDIR /opt/e2/
+RUN mkdir -p /opt/e2/RIC-E2-TERMINATION/TEST \
+    && mkdir -p /opt/e2/RIC-E2-TERMINATION/TEST/e2smTest \
+    && mkdir -p /opt/e2/RIC-E2-TERMINATION/TEST/asn1c
+COPY . /opt/e2/RIC-E2-TERMINATION/
+RUN mv /opt/e2/RIC-E2-TERMINATION/CMakeLists.txt /opt/e2/
+
+RUN echo "137.135.91.204 gerrit.ranco-dev-tools.eastus.cloudapp.azure.com" >> /etc/hosts \
+    && apt-get install -y autoconf gawk libtool automake bison flex pkg-config autoconf-archive \
+    && git clone http://gerrit.ranco-dev-tools.eastus.cloudapp.azure.com/com/log \
+    && cd log && ./autogen.sh && ./configure && make && make install && ldconfig \
+    && cd /opt/e2/
+
+
+RUN  git clone https://github.com/vlm/asn1c.git \
+     && cd asn1c/; test -f configure || autoreconf -iv; ./configure; make install; ldconfig \
+     && cd /opt/e2/
+
+
+RUN  git clone https://gerrit.o-ran-sc.org/r/ric-plt/lib/rmr \
+     && cd rmr/; mkdir build; cd build; /opt/bin/cmake -DDEV_PKG=1 ..; make install \
+     && cd /opt/e2/ && /opt/bin/cmake . && make
+
+
+
+
+
+FROM ubuntu:16.04
+COPY --from=ubuntu /opt/e2/e2smtest /opt/e2/e2smtest
+COPY --from=ubuntu /opt/e2/RIC-E2-TERMINATION/TEST/T1/dockerRouter.txt /opt/e2/dockerRouter.txt
+COPY --from=ubuntu /usr/local/lib/librmr_nng.so.1 /usr/local/lib/librmr_nng.so.1
+COPY --from=ubuntu /usr/local/lib/libnng.so.1 /usr/local/lib/libnng.so.1
+COPY --from=ubuntu /usr/local/lib/libmdclog.so.0 /usr/local/lib/libmdclog.so.0
+COPY --from=ubuntu /opt/e2/libe2sm.a /usr/local/lib/libe2sm.a
+
+WORKDIR /opt/e2/
+ENV LD_LIBRARY_PATH=/usr/local/lib
+#ENV RMR_RTG_SVC=127.0.0.1
+ENV RMR_SEED_RT=dockerRouter.txt
+ENV host=127.0.0.1
+ENV port=5566
+ENV ran=ranname
+ENV rmr=38012
+ENV loglevel=info
+EXPOSE 5566
+EXPOSE 38012
+CMD ["sh", "-c", "./e2smtest" ]
diff --git a/RIC-E2-TERMINATION/config/config.conf b/RIC-E2-TERMINATION/config/config.conf
new file mode 100644 (file)
index 0000000..0b9dab1
--- /dev/null
@@ -0,0 +1,6 @@
+nano=38000
+loglevel=info
+volume=log
+local-ip=127.0.0.1
+#trace is start, stop
+trace=start
index ecd34c6..60ce207 100644 (file)
@@ -1,4 +1,3 @@
 # The Jenkins job requires a tag to build the Docker image.
 # Global-JJB script assumes this file is in the repo root.
----
-tag: 3.0.1
+tag: 3.0.2
index c533315..70657d8 100644 (file)
@@ -20,6 +20,8 @@
 
 
 using namespace std::placeholders;
+using namespace boost::filesystem;
+
 #ifdef __TRACING__
 using namespace opentracing;
 #endif
@@ -31,6 +33,8 @@ using namespace opentracing;
 BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, src::logger_mt)
 
 boost::shared_ptr<sinks::synchronous_sink<sinks::text_file_backend>> boostLogger;
+double cpuClock = 0.0;
+bool jsonTrace = true;
 
 void init_log() {
     mdclog_attr_t *attr;
@@ -39,15 +43,32 @@ void init_log() {
     mdclog_init(attr);
     mdclog_attr_destroy(attr);
 }
+auto start_time = std::chrono::high_resolution_clock::now();
+typedef std::chrono::duration<double, std::ratio<1,1>> seconds_t;
 
+double age() {
+    return seconds_t(std::chrono::high_resolution_clock::now() - start_time).count();
+}
+
+double approx_CPU_MHz(unsigned sleeptime) {
+    using namespace std::chrono_literals;
+    uint32_t aux = 0;
+    uint64_t cycles_start = rdtscp(aux);
+    double time_start = age();
+    std::this_thread::sleep_for(sleeptime * 1ms);
+    uint64_t elapsed_cycles = rdtscp(aux) - cycles_start;
+    double elapsed_time = age() - time_start;
+    return elapsed_cycles / elapsed_time;
+}
 
 //std::atomic<int64_t> rmrCounter{0};
 std::atomic<int64_t> num_of_messages{0};
+std::atomic<int64_t> num_of_XAPP_messages{0};
 static long transactionCounter = 0;
 
 
 int main(const int argc, char **argv) {
-    sctp_params_t pSctpParams;
+    sctp_params_t sctpParams;
 #ifdef __TRACING__
     opentracing::Tracer::InitGlobal(tracelibcpp::createTracer("E2 Terminator"));
     auto span = opentracing::Tracer::Global()->StartSpan(__FUNCTION__);
@@ -55,64 +76,123 @@ int main(const int argc, char **argv) {
     otSpan span = 0;
 #endif
 
+    {
+        std::random_device device{};
+        std::mt19937 generator(device());
+        std::uniform_int_distribution<long> distribution(1, (long) 1e12);
+        transactionCounter = distribution(generator);
+    }
+
+    uint64_t st = 0,en = 0;
+    uint32_t aux1 = 0;
+    uint32_t aux2 = 0;
+    st = rdtscp(aux1);
+
     unsigned num_cpus = std::thread::hardware_concurrency();
-#ifdef ERROR_LEVEL
-    mdclog_severity_t loglevel = MDCLOG_ERR;
-#else
-    mdclog_severity_t loglevel = MDCLOG_INFO;
-#endif
     init_log();
-    mdclog_level_set(loglevel);
+    mdclog_level_set(MDCLOG_INFO);
 
-    if (argc < 7) {
-        mdclog_mdc_add("app", argv[0]);
-        mdclog_write(MDCLOG_ERR, "Usage nano <rmr port> logLevel <debug/warning/info/error> volume <PATH to log file location>");
-        return -1;
+    cpuClock = approx_CPU_MHz(100);
+
+    mdclog_write(MDCLOG_ERR, "CPU speed %11.11f", cpuClock);
+    auto result = parse(argc, argv, sctpParams);
+
+    path p = (sctpParams.configFilePath + "/" + sctpParams.configFileName).c_str();
+    if (exists(p)) {
+        const int size = 2048;
+        auto fileSize = file_size(p);
+        if (fileSize > size) {
+            mdclog_write(MDCLOG_ERR, "File %s larger than %d", p.string().c_str(), size);
+            exit(-1);
+        }
+    } else {
+        mdclog_write(MDCLOG_ERR, "Configuration File %s not exists", p.string().c_str());
+        exit(-1);
     }
 
-    {
-        std::random_device device{};
-        std::mt19937 generator(device());
-        std::uniform_int_distribution<long> distribution(1, (long) 1e12);
 
-        transactionCounter = distribution(generator);
+    ReadConfigFile conf;
+    if (conf.openConfigFile(p.string()) == -1) {
+        mdclog_write(MDCLOG_ERR, "Filed to open config file %s, %s",
+                     p.string().c_str(), strerror(errno));
+        exit(-1);
+    }
+    int rmrPort = conf.getIntValue("nano");
+    if (rmrPort == -1) {
+        mdclog_write(MDCLOG_ERR, "illigal RMR port ");
+        exit(-1);
+    }
+    sctpParams.rmrPort = (uint16_t)rmrPort;
+    snprintf(sctpParams.rmrAddress, sizeof(sctpParams.rmrAddress), "%d", (int) (sctpParams.rmrPort));
+
+    auto tmpStr = conf.getStringValue("loglevel");
+    if (tmpStr.length() == 0) {
+        mdclog_write(MDCLOG_ERR, "illigal loglevel. Set loglevel to MDCLOG_INFO");
+        tmpStr = "info";
+    }
+    transform(tmpStr.begin(), tmpStr.end(), tmpStr.begin(), ::tolower);
+
+    if ((tmpStr.compare("debug")) == 0) {
+        sctpParams.logLevel = MDCLOG_DEBUG;
+    } else if ((tmpStr.compare("info")) == 0) {
+        sctpParams.logLevel = MDCLOG_INFO;
+    } else if ((tmpStr.compare("warning")) == 0) {
+        sctpParams.logLevel = MDCLOG_WARN;
+    } else if ((tmpStr.compare("error")) == 0) {
+        sctpParams.logLevel = MDCLOG_ERR;
+    } else {
+        mdclog_write(MDCLOG_ERR, "illigal loglevel = %s. Set loglevel to MDCLOG_INFO", tmpStr.c_str());
+        sctpParams.logLevel = MDCLOG_INFO;
+    }
+    mdclog_level_set(sctpParams.logLevel);
+
+    tmpStr = conf.getStringValue("volume");
+    if (tmpStr.length() == 0) {
+        mdclog_write(MDCLOG_ERR, "illigal volume.");
+        exit(-1);
     }
 
     char tmpLogFilespec[VOLUME_URL_SIZE];
     tmpLogFilespec[0] = 0;
-    pSctpParams.volume[0] = 0;
-    //read paramters from CLI
-    for (auto i = 1; i < argc; i += 2) {
-        char *dummy;
-        if (strcasecmp("nano", argv[i]) == 0) {
-            pSctpParams.rmrPort = (uint16_t) (uint16_t) strtol(argv[i + 1], &dummy, 10);
-        } else if (strcasecmp("loglevel", argv[i]) == 0) {
-            if (strcasecmp("debug", argv[i + 1]) == 0) {
-                loglevel = MDCLOG_DEBUG;
-            } else if (strcasecmp("info", argv[i + 1]) == 0) {
-                loglevel = MDCLOG_INFO;
-            } else if (strcasecmp("warning", argv[i + 1]) == 0) {
-                loglevel = MDCLOG_WARN;
-            } else if (strcasecmp("error", argv[i + 1]) == 0) {
-                loglevel = MDCLOG_ERR;
-            }
-        } else if (strcasecmp("volume", argv[i]) == 0) {
-            snprintf(pSctpParams.volume, VOLUME_URL_SIZE, "%s", argv[i + 1]);
-            snprintf(tmpLogFilespec, VOLUME_URL_SIZE, "%s", argv[i + 1]);
-        }
+    sctpParams.volume[0] = 0;
+    snprintf(sctpParams.volume, VOLUME_URL_SIZE, "%s", tmpStr.c_str());
+    // copy the name to temp file as well
+    snprintf(tmpLogFilespec, VOLUME_URL_SIZE, "%s", tmpStr.c_str());
+
+
+    // define the file name in the tmp directory under the volume
+    strcat(tmpLogFilespec,"/tmp/E2Term_%Y-%m-%d_%H-%M-%S.%N.tmpStr");
+
+    sctpParams.myIP = conf.getStringValue("local-ip");
+    if (sctpParams.myIP.length() == 0) {
+        mdclog_write(MDCLOG_ERR, "illigal local-ip.");
+        exit(-1);
     }
 
+    tmpStr = conf.getStringValue("trace");
+    transform(tmpStr.begin(), tmpStr.end(), tmpStr.begin(), ::tolower);
+    if ((tmpStr.compare("start")) == 0) {
+        mdclog_write(MDCLOG_INFO, "Trace set to: start");
+        sctpParams.trace = true;
+    } else if ((tmpStr.compare("stop")) == 0) {
+        mdclog_write(MDCLOG_INFO, "Trace set to: stop");
+        sctpParams.trace = false;
+    }
+    jsonTrace = sctpParams.trace;
 
-    pSctpParams.logLevel = loglevel;
-    snprintf(pSctpParams.rmrAddress, sizeof(pSctpParams.rmrAddress) - 1, "%d", (int) (pSctpParams.rmrPort));
+    en = rdtscp(aux2);
 
-    strcat(tmpLogFilespec,"/tmp/E2Term_%Y-%m-%d_%H-%M-%S.%N.log");
+    mdclog_write(MDCLOG_INFO, "start = %lx end = %lx diff = %lx\n", st, en, en - st);
+    mdclog_write(MDCLOG_INFO, "start high = %lx start lo = %lx end high = %lx end lo = %lx\n",
+            st >> 32, st & 0xFFFFFFFF, (int64_t)en >> 32, en & 0xFFFFFFFF);
+    mdclog_write(MDCLOG_INFO, "ellapsed time = %5.9f\n", (double)(en - st)/cpuClock);
 
     if (mdclog_level_get() >= MDCLOG_INFO) {
-        mdclog_mdc_add("RMR Port", to_string(pSctpParams.rmrPort).c_str());
-        mdclog_mdc_add("LogLevel", to_string(pSctpParams.logLevel).c_str());
-        mdclog_mdc_add("volume", pSctpParams.volume);
+        mdclog_mdc_add("RMR Port", to_string(sctpParams.rmrPort).c_str());
+        mdclog_mdc_add("LogLevel", to_string(sctpParams.logLevel).c_str());
+        mdclog_mdc_add("volume", sctpParams.volume);
         mdclog_mdc_add("tmpLogFilespec", tmpLogFilespec);
+        mdclog_mdc_add("my ip", sctpParams.myIP.c_str());
 
         mdclog_write(MDCLOG_INFO, "running parameters");
     }
@@ -120,65 +200,54 @@ int main(const int argc, char **argv) {
 
     // Files written to the current working directory
     boostLogger = logging::add_file_log(
-            keywords::file_name = tmpLogFilespec,
+            keywords::file_name = tmpLogFilespec, // to temp directory
             keywords::rotation_size = 10 * 1024 * 1024,
             keywords::time_based_rotation = sinks::file::rotation_at_time_interval(posix_time::hours(1)),
             keywords::format = "%Message%"
-            //keywords::format = "[%TimeStamp%]: %Message%" // use each log with time stamp
+            //keywords::format = "[%TimeStamp%]: %Message%" // use each tmpStr with time stamp
     );
 
     // Setup a destination folder for collecting rotated (closed) files --since the same volumn can use rename()
     boostLogger->locked_backend()->set_file_collector(sinks::file::make_collector(
-        keywords::target = pSctpParams.volume 
-        //keywords::max_size = 16 * 1024 * 1024, 
-        //keywords::min_free_space = 100 * 1024 * 1024  
+            keywords::target = sctpParams.volume
     ));
 
     // Upon restart, scan the directory for files matching the file_name pattern
     boostLogger->locked_backend()->scan_for_files();
 
-    // Enable auto-flushing after each log record written
+    // Enable auto-flushing after each tmpStr record written
     if (mdclog_level_get() >= MDCLOG_DEBUG) {
        boostLogger->locked_backend()->auto_flush(true);
     }
 
     // start epoll
-    pSctpParams.epoll_fd = epoll_create1(0);
-    if (pSctpParams.epoll_fd == -1) {
+    sctpParams.epoll_fd = epoll_create1(0);
+    if (sctpParams.epoll_fd == -1) {
         mdclog_write(MDCLOG_ERR, "failed to open epoll descriptor");
         exit(-1);
     }
 
-    pSctpParams.rmrCtx = getRmrContext(pSctpParams.rmrAddress, &span);
-    if (pSctpParams.rmrCtx == nullptr) {
-        mdclog_write(MDCLOG_ERR, "Failed to initialize RMR");
-        close(pSctpParams.epoll_fd);
+    getRmrContext(sctpParams, &span);
+    if (sctpParams.rmrCtx == nullptr) {
+        close(sctpParams.epoll_fd);
         exit(-1);
     }
-    rmr_init_trace(pSctpParams.rmrCtx, 200);
-    // get the RMR fd for the epoll
-    pSctpParams.rmrListenFd = rmr_get_rcvfd(pSctpParams.rmrCtx);
-    struct epoll_event event{};
-    // add RMR fd to epoll
-    event.events = (EPOLLIN);
-    event.data.fd = pSctpParams.rmrListenFd;
-    // add listening RMR FD to epoll
-    if (epoll_ctl(pSctpParams.epoll_fd, EPOLL_CTL_ADD, pSctpParams.rmrListenFd, &event)) {
-        mdclog_write(MDCLOG_ERR, "Failed to add RMR descriptor to epoll");
-        close(pSctpParams.rmrListenFd);
-        rmr_close(pSctpParams.rmrCtx);
-        close(pSctpParams.epoll_fd);
+
+    if (buildInotify(sctpParams) == -1) {
+        close(sctpParams.rmrListenFd);
+        rmr_close(sctpParams.rmrCtx);
+        close(sctpParams.epoll_fd);
         exit(-1);
-    }
+     }
 
-    pSctpParams.sctpMap = new mapWrapper();
+    sctpParams.sctpMap = new mapWrapper();
 
     std::vector<std::thread> threads(num_cpus);
 //    std::vector<std::thread> threads;
 
     num_cpus = 1;
     for (unsigned int i = 0; i < num_cpus; i++) {
-        threads[i] = std::thread(listener, &pSctpParams);
+        threads[i] = std::thread(listener, &sctpParams);
 
         cpu_set_t cpuset;
         CPU_ZERO(&cpuset);
@@ -187,17 +256,49 @@ int main(const int argc, char **argv) {
         if (rc != 0) {
             mdclog_write(MDCLOG_ERR, "Error calling pthread_setaffinity_np: %d", rc);
         }
+    }
 
-//        threads.emplace_back(std::thread(listener, &pSctpParams));
+    //loop over term_init until first message from xApp
+    handleTermInit(sctpParams);
+
+    for (auto &t : threads) {
+        t.join();
     }
 
+#ifdef __TRACING__
+    opentracing::Tracer::Global()->Close();
+#endif
+    return 0;
+}
+
+void handleTermInit(sctp_params_t &sctpParams) {
+    sendTermInit(sctpParams);
     //send to e2 manager init of e2 term
     //E2_TERM_INIT
+
+    int count = 0;
+    auto exitCond = true;
+    while (exitCond) {
+        auto xappMessages = num_of_XAPP_messages.load(std::memory_order_acquire);
+        if (xappMessages > 0) {
+            exitCond = false;
+            continue;
+        }
+        usleep(10000);
+        count++;
+        if (count % 100 == 0) {
+            mdclog_write(MDCLOG_ERR, "No messages from any xApp : %ld", xappMessages);
+            sendTermInit(sctpParams);
+        }
+    }
+}
+
+void sendTermInit(sctp_params_t &sctpParams) {
     auto term_init = false;
 
-    char buff[128]{};
-    auto len = snprintf(buff, 128, "E2 terminator started");
-    rmr_mbuf_t *msg = rmr_alloc_msg(pSctpParams.rmrCtx, 200);
+    char *buff = (char *)calloc(1, sctpParams.myIP.length());
+    auto len = snprintf(buff, sctpParams.myIP.length(), "%s:%d", (const char *)sctpParams.myIP.c_str(),sctpParams.rmrPort);
+    rmr_mbuf_t *msg = rmr_alloc_msg(sctpParams.rmrCtx, sctpParams.myIP.length());
     auto count = 0;
     while (!term_init) {
         msg->mtype = E2_TERM_INIT;
@@ -206,9 +307,9 @@ int main(const int argc, char **argv) {
         static unsigned char tx[32];
         auto txLen = snprintf((char *) tx, sizeof tx, "%15ld", transactionCounter++);
         rmr_bytes2xact(msg, tx, txLen);
-        msg = rmr_send_msg(pSctpParams.rmrCtx, msg);
+        msg = rmr_send_msg(sctpParams.rmrCtx, msg);
         if (msg == nullptr) {
-            msg = rmr_alloc_msg(pSctpParams.rmrCtx, 200);
+            msg = rmr_alloc_msg(sctpParams.rmrCtx, sctpParams.myIP.length());
         } else if (msg->state == 0) {
             term_init = true;
             rmr_free_msg(msg);
@@ -222,13 +323,68 @@ int main(const int argc, char **argv) {
         count++;
     }
 
-    for (auto &t : threads) {
-        t.join();
+    free(buff);
+}
+
+/**
+ *
+ * @param argc
+ * @param argv
+ * @param sctpParams
+ * @return
+ */
+cxxopts::ParseResult parse(int argc, char *argv[], sctp_params_t &sctpParams) {
+    cxxopts::Options options(argv[0], "e2 term help");
+    options.positional_help("[optional args]").show_positional_help();
+    options.allow_unrecognised_options().add_options()
+            ("p,path", "config file path", cxxopts::value<std::string>(sctpParams.configFilePath)->default_value("config"))
+            ("f,file", "config file name", cxxopts::value<std::string>(sctpParams.configFileName)->default_value("config.conf"))
+            ("h,help", "Print help");
+
+    auto result = options.parse(argc, argv);
+
+    if (result.count("help")) {
+        std::cout << options.help({""}) << std::endl;
+        exit(0);
     }
+    return result;
+}
 
-#ifdef __TRACING__
-    opentracing::Tracer::Global()->Close();
-#endif
+/**
+ *
+ * @param sctpParams
+ * @return -1 failed 0 success
+ */
+int buildInotify(sctp_params_t &sctpParams) {
+    sctpParams.inotifyFD = inotify_init1(IN_NONBLOCK);
+    if (sctpParams.inotifyFD == -1) {
+        mdclog_write(MDCLOG_ERR, "Failed to init inotify (inotify_init1) %s", strerror(errno));
+        close(sctpParams.rmrListenFd);
+        rmr_close(sctpParams.rmrCtx);
+        close(sctpParams.epoll_fd);
+        return -1;
+    }
+
+    sctpParams.inotifyWD = inotify_add_watch(sctpParams.inotifyFD,
+                                              (const char *)sctpParams.configFilePath.c_str(),
+                                              IN_OPEN | IN_CLOSE);
+    if (sctpParams.inotifyWD == -1) {
+        mdclog_write(MDCLOG_ERR, "Failed to add directory : %s to  inotify (inotify_add_watch) %s",
+                sctpParams.configFilePath.c_str(),
+                strerror(errno));
+        close(sctpParams.inotifyFD);
+        return -1;
+    }
+
+    struct epoll_event event{};
+    event.events = (EPOLLIN);
+    event.data.fd = sctpParams.inotifyFD;
+    // add listening RMR FD to epoll
+    if (epoll_ctl(sctpParams.epoll_fd, EPOLL_CTL_ADD, sctpParams.inotifyFD, &event)) {
+        mdclog_write(MDCLOG_ERR, "Failed to add inotify FD to epoll");
+        close(sctpParams.inotifyFD);
+        return -1;
+    }
     return 0;
 }
 
@@ -244,7 +400,6 @@ void listener(sctp_params_t *params) {
     otSpan span = 0;
 #endif
     int num_of_SCTP_messages = 0;
-    int num_of_XAPP_messages = 0;
     auto totalTime = 0.0;
     mdclog_mdc_clean();
     mdclog_level_set(params->logLevel);
@@ -308,94 +463,15 @@ void listener(sctp_params_t *params) {
             clock_gettime(CLOCK_MONOTONIC, &message.message.time);
             start.tv_sec = message.message.time.tv_sec;
             start.tv_nsec = message.message.time.tv_nsec;
-            if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP)) {
-                if (events[i].data.fd != params->rmrListenFd) {
-                    auto *peerInfo = (ConnectedCU_t *)events[i].data.ptr;
-                    mdclog_write(MDCLOG_ERR, "epoll error, events %0x on fd %d, RAN NAME : %s",
-                                 events[i].events, peerInfo->fileDescriptor, peerInfo->enodbName);
 
-                    rmrMessageBuffer.sendMessage->len = snprintf((char *)rmrMessageBuffer.sendMessage->payload, 256,
-                                                         "%s|Failed SCTP Connection",
-                                                         peerInfo->enodbName);
-                    message.message.asndata = rmrMessageBuffer.sendMessage->payload;
-                    message.message.asnLength = rmrMessageBuffer.sendMessage->len;
 
-                    memcpy(message.message.enodbName, peerInfo->enodbName, sizeof(peerInfo->enodbName));
-                    message.message.direction = 'N';
-                    if (sendRequestToXapp(message, RIC_SCTP_CONNECTION_FAILURE, rmrMessageBuffer, &span) != 0) {
-                        mdclog_write(MDCLOG_ERR, "SCTP_CONNECTION_FAIL message failed to send to xAPP");
-                    }
-
-                    close(peerInfo->fileDescriptor);
-                    cleanHashEntry((ConnectedCU_t *) events[i].data.ptr, params->sctpMap, &span);
-                } else {
-                    mdclog_write(MDCLOG_ERR, "epoll error, events %0x on RMR FD", events[i].events);
-                }
+            if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP)) {
+                handlepoll_error(events[i], message, rmrMessageBuffer, params, &span);
             } else if (events[i].events & EPOLLOUT) {
-                // this need to send waiting message from connection EINPROGRESS
-                auto *peerInfo = (ConnectedCU_t *) events[i].data.ptr;
-
-                memcpy(message.message.enodbName, peerInfo->enodbName, sizeof(peerInfo->enodbName));
-
-                mdclog_write(MDCLOG_INFO, "file descriptor %d got EPOLLOUT", peerInfo->fileDescriptor);
-                auto retVal = 0;
-                socklen_t retValLen = 0;
-                auto rc = getsockopt(peerInfo->fileDescriptor, SOL_SOCKET, SO_ERROR, &retVal, &retValLen);
-                if (rc != 0 || retVal != 0) {
-                    if (rc != 0) {
-                        rmrMessageBuffer.sendMessage->len = snprintf((char *)rmrMessageBuffer.sendMessage->payload, 256,
-                                                                       "%s|Failed SCTP Connection, after EINPROGRESS the getsockopt%s",
-                                                                       peerInfo->enodbName, strerror(errno));
-                    } else if (retVal != 0) {
-                        rmrMessageBuffer.sendMessage->len = snprintf((char *)rmrMessageBuffer.sendMessage->payload, 256,
-                                                                       "%s|Failed SCTP Connection after EINPROGRESS, SO_ERROR",
-                                                                       peerInfo->enodbName);
-                    }
-
-                    message.message.asndata = rmrMessageBuffer.sendMessage->payload;
-                    message.message.asnLength = rmrMessageBuffer.sendMessage->len;
-                    mdclog_write(MDCLOG_ERR, "%s", rmrMessageBuffer.sendMessage->payload);
-                    message.message.direction = 'N';
-                    if (sendRequestToXapp(message, RIC_SCTP_CONNECTION_FAILURE, rmrMessageBuffer, &span) != 0) {
-                        mdclog_write(MDCLOG_ERR, "SCTP_CONNECTION_FAIL message failed to send to xAPP");
-                    }
-                    memset(peerInfo->asnData, 0, peerInfo->asnLength);
-                    peerInfo->asnLength = 0;
-                    peerInfo->mtype = 0;
-                    continue;
-                }
-
-               peerInfo->isConnected = true;
-
-                if (modifyToEpoll(params->epoll_fd, peerInfo, (EPOLLIN | EPOLLET), params->sctpMap, peerInfo->enodbName,
-                                  peerInfo->mtype, &span) != 0) {
-                    mdclog_write(MDCLOG_ERR, "epoll_ctl EPOLL_CTL_MOD");
-                    continue;
-                }
-
-                message.message.asndata = (unsigned char *)peerInfo->asnData;
-                message.message.asnLength = peerInfo->asnLength;
-                message.message.messageType = peerInfo->mtype;
-                memcpy(message.message.enodbName, peerInfo->enodbName, sizeof(peerInfo->enodbName));
-                num_of_messages.fetch_add(1, std::memory_order_release);
-                if (mdclog_level_get() >= MDCLOG_DEBUG) {
-                    mdclog_write(MDCLOG_DEBUG, "send the delayed SETUP/ENDC SETUP to sctp for %s",
-                                 message.message.enodbName);
-                }
-                if (sendSctpMsg(peerInfo, message, params->sctpMap, &span) != 0) {
-                    if (mdclog_level_get() >= MDCLOG_DEBUG) {
-                        mdclog_write(MDCLOG_DEBUG, "Error write to SCTP  %s %d", __func__, __LINE__);
-                    }
-                    continue;
-                }
-
-                memset(peerInfo->asnData, 0, peerInfo->asnLength);
-                peerInfo->asnLength = 0;
-                peerInfo->mtype = 0;
-
+                handleEinprogressMessages(events[i], message, rmrMessageBuffer, params, &span);
             } else if (params->rmrListenFd == events[i].data.fd) {
                 // got message from XAPP
-                num_of_XAPP_messages++;
+                num_of_XAPP_messages.fetch_add(1, std::memory_order_release);
                 num_of_messages.fetch_add(1, std::memory_order_release);
                 if (mdclog_level_get() >= MDCLOG_DEBUG) {
                     mdclog_write(MDCLOG_DEBUG, "new message from RMR");
@@ -407,6 +483,9 @@ void listener(sctp_params_t *params) {
                                         &span) != 0) {
                     mdclog_write(MDCLOG_ERR, "Error handling Xapp message");
                 }
+            } else if (params->inotifyFD == events[i].data.fd) {
+                mdclog_write(MDCLOG_INFO, "Got event from inotify (configuration update)");
+                handleConfigChange(params);
             } else {
                 /* We RMR_ERR_RETRY have data on the fd waiting to be read. Read and display it.
                  * We must read whatever data is available completely, as we are running
@@ -442,6 +521,247 @@ void listener(sctp_params_t *params) {
 #endif
 }
 
+/**
+ *
+ * @param sctpParams
+ */
+void handleConfigChange(sctp_params_t *sctpParams) {
+    char buf[4096] __attribute__ ((aligned(__alignof__(struct inotify_event))));
+    const struct inotify_event *event;
+    char *ptr;
+
+    path p = (sctpParams->configFilePath + "/" + sctpParams->configFileName).c_str();
+    auto endlessLoop = true;
+    while (endlessLoop) {
+        auto len = read(sctpParams->inotifyFD, buf, sizeof buf);
+        if (len == -1) {
+            if (errno != EAGAIN) {
+                mdclog_write(MDCLOG_ERR, "read %s ", strerror(errno));
+                endlessLoop = false;
+                continue;
+            }
+            else {
+                endlessLoop = false;
+                continue;
+            }
+        }
+
+        for (ptr = buf; ptr < buf + len; ptr += sizeof(struct inotify_event) + event->len) {
+            event = (const struct inotify_event *)ptr;
+            if (event->mask & (uint32_t)IN_ISDIR) {
+                continue;
+            }
+
+            // the directory name
+            if (sctpParams->inotifyWD == event->wd) {
+                // not the directory
+            }
+            if (event->len) {
+                if (!(sctpParams->configFileName.compare(event->name))) {
+                    continue;
+                }
+            }
+            // only the file we want
+            if (event->mask & (uint32_t)IN_CLOSE_WRITE) {
+                if (exists(p)) {
+                    const int size = 2048;
+                    auto fileSize = file_size(p);
+                    if (fileSize > size) {
+                        mdclog_write(MDCLOG_ERR, "File %s larger than %d", p.string().c_str(), size);
+                        return;
+                    }
+                } else {
+                    mdclog_write(MDCLOG_ERR, "Configuration File %s not exists", p.string().c_str());
+                    return;
+                }
+
+                ReadConfigFile conf;
+                if (conf.openConfigFile(p.string()) == -1) {
+                    mdclog_write(MDCLOG_ERR, "Filed to open config file %s, %s",
+                                 p.string().c_str(), strerror(errno));
+                    return;
+                }
+
+                auto tmpStr = conf.getStringValue("loglevel");
+                if (tmpStr.length() == 0) {
+                    mdclog_write(MDCLOG_ERR, "illigal loglevel. Set loglevel to MDCLOG_INFO");
+                    tmpStr = "info";
+                }
+                transform(tmpStr.begin(), tmpStr.end(), tmpStr.begin(), ::tolower);
+
+                if ((tmpStr.compare("debug")) == 0) {
+                    mdclog_write(MDCLOG_INFO, "Log level set to MDCLOG_DEBUG");
+                    sctpParams->logLevel = MDCLOG_DEBUG;
+                } else if ((tmpStr.compare("info")) == 0) {
+                    mdclog_write(MDCLOG_INFO, "Log level set to MDCLOG_INFO");
+                    sctpParams->logLevel = MDCLOG_INFO;
+                } else if ((tmpStr.compare("warning")) == 0) {
+                    mdclog_write(MDCLOG_INFO, "Log level set to MDCLOG_WARN");
+                    sctpParams->logLevel = MDCLOG_WARN;
+                } else if ((tmpStr.compare("error")) == 0) {
+                    mdclog_write(MDCLOG_INFO, "Log level set to MDCLOG_ERR");
+                    sctpParams->logLevel = MDCLOG_ERR;
+                } else {
+                    mdclog_write(MDCLOG_ERR, "illigal loglevel = %s. Set loglevel to MDCLOG_INFO", tmpStr.c_str());
+                    sctpParams->logLevel = MDCLOG_INFO;
+                }
+                mdclog_level_set(sctpParams->logLevel);
+
+
+                tmpStr = conf.getStringValue("trace");
+                if (tmpStr.length() == 0) {
+                    mdclog_write(MDCLOG_ERR, "illigal trace. Set trace to stop");
+                    tmpStr = "stop";
+                }
+
+                transform(tmpStr.begin(), tmpStr.end(), tmpStr.begin(), ::tolower);
+                if ((tmpStr.compare("start")) == 0) {
+                    mdclog_write(MDCLOG_INFO, "Trace set to: start");
+                    sctpParams->trace = true;
+                } else if ((tmpStr.compare("stop")) == 0) {
+                    mdclog_write(MDCLOG_INFO, "Trace set to: stop");
+                    sctpParams->trace = false;
+                } else {
+                    mdclog_write(MDCLOG_ERR, "Trace was set to wrong value %s, set to stop", tmpStr.c_str());
+                    sctpParams->trace = false;
+                }
+                jsonTrace = sctpParams->trace;
+                endlessLoop = false;
+            }
+        }
+    }
+}
+
+/**
+ *
+ * @param event
+ * @param message
+ * @param rmrMessageBuffer
+ * @param params
+ * @param pSpan
+ */
+void handleEinprogressMessages(struct epoll_event &event,
+                               ReportingMessages_t &message,
+                               RmrMessagesBuffer_t &rmrMessageBuffer,
+                               sctp_params_t *params,
+                               otSpan *pSpan) {
+#ifdef __TRACING__
+    auto lspan = opentracing::Tracer::Global()->StartSpan(
+            __FUNCTION__, { opentracing::ChildOf(&pSpan->get()->context()) });
+#else
+    otSpan lspan = 0;
+#endif
+    auto *peerInfo = (ConnectedCU_t *)event.data.ptr;
+    memcpy(message.message.enodbName, peerInfo->enodbName, sizeof(peerInfo->enodbName));
+
+    mdclog_write(MDCLOG_INFO, "file descriptor %d got EPOLLOUT", peerInfo->fileDescriptor);
+    auto retVal = 0;
+    socklen_t retValLen = 0;
+    auto rc = getsockopt(peerInfo->fileDescriptor, SOL_SOCKET, SO_ERROR, &retVal, &retValLen);
+    if (rc != 0 || retVal != 0) {
+        if (rc != 0) {
+            rmrMessageBuffer.sendMessage->len = snprintf((char *)rmrMessageBuffer.sendMessage->payload, 256,
+                                                         "%s|Failed SCTP Connection, after EINPROGRESS the getsockopt%s",
+                                                         peerInfo->enodbName, strerror(errno));
+        } else if (retVal != 0) {
+            rmrMessageBuffer.sendMessage->len = snprintf((char *)rmrMessageBuffer.sendMessage->payload, 256,
+                                                         "%s|Failed SCTP Connection after EINPROGRESS, SO_ERROR",
+                                                         peerInfo->enodbName);
+        }
+
+        message.message.asndata = rmrMessageBuffer.sendMessage->payload;
+        message.message.asnLength = rmrMessageBuffer.sendMessage->len;
+        mdclog_write(MDCLOG_ERR, "%s", rmrMessageBuffer.sendMessage->payload);
+        message.message.direction = 'N';
+        if (sendRequestToXapp(message, RIC_SCTP_CONNECTION_FAILURE, rmrMessageBuffer, &lspan) != 0) {
+            mdclog_write(MDCLOG_ERR, "SCTP_CONNECTION_FAIL message failed to send to xAPP");
+        }
+        memset(peerInfo->asnData, 0, peerInfo->asnLength);
+        peerInfo->asnLength = 0;
+        peerInfo->mtype = 0;
+#ifdef __TRACING__
+        lspan->Finish();
+#endif
+        return;
+    }
+
+    peerInfo->isConnected = true;
+
+    if (modifyToEpoll(params->epoll_fd, peerInfo, (EPOLLIN | EPOLLET), params->sctpMap, peerInfo->enodbName,
+                      peerInfo->mtype, &lspan) != 0) {
+        mdclog_write(MDCLOG_ERR, "epoll_ctl EPOLL_CTL_MOD");
+#ifdef __TRACING__
+        lspan->Finish();
+#endif
+        return;
+    }
+
+    message.message.asndata = (unsigned char *)peerInfo->asnData;
+    message.message.asnLength = peerInfo->asnLength;
+    message.message.messageType = peerInfo->mtype;
+    memcpy(message.message.enodbName, peerInfo->enodbName, sizeof(peerInfo->enodbName));
+    num_of_messages.fetch_add(1, std::memory_order_release);
+    if (mdclog_level_get() >= MDCLOG_DEBUG) {
+        mdclog_write(MDCLOG_DEBUG, "send the delayed SETUP/ENDC SETUP to sctp for %s",
+                     message.message.enodbName);
+    }
+    if (sendSctpMsg(peerInfo, message, params->sctpMap, &lspan) != 0) {
+        if (mdclog_level_get() >= MDCLOG_DEBUG) {
+            mdclog_write(MDCLOG_DEBUG, "Error write to SCTP  %s %d", __func__, __LINE__);
+        }
+#ifdef __TRACING__
+        lspan->Finish();
+#endif
+        return;
+    }
+
+    memset(peerInfo->asnData, 0, peerInfo->asnLength);
+    peerInfo->asnLength = 0;
+    peerInfo->mtype = 0;
+#ifdef __TRACING__
+    lspan->Finish();
+#endif
+}
+
+
+void handlepoll_error(struct epoll_event &event,
+                      ReportingMessages_t &message,
+                      RmrMessagesBuffer_t &rmrMessageBuffer,
+                      sctp_params_t *params,
+                      otSpan *pSpan) {
+#ifdef __TRACING__
+    auto lspan = opentracing::Tracer::Global()->StartSpan(
+            __FUNCTION__, { opentracing::ChildOf(&pSpan->get()->context()) });
+#else
+    otSpan lspan = 0;
+#endif
+    if (event.data.fd != params->rmrListenFd) {
+        auto *peerInfo = (ConnectedCU_t *)event.data.ptr;
+        mdclog_write(MDCLOG_ERR, "epoll error, events %0x on fd %d, RAN NAME : %s",
+                     event.events, peerInfo->fileDescriptor, peerInfo->enodbName);
+
+        rmrMessageBuffer.sendMessage->len = snprintf((char *)rmrMessageBuffer.sendMessage->payload, 256,
+                                                     "%s|Failed SCTP Connection",
+                                                     peerInfo->enodbName);
+        message.message.asndata = rmrMessageBuffer.sendMessage->payload;
+        message.message.asnLength = rmrMessageBuffer.sendMessage->len;
+
+        memcpy(message.message.enodbName, peerInfo->enodbName, sizeof(peerInfo->enodbName));
+        message.message.direction = 'N';
+        if (sendRequestToXapp(message, RIC_SCTP_CONNECTION_FAILURE, rmrMessageBuffer, &lspan) != 0) {
+            mdclog_write(MDCLOG_ERR, "SCTP_CONNECTION_FAIL message failed to send to xAPP");
+        }
+
+        close(peerInfo->fileDescriptor);
+        cleanHashEntry((ConnectedCU_t *) event.data.ptr, params->sctpMap, &lspan);
+    } else {
+        mdclog_write(MDCLOG_ERR, "epoll error, events %0x on RMR FD", event.events);
+    }
+#ifdef __TRACING__
+    lspan->Finish();
+#endif
+
+}
 /**
  *
  * @param socket
@@ -1178,7 +1498,9 @@ void asnSuccsesfulMsg(E2AP_PDU_t *pdu, ReportingMessages_t &message, Sctp_Map_t
                         static unsigned char tx[32];
                         snprintf((char *) tx, sizeof tx, "%15ld", transactionCounter++);
                         rmr_bytes2xact(rmrMessageBuffer.sendMessage, tx, strlen((const char *) tx));
-                       rmr_bytes2meid(rmrMessageBuffer.sendMessage, (unsigned char *)message.message.enodbName, strlen(message.message.enodbName));
+                        rmr_bytes2meid(rmrMessageBuffer.sendMessage,
+                                (unsigned char *)message.message.enodbName,
+                                strlen(message.message.enodbName));
 
                         sendRmrMessage(rmrMessageBuffer, message, &lspan);
                         messageSent = true;
@@ -1393,26 +1715,24 @@ int sendRequestToXapp(ReportingMessages_t &message,
 }
 
 
-void *getRmrContext(char *rmrAddress, otSpan *pSpan) {
+void getRmrContext(sctp_params_t &pSctpParams, otSpan *pSpan) {
 #ifdef __TRACING__
     auto lspan = opentracing::Tracer::Global()->StartSpan(
             __FUNCTION__, { opentracing::ChildOf(&pSpan->get()->context()) });
 #else
 //    otSpan lspan = 0;
 #endif
-    void *rmrCtx = rmr_init(rmrAddress, RMR_MAX_RCV_BYTES, RMRFL_NONE);
-
-
-    if (rmrCtx == nullptr) {
-        mdclog_write(MDCLOG_ERR, "RMR failed to initialise : %s", strerror(errno));
+    pSctpParams.rmrCtx = nullptr;
+    pSctpParams.rmrCtx = rmr_init(pSctpParams.rmrAddress, RMR_MAX_RCV_BYTES, RMRFL_NONE);
+    if (pSctpParams.rmrCtx == nullptr) {
+        mdclog_write(MDCLOG_ERR, "Failed to initialize RMR");
 #ifdef __TRACING__
         lspan->Finish();
 #endif
-
-        return (nullptr);
+        return;
     }
 
-    rmr_set_stimeout(rmrCtx, 0);    // disable retries for any send operation
+    rmr_set_stimeout(pSctpParams.rmrCtx, 0);    // disable retries for any send operation
     // we need to find that routing table exist and we can run
     if (mdclog_level_get() >= MDCLOG_INFO) {
         mdclog_write(MDCLOG_INFO, "We are after RMR INIT wait for RMR_Ready");
@@ -1420,7 +1740,7 @@ void *getRmrContext(char *rmrAddress, otSpan *pSpan) {
     int rmrReady = 0;
     int count = 0;
     while (!rmrReady) {
-        if ((rmrReady = rmr_ready(rmrCtx)) == 0) {
+        if ((rmrReady = rmr_ready(pSctpParams.rmrCtx)) == 0) {
             sleep(1);
         }
         count++;
@@ -1434,8 +1754,20 @@ void *getRmrContext(char *rmrAddress, otSpan *pSpan) {
 #ifdef __TRACING__
     lspan->Finish();
 #endif
-
-    return rmrCtx;
+    rmr_init_trace(pSctpParams.rmrCtx, 200);
+    // get the RMR fd for the epoll
+    pSctpParams.rmrListenFd = rmr_get_rcvfd(pSctpParams.rmrCtx);
+    struct epoll_event event{};
+    // add RMR fd to epoll
+    event.events = (EPOLLIN);
+    event.data.fd = pSctpParams.rmrListenFd;
+    // add listening RMR FD to epoll
+    if (epoll_ctl(pSctpParams.epoll_fd, EPOLL_CTL_ADD, pSctpParams.rmrListenFd, &event)) {
+        mdclog_write(MDCLOG_ERR, "Failed to add RMR descriptor to epoll");
+        close(pSctpParams.rmrListenFd);
+        rmr_close(pSctpParams.rmrCtx);
+        pSctpParams.rmrCtx = nullptr;
+    }
 }
 
 /**
@@ -2417,16 +2749,17 @@ int sendRmrMessage(RmrMessagesBuffer_t &rmrMessageBuffer, ReportingMessages_t &m
 }
 
 void buildJsonMessage(ReportingMessages_t &message) {
-       message.outLen = sizeof(message.base64Data);
-    base64::encode((const unsigned char *)message.message.asndata,
-                   (const int)message.message.asnLength,
-                  message.base64Data,
-                  message.outLen);
-    if (mdclog_level_get() >= MDCLOG_DEBUG) {
-        mdclog_write(MDCLOG_DEBUG, "asn data length = %d, base64 message length = %d ",
-                     (int)message.message.asnLength,
-                     (int)message.outLen);
-    }
+    if (jsonTrace) {
+        message.outLen = sizeof(message.base64Data);
+        base64::encode((const unsigned char *) message.message.asndata,
+                       (const int) message.message.asnLength,
+                       message.base64Data,
+                       message.outLen);
+        if (mdclog_level_get() >= MDCLOG_DEBUG) {
+            mdclog_write(MDCLOG_DEBUG, "asn data length = %d, base64 message length = %d ",
+                         (int) message.message.asnLength,
+                         (int) message.outLen);
+        }
 
 //    char buff[256];
 //    // build day time to seconds from epoc
@@ -2434,24 +2767,24 @@ void buildJsonMessage(ReportingMessages_t &message) {
 //    // add nanosecond
 //    snprintf(buff, sizeof buff, "%s.%09ld UTC\n", buff, message.message.time.tv_nsec);
 
-    message.bufferLen = snprintf(message.buffer, sizeof(message.buffer),
-            "{\"header\": {\"ts\": \"%ld.%09ld\","
-            "\"ranName\": \"%s\","
-            "\"messageType\": %d,"
-            "\"direction\": \"%c\"},"
-            "\"base64Length\": %d,"
-            "\"asnBase64\": \"%s\"}",
-            message.message.time.tv_sec,
-            message.message.time.tv_nsec,
-            message.message.enodbName,
-            message.message.messageType,
-            message.message.direction,
-            (int)message.outLen,
-            message.base64Data);
-    static src::logger_mt& lg = my_logger::get();
-
-    BOOST_LOG(lg) << message.buffer;
-
+        message.bufferLen = snprintf(message.buffer, sizeof(message.buffer),
+                                     "{\"header\": {\"ts\": \"%ld.%09ld\","
+                                     "\"ranName\": \"%s\","
+                                     "\"messageType\": %d,"
+                                     "\"direction\": \"%c\"},"
+                                     "\"base64Length\": %d,"
+                                     "\"asnBase64\": \"%s\"}",
+                                     message.message.time.tv_sec,
+                                     message.message.time.tv_nsec,
+                                     message.message.enodbName,
+                                     message.message.messageType,
+                                     message.message.direction,
+                                     (int) message.outLen,
+                                     message.base64Data);
+        static src::logger_mt &lg = my_logger::get();
+
+        BOOST_LOG(lg) << message.buffer;
+    }
 }
 
 
index a919c1b..1aa4f78 100644 (file)
@@ -43,6 +43,7 @@
 #include <shared_mutex>
 #include <iterator>
 #include <map>
+#include <sys/inotify.h>
 
 #include <rmr/rmr.h>
 #include <rmr/RIC_message_types.h>
 #include <boost/log/sources/global_logger_storage.hpp>
 #include <boost/log/utility/setup/file.hpp>
 #include <boost/log/utility/setup/common_attributes.hpp>
-
+#include <boost/filesystem.hpp>
 
 #include <mdclog/mdclog.h>
 
 #include "asn1cFiles/E2AP-PDU.h"
-#include <asn1cFiles/ProtocolIE-Container.h>
+#include "asn1cFiles/ProtocolIE-Container.h"
 #include "asn1cFiles/InitiatingMessage.h"
 #include "asn1cFiles/SuccessfulOutcome.h"
 #include "asn1cFiles/UnsuccessfulOutcome.h"
 #include "asn1cFiles/ProtocolIE-Container.h"
 #include "asn1cFiles/ProtocolIE-Field.h"
 
+#include "cxxopts.hpp"
+//#include "config-cpp/include/config-cpp/config-cpp.h"
+
 #ifdef __TRACING__
 #include "openTracing.h"
 #endif
@@ -78,6 +82,8 @@
 
 #include "base64.h"
 
+#include "ReadConfigFile.h"
+
 using namespace std;
 namespace logging = boost::log;
 namespace src = boost::log::sources;
@@ -109,11 +115,17 @@ typedef struct sctp_params {
     uint16_t rmrPort = 0;
     int      epoll_fd = 0;
     int      rmrListenFd = 0;
+    int      inotifyFD = 0;
+    int      inotifyWD = 0;
     void     *rmrCtx = nullptr;
     Sctp_Map_t *sctpMap = nullptr;
     char       rmrAddress[256] {}; // "tcp:portnumber" "tcp:5566" listen to all address on port 5566
     mdclog_severity_t logLevel = MDCLOG_INFO;
     char volume[VOLUME_URL_SIZE];
+    string myIP {};
+    string configFilePath {};
+    string configFileName {};
+    bool trace = true;
     //shared_timed_mutex fence; // moved to mapWrapper
 } sctp_params_t;
 
@@ -154,11 +166,33 @@ typedef struct ReportingMessages {
     size_t bufferLen;
 } ReportingMessages_t;
 
+cxxopts::ParseResult parse(int argc, char *argv[], sctp_params_t &pSctpParams);
+
+int buildInotify(sctp_params_t &sctpParams);
+
+void handleTermInit(sctp_params_t &sctpParams);
+
+void handleConfigChange(sctp_params_t *sctpParams);
 
 void listener(sctp_params_t *params);
 
+void sendTermInit(sctp_params_t &sctpParams);
+
 int setSocketNoBlocking(int socket);
 
+void handleEinprogressMessages(struct epoll_event &event,
+                               ReportingMessages_t &message,
+                               RmrMessagesBuffer_t &rmrMessageBuffer,
+                               sctp_params_t *params,
+                               otSpan *pSpan);
+
+void handlepoll_error(struct epoll_event &event,
+                      ReportingMessages_t &message,
+                      RmrMessagesBuffer_t &rmrMessageBuffer,
+                      sctp_params_t *params,
+                      otSpan *pSpan);
+
+
 void cleanHashEntry(ConnectedCU_t *peerInfo, Sctp_Map_t *m, otSpan *pSpan);
 
 int getSetupRequestMetaData(ReportingMessages_t &message, char *data, char *host, uint16_t &port, otSpan *pSpan);
@@ -248,7 +282,7 @@ int receiveDataFromSctp(struct epoll_event *events,
  * @param pSpan
  * @return
  */
-void *getRmrContext(char *rmrAddress, otSpan *pSpan);
+void getRmrContext(sctp_params_t &pSctpParams, otSpan *pSpan);
 
 /**
  *
@@ -379,6 +413,12 @@ void buildJsonMessage(ReportingMessages_t &message);
  */
 string translateRmrErrorMessages(int state);
 
+
+static inline uint64_t rdtscp(uint32_t &aux) {
+    uint64_t rax,rdx;
+    asm volatile ("rdtscp\n" : "=a" (rax), "=d" (rdx), "=c" (aux) : :);
+    return (rdx << 32) + rax;
+}
 #ifndef RIC_SCTP_CONNECTION_FAILURE
 #define RIC_SCTP_CONNECTION_FAILURE  10080
 #endif