cmake_install.cmake
e2.cbp
e2
+T1
setUpTest
subscriptionTest
CMakeLists.txt
RIC-E2-TERMINATION/nlohmann/
RIC-E2-TERMINATION/concurrentqueue/
/RIC-E2-TERMINATION/base64/
-# documentation
-.tox
-docs/_build/
+/RIC-E2-TERMINATION/3rdparty/cxxopts/
+/RIC-E2-TERMINATION/3rdparty/cgreen_1.2.0_amd64.deb
+/testConfigFile
+/config/config.conf
+/logTest
+/b64Test
+/T1
+/e2Cov
+/RIC-E2-TERMINATION/3rdparty/pistache/
+/CMakeLists.txt.old
+/cmake-modules/
+/e2_coverage.base
+/teste2
cmake_minimum_required(VERSION 3.13)
project(e2)
-set(CMAKE_VERBOSE_MAKEFILE on)
+set(CMAKE_VERBOSE_MAKEFILE off)
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")
-#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")
-
-include_directories(RIC-E2-TERMINATION)
-include_directories(RIC-E2-TERMINATION/3rdparty/asn1cFiles)
+set(PROJECT_NAME "e2")
+set(PROJECT_TEST_NAME "e2")
+
+
+if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
+ #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. -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. -O3 -L/usr/lib -Wall -W -Wpedantic")
+else ()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DASN_DISABLE_OER_SUPPORT -DASN_PDU_COLLECTION -L. -ggdb3 --coverage -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. -ggdb3 -L/usr/lib -Wall -W -Wpedantic")
+
+endif ()
+include_directories(RIC-E2-TERMINATION
+ RIC-E2-TERMINATION/3rdparty/asn1cFiles
+ RIC-E2-TERMINATION/3rdparty
+ cmake-modules)
file(GLOB ASN_MODULE_SRCS "RIC-E2-TERMINATION/3rdparty/asn1cFiles/*.c")
file(GLOB ASN_MODULE_HDRS "RIC-E2-TERMINATION/3rdparty/asn1cFiles/*.h")
include_directories(RIC-E2-TERMINATION/TEST/e2smTest)
include_directories(RIC-E2-TERMINATION/TEST/T1)
include_directories(RIC-E2-TERMINATION/TEST/T2)
-include_directories(RIC-E2-TERMINATION/base64/include)
-include_directories(RIC-E2-TERMINATION/base64/lib)
+
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
+ gcov
+ 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
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)
+
+add_executable(b64Test
+ RIC-E2-TERMINATION/base64.cpp
+ RIC-E2-TERMINATION/base64.h
+ RIC-E2-TERMINATION/TEST/base64/testBase64.cpp)
+
+add_executable(T1
+ RIC-E2-TERMINATION/TEST/T1/E2Builder.h
+ RIC-E2-TERMINATION/TEST/T1/E2Setup.cpp
+ #RIC-E2-TERMINATION/TEST/T1/Test1.cpp
+ #RIC-E2-TERMINATION/TEST/T1/
+ )
+
+
+find_package(RapidJSON)
+
+add_executable(logTest
+ RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.h
+ RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.cpp)
+
+add_executable(teste2
+ RIC-E2-TERMINATION/TEST/e2test.h
+ RIC-E2-TERMINATION/TEST/e2test.cpp
+ )
+
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+ LIST(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
+ set(CMAKE_BUILD_TYPE "Debug")
+ include(cmake-modules/CodeCoverage.cmake)
+ target_link_libraries(${PROJECT_TEST_NAME} gcov)
+
+ set(LDFLAGS "--coverage -fprofile-arcs")
+
+ # setup_target_for_coverage_lcov(${PROJECT_NAME}_coverage ${PROJECT_TEST_NAME} coverage)
+ set(COVERAGE_LCOV_EXCLUDES ${PROJECT_SOURCE_DIR}/config'
+ ${PROJECT_SOURCE_DIR}/log'
+ '${PROJECT_SOURCE_DIR}/docs'
+ '${PROJECT_SOURCE_DIR}/RIC-E2-TERMINATION/3rdparty'
+ '${PROJECT_SOURCE_DIR}/RIC-E2-TERMINATION/asn1cFiles'
+ '${PROJECT_SOURCE_DIR}/RIC-E2-TERMINATION/TEST'
+ '${PROJECT_SOURCE_DIR}/RIC-E2-TERMINATION/config')
+
+ set(COVERAGE_EXCLUDES '${PROJECT_SOURCE_DIR}/config'
+ ${PROJECT_SOURCE_DIR}/log'
+ '${PROJECT_SOURCE_DIR}/docs'
+ '${PROJECT_SOURCE_DIR}/RIC-E2-TERMINATION/3rdparty'
+ '${PROJECT_SOURCE_DIR}/RIC-E2-TERMINATION/asn1cFiles'
+ '${PROJECT_SOURCE_DIR}/RIC-E2-TERMINATION/TEST'
+ '${PROJECT_SOURCE_DIR}/RIC-E2-TERMINATION/config')
+ append_coverage_compiler_flags()
+ SETUP_TARGET_FOR_COVERAGE_LCOV(NAME e2_coverage
+ EXECUTABLE e2
+ DEPENDENCIES e2)
+endif ()
\ No newline at end of file
# limitations under the License.
#
##############################################################################
+
#
# This source code is part of the near-RT RIC (RAN Intelligent Controller)
# platform project (RICP).
#
-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:3-u16.04-nng as ubuntu
WORKDIR /opt/e2/
RUN mkdir -p /opt/e2/RIC-E2-TERMINATION/ \
&& mkdir -p /opt/e2/RIC-E2-TERMINATION/TEST/T1 \
- && mkdir -p /opt/e2/RIC-E2-TERMINATION/TEST/T2
+ && mkdir -p /opt/e2/RIC-E2-TERMINATION/TEST/T2 \
+ && mkdir -p /opt/e2/RIC-E2-TERMINATION/3rdparty
+
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.13.0_amd64.deb/download.deb
+RUN dpkg -i rmr_1.13.0_amd64.deb
+RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_1.13.0_amd64.deb/download.deb
+RUN dpkg -i rmr-dev_1.13.0_amd64.deb
+
+ARG BUILD_TYPE=Release
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/ && /usr/local/bin/cmake . && make
+ && 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 && git clone https://github.com/Tencent/rapidjson.git \
+ && cd rapidjson && mkdir build && cd build && cmake .. && make install && ldconfig \
+ && cd /opt/e2/RIC-E2-TERMINATION/3rdparty && git clone https://github.com/oktal/pistache.git\
+ && cd pistache && 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/ && git clone https://github.com/bilke/cmake-modules.git \
+ && cd /opt/e2/ && /usr/local/bin/cmake -D CMAKE_BUILD_TYPE=$BUILD_TYPE . && make
+
+RUN if [$BUILD_TYPE == "Debug"] ; then make e2_coverage ; fi
# && git clone http://gerrit.o-ran-sc.org/r/ric-plt/tracelibcpp \
# && cd tracelibcpp && mkdir build && cd build \
# && 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 -p /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
#COPY --from=ubuntu /usr/local/lib/librmr_nng.a /usr/local/lib/librmr_nng.a
COPY --from=ubuntu /usr/local/lib/librmr_nng.so.1 /usr/local/lib/librmr_nng.so.1
COPY --from=ubuntu /usr/local/lib/librmr_nng.so /usr/local/lib/librmr_nng.so
-COPY --from=ubuntu /usr/local/lib/librmr_nng.so.1.10.0 /usr/local/lib/librmr_nng.so.1.10.0
+COPY --from=ubuntu /usr/local/lib/librmr_nng.so.1.13.0 /usr/local/lib/librmr_nng.so.1.13.0
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/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
+COPY --from=ubuntu /usr/local/lib/libpistache.so /usr/local/lib/libpistache.so
+COPY --from=ubuntu /usr/local/lib/libpistache.so.0 /usr/local/lib/libpistache.so.0
+COPY --from=ubuntu /usr/local/lib/libpistache.so.0.0.001-git20191031 /usr/local/lib/libpistache.so.0.0.001-git20191031
+
+
COPY --from=ubuntu /usr/lib/libboost_log.so /usr/lib/libboost_log.so
COPY --from=ubuntu /usr/lib/libboost_log.so.1.69.0 /usr/lib/libboost_log.so.1.69.0
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"]
--- /dev/null
+/*
+ * 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>
+#include <mdclog/mdclog.h>
+
+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
+ mdclog_write(MDCLOG_ERR, "File: %s, failed to open", configFile.c_str());
+ return -1;
+ }
+ std::string line;
+ std::string section;
+
+ while (std::getline(file,line)) {
+ if (!line.length() || line[0] == '#' || line[0] == ';' || line[0] == '{') {
+ continue;
+ }
+// else if (line[0] == '#') {
+// continue;
+// } else if (line[0] == ';') {
+// continue;
+// }
+
+
+ if (line[0] =='[') { //section
+ auto sectionEnd = line.find(']');
+ if (sectionEnd == std::string::npos) {
+ mdclog_write(MDCLOG_ERR, "Error section definition: %s ", line.c_str());
+ section.clear();
+ return -1;
+// continue;
+ }
+ section = line.substr(1, sectionEnd - 1) + ".";
+ continue;
+ }
+
+ auto leftHand = line.find('=');
+ if (leftHand == std::string::npos) {
+ mdclog_write(MDCLOG_ERR, "problematic entry: %s ", line.c_str());
+ continue;
+ }
+// auto name = line.substr(0,leftHand);
+// trim(name);
+ auto name = section + trim(line.substr(0, leftHand));
+
+ auto value = line.substr(leftHand+1);
+ if (value.length() == 0) {
+ mdclog_write(MDCLOG_ERR, "problematic entry: %s no value ", line.c_str());
+ continue;
+
+ }
+ 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(basic_string<char> str, const std::string& chars = "\t\n\v\f\r ") {
+ return ltrim(rtrim(str, chars), chars);
+ }
+};
+
+
+#endif //E2_READCONFIGFILE_H
--- /dev/null
+/*
+ * 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"
+
+string LogTest::getLine() {
+ std::string line;
+
+ if (std::getline(file, line)) {
+ return line;
+ }
+ return "";
+}
+
+void LogTest::getJsonDoc(string json) {
+ if (json.length() != 0) {
+ document.Parse(json.c_str());
+ }
+}
+
+string LogTest::getBase64(Document &document) {
+ if (document.HasMember("asnBase64")) {
+ return document["asnBase64"].GetString();
+ }
+ return "";
+}
--- /dev/null
+/*
+ * 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>
+#include <fstream>
+
+#include "rapidjson/document.h"
+#include "rapidjson/writer.h"
+#include "rapidjson/stringbuffer.h"
+
+using namespace std;
+using namespace rapidjson;
+
+class LogTest {
+public:
+ LogTest() = default;
+
+ int openFile(string const& configFile) {
+ file.open(configFile.c_str());
+ if (!file) {
+ return -1;
+ }
+ return 0;
+ }
+
+ string getLine();
+ void getJsonDoc(string json);
+
+ string getBase64(Document &document);
+
+private:
+ std::ifstream file;
+ Document document;
+};
+
+
+#endif //E2_LOGTEST_H
--- /dev/null
+/*
+ * 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/config.conf") == 0);
+}
+
+Ensure(Cgreen, goodparams) {
+ ReadConfigFile conf {};
+ assert_that(conf.openConfigFile("config/config.conf") == 0);
+ assert_that(conf.getIntValue("nano") == 38000);
+ assert_that(conf.getStringValue("loglevel") == "info");
+ assert_that(conf.getStringValue("volume") == "log");
+
+}
+
+Ensure(Cgreen, badParams) {
+ ReadConfigFile conf {};
+ assert_that(conf.openConfigFile("config/config.conf") == 0);
+ assert_that(conf.getIntValue("nano") != 38002);
+ 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/config.conf") == 0);
+ assert_that(conf.getStringValue("nano") != "debug");
+ assert_that(conf.getIntValue("loglevel") != 3);
+ assert_that(conf.getDoubleValue("loglevel") != 3.0);
+}
+
+Ensure(Cgreen, badValues) {
+ ReadConfigFile conf {};
+ assert_that(conf.openConfigFile("config/config.bad") == 0);
+}
+
+Ensure(Cgreen, sectionTest) {
+ ReadConfigFile conf {};
+ assert_that(conf.openConfigFile("config/config.sec") == 0);
+ assert_that(conf.getIntValue("config.nano") == 38000);
+}
+
+Ensure(Cgreen, sectionBadTest) {
+ ReadConfigFile conf {};
+ assert_that(conf.openConfigFile("config/config.secbad") == -1);
+ //assert_that(conf.getIntValue("config.nano") == 38000);
+}
+
+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);
+ add_test_with_context(suite, Cgreen, badValues);
+ add_test_with_context(suite, Cgreen, sectionTest);
+ add_test_with_context(suite, Cgreen, sectionBadTest);
+
+ return cgreen::run_test_suite(suite, create_text_reporter());
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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 12/10/19.
+//
+
+#ifndef E2_E2BUILDER_H
+#define E2_E2BUILDER_H
+
+#include <cstring>
+#include <cstdio>
+#include <cerrno>
+#include <cstdlib>
+#include <sys/types.h>
+#include <error.h>
+#include <mdclog/mdclog.h>
+#include <algorithm>
+
+
+#include <mdclog/mdclog.h>
+
+
+#include "asn1cFiles/E2AP-PDU.h"
+#include "asn1cFiles/InitiatingMessage.h"
+#include "asn1cFiles/SuccessfulOutcome.h"
+#include "asn1cFiles/UnsuccessfulOutcome.h"
+
+#include "asn1cFiles/ProtocolIE-Field.h"
+
+#include "asn1cFiles/FDD-Info.h"
+#include "asn1cFiles/TDD-Info.h"
+#include "asn1cFiles/Neighbour-Information.h"
+
+
+#include "asn1cFiles/constr_TYPE.h"
+#include "asn1cFiles/asn_constant.h"
+
+using namespace std;
+
+#define printEntry(type, function) \
+ if (mdclog_level_get() >= MDCLOG_DEBUG) { \
+ mdclog_write(MDCLOG_DEBUG, "start Test %s , %s", type, function); \
+ }
+
+
+static void checkAndPrint(asn_TYPE_descriptor_t *typeDescriptor, void *data, char *dataType, const char *function) {
+ char errbuf[128]; /* Buffer for error message */
+ size_t errlen = sizeof(errbuf); /* Size of the buffer */
+ if (asn_check_constraints(typeDescriptor, data, errbuf, &errlen) != 0) {
+ mdclog_write(MDCLOG_ERR, "%s Constraint validation failed: %s", dataType, errbuf);
+ } else if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ mdclog_write(MDCLOG_DEBUG, "%s successes function %s", dataType, function);
+ }
+}
+
+BIT_STRING_t *createBIT_STRING(int size, int unusedBits, uint8_t *data) {
+ printEntry("BIT_STRING_t", __func__)
+ auto *bitString = (BIT_STRING_t *)calloc(1, sizeof(BIT_STRING_t));
+ ASN_STRUCT_RESET(asn_DEF_BIT_STRING, bitString);
+ bitString->size = size;
+ bitString->bits_unused = unusedBits;
+ bitString->buf = (uint8_t *)calloc(1, size);
+ // set bits to zero
+ data[bitString->size - 1] = ((unsigned)(data[bitString->size - 1] >>
+ (unsigned)bitString->bits_unused) << (unsigned)bitString->bits_unused);
+ memcpy(bitString->buf, data, size);
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_BIT_STRING, bitString, (char *)"BIT_STRING_t", __func__);
+ }
+
+ return bitString;
+}
+
+
+OCTET_STRING_t *createOCTET_STRING(const unsigned char *data, int size) {
+ printEntry("OCTET_STRING_t", __func__)
+ auto *octs = (PLMN_Identity_t *)calloc(1, sizeof(PLMN_Identity_t));
+ ASN_STRUCT_RESET(asn_DEF_OCTET_STRING, octs);
+ octs->size = size;
+ octs->buf = (uint8_t *)calloc(1, size);
+ memcpy(octs->buf, data, size);
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_OCTET_STRING, octs, (char *)"OCTET_STRING_t", __func__);
+ }
+ return octs;
+}
+
+
+PLMN_Identity_t *createPLMN_ID(const unsigned char *data) {
+ printEntry("PLMN_Identity_t", __func__)
+ auto *plmnId = (PLMN_Identity_t *)calloc(1, sizeof(PLMN_Identity_t));
+ ASN_STRUCT_RESET(asn_DEF_PLMN_Identity, plmnId);
+ plmnId->size = 3;
+ plmnId->buf = (uint8_t *)calloc(1, 3);
+ memcpy(plmnId->buf, data, 3);
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_PLMN_Identity, plmnId, (char *)"PLMN_Identity_t", __func__);
+ }
+ return plmnId;
+}
+
+ENB_ID_t *createENB_ID(ENB_ID_PR enbType, unsigned char *data) {
+ printEntry("ENB_ID_t", __func__)
+ auto *enb = (ENB_ID_t *)calloc(1, sizeof(ENB_ID_t));
+ ASN_STRUCT_RESET(asn_DEF_ENB_ID, enb);
+
+ enb->present = enbType;
+
+ switch (enbType) {
+ case ENB_ID_PR_macro_eNB_ID: { // 20 bit 3 bytes
+ enb->choice.macro_eNB_ID.size = 3;
+ enb->choice.macro_eNB_ID.bits_unused = 4;
+
+ enb->present = ENB_ID_PR_macro_eNB_ID;
+
+ enb->choice.macro_eNB_ID.buf = (uint8_t *)calloc(1, enb->choice.macro_eNB_ID.size);
+ data[enb->choice.macro_eNB_ID.size - 1] = ((unsigned)(data[enb->choice.macro_eNB_ID.size - 1] >>
+ (unsigned)enb->choice.macro_eNB_ID.bits_unused) << (unsigned)enb->choice.macro_eNB_ID.bits_unused);
+ memcpy(enb->choice.macro_eNB_ID.buf, data, enb->choice.macro_eNB_ID.size);
+
+ break;
+ }
+ case ENB_ID_PR_home_eNB_ID: { // 28 bit 4 bytes
+ enb->choice.home_eNB_ID.size = 4;
+ enb->choice.home_eNB_ID.bits_unused = 4;
+ enb->present = ENB_ID_PR_home_eNB_ID;
+
+ enb->choice.home_eNB_ID.buf = (uint8_t *)calloc(1, enb->choice.home_eNB_ID.size);
+ data[enb->choice.home_eNB_ID.size - 1] = ((unsigned)(data[enb->choice.home_eNB_ID.size - 1] >>
+ (unsigned)enb->choice.home_eNB_ID.bits_unused) << (unsigned)enb->choice.home_eNB_ID.bits_unused);
+ memcpy(enb->choice.home_eNB_ID.buf, data, enb->choice.home_eNB_ID.size);
+ break;
+ }
+ case ENB_ID_PR_short_Macro_eNB_ID: { // 18 bit - 3 bytes
+ enb->choice.short_Macro_eNB_ID.size = 3;
+ enb->choice.short_Macro_eNB_ID.bits_unused = 6;
+ enb->present = ENB_ID_PR_short_Macro_eNB_ID;
+
+ enb->choice.short_Macro_eNB_ID.buf = (uint8_t *)calloc(1, enb->choice.short_Macro_eNB_ID.size);
+ data[enb->choice.short_Macro_eNB_ID.size - 1] = ((unsigned)(data[enb->choice.short_Macro_eNB_ID.size - 1] >>
+ (unsigned)enb->choice.short_Macro_eNB_ID.bits_unused) << (unsigned)enb->choice.short_Macro_eNB_ID.bits_unused);
+ memcpy(enb->choice.short_Macro_eNB_ID.buf, data, enb->choice.short_Macro_eNB_ID.size);
+ break;
+ }
+ case ENB_ID_PR_long_Macro_eNB_ID: { // 21
+ enb->choice.long_Macro_eNB_ID.size = 3;
+ enb->choice.long_Macro_eNB_ID.bits_unused = 3;
+ enb->present = ENB_ID_PR_long_Macro_eNB_ID;
+
+ enb->choice.long_Macro_eNB_ID.buf = (uint8_t *)calloc(1, enb->choice.long_Macro_eNB_ID.size);
+ data[enb->choice.long_Macro_eNB_ID.size - 1] = ((unsigned)(data[enb->choice.long_Macro_eNB_ID.size - 1] >>
+ (unsigned)enb->choice.long_Macro_eNB_ID.bits_unused) << (unsigned)enb->choice.long_Macro_eNB_ID.bits_unused);
+ memcpy(enb->choice.long_Macro_eNB_ID.buf, data, enb->choice.long_Macro_eNB_ID.size);
+ break;
+ }
+ default:
+ free(enb);
+ return nullptr;
+ }
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_ENB_ID, enb, (char *)"ENB_ID_t", __func__);
+ }
+ return enb;
+}
+
+GlobalENB_ID_t *createGlobalENB_ID(PLMN_Identity_t *plmnIdentity, ENB_ID_t *enbId) {
+ printEntry("GlobalENB_ID_t", __func__)
+ auto *genbId = (GlobalENB_ID_t *)calloc(1, sizeof(GlobalENB_ID_t));
+ ASN_STRUCT_RESET(asn_DEF_GlobalENB_ID, genbId);
+ memcpy(&genbId->pLMN_Identity, plmnIdentity, sizeof(PLMN_Identity_t));
+ memcpy(&genbId->eNB_ID, enbId, sizeof(ENB_ID_t));
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_GlobalENB_ID, genbId, (char *)"GlobalENB_ID_t", __func__);
+ }
+ return genbId;
+}
+
+
+ECGI_t *CreateECGI(PLMN_Identity_t *plmnIdentity, BIT_STRING_t * eUtran) {
+ printEntry("ECGI_t", __func__)
+ auto *ecgi = (ECGI_t *)calloc(1, sizeof(ECGI_t));
+ ASN_STRUCT_RESET(asn_DEF_ECGI, ecgi);
+
+ memcpy(&ecgi->pLMN_Identity, plmnIdentity, sizeof(PLMN_Identity_t));
+ memcpy(&ecgi->eUTRANcellIdentifier, eUtran, sizeof(BIT_STRING_t));
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_ECGI, ecgi, (char *)"ECGI_t", __func__);
+ }
+ return ecgi;
+}
+
+//
+//FDD-Info ::= SEQUENCE {
+// uL-EARFCN EARFCN,
+// dL-EARFCN EARFCN,
+// uL-Transmission-Bandwidth Transmission-Bandwidth,
+// dL-Transmission-Bandwidth Transmission-Bandwidth,
+// iE-Extensions ProtocolExtensionContainer { {FDD-Info-ExtIEs} } OPTIONAL,
+// ...
+//}
+//
+//FDD-Info-ExtIEs X2AP-PROTOCOL-EXTENSION ::= {
+// { ID id-UL-EARFCNExtension CRITICALITY reject EXTENSION EARFCNExtension PRESENCE optional}|
+// { ID id-DL-EARFCNExtension CRITICALITY reject EXTENSION EARFCNExtension PRESENCE optional}|
+// { ID id-OffsetOfNbiotChannelNumberToDL-EARFCN CRITICALITY reject EXTENSION OffsetOfNbiotChannelNumberToEARFCN PRESENCE optional}|
+// { ID id-OffsetOfNbiotChannelNumberToUL-EARFCN CRITICALITY reject EXTENSION OffsetOfNbiotChannelNumberToEARFCN PRESENCE optional}|
+// { ID id-NRS-NSSS-PowerOffset CRITICALITY ignore EXTENSION NRS-NSSS-PowerOffset PRESENCE optional}|
+// { ID id-NSSS-NumOccasionDifferentPrecoder CRITICALITY ignore EXTENSION NSSS-NumOccasionDifferentPrecoder PRESENCE optional},
+// ...
+//}
+
+static FDD_Info_t *create_fdd(long dL_EARFCN,
+ long uL_EARFCN,
+ e_Transmission_Bandwidth ultb,
+ e_Transmission_Bandwidth dltb) {
+ printEntry("FDD_Info_t", __func__)
+ auto *fdd = (FDD_Info_t *)calloc(1, sizeof(FDD_Info_t));
+ ASN_STRUCT_RESET(asn_DEF_FDD_Info, fdd);
+
+ //EARFCN ::= INTEGER (0..maxEARFCN)
+
+ if (dL_EARFCN >= 0 && dL_EARFCN <= maxEARFCN) {
+ fdd->dL_EARFCN = dL_EARFCN;
+ } else {
+ fdd->dL_EARFCN = maxEARFCN;
+ }
+ if (uL_EARFCN >= 0 && uL_EARFCN <= maxEARFCN) {
+ fdd->uL_EARFCN = uL_EARFCN;
+ } else {
+ fdd->uL_EARFCN = maxEARFCN;
+ }
+
+ fdd->uL_Transmission_Bandwidth = ultb;
+ fdd->dL_Transmission_Bandwidth = dltb;
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_FDD_Info, fdd, (char *)"FDD_Info_t", __func__);
+ }
+
+ return fdd;
+}
+
+SpecialSubframe_Info_t *createSpecialSubframe_Info(e_CyclicPrefixDL eCyclicPrefixDl,
+ e_CyclicPrefixUL eCyclicPrefixUl,
+ e_SpecialSubframePatterns eSpecialSubframePatterns) {
+ printEntry("SpecialSubframe_Info_t", __func__)
+ auto *ssf = (SpecialSubframe_Info_t *)calloc(1, sizeof(SpecialSubframe_Info_t));
+ ASN_STRUCT_RESET(asn_DEF_SpecialSubframe_Info, ssf);
+
+ ssf->cyclicPrefixDL = eCyclicPrefixDl;
+ ssf->cyclicPrefixUL = eCyclicPrefixUl;
+ ssf->specialSubframePatterns = eSpecialSubframePatterns;
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_SpecialSubframe_Info, ssf, (char *)"SpecialSubframe_Info_t", __func__);
+ }
+ return ssf;
+}
+
+//TDD-Info ::= SEQUENCE {
+// eARFCN EARFCN,
+// transmission-Bandwidth Transmission-Bandwidth,
+// subframeAssignment SubframeAssignment,
+// specialSubframe-Info SpecialSubframe-Info,
+// iE-Extensions ProtocolExtensionContainer { {TDD-Info-ExtIEs} } OPTIONAL,
+// ...
+//}
+//
+//TDD-Info-ExtIEs X2AP-PROTOCOL-EXTENSION ::= {
+// { ID id-AdditionalSpecialSubframe-Info CRITICALITY ignore EXTENSION AdditionalSpecialSubframe-Info PRESENCE optional}|
+// { ID id-eARFCNExtension CRITICALITY reject EXTENSION EARFCNExtension PRESENCE optional}|
+// { ID id-AdditionalSpecialSubframeExtension-Info CRITICALITY ignore EXTENSION AdditionalSpecialSubframeExtension-Info PRESENCE optional}|
+// { ID id-OffsetOfNbiotChannelNumberToDL-EARFCN CRITICALITY reject EXTENSION OffsetOfNbiotChannelNumberToEARFCN PRESENCE optional}|
+// { ID id-NBIoT-UL-DL-AlignmentOffset CRITICALITY reject EXTENSION NBIoT-UL-DL-AlignmentOffset PRESENCE optional},
+// ...
+//}
+
+static TDD_Info_t *create_Tdd(long eARFCN,
+ e_Transmission_Bandwidth tb,
+ e_SubframeAssignment sfA,
+ SpecialSubframe_Info_t *ssfi) {
+ printEntry("TDD_Info_t", __func__)
+ auto *tdd = (TDD_Info_t *)calloc(1, sizeof(FDD_Info_t));
+ ASN_STRUCT_RESET(asn_DEF_TDD_Info, tdd);
+
+ if (eARFCN >= 0 && eARFCN <= maxEARFCN) {
+ tdd->eARFCN = eARFCN;
+ } else {
+ tdd->eARFCN = maxEARFCN;
+ }
+ tdd->transmission_Bandwidth = tb;
+ tdd->subframeAssignment = sfA;
+ memcpy(&tdd->specialSubframe_Info, ssfi, sizeof(SpecialSubframe_Info_t));
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_TDD_Info, tdd, (char *)"TDD_Info_t", __func__);
+ }
+ return tdd;
+}
+
+static EUTRA_Mode_Info_t *createEUTRA_Mode_Info_FDD(FDD_Info_t *fdd) {
+ printEntry("EUTRA_Mode_Info_t", __func__)
+ auto *eutraModeInfo = (EUTRA_Mode_Info_t *)calloc(1, sizeof(EUTRA_Mode_Info_t));
+ ASN_STRUCT_RESET(asn_DEF_EUTRA_Mode_Info, eutraModeInfo);
+
+ eutraModeInfo->present = EUTRA_Mode_Info_PR_fDD;
+ eutraModeInfo->choice.fDD = fdd;
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_EUTRA_Mode_Info, eutraModeInfo, (char *)"EUTRA_Mode_Info_t", __func__);
+ }
+ return eutraModeInfo;
+
+}
+
+static EUTRA_Mode_Info_t *createEUTRA_Mode_Info_TDD(TDD_Info_t *tdd) {
+ printEntry("EUTRA_Mode_Info_t", __func__)
+ auto *eutraModeInfo = (EUTRA_Mode_Info_t *)calloc(1, sizeof(EUTRA_Mode_Info_t));
+ ASN_STRUCT_RESET(asn_DEF_EUTRA_Mode_Info, eutraModeInfo);
+
+ eutraModeInfo->present = EUTRA_Mode_Info_PR_tDD;
+ eutraModeInfo->choice.tDD = tdd;
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_EUTRA_Mode_Info, eutraModeInfo, (char *)"EUTRA_Mode_Info_t", __func__);
+ }
+ return eutraModeInfo;
+
+}
+
+Neighbour_Information__Member *createNeighbour_Information__Member(ECGI_t *eCGI, long pci, long eARFCN) {
+ printEntry("Neighbour_Information__Member", __func__)
+ auto *nigborInformation = (Neighbour_Information__Member *)calloc(1, sizeof(Neighbour_Information__Member));
+ ASN_STRUCT_RESET(asn_DEF_Neighbour_Information, nigborInformation);
+
+ memcpy(&nigborInformation->eCGI, eCGI, sizeof(ECGI_t));
+ nigborInformation->pCI = pci;
+ nigborInformation->eARFCN = eARFCN;
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_Neighbour_Information, nigborInformation, (char *)"Neighbour_Information__Member", __func__);
+ }
+ return nigborInformation;
+}
+
+void buildNeighbour_InformationVector(Neighbour_Information_t *neighbourInformation, Neighbour_Information__Member *member) {
+ ASN_SEQUENCE_ADD(&neighbourInformation->list, member);
+}
+
+//ServedCell-Information ::= SEQUENCE {
+// pCI PCI,
+// cellId ECGI,
+// tAC TAC,
+// broadcastPLMNs BroadcastPLMNs-Item,
+// eUTRA-Mode-Info EUTRA-Mode-Info,
+// iE-Extensions ProtocolExtensionContainer { {ServedCell-Information-ExtIEs} } OPTIONAL,
+// ...
+//}
+//
+//ServedCell-Information-ExtIEs X2AP-PROTOCOL-EXTENSION ::= {
+// { ID id-Number-of-Antennaports CRITICALITY ignore EXTENSION Number-of-Antennaports PRESENCE optional}|
+// { ID id-PRACH-Configuration CRITICALITY ignore EXTENSION PRACH-Configuration PRESENCE optional}|
+// { ID id-MBSFN-Subframe-Info CRITICALITY ignore EXTENSION MBSFN-Subframe-Infolist PRESENCE optional}|
+// { ID id-CSG-Id CRITICALITY ignore EXTENSION CSG-Id PRESENCE optional}|
+// { ID id-MBMS-Service-Area-List CRITICALITY ignore EXTENSION MBMS-Service-Area-Identity-List PRESENCE optional}|
+// { ID id-MultibandInfoList CRITICALITY ignore EXTENSION MultibandInfoList PRESENCE optional}|
+// { ID id-FreqBandIndicatorPriority CRITICALITY ignore EXTENSION FreqBandIndicatorPriority PRESENCE optional}|
+// { ID id-BandwidthReducedSI CRITICALITY ignore EXTENSION BandwidthReducedSI PRESENCE optional}|
+// { ID id-ProtectedEUTRAResourceIndication CRITICALITY ignore EXTENSION ProtectedEUTRAResourceIndication PRESENCE optional}|
+// { ID id-BPLMN-ID-Info-EUTRA CRITICALITY ignore EXTENSION BPLMN-ID-Info-EUTRA PRESENCE optional},
+// ...
+//}
+
+/**
+ *
+ * @param pci
+ * @param cellId
+ * @param tac
+ * @param broadcastPLMNs
+ * @param eutranModeInfo
+ * @return
+ */
+ServedCell_Information_t *createServedCellInfo(long pci,
+ ECGI_t *cellId,
+ TAC_t *tac,
+ vector<PLMN_Identity_t> &broadcastPLMNs,
+ EUTRA_Mode_Info_t *eutranModeInfo) {
+
+ printEntry("ServedCell_Information_t", __func__)
+ auto servedCellinfo = (ServedCell_Information_t *)calloc(1, sizeof(ServedCell_Information_t));
+ ASN_STRUCT_RESET(asn_DEF_ServedCell_Information, servedCellinfo);
+
+ servedCellinfo->pCI = pci;
+ memcpy(&servedCellinfo->cellId, cellId, sizeof(ECGI_t));
+ memcpy(&servedCellinfo->tAC, tac, sizeof(TAC_t));
+
+ for (auto v : broadcastPLMNs) {
+ ASN_SEQUENCE_ADD(&servedCellinfo->broadcastPLMNs.list, &v);
+ }
+
+ memcpy(&servedCellinfo->eUTRA_Mode_Info, eutranModeInfo, sizeof(EUTRA_Mode_Info_t));
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_ServedCell_Information, servedCellinfo, (char *)"ServedCell_Information_t", __func__);
+ }
+
+ return servedCellinfo;
+}
+
+
+ServedCells__Member *createServedCellsMember(ServedCell_Information_t *servedCellInfo, Neighbour_Information_t *neighbourInformation) {
+ printEntry("ServedCells__Member", __func__)
+ auto servedCellMember = (ServedCells__Member *)calloc(1, sizeof(ServedCells__Member));
+
+ memcpy(&servedCellMember->servedCellInfo, servedCellInfo, sizeof(ServedCell_Information_t));
+ servedCellMember->neighbour_Info = neighbourInformation;
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_ServedCells, servedCellMember, (char *)"ServedCells__Member", __func__);
+ }
+
+ return servedCellMember;
+}
+
+void buildServedCells(ServedCells_t *servedCells, ServedCells__Member *member) {
+ ASN_SEQUENCE_ADD(&servedCells->list, member);
+}
+
+
+static void buildInitiatingMessagePDU(E2AP_PDU_t &pdu, InitiatingMessage_t *initMsg) {
+ pdu.present = E2AP_PDU_PR_initiatingMessage;
+ pdu.choice.initiatingMessage = initMsg;
+}
+
+template<typename T>
+static void buildInitMsg(InitiatingMessage_t &initMsg,
+ InitiatingMessage__value_PR present,
+ ProcedureCode_t procedureCode,
+ Criticality_t criticality,
+ T *value) {
+ initMsg.value.present = present;
+ initMsg.procedureCode = procedureCode;
+ initMsg.criticality = criticality;
+
+ switch (present) {
+ case InitiatingMessage__value_PR_RICsubscriptionRequest: {
+ memcpy(&initMsg.value.choice.RICsubscriptionRequest, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_RICsubscriptionDeleteRequest: {
+ memcpy(&initMsg.value.choice.RICsubscriptionDeleteRequest, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_RICserviceUpdate: {
+ memcpy(&initMsg.value.choice.RICserviceUpdate, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_RICcontrolRequest: {
+ memcpy(&initMsg.value.choice.RICcontrolRequest, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_X2SetupRequest: {
+ memcpy(&initMsg.value.choice.X2SetupRequest, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_ENDCX2SetupRequest: {
+ memcpy(&initMsg.value.choice.ENDCX2SetupRequest, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_ResourceStatusRequest: {
+ memcpy(&initMsg.value.choice.ResourceStatusRequest, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_ENBConfigurationUpdate: {
+ memcpy(&initMsg.value.choice.ENBConfigurationUpdate, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_ENDCConfigurationUpdate: {
+ memcpy(&initMsg.value.choice.ENDCConfigurationUpdate, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_ResetRequest: {
+ memcpy(&initMsg.value.choice.ResetRequest, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_RICindication: {
+ memcpy(&initMsg.value.choice.RICindication, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_RICserviceQuery: {
+ memcpy(&initMsg.value.choice.RICserviceQuery, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_LoadInformation: {
+ memcpy(&initMsg.value.choice.LoadInformation, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_GNBStatusIndication: {
+ memcpy(&initMsg.value.choice.GNBStatusIndication, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_ResourceStatusUpdate: {
+ memcpy(&initMsg.value.choice.ResourceStatusUpdate, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_ErrorIndication: {
+ memcpy(&initMsg.value.choice.ErrorIndication, value, sizeof(*value));
+ break;
+ }
+ case InitiatingMessage__value_PR_NOTHING:
+ default : {
+ break;
+ }
+ }
+}
+
+static void buildSuccsesfulMessagePDU(E2AP_PDU_t &pdu, SuccessfulOutcome_t *succMsg) {
+ pdu.present = E2AP_PDU_PR_successfulOutcome;
+ pdu.choice.successfulOutcome = succMsg;
+}
+
+template<typename T>
+static void buildSuccMsg(SuccessfulOutcome_t &succMsg,
+ SuccessfulOutcome__value_PR present,
+ ProcedureCode_t procedureCode,
+ Criticality_t criticality,
+ T *value) {
+ succMsg.value.present = present;
+ succMsg.procedureCode = procedureCode;
+ succMsg.criticality = criticality;
+
+ switch (present) {
+ case SuccessfulOutcome__value_PR_RICsubscriptionResponse: {
+ memcpy(&succMsg.value.choice.RICsubscriptionResponse, value, sizeof(*value));
+ break;
+ }
+ case SuccessfulOutcome__value_PR_RICsubscriptionDeleteResponse: {
+ memcpy(&succMsg.value.choice.RICsubscriptionDeleteResponse, value, sizeof(*value));
+ break;
+ }
+ case SuccessfulOutcome__value_PR_RICserviceUpdateAcknowledge: {
+ memcpy(&succMsg.value.choice.RICserviceUpdateAcknowledge, value, sizeof(*value));
+ break;
+ }
+ case SuccessfulOutcome__value_PR_RICcontrolAcknowledge: {
+ memcpy(&succMsg.value.choice.RICcontrolAcknowledge, value, sizeof(*value));
+ break;
+ }
+ case SuccessfulOutcome__value_PR_X2SetupResponse: {
+ memcpy(&succMsg.value.choice.X2SetupResponse, value, sizeof(*value));
+ break;
+ }
+ case SuccessfulOutcome__value_PR_ENDCX2SetupResponse: {
+ memcpy(&succMsg.value.choice.ENDCX2SetupResponse, value, sizeof(*value));
+ break;
+ }
+ case SuccessfulOutcome__value_PR_ResourceStatusResponse: {
+ memcpy(&succMsg.value.choice.ResourceStatusResponse, value, sizeof(*value));
+ break;
+ }
+ case SuccessfulOutcome__value_PR_ENBConfigurationUpdateAcknowledge: {
+ memcpy(&succMsg.value.choice.ENBConfigurationUpdateAcknowledge, value, sizeof(*value));
+ break;
+ }
+ case SuccessfulOutcome__value_PR_ENDCConfigurationUpdateAcknowledge: {
+ memcpy(&succMsg.value.choice.ENDCConfigurationUpdateAcknowledge, value, sizeof(*value));
+ break;
+ }
+ case SuccessfulOutcome__value_PR_ResetResponse: {
+ memcpy(&succMsg.value.choice.ResetResponse, value, sizeof(*value));
+ break;
+ }
+ case SuccessfulOutcome__value_PR_NOTHING:
+ default:
+ break;
+ }
+}
+
+
+static void buildUnSucssesfullMessagePDU(E2AP_PDU_t &pdu, UnsuccessfulOutcome_t *unSuccMsg) {
+ pdu.present = E2AP_PDU_PR_unsuccessfulOutcome;
+ pdu.choice.unsuccessfulOutcome = unSuccMsg;
+}
+
+template<typename T>
+static void buildUnSuccMsg(UnsuccessfulOutcome_t &unSuccMsg,
+ UnsuccessfulOutcome__value_PR present,
+ ProcedureCode_t procedureCode,
+ Criticality_t criticality,
+ T *value) {
+ unSuccMsg.value.present = present;
+ unSuccMsg.procedureCode = procedureCode;
+ unSuccMsg.criticality = criticality;
+
+ switch (present) {
+ case UnsuccessfulOutcome__value_PR_RICsubscriptionFailure: {
+ memcpy(&unSuccMsg.value.choice.RICsubscriptionFailure, value, sizeof(*value));
+ break;
+ }
+ case UnsuccessfulOutcome__value_PR_RICsubscriptionDeleteFailure: {
+ memcpy(&unSuccMsg.value.choice.RICsubscriptionDeleteFailure, value, sizeof(*value));
+ break;
+ }
+ case UnsuccessfulOutcome__value_PR_RICserviceUpdateFailure: {
+ memcpy(&unSuccMsg.value.choice.RICserviceUpdateFailure, value, sizeof(*value));
+ break;
+ }
+ case UnsuccessfulOutcome__value_PR_RICcontrolFailure: {
+ memcpy(&unSuccMsg.value.choice.RICcontrolFailure, value, sizeof(*value));
+ break;
+ }
+ case UnsuccessfulOutcome__value_PR_X2SetupFailure: {
+ memcpy(&unSuccMsg.value.choice.X2SetupFailure, value, sizeof(*value));
+ break;
+ }
+ case UnsuccessfulOutcome__value_PR_ENDCX2SetupFailure: {
+ memcpy(&unSuccMsg.value.choice.ENDCX2SetupFailure, value, sizeof(*value));
+ break;
+ }
+ case UnsuccessfulOutcome__value_PR_ResourceStatusFailure: {
+ memcpy(&unSuccMsg.value.choice.ResourceStatusFailure, value, sizeof(*value));
+ break;
+ }
+ case UnsuccessfulOutcome__value_PR_ENBConfigurationUpdateFailure: {
+ memcpy(&unSuccMsg.value.choice.ENBConfigurationUpdateFailure, value, sizeof(*value));
+ break;
+ }
+ case UnsuccessfulOutcome__value_PR_ENDCConfigurationUpdateFailure: {
+ memcpy(&unSuccMsg.value.choice.ENDCConfigurationUpdateFailure, value, sizeof(*value));
+ break;
+ }
+ case UnsuccessfulOutcome__value_PR_NOTHING:
+ default:
+ break;
+ }
+}
+
+
+static void createPLMN_ID(PLMN_Identity_t &plmnId, const unsigned char *data) {
+ //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;
+ plmnId.buf = (uint8_t *) calloc(1, 3);
+ memcpy(plmnId.buf, data, 3);
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_PLMN_Identity, &plmnId, (char *) "PLMN_Identity_t", __func__);
+ }
+
+}
+
+static void createENB_ID(ENB_ID_t &enb, ENB_ID_PR enbType, unsigned char *data) {
+ //printEntry("ENB_ID_t", __func__)
+ ASN_STRUCT_RESET(asn_DEF_ENB_ID, &enb);
+ enb.present = enbType;
+ switch (enbType) {
+ case ENB_ID_PR_macro_eNB_ID: { // 20 bit 3 bytes
+ enb.choice.macro_eNB_ID.size = 3;
+ enb.choice.macro_eNB_ID.bits_unused = 4;
+
+ enb.present = ENB_ID_PR_macro_eNB_ID;
+
+ enb.choice.macro_eNB_ID.buf = (uint8_t *) calloc(1, enb.choice.macro_eNB_ID.size);
+ data[enb.choice.macro_eNB_ID.size - 1] = ((unsigned) (data[enb.choice.macro_eNB_ID.size - 1]
+ >> (unsigned) enb.choice.macro_eNB_ID.bits_unused)
+ << (unsigned) enb.choice.macro_eNB_ID.bits_unused);
+ memcpy(enb.choice.macro_eNB_ID.buf, data, enb.choice.macro_eNB_ID.size);
+
+ break;
+ }
+ case ENB_ID_PR_home_eNB_ID: { // 28 bit 4 bytes
+ enb.choice.home_eNB_ID.size = 4;
+ enb.choice.home_eNB_ID.bits_unused = 4;
+ enb.present = ENB_ID_PR_home_eNB_ID;
+
+ enb.choice.home_eNB_ID.buf = (uint8_t *) calloc(1, enb.choice.home_eNB_ID.size);
+ data[enb.choice.home_eNB_ID.size - 1] = ((unsigned) (data[enb.choice.home_eNB_ID.size - 1]
+ >> (unsigned) enb.choice.home_eNB_ID.bits_unused)
+ << (unsigned) enb.choice.home_eNB_ID.bits_unused);
+ memcpy(enb.choice.home_eNB_ID.buf, data, enb.choice.home_eNB_ID.size);
+ break;
+ }
+ case ENB_ID_PR_short_Macro_eNB_ID: { // 18 bit - 3 bytes
+ enb.choice.short_Macro_eNB_ID.size = 3;
+ enb.choice.short_Macro_eNB_ID.bits_unused = 6;
+ enb.present = ENB_ID_PR_short_Macro_eNB_ID;
+
+ enb.choice.short_Macro_eNB_ID.buf = (uint8_t *) calloc(1, enb.choice.short_Macro_eNB_ID.size);
+ data[enb.choice.short_Macro_eNB_ID.size - 1] = ((unsigned) (data[enb.choice.short_Macro_eNB_ID.size - 1]
+ >> (unsigned) enb.choice.short_Macro_eNB_ID.bits_unused)
+ << (unsigned) enb.choice.short_Macro_eNB_ID.bits_unused);
+ memcpy(enb.choice.short_Macro_eNB_ID.buf, data, enb.choice.short_Macro_eNB_ID.size);
+ break;
+ }
+ case ENB_ID_PR_long_Macro_eNB_ID: { // 21
+ enb.choice.long_Macro_eNB_ID.size = 3;
+ enb.choice.long_Macro_eNB_ID.bits_unused = 3;
+ enb.present = ENB_ID_PR_long_Macro_eNB_ID;
+
+ enb.choice.long_Macro_eNB_ID.buf = (uint8_t *) calloc(1, enb.choice.long_Macro_eNB_ID.size);
+ data[enb.choice.long_Macro_eNB_ID.size - 1] = ((unsigned) (data[enb.choice.long_Macro_eNB_ID.size - 1]
+ >> (unsigned) enb.choice.long_Macro_eNB_ID.bits_unused)
+ << (unsigned) enb.choice.long_Macro_eNB_ID.bits_unused);
+ memcpy(enb.choice.long_Macro_eNB_ID.buf, data, enb.choice.long_Macro_eNB_ID.size);
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_ENB_ID, &enb, (char *) "ENB_ID_t", __func__);
+ }
+}
+
+
+static void buildGlobalENB_ID(GlobalENB_ID_t *gnbId,
+ const unsigned char *gnbData,
+ ENB_ID_PR enbType,
+ unsigned char *enbData) {
+ createPLMN_ID(gnbId->pLMN_Identity, gnbData);
+ createENB_ID(gnbId->eNB_ID, enbType, enbData);
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ checkAndPrint(&asn_DEF_GlobalENB_ID, gnbId, (char *) "GlobalENB_ID_t", __func__);
+ }
+}
+
+#endif //E2_E2BUILDER_H
--- /dev/null
+/*
+ * 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 12/10/19.
+//
+
+#include "E2Builder.h"
+
+#include "asn1cFiles/ProtocolIE-Field.h"
+
+template<typename T>
+X2SetupRequest_IEs_t *buildX2SetupIE(ProtocolIE_ID_t id,
+ Criticality_t criticality,
+ X2SetupRequest_IEs__value_PR present,
+ T *value) {
+ auto *x2SetupIE = (X2SetupRequest_IEs_t *)calloc(1, sizeof(X2SetupRequest_IEs_t));
+ x2SetupIE->id = id;
+ x2SetupIE->criticality = criticality;
+ x2SetupIE->value.present = present;
+
+ switch (present) {
+ case X2SetupRequest_IEs__value_PR_GlobalENB_ID: {
+ memcpy(&x2SetupIE->value.choice.GlobalENB_ID, value, sizeof(GlobalENB_ID_t));
+ break;
+ }
+ case X2SetupRequest_IEs__value_PR_ServedCells: {
+ memcpy(&x2SetupIE->value.choice.ServedCells, value, sizeof(ServedCells_t));
+ break;
+ }
+ case X2SetupRequest_IEs__value_PR_GUGroupIDList: {
+ memcpy(&x2SetupIE->value.choice.GUGroupIDList, value, sizeof(GUGroupIDList_t));
+ break;
+ }
+ case X2SetupRequest_IEs__value_PR_LHN_ID: {
+ memcpy(&x2SetupIE->value.choice.LHN_ID, value, sizeof(LHN_ID_t));
+ break;
+ }
+ case X2SetupRequest_IEs__value_PR_NOTHING:
+ default:
+ free(x2SetupIE);
+ x2SetupIE = nullptr;
+ break;
+ }
+ return x2SetupIE;
+}
+
+/**
+ *
+ * @param x2Setup
+ * @param member
+ */
+void buildE2SetupRequest(X2SetupRequest_t *x2Setup, vector<X2SetupRequest_IEs_t> &member) {
+ for (auto v : member) {
+ ASN_SEQUENCE_ADD(&x2Setup->protocolIEs.list, &v);
+ }
+}
+
+void init_log() {
+ mdclog_attr_t *attr;
+ mdclog_attr_init(&attr);
+ mdclog_attr_set_ident(attr, "setup Request");
+ mdclog_init(attr);
+ mdclog_attr_destroy(attr);
+}
+
+int main(const int argc, char **argv) {
+ init_log();
+ //mdclog_level_set(MDCLOG_WARN);
+ //mdclog_level_set(MDCLOG_INFO);
+ mdclog_level_set(MDCLOG_DEBUG);
+
+// x2Setup X2AP-ELEMENTARY-PROCEDURE ::= {
+// INITIATING MESSAGE X2SetupRequest
+// SUCCESSFUL OUTCOME X2SetupResponse
+// UNSUCCESSFUL OUTCOME X2SetupFailure
+// PROCEDURE CODE id-x2Setup
+// CRITICALITY reject
+// }
+//
+//
+
+// X2SetupRequest ::= SEQUENCE {
+// protocolIEs ProtocolIE-Container {{X2SetupRequest-IEs}},
+// ...
+// }
+//
+// X2SetupRequest-IEs X2AP-PROTOCOL-IES ::= {
+// { ID id-GlobalENB-ID CRITICALITY reject TYPE GlobalENB-ID PRESENCE mandatory}|
+// { ID id-ServedCells CRITICALITY reject TYPE ServedCells PRESENCE mandatory}|
+// { ID id-GUGroupIDList CRITICALITY reject TYPE GUGroupIDList PRESENCE optional}|
+// { ID id-LHN-ID CRITICALITY ignore TYPE LHN-ID PRESENCE optional},
+// ...
+// }
+
+
+
+}
\ No newline at end of file
#include <mdclog/mdclog.h>
-#include "asn/type_defs.h"
-#include "asn/per/codec.hpp"
-#include "asn/printer.hpp"
+#include "asn1cFiles/E2AP-PDU.h"
+#include "asn1cFiles/InitiatingMessage.h"
+
-#include "X2AP-CommonDataTypes.hpp"
-#include "X2AP-Containers.hpp"
-#include "X2AP-Constants.hpp"
-#include "X2AP-IEs.hpp"
-#include "X2AP-PDU-Contents.hpp"
-#include "E2AP-Constants.hpp"
-#include "E2AP-IEs.hpp"
-#include "E2AP-PDU-Contents.hpp"
-#include "E2AP-PDU-Descriptions.hpp"
#include <iostream>
#include <cstdio>
#include <cctype>
#include <cstring>
+#include <unistd.h>
#include <pthread.h>
#include <rmr/rmr.h>
mdclog_write(MDCLOG_INFO, "RMR running");
}
- E2AP_PDU pdu {};
+ E2AP_PDU_t pdu {};
auto &initiatingMsg = pdu.select_initiatingMessage();
initiatingMsg.ref_procedureCode().select_id_x2Setup();
initiatingMsg.ref_criticality().select_id_x2Setup();
--- /dev/null
+/*
+ * 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/27/19.
+//
+
+#include "base64.h"
+#include <mdclog/mdclog.h>
+#include <cgreen/cgreen.h>
+#include <cstdio>
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+
+using namespace std;
+
+Describe(base64);
+BeforeEach(base64) {}
+AfterEach(base64) {}
+
+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);
+}
+
+const char *data = "ABC123Test Lets Try this' input and see What \"happens\"";
+
+Ensure(base64, encDec) {
+ string str = "ABC123Test Lets Try this' input and see What \"happens\"";
+ auto *buf = (unsigned char *)malloc(str.length() * 2);
+ auto length = (long)(str.length() * 2);
+ base64::encode((unsigned char *)str.c_str(), str.length(), buf, length);
+ auto *backBackBuff = (unsigned char *)malloc(length);
+ auto length2 = length;
+ assert_that(base64::decode(buf, length, backBackBuff, length2) == 0);
+ std::string str1( backBackBuff, backBackBuff + sizeof backBackBuff / sizeof backBackBuff[0]);
+
+ assert_that(str.length() == (ulong)length2)
+ //auto val = str.compare((const char *)backBackBuff);
+ assert_that(str.compare((const char *)backBackBuff) == 0)
+ free(backBackBuff);
+ free(buf);
+}
+
+Ensure(base64, errorsHandling) {
+ string str = "ABC123Test Lets Try this' input and see What \"happens\"";
+ auto *buf = (unsigned char *)malloc(str.length() * 2);
+ auto length = (long)(str.length());
+ assert_that(base64::encode((unsigned char *)str.c_str(), str.length(), buf, length) == -1);
+ length = (long)(str.length() * 2);
+ assert_that(base64::encode((unsigned char *)str.c_str(), str.length(), buf, length) == 0);
+ auto *backBackBuff = (unsigned char *)malloc(length);
+ auto length2 = length >> 2;
+ assert_that(base64::decode(buf, length, backBackBuff, length2) == -1);
+ //std::string str1( backBackBuff, backBackBuff + sizeof backBackBuff / sizeof backBackBuff[0]);
+ auto length1 = 0l;
+ assert_that(base64::encode((unsigned char *)str.c_str(), str.length(), nullptr , length) == -1);
+// assert_that(base64::encode((unsigned char *)str.c_str(), str.length(), nullptr , length) == -1);
+ assert_that(base64::encode(nullptr, str.length(), backBackBuff , length) == -1);
+ assert_that(base64::encode((unsigned char *)str.c_str(), length1, backBackBuff , length) == -1);
+ assert_that(base64::encode(nullptr, str.length(), backBackBuff , length1) == -1);
+ length1 = -1;
+ assert_that(base64::encode((unsigned char *)str.c_str(), length1, backBackBuff , length) == -1);
+ assert_that(base64::encode(nullptr, str.length(), backBackBuff , length1) == -1);
+
+}
+
+
+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, base64, encDec);
+ add_test_with_context(suite, base64, errorsHandling);
+
+ return cgreen::run_test_suite(suite, create_text_reporter());
+
+}
\ No newline at end of file
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
+
+ /*
* This source code is part of the near-RT RIC (RAN Intelligent Controller)
* platform project (RICP).
*/
-
//
// Created by adi ENZEL on 6/19/19.
//
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) {
}
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;
}
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);
+
+ enb->present = enbType;
+
switch (enbType) {
case ENB_ID_PR_macro_eNB_ID: { // 20 bit 3 bytes
enb->choice.macro_eNB_ID.size = 3;
}
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;
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] =
}
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));
}
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);
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);
}
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);
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);
}
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);
}
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);
}
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);
}
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);
}
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);
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__);
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);
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);
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);
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);
}
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);
}
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);
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);
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);
* @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);
}
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;
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);
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,
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);
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,
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);
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,
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;
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,
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);
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,
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);
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,
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);
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,
}
return len;
-}
\ No newline at end of file
+}
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
+
+ /*
* This source code is part of the near-RT RIC (RAN Intelligent Controller)
* platform project (RICP).
*/
-
//
// Created by adi ENZEL on 6/19/19.
//
#include <math.h>
-#include "../asn1cFiles/ENB-ID.h"
+#include "asn1cFiles/ENB-ID.h"
-#include "../asn1cFiles/E2SM-gNB-X2-actionDefinition.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/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/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"
/**
*
GlobalENB_ID_t *createGlobalENB_ID(PLMN_Identity_t *plmnIdentity, ENB_ID_t *enbId);
/**
*
- * @param plmnIdentity
+ * @param plmnIdent#ifdef __cplusplus
+}
+#endif
+ity
* @param gnb
* @return
*/
--- /dev/null
+/*
+ * 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.
+ */
+
+ /*
+ * This source code is part of the near-RT RIC (RAN Intelligent Controller)
+ * platform project (RICP).
+ */
+
+//
+// Created by adi ENZEL on 12/19/19.
+//
+
+#include "e2test.h"
+
+
+
+int main(const int argc, char **argv) {
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ */
+
+ /*
+ * This source code is part of the near-RT RIC (RAN Intelligent Controller)
+ * platform project (RICP).
+ */
+
+//
+// Created by adi ENZEL on 12/19/19.
+//
+
+#ifndef E2_E2TEST_H
+#define E2_E2TEST_H
+
+#include <algorithm>
+
+#include <pistache/net.h>
+#include <pistache/http.h>
+#include <pistache/peer.h>
+#include <pistache/http_headers.h>
+#include <pistache/cookie.h>
+#include <pistache/endpoint.h>
+#include <pistache/common.h>
+#include <pistache/router.h>
+
+
+using namespace Pistache;
+
+class e2test {
+
+ Rest::Router router;
+
+};
+
+
+#endif //E2_E2TEST_H
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
+
+ /*
* This source code is part of the near-RT RIC (RAN Intelligent Controller)
* platform project (RICP).
*/
-
//
// Created by adi ENZEL on 9/26/19.
//
#include "base64.h"
-void base64::encode(const unsigned char *src, const int srcLen, char unsigned *dst, int &dstLen) {
+int base64::encode(const unsigned char *src, int srcLen, char unsigned *dst, long &dstLen) {
unsigned char *pos;
const unsigned char *end, *in;
- if (dstLen < srcLen) {
- mdclog_write(MDCLOG_ERR, "Destination size %d must be at least 140 percent from source size %d",
+
+ if (dstLen <= 0 || srcLen <= 0) {
+ mdclog_write(MDCLOG_ERR, "source or destination length are 0. dst =%ld source = %d",
dstLen, srcLen);
- return;
+ return -1;
+ }
+ if (dstLen < (srcLen * 4 / 3)) {
+ mdclog_write(MDCLOG_ERR, "Destination size %ld must be at least 140 percent from source size %d",
+ dstLen, srcLen);
+ return -1;
}
if (dst == nullptr) {
mdclog_write(MDCLOG_ERR, "Destination must be allocated and freed by caller the function not allocate the memory");
- return;
+ return -1;
+ }
+ if (src == nullptr) {
+ mdclog_write(MDCLOG_ERR, "source is null pointer");
+ return -1;
}
end = src + srcLen;
}
*pos = '\0';
- dstLen = pos - dst;
+ dstLen = pos - dst;return 0;
}
+int base64::decode(const unsigned char *src, int srcLen, char unsigned *dst, long &dstLen) {
+ unsigned char inv_table[INVERSE_TABLE_SIZE];
+ memset(inv_table, 0x80, INVERSE_TABLE_SIZE);
+ for (ulong i = 0; i < sizeof(base64_table) - 1; i++) {
+ inv_table[base64_table[i]] = (unsigned char) i;
+ }
+ inv_table['='] = 0;
+
+
+ if (dstLen == 0 || dstLen < (int)(srcLen / 4 * 3)) {
+ mdclog_write(MDCLOG_ERR, "Destination size %ld can be up to 40 smaller then source size %d",
+ dstLen, srcLen);
+ return -1;
+ }
+ if (dst == nullptr) {
+ mdclog_write(MDCLOG_ERR, "Destination must be allocated and freed by caller the function not allocate the memory");
+ return -1;
+ }
+
+ unsigned char *pos, block[4], tmp;
+ long i;
+ int pad = 0;
+
+ size_t count = 0;
+
+ for (i = 0; i < srcLen; i++) {
+ if (inv_table[src[i]] != 0x80) {
+ count++;
+ }
+ }
+
+ if (count == 0 || count % 4)
+ return -1;
+
+ pos = dst;
+ count = 0;
+ for (i = 0; i < srcLen; i++) {
+ tmp = inv_table[src[i]];
+ if (tmp == 0x80) {
+ continue;
+ }
+ block[count] = tmp;
+
+ if (src[i] == '=') {
+ pad++;
+ }
+
+ count++;
+ if (count == 4) {
+ *pos++ = (block[0] << 2) | ((unsigned char)block[1] >> (unsigned int)4);
+ *pos++ = (block[1] << 4) | ((unsigned char)block[2] >> (unsigned int)2);
+ *pos++ = (block[2] << 6) | block[3];
+ count = 0;
+ if (pad) {
+ if (pad == 1) {
+ pos--;
+ }
+ else if (pad == 2) {
+ pos -= 2;
+ }
+ else {
+ return -1;
+ }
+ break;
+ }
+ }
+ }
+
+ dstLen = pos - dst;
+ return 0;
+}
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
+
+ /*
* This source code is part of the near-RT RIC (RAN Intelligent Controller)
* platform project (RICP).
*/
-
//
// Created by adi ENZEL on 9/26/19.
//
#define E2_BASE64_H
#include <mdclog/mdclog.h>
+#include <cstring>
+#include <zconf.h>
static const unsigned char base64_table[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+#define INVERSE_TABLE_SIZE 256
+
class base64 {
public:
- static void encode(const unsigned char *src, const int srcLen, char unsigned *dst, int &dstLen);
+ /**
+ *
+ * @param src
+ * @param srcLen
+ * @param dst
+ * @param dstLen
+ * @return 0 = OK -1 fault
+ */
+ static int encode(const unsigned char *src, int srcLen, char unsigned *dst, long &dstLen);
+ /**
+ *
+ * @param src
+ * @param srcLen
+ * @param dst
+ * @param dstLen
+ * @return 0 = OK -1 fault
+ */
+ static int decode(const unsigned char *src, int srcLen, char unsigned *dst, long &dstLen);
+
};
--- /dev/null
+nano=38000
+loglevel=info
+volume=log
+local-ip=127.0.0.1
+#trace is start, stop
+trace=start
+external-fqdn=e2t.att.com
\ No newline at end of file
# The Jenkins job requires a tag to build the Docker image.
# Global-JJB script assumes this file is in the repo root.
----
-tag: 2.0.10
+tag: 3.0.4.1
rte|1090|10.0.2.15:38000
rte|1100|10.0.2.15:3801
rte|12010|10.0.2.15:38010
+rte|10091|10.0.2.15:4801
+rte|10092|10.0.2.15:4801
+rte|1101|10.0.2.15:38000
+rte|1102|10.0.2.15:3801
newrt|end
using namespace std::placeholders;
+using namespace boost::filesystem;
+
#ifdef __TRACING__
using namespace opentracing;
#endif
//{
//#endif
+// need to expose without the include of gcov
+extern "C" void __gcov_flush(void);
+
+static void catch_function(int signal) {
+ __gcov_flush();
+ exit(signal);
+}
+
+
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;
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__);
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;
+ if (std::signal(SIGINT, catch_function) == SIG_ERR) {
+ mdclog_write(MDCLOG_ERR, "Errir initializing SIGINT");
+ exit(1);
+ }
+ if (std::signal(SIGABRT, catch_function)== SIG_ERR) {
+ mdclog_write(MDCLOG_ERR, "Errir initializing SIGABRT");
+ exit(1);
+ }
+ if (std::signal(SIGTERM, catch_function)== SIG_ERR) {
+ mdclog_write(MDCLOG_ERR, "Errir initializing SIGTERM");
+ exit(1);
}
- {
- std::random_device device{};
- std::mt19937 generator(device());
- std::uniform_int_distribution<long> distribution(1, (long) 1e12);
- transactionCounter = distribution(generator);
+ cpuClock = approx_CPU_MHz(100);
+
+ mdclog_write(MDCLOG_DEBUG, "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);
+ }
+
+
+ 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);
+ }
+
+ sctpParams.myIP = conf.getStringValue("external-fqdn");
+ if (sctpParams.myIP.length() == 0) {
+ mdclog_write(MDCLOG_ERR, "illigal external-fqdn.");
+ 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");
}
mdclog_mdc_clean();
+ sctpParams.ka_message_length = snprintf(sctpParams.ka_message, 4096, "{\"address\": \"%s:%d\","
+ "\"fqdn\": \"%s\"}",
+ (const char *)sctpParams.myIP.c_str(),
+ sctpParams.rmrPort,
+ sctpParams.fqdn.c_str());
+
// 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);
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
- 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);
+ int count = 0;
+ while (true) {
+ auto xappMessages = num_of_XAPP_messages.load(std::memory_order_acquire);
+ if (xappMessages > 0) {
+ if (mdclog_level_get() >= MDCLOG_INFO) {
+ mdclog_write(MDCLOG_INFO, "Got a message from some appliction, stop sending E@_TERM_INIT");
+ }
+ return;
+ }
+ usleep(100000);
+ count++;
+ if (count % 1000 == 0) {
+ mdclog_write(MDCLOG_ERR, "GOT No messages from any xApp");
+ sendTermInit(sctpParams);
+ }
+ }
+}
+
+void sendTermInit(sctp_params_t &sctpParams) {
+ rmr_mbuf_t *msg = rmr_alloc_msg(sctpParams.rmrCtx, sctpParams.ka_message_length);
auto count = 0;
- while (!term_init) {
+ while (true) {
msg->mtype = E2_TERM_INIT;
msg->state = 0;
- rmr_bytes2payload(msg, (unsigned char *) buff, len);
+ rmr_bytes2payload(msg, (unsigned char *)sctpParams.ka_message, sctpParams.ka_message_length);
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);
- //break;
+ if (mdclog_level_get() >= MDCLOG_INFO) {
+ mdclog_write(MDCLOG_INFO, "E2_TERM_INIT succsesfuly sent ");
+ }
+ return;
} else {
if (count % 100 == 0) {
mdclog_write(MDCLOG_ERR, "Error sending E2_TERM_INIT cause : %d ", msg->state);
count++;
}
- for (auto &t : threads) {
- t.join();
+}
+
+/**
+ *
+ * @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;
}
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);
rmrMessageBuffer.rcvMessage = rmr_alloc_msg(rmrMessageBuffer.rmrCtx, RECEIVE_XAPP_BUFFER_SIZE);
rmrMessageBuffer.sendMessage = rmr_alloc_msg(rmrMessageBuffer.rmrCtx, RECEIVE_XAPP_BUFFER_SIZE);
+ memcpy(rmrMessageBuffer.ka_message, params->ka_message, params->ka_message_length);
+ rmrMessageBuffer.ka_message_len = params->ka_message_length;
+ rmrMessageBuffer.ka_message[rmrMessageBuffer.ka_message_len] = 0;
+
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ mdclog_write(MDCLOG_DEBUG, "keep alive message is : %s", rmrMessageBuffer.ka_message);
+ }
+
ReportingMessages_t message {};
for (int i = 0; i < MAX_RMR_BUFF_ARRY; i++) {
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");
&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
#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
message.message.messageType = rmrMessageBuffer.sendMessage->mtype = RIC_INDICATION;
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));
rmrMessageBuffer.sendMessage->state = 0;
rmrMessageBuffer.sendMessage->sub_id = (int) ie->value.choice.RICrequestID.ricRequestorID;
+ if (mdclog_level_get() >= MDCLOG_DEBUG) {
+ mdclog_write(MDCLOG_DEBUG, "RIC sub id = %d, message type = %d",
+ rmrMessageBuffer.sendMessage->sub_id,
+ rmrMessageBuffer.sendMessage->mtype);
+ }
sendRmrMessage(rmrMessageBuffer, message, &lspan);
messageSent = true;
} else {
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;
}
-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");
int rmrReady = 0;
int count = 0;
while (!rmrReady) {
- if ((rmrReady = rmr_ready(rmrCtx)) == 0) {
+ if ((rmrReady = rmr_ready(pSctpParams.rmrCtx)) == 0) {
sleep(1);
}
count++;
#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;
+ }
}
/**
sctpMap->clear();
break;
}
+ case E2_TERM_KEEP_ALIVE_REQ: {
+ // send message back
+ if (mdclog_level_get() >= MDCLOG_INFO) {
+ mdclog_write(MDCLOG_INFO, "Got Keep Alive Request send : %s", rmrMessageBuffer.ka_message);
+ }
+ rmr_bytes2payload(rmrMessageBuffer.sendMessage,
+ (unsigned char *)rmrMessageBuffer.ka_message,
+ rmrMessageBuffer.ka_message_len);
+ rmrMessageBuffer.sendMessage->mtype = E2_TERM_KEEP_ALIVE_RESP;
+ rmrMessageBuffer.sendMessage->state = 0;
+ static unsigned char tx[32];
+ auto txLen = snprintf((char *) tx, sizeof tx, "%15ld", transactionCounter++);
+ rmr_bytes2xact(rmrMessageBuffer.sendMessage, tx, txLen);
+ rmrMessageBuffer.sendMessage = rmr_send_msg(rmrMessageBuffer.rmrCtx, rmrMessageBuffer.sendMessage);
+ if (rmrMessageBuffer.sendMessage == nullptr) {
+ rmrMessageBuffer.sendMessage = rmr_alloc_msg(rmrMessageBuffer.rmrCtx, RECEIVE_XAPP_BUFFER_SIZE);
+ mdclog_write(MDCLOG_ERR, "Failed to send E2_TERM_KEEP_ALIVE_RESP");
+ } else if (rmrMessageBuffer.sendMessage->state != 0) {
+ mdclog_write(MDCLOG_ERR, "Failed to send E2_TERM_KEEP_ALIVE_RESP");
+ }
+ break;
+ }
default:
mdclog_write(MDCLOG_WARN, "Message Type : %d is not seported", rmrMessageBuffer.rcvMessage->mtype);
message.message.asndata = rmrMessageBuffer.rcvMessage->payload;
}
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);
- }
-
-// char buff[256];
-// // build day time to seconds from epoc
-// strftime(buff, sizeof message.message.time, "%D %T", gmtime(&message.message.time.tv_sec));
-// // 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;
-
+ 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);
+ }
+
+ 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;
+ }
}
* 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.
- */
+*/
/*
* This source code is part of the near-RT RIC (RAN Intelligent Controller)
* platform project (RICP).
*/
-
#ifndef X2_SCTP_THREAD_H
#define X2_SCTP_THREAD_H
#include <shared_mutex>
#include <iterator>
#include <map>
+#include <sys/inotify.h>
+#include <csignal>
#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 "3rdparty/asn1cFiles/E2AP-PDU.h"
-#include <3rdparty/asn1cFiles/ProtocolIE-Container.h>
-#include "3rdparty/asn1cFiles/InitiatingMessage.h"
-#include "3rdparty/asn1cFiles/SuccessfulOutcome.h"
-#include "3rdparty/asn1cFiles/UnsuccessfulOutcome.h"
-#include "3rdparty/asn1cFiles/ProtocolIE-Container.h"
-#include "3rdparty/asn1cFiles/ProtocolIE-Field.h"
+#include "asn1cFiles/E2AP-PDU.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"
#include "base64.h"
+#include "ReadConfigFile.h"
+
using namespace std;
namespace logging = boost::log;
namespace src = boost::log::sources;
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 ka_message[4096] {};
+ int ka_message_length = 0;
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 fqdn {};
+ string configFilePath {};
+ string configFileName {};
+ bool trace = true;
//shared_timed_mutex fence; // moved to mapWrapper
} sctp_params_t;
#define MAX_RMR_BUFF_ARRY 32
typedef struct RmrMessagesBuffer {
- void *rmrCtx;
- rmr_mbuf_t *sendMessage;
- rmr_mbuf_t *sendBufferedMessages[MAX_RMR_BUFF_ARRY];
- rmr_mbuf_t *rcvMessage;
- rmr_mbuf_t *rcvBufferedMessages[MAX_RMR_BUFF_ARRY];
+ char ka_message[4096] {};
+ int ka_message_len = 0;
+ void *rmrCtx = nullptr;
+ rmr_mbuf_t *sendMessage= nullptr;
+ rmr_mbuf_t *sendBufferedMessages[MAX_RMR_BUFF_ARRY] {};
+ rmr_mbuf_t *rcvMessage= nullptr;
+ rmr_mbuf_t *rcvBufferedMessages[MAX_RMR_BUFF_ARRY] {};
} RmrMessagesBuffer_t;
typedef struct formatedMessage {
typedef struct ReportingMessages {
FormatedMessage_t message;
- int outLen;
+ long outLen;
unsigned char base64Data[RECEIVE_SCTP_BUFFER_SIZE * 2];
char buffer[RECEIVE_SCTP_BUFFER_SIZE * 8];
- 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);
* @param pSpan
* @return
*/
-void *getRmrContext(char *rmrAddress, otSpan *pSpan);
+void getRmrContext(sctp_params_t &pSctpParams, otSpan *pSpan);
/**
*
*/
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
--- /dev/null
+nano=38000
+loglevel=info
+volume=log
+local-ip=127.0.0.1
+stam string
+
+xxx=
+#trace is start, stop
+trace=start
+external-fqdn=e2t.att.com
\ No newline at end of file
--- /dev/null
+[config]
+nano=38000
+loglevel=info
+volume=log
+local-ip=127.0.0.1
+[xxxyyy]
+#trace is start, stop
+trace=start
+external-fqdn=e2t.att.com
\ No newline at end of file
--- /dev/null
+[config]
+nano=38000
+loglevel=info
+volume=log
+local-ip=127.0.0.1
+[xxxyyy
+#trace is start, stop
+trace=start
+external-fqdn=e2t.att.com
\ No newline at end of file