From: ss412g Date: Sun, 5 Jan 2020 09:52:19 +0000 (+0200) Subject: Copy latest code to master X-Git-Tag: 5.4.8~100 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=3bac2da3306cb753f967ce41dad1e7719380c916;p=ric-plt%2Fe2.git Copy latest code to master Change-Id: Ia3dc1891e8489b0241a45d54ac13da427337a682 Signed-off-by: ss412g --- diff --git a/.gitignore b/.gitignore index 853d153..ad33e82 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ cmake-build-release/ cmake_install.cmake e2.cbp e2 +T1 setUpTest subscriptionTest CMakeLists.txt @@ -36,6 +37,16 @@ RIC-E2-TERMINATION/tracelibcpp/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 diff --git a/RIC-E2-TERMINATION/CMakeLists.txt b/RIC-E2-TERMINATION/CMakeLists.txt index c9d0be3..b941163 100644 --- a/RIC-E2-TERMINATION/CMakeLists.txt +++ b/RIC-E2-TERMINATION/CMakeLists.txt @@ -19,19 +19,30 @@ 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") @@ -54,16 +65,36 @@ include_directories(RIC-E2-TERMINATION/TEST) 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 @@ -71,7 +102,66 @@ add_executable(e2 RIC-E2-TERMINATION/sctpThread.cpp RIC-E2-TERMINATION/mapWrapper.h RIC-E2-TERMINATION/base64.h RIC-E2-TERMINATION/base64.cpp + RIC-E2-TERMINATION/ReadConfigFile.h ) add_executable(e2smtest RIC-E2-TERMINATION/TEST/e2smTest/e2smtest.cpp) + +add_executable(testConfigFile + RIC-E2-TERMINATION/ReadConfigFile.h + RIC-E2-TERMINATION/TEST/ConfigurationFileTest/testConfigFile.cpp) + +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 diff --git a/RIC-E2-TERMINATION/Dockerfile b/RIC-E2-TERMINATION/Dockerfile index d86523e..5604fcb 100644 --- a/RIC-E2-TERMINATION/Dockerfile +++ b/RIC-E2-TERMINATION/Dockerfile @@ -15,31 +15,47 @@ # 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 \ @@ -52,23 +68,29 @@ RUN apt-get install -y autoconf gawk libtool automake pkg-config autoconf-archiv # && find / -type f -name "libopentracing.a" -exec cp {} libopentracing.a \; && cd /opt/e2/RIC-E2-TERMINATION && ls nlohmann \ FROM ubuntu:16.04 -RUN apt-get update && apt-get install -y net-tools iputils-ping curl tcpdump +RUN apt-get update && apt-get install -y net-tools iputils-ping curl tcpdump && mkdir -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 @@ -97,8 +119,5 @@ COPY --from=ubuntu /usr/lib/x86_64-linux-gnu/libicudata.so.55.1 /usr/lib/x86_64- WORKDIR /opt/e2/ ENV LD_LIBRARY_PATH=/usr/local/lib ENV RMR_SEED_RT=dockerRouter.txt -ENV nano=38000 -ENV loglevel=info -ENV volume="." EXPOSE 38000 -CMD ["sh", "-c", "./e2 nano $nano loglevel $loglevel volume $volume"] +CMD ["sh", "-c", "./e2 -p config -f config.conf"] diff --git a/RIC-E2-TERMINATION/ReadConfigFile.h b/RIC-E2-TERMINATION/ReadConfigFile.h new file mode 100644 index 0000000..469d5ef --- /dev/null +++ b/RIC-E2-TERMINATION/ReadConfigFile.h @@ -0,0 +1,155 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include +#include + +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 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 str, const std::string& chars = "\t\n\v\f\r ") { + return ltrim(rtrim(str, chars), chars); + } +}; + + +#endif //E2_READCONFIGFILE_H diff --git a/RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.cpp b/RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.cpp new file mode 100644 index 0000000..89bc48a --- /dev/null +++ b/RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.cpp @@ -0,0 +1,44 @@ +/* + * 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 ""; +} diff --git a/RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.h b/RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.h new file mode 100644 index 0000000..d264fef --- /dev/null +++ b/RIC-E2-TERMINATION/TEST/ASN_LOG/LogTest.h @@ -0,0 +1,81 @@ +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 diff --git a/RIC-E2-TERMINATION/TEST/ConfigurationFileTest/testConfigFile.cpp b/RIC-E2-TERMINATION/TEST/ConfigurationFileTest/testConfigFile.cpp new file mode 100644 index 0000000..33deb2b --- /dev/null +++ b/RIC-E2-TERMINATION/TEST/ConfigurationFileTest/testConfigFile.cpp @@ -0,0 +1,112 @@ +/* + * 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 +#include + +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 diff --git a/RIC-E2-TERMINATION/TEST/T1/E2Builder.h b/RIC-E2-TERMINATION/TEST/T1/E2Builder.h new file mode 100644 index 0000000..78b853c --- /dev/null +++ b/RIC-E2-TERMINATION/TEST/T1/E2Builder.h @@ -0,0 +1,750 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + + +#include + + +#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 &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 +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 +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 +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 diff --git a/RIC-E2-TERMINATION/TEST/T1/E2Setup.cpp b/RIC-E2-TERMINATION/TEST/T1/E2Setup.cpp new file mode 100644 index 0000000..efc3bd3 --- /dev/null +++ b/RIC-E2-TERMINATION/TEST/T1/E2Setup.cpp @@ -0,0 +1,112 @@ +/* + * 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 +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 &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 diff --git a/RIC-E2-TERMINATION/TEST/T1/Test1.cpp b/RIC-E2-TERMINATION/TEST/T1/Test1.cpp index 2ba5fed..fa20111 100644 --- a/RIC-E2-TERMINATION/TEST/T1/Test1.cpp +++ b/RIC-E2-TERMINATION/TEST/T1/Test1.cpp @@ -27,25 +27,17 @@ #include -#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 #include #include #include +#include #include #include @@ -156,7 +148,7 @@ int main(const int argc, char **argv) { 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(); diff --git a/RIC-E2-TERMINATION/TEST/base64/testBase64.cpp b/RIC-E2-TERMINATION/TEST/base64/testBase64.cpp new file mode 100644 index 0000000..e30dca9 --- /dev/null +++ b/RIC-E2-TERMINATION/TEST/base64/testBase64.cpp @@ -0,0 +1,102 @@ +/* + * 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 +#include +#include +#include +#include +#include + +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 diff --git a/RIC-E2-TERMINATION/TEST/e2sm.c b/RIC-E2-TERMINATION/TEST/e2sm.c index 9915948..12d6097 100644 --- a/RIC-E2-TERMINATION/TEST/e2sm.c +++ b/RIC-E2-TERMINATION/TEST/e2sm.c @@ -14,13 +14,12 @@ * 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. // @@ -56,7 +55,7 @@ static size_t encodebuff(int codingType, clock_gettime(CLOCK_MONOTONIC, &end); if (er.encoded == -1) { mdclog_write(MDCLOG_ERR, "encoding of %s failed, %s", asn_DEF_E2SM_gNB_X2_eventTriggerDefinition.name, strerror(errno)); - } else if (er.encoded > buffer_size) { + } else if (er.encoded > (ssize_t)buffer_size) { mdclog_write(MDCLOG_ERR, "Buffer of size %d is to small for %s", (int) buffer_size, typeDescriptor->name); } else if (mdclog_level_get() >= MDCLOG_DEBUG) { @@ -82,7 +81,7 @@ static size_t encodebuff(int codingType, } PLMN_Identity_t *createPLMN_ID(const unsigned char *data) { - printEntry("PLMN_Identity_t", __func__); + printEntry("PLMN_Identity_t", __func__) PLMN_Identity_t *plmnId = calloc(1, sizeof(PLMN_Identity_t)); ASN_STRUCT_RESET(asn_DEF_PLMN_Identity, plmnId); plmnId->size = 3; @@ -97,9 +96,12 @@ PLMN_Identity_t *createPLMN_ID(const unsigned char *data) { } ENB_ID_t *createENB_ID(ENB_ID_PR enbType, unsigned char *data) { - printEntry("ENB_ID_t", __func__); + printEntry("ENB_ID_t", __func__) ENB_ID_t *enb = calloc(1, sizeof(ENB_ID_t)); ASN_STRUCT_RESET(asn_DEF_ENB_ID, enb); + + enb->present = enbType; + switch (enbType) { case ENB_ID_PR_macro_eNB_ID: { // 20 bit 3 bytes enb->choice.macro_eNB_ID.size = 3; @@ -160,7 +162,7 @@ ENB_ID_t *createENB_ID(ENB_ID_PR enbType, unsigned char *data) { } GNB_ID_t *createGnb_id(const unsigned char *data, int numOfBits) { - printEntry("GNB_ID_t", __func__); + printEntry("GNB_ID_t", __func__) if (numOfBits < 22 || numOfBits > 32) { mdclog_write(MDCLOG_ERR, "GNB_ID_t number of bits = %d, needs to be 22 .. 32", numOfBits); return NULL; @@ -170,7 +172,7 @@ GNB_ID_t *createGnb_id(const unsigned char *data, int numOfBits) { gnb->present = GNB_ID_PR_gNB_ID; gnb->choice.gNB_ID.size = numOfBits % 8 == 0 ? (unsigned int)(numOfBits / 8) : (unsigned int)(numOfBits / 8 + 1); - gnb->choice.gNB_ID.bits_unused = gnb->choice.gNB_ID.size * 8 - numOfBits; + gnb->choice.gNB_ID.bits_unused = (int)gnb->choice.gNB_ID.size * 8 - numOfBits; gnb->choice.gNB_ID.buf = calloc(1, gnb->choice.gNB_ID.size); memcpy(gnb->choice.gNB_ID.buf, data, gnb->choice.gNB_ID.size); gnb->choice.gNB_ID.buf[gnb->choice.gNB_ID.size - 1] = @@ -186,7 +188,7 @@ GNB_ID_t *createGnb_id(const unsigned char *data, int numOfBits) { } GlobalENB_ID_t *createGlobalENB_ID(PLMN_Identity_t *plmnIdentity, ENB_ID_t *enbId) { - printEntry("GlobalENB_ID_t", __func__); + printEntry("GlobalENB_ID_t", __func__) GlobalENB_ID_t *genbId = calloc(1, sizeof(GlobalENB_ID_t)); ASN_STRUCT_RESET(asn_DEF_GlobalENB_ID, genbId); memcpy(&genbId->pLMN_Identity, plmnIdentity, sizeof(PLMN_Identity_t)); @@ -199,7 +201,7 @@ GlobalENB_ID_t *createGlobalENB_ID(PLMN_Identity_t *plmnIdentity, ENB_ID_t *enbI } GlobalGNB_ID_t *createGlobalGNB_ID(PLMN_Identity_t *plmnIdentity, GNB_ID_t *gnb) { - printEntry("GlobalGNB_ID_t", __func__); + printEntry("GlobalGNB_ID_t", __func__) GlobalGNB_ID_t *ggnbId = calloc(1, sizeof(GlobalGNB_ID_t)); ASN_STRUCT_RESET(asn_DEF_GlobalGNB_ID, ggnbId); @@ -215,7 +217,7 @@ GlobalGNB_ID_t *createGlobalGNB_ID(PLMN_Identity_t *plmnIdentity, GNB_ID_t *gnb) Interface_ID_t *createInterfaceIDForGnb(GlobalGNB_ID_t *gnb) { - printEntry("Interface_ID_t", __func__); + printEntry("Interface_ID_t", __func__) Interface_ID_t *interfaceId = calloc(1, sizeof(Interface_ID_t)); ASN_STRUCT_RESET(asn_DEF_Interface_ID, interfaceId); @@ -231,7 +233,7 @@ Interface_ID_t *createInterfaceIDForGnb(GlobalGNB_ID_t *gnb) { } Interface_ID_t *createInterfaceIDForEnb(GlobalENB_ID_t *enb) { - printEntry("Interface_ID_t", __func__); + printEntry("Interface_ID_t", __func__) Interface_ID_t *interfaceId = calloc(1, sizeof(Interface_ID_t)); ASN_STRUCT_RESET(asn_DEF_Interface_ID, interfaceId); @@ -249,7 +251,7 @@ Interface_ID_t *createInterfaceIDForEnb(GlobalENB_ID_t *enb) { InterfaceMessageType_t *createInterfaceMessageInitiating(long procedureCode) { - printEntry("InterfaceMessageType_t", __func__); + printEntry("InterfaceMessageType_t", __func__) InterfaceMessageType_t *intMsgT = calloc(1, sizeof(InterfaceMessageType_t)); ASN_STRUCT_RESET(asn_DEF_InterfaceMessageType, intMsgT); @@ -264,7 +266,7 @@ InterfaceMessageType_t *createInterfaceMessageInitiating(long procedureCode) { } InterfaceMessageType_t *createInterfaceMessageSuccsesful(long procedureCode) { - printEntry("InterfaceMessageType_t", __func__); + printEntry("InterfaceMessageType_t", __func__) InterfaceMessageType_t *intMsgT = calloc(1, sizeof(InterfaceMessageType_t)); ASN_STRUCT_RESET(asn_DEF_InterfaceMessageType, intMsgT); @@ -279,7 +281,7 @@ InterfaceMessageType_t *createInterfaceMessageSuccsesful(long procedureCode) { } InterfaceMessageType_t *createInterfaceMessageUnsuccessful(long procedureCode) { - printEntry("InterfaceMessageType_t", __func__); + printEntry("InterfaceMessageType_t", __func__) InterfaceMessageType_t *intMsgT = calloc(1, sizeof(InterfaceMessageType_t)); ASN_STRUCT_RESET(asn_DEF_InterfaceMessageType, intMsgT); @@ -294,7 +296,7 @@ InterfaceMessageType_t *createInterfaceMessageUnsuccessful(long procedureCode) { } InterfaceProtocolIE_Value_t *createInterfaceProtocolValueInt(long number) { - printEntry("InterfaceProtocolIE_Value_t", __func__); + printEntry("InterfaceProtocolIE_Value_t", __func__) InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t)); ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value); @@ -309,7 +311,7 @@ InterfaceProtocolIE_Value_t *createInterfaceProtocolValueInt(long number) { } InterfaceProtocolIE_Value_t *createInterfaceProtocolValueEnum(long number) { - printEntry("InterfaceProtocolIE_Value_t", __func__); + printEntry("InterfaceProtocolIE_Value_t", __func__) InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t)); ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value); @@ -324,7 +326,7 @@ InterfaceProtocolIE_Value_t *createInterfaceProtocolValueEnum(long number) { } InterfaceProtocolIE_Value_t *createInterfaceProtocolValueBool(int val) { - printEntry("InterfaceProtocolIE_Value_t", __func__); + printEntry("InterfaceProtocolIE_Value_t", __func__) InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t)); ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value); @@ -340,7 +342,7 @@ InterfaceProtocolIE_Value_t *createInterfaceProtocolValueBool(int val) { InterfaceProtocolIE_Value_t *createInterfaceProtocolValueBitString(unsigned char *buf, int numOfBits) { - printEntry("InterfaceProtocolIE_Value_t", __func__); + printEntry("InterfaceProtocolIE_Value_t", __func__) size_t size = numOfBits % 8 == 0 ? (unsigned int)(numOfBits / 8) : (unsigned int)(numOfBits / 8 + 1); if (strlen((const char *)buf) < size) { mdclog_write(MDCLOG_ERR, "size of buffer is small : %d needs to be %d in %s", (int)strlen((const char *)buf), (int)size, __func__); @@ -351,7 +353,7 @@ InterfaceProtocolIE_Value_t *createInterfaceProtocolValueBitString(unsigned char value->present = InterfaceProtocolIE_Value_PR_valueBitS; value->choice.valueBitS.size = numOfBits % 8 == 0 ? (unsigned int)(numOfBits / 8) : (unsigned int)(numOfBits / 8 + 1); value->choice.valueBitS.buf = calloc(1, value->choice.valueBitS.size); - int bits_unused = value->choice.valueBitS.size * 8 - numOfBits; + int bits_unused = (int)value->choice.valueBitS.size * 8 - numOfBits; value->choice.valueBitS.bits_unused = bits_unused; memcpy(value->choice.valueBitS.buf, buf, value->choice.valueBitS.size); @@ -366,7 +368,7 @@ InterfaceProtocolIE_Value_t *createInterfaceProtocolValueBitString(unsigned char InterfaceProtocolIE_Value_t *createInterfaceProtocolValueOCTETS(uint8_t *buf) { - printEntry("InterfaceProtocolIE_Value_t", __func__); + printEntry("InterfaceProtocolIE_Value_t", __func__) size_t size = strlen((const char *)buf); InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t)); ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value); @@ -385,7 +387,7 @@ InterfaceProtocolIE_Value_t *createInterfaceProtocolValueOCTETS(uint8_t *buf) { InterfaceProtocolIE_Item_t *createInterfaceProtocolIE_Item(long id, long test, InterfaceProtocolIE_Value_t *value) { - printEntry("InterfaceProtocolIE_Item_t", __func__); + printEntry("InterfaceProtocolIE_Item_t", __func__) if (test < InterfaceProtocolIE_Test_equal || test > InterfaceProtocolIE_Test_present) { mdclog_write(MDCLOG_ERR, "InterfaceProtocolIE_Item_t test value is %ld, out of scope %d .. %d ", test, InterfaceProtocolIE_Test_equal, InterfaceProtocolIE_Test_present); @@ -412,7 +414,7 @@ InterfaceProtocolIE_Item_t *createInterfaceProtocolIE_Item(long id, long test, I ActionParameter_Value_t *createActionParameterValue_Int(long number) { - printEntry("ActionParameter_Value_t", __func__); + printEntry("ActionParameter_Value_t", __func__) ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t)); ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value); @@ -427,7 +429,7 @@ ActionParameter_Value_t *createActionParameterValue_Int(long number) { } ActionParameter_Value_t *createActionParameterValue_Enum(long number) { - printEntry("ActionParameter_Value_t", __func__); + printEntry("ActionParameter_Value_t", __func__) ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t)); ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value); @@ -442,7 +444,7 @@ ActionParameter_Value_t *createActionParameterValue_Enum(long number) { } ActionParameter_Value_t *createActionParameterValue_Bool(int val) { - printEntry("ActionParameter_Value_t", __func__); + printEntry("ActionParameter_Value_t", __func__) ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t)); ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value); @@ -458,12 +460,12 @@ ActionParameter_Value_t *createActionParameterValue_Bool(int val) { ActionParameter_Value_t *createActionParameterValue_Bit_String(unsigned char *buf, int numOfBits) { - printEntry("ActionParameter_Value_t", __func__); + printEntry("ActionParameter_Value_t", __func__) size_t size = numOfBits % 8 == 0 ? (unsigned int)(numOfBits / 8) : (unsigned int)(numOfBits / 8 + 1); if (strlen((const char *)buf) < size) { mdclog_write(MDCLOG_ERR, "size of buffer is small : %d needs to be %d in %s", (int)strlen((const char *)buf), (int)size, __func__); } - int bits_unused = size * 8 - numOfBits; + int bits_unused = (int)size * 8 - numOfBits; ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t)); ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value); @@ -485,7 +487,7 @@ ActionParameter_Value_t *createActionParameterValue_Bit_String(unsigned char *bu ActionParameter_Value_t *createActionParameterValue_OCTETS(uint8_t *buf) { - printEntry("ActionParameter_Value_t", __func__); + printEntry("ActionParameter_Value_t", __func__) size_t size = strlen((const char *)buf); ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t)); ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value); @@ -508,7 +510,7 @@ ActionParameter_Value_t *createActionParameterValue_OCTETS(uint8_t *buf) { * @return ActionParameter_Value_t * */ ActionParameter_Value_t *createActionParameterValue_PRINTS(char *buf) { - printEntry("ActionParameter_Value_t", __func__); + printEntry("ActionParameter_Value_t", __func__) size_t size = strlen((const char *)buf); ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t)); ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value); @@ -526,7 +528,7 @@ ActionParameter_Value_t *createActionParameterValue_PRINTS(char *buf) { } ActionParameter_Item_t *creatActionParameter_Item(long id, ActionParameter_Value_t *val) { - printEntry("ActionParameter_Item_t", __func__); + printEntry("ActionParameter_Item_t", __func__) if (id < 0 || id > 255) { mdclog_write(MDCLOG_ERR, "ActionParameter_Item_t id = %ld, values are 0 .. 255", id); return NULL; @@ -561,7 +563,7 @@ size_t createEventTrigger(Interface_ID_t *interfaceId, long direction, int listSize, uint8_t *buffer, size_t buffer_size) { - printEntry("E2SM_gNB_X2_eventTriggerDefinition_t", __func__); + printEntry("E2SM_gNB_X2_eventTriggerDefinition_t", __func__) if (direction < InterfaceDirection_incoming || direction > InterfaceDirection_outgoing) { mdclog_write(MDCLOG_ERR, "E2SM_gNB_X2_eventTriggerDefinition_t direction = %ld, values are %d .. %d", direction, InterfaceDirection_incoming, InterfaceDirection_outgoing); @@ -592,7 +594,7 @@ size_t createEventTrigger(Interface_ID_t *interfaceId, long direction, if (mdclog_level_get() >= MDCLOG_INFO) { uint8_t buf1[4096]; - asn_enc_rval_t er1; + //asn_enc_rval_t er1; encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_eventTriggerDefinition, eventTrigger, buf1, @@ -607,7 +609,7 @@ size_t createEventTrigger(Interface_ID_t *interfaceId, long direction, size_t createActionDefinition(long styleId, ActionParameter_Item_t actionParamList[], int listSize, uint8_t *buffer, size_t buffer_size) { - printEntry("E2SM_gNB_X2_actionDefinition_t", __func__); + printEntry("E2SM_gNB_X2_actionDefinition_t", __func__) E2SM_gNB_X2_actionDefinition_t *actDef = calloc(1, sizeof(E2SM_gNB_X2_actionDefinition_t)); ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_actionDefinition, actDef); @@ -628,7 +630,7 @@ size_t createActionDefinition(long styleId, ActionParameter_Item_t actionParamLi if (mdclog_level_get() >= MDCLOG_INFO) { uint8_t buf1[4096]; - asn_enc_rval_t er1; + //asn_enc_rval_t er1; encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_actionDefinition, actDef, buf1, @@ -645,7 +647,7 @@ size_t createE2SM_gNB_X2_indicationHeader(long direction, int size, uint8_t *buffer, size_t buffer_size) { - printEntry("E2SM_gNB_X2_indicationHeader_t", __func__); + printEntry("E2SM_gNB_X2_indicationHeader_t", __func__) if (direction < InterfaceDirection_incoming || direction > InterfaceDirection_outgoing) { mdclog_write(MDCLOG_ERR, "E2SM_gNB_X2_indicationHeader_t direction = %ld, values are %d .. %d", direction, InterfaceDirection_incoming, InterfaceDirection_outgoing); @@ -674,7 +676,7 @@ size_t createE2SM_gNB_X2_indicationHeader(long direction, if (mdclog_level_get() >= MDCLOG_INFO) { uint8_t buf1[4096]; - asn_enc_rval_t er1; + //asn_enc_rval_t er1; encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_indicationHeader, indiHead, buf1, @@ -688,7 +690,7 @@ size_t createE2SM_gNB_X2_indicationHeader(long direction, size_t createE2SM_gNB_X2_indicationMessage(uint8_t *message, uint msgSize, uint8_t *buffer, size_t buffer_size) { - printEntry("E2SM_gNB_X2_indicationMessage_t", __func__); + printEntry("E2SM_gNB_X2_indicationMessage_t", __func__) if (msgSize <= 0) { mdclog_write(MDCLOG_ERR, "E2SM_gNB_X2_indicationMessage_t failed messsage size = %d", msgSize); return -1; @@ -713,7 +715,7 @@ size_t createE2SM_gNB_X2_indicationMessage(uint8_t *message, uint msgSize, if (mdclog_level_get() >= MDCLOG_INFO) { uint8_t buf1[4096]; - asn_enc_rval_t er1; + //asn_enc_rval_t er1; encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_indicationMessage, indicationMessage, buf1, @@ -728,7 +730,7 @@ size_t createE2SM_gNB_X2_indicationMessage(uint8_t *message, uint msgSize, size_t createE2SM_gNB_X2_callProcessID(long callProcess_Id, uint8_t *buffer, size_t buffer_size) { - printEntry("E2SM_gNB_X2_callProcessID_t", __func__); + printEntry("E2SM_gNB_X2_callProcessID_t", __func__) E2SM_gNB_X2_callProcessID_t *callProcessId = calloc(1, sizeof(E2SM_gNB_X2_callProcessID_t)); ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_callProcessID, callProcessId); @@ -746,7 +748,7 @@ size_t createE2SM_gNB_X2_callProcessID(long callProcess_Id, if (mdclog_level_get() >= MDCLOG_INFO) { uint8_t buf1[4096]; - asn_enc_rval_t er1; + //asn_enc_rval_t er1; encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_callProcessID, callProcessId, buf1, @@ -760,7 +762,7 @@ size_t createE2SM_gNB_X2_callProcessID(long callProcess_Id, size_t createE2SM_gNB_X2_controlHeader(Interface_ID_t *interfaceId, long direction, uint8_t *buffer, size_t buffer_size) { - printEntry("E2SM_gNB_X2_controlHeader_t", __func__); + printEntry("E2SM_gNB_X2_controlHeader_t", __func__) if (direction < InterfaceDirection_incoming || direction > InterfaceDirection_outgoing) { mdclog_write(MDCLOG_ERR, "E2SM_gNB_X2_controlHeader_t direction = %ld, values are %d .. %d", direction, InterfaceDirection_incoming, InterfaceDirection_outgoing); @@ -784,7 +786,7 @@ size_t createE2SM_gNB_X2_controlHeader(Interface_ID_t *interfaceId, long directi if (mdclog_level_get() >= MDCLOG_INFO) { uint8_t buf1[4096]; - asn_enc_rval_t er1; + //asn_enc_rval_t er1; encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_controlHeader, controlHeader, buf1, @@ -799,7 +801,7 @@ size_t createE2SM_gNB_X2_controlHeader(Interface_ID_t *interfaceId, long directi size_t createE2SM_gNB_X2_controlMessage(uint8_t *message, uint msgSize, uint8_t *buffer, size_t buffer_size) { - printEntry("E2SM_gNB_X2_controlMessage_t", __func__); + printEntry("E2SM_gNB_X2_controlMessage_t", __func__) E2SM_gNB_X2_controlMessage_t *controlMsg = calloc(1, sizeof(E2SM_gNB_X2_controlMessage_t)); ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_controlMessage, controlMsg); @@ -819,7 +821,7 @@ size_t createE2SM_gNB_X2_controlMessage(uint8_t *message, uint msgSize, if (mdclog_level_get() >= MDCLOG_INFO) { uint8_t buf1[4096]; - asn_enc_rval_t er1; + //asn_enc_rval_t er1; encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_controlMessage, controlMsg, buf1, @@ -828,4 +830,4 @@ size_t createE2SM_gNB_X2_controlMessage(uint8_t *message, uint msgSize, } return len; -} \ No newline at end of file +} diff --git a/RIC-E2-TERMINATION/TEST/e2sm.h b/RIC-E2-TERMINATION/TEST/e2sm.h index 6cc3729..7cbc24d 100644 --- a/RIC-E2-TERMINATION/TEST/e2sm.h +++ b/RIC-E2-TERMINATION/TEST/e2sm.h @@ -14,13 +14,12 @@ * 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. // @@ -49,26 +48,26 @@ extern "C" #include -#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" /** * @@ -99,7 +98,10 @@ GNB_ID_t *createGnb_id(const unsigned char *data, int numOfBits); GlobalENB_ID_t *createGlobalENB_ID(PLMN_Identity_t *plmnIdentity, ENB_ID_t *enbId); /** * - * @param plmnIdentity + * @param plmnIdent#ifdef __cplusplus +} +#endif +ity * @param gnb * @return */ diff --git a/RIC-E2-TERMINATION/TEST/e2test.cpp b/RIC-E2-TERMINATION/TEST/e2test.cpp new file mode 100644 index 0000000..fad77b8 --- /dev/null +++ b/RIC-E2-TERMINATION/TEST/e2test.cpp @@ -0,0 +1,33 @@ +/* + * 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 diff --git a/RIC-E2-TERMINATION/TEST/e2test.h b/RIC-E2-TERMINATION/TEST/e2test.h new file mode 100644 index 0000000..527bfab --- /dev/null +++ b/RIC-E2-TERMINATION/TEST/e2test.h @@ -0,0 +1,51 @@ +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace Pistache; + +class e2test { + + Rest::Router router; + +}; + + +#endif //E2_E2TEST_H diff --git a/RIC-E2-TERMINATION/base64.cpp b/RIC-E2-TERMINATION/base64.cpp index 9b97d82..fa9e498 100644 --- a/RIC-E2-TERMINATION/base64.cpp +++ b/RIC-E2-TERMINATION/base64.cpp @@ -14,30 +14,39 @@ * 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; @@ -64,6 +73,77 @@ void base64::encode(const unsigned char *src, const int srcLen, char unsigned *d } *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; +} diff --git a/RIC-E2-TERMINATION/base64.h b/RIC-E2-TERMINATION/base64.h index 61fdd63..f2f7b6f 100644 --- a/RIC-E2-TERMINATION/base64.h +++ b/RIC-E2-TERMINATION/base64.h @@ -14,13 +14,12 @@ * 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. // @@ -29,13 +28,35 @@ #define E2_BASE64_H #include +#include +#include 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); + }; diff --git a/RIC-E2-TERMINATION/config/config.conf b/RIC-E2-TERMINATION/config/config.conf new file mode 100644 index 0000000..ab7be5e --- /dev/null +++ b/RIC-E2-TERMINATION/config/config.conf @@ -0,0 +1,7 @@ +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 diff --git a/RIC-E2-TERMINATION/container-tag.yaml b/RIC-E2-TERMINATION/container-tag.yaml index feb9ae0..e69aab4 100644 --- a/RIC-E2-TERMINATION/container-tag.yaml +++ b/RIC-E2-TERMINATION/container-tag.yaml @@ -1,4 +1,3 @@ # The Jenkins job requires a tag to build the Docker image. # Global-JJB script assumes this file is in the repo root. ---- -tag: 2.0.10 +tag: 3.0.4.1 diff --git a/RIC-E2-TERMINATION/dockerRouter.txt b/RIC-E2-TERMINATION/dockerRouter.txt index 30b8864..5588419 100644 --- a/RIC-E2-TERMINATION/dockerRouter.txt +++ b/RIC-E2-TERMINATION/dockerRouter.txt @@ -18,4 +18,8 @@ rte|1080|10.0.2.15:3801 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 diff --git a/RIC-E2-TERMINATION/sctpThread.cpp b/RIC-E2-TERMINATION/sctpThread.cpp index f4cd98f..31a7e23 100644 --- a/RIC-E2-TERMINATION/sctpThread.cpp +++ b/RIC-E2-TERMINATION/sctpThread.cpp @@ -23,6 +23,8 @@ using namespace std::placeholders; +using namespace boost::filesystem; + #ifdef __TRACING__ using namespace opentracing; #endif @@ -31,9 +33,20 @@ using namespace opentracing; //{ //#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> boostLogger; +double cpuClock = 0.0; +bool jsonTrace = true; void init_log() { mdclog_attr_t *attr; @@ -42,15 +55,35 @@ void init_log() { mdclog_init(attr); mdclog_attr_destroy(attr); } +auto start_time = std::chrono::high_resolution_clock::now(); +typedef std::chrono::duration> 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 rmrCounter{0}; std::atomic num_of_messages{0}; +std::atomic 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__); @@ -58,130 +91,204 @@ int main(const int argc, char **argv) { otSpan span = 0; #endif + { + std::random_device device{}; + std::mt19937 generator(device()); + std::uniform_int_distribution 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 logLevel volume "); - 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 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 threads(num_cpus); // std::vector 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); @@ -190,32 +297,63 @@ int main(const int argc, char **argv) { if (rc != 0) { mdclog_write(MDCLOG_ERR, "Error calling pthread_setaffinity_np: %d", rc); } + } -// threads.emplace_back(std::thread(listener, &pSctpParams)); + //loop over term_init until first message from xApp + handleTermInit(sctpParams); + + for (auto &t : threads) { + t.join(); } +#ifdef __TRACING__ + opentracing::Tracer::Global()->Close(); +#endif + return 0; +} + +void handleTermInit(sctp_params_t &sctpParams) { + sendTermInit(sctpParams); //send to e2 manager init of e2 term //E2_TERM_INIT - 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); @@ -225,13 +363,67 @@ int main(const int argc, char **argv) { 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(sctpParams.configFilePath)->default_value("config")) + ("f,file", "config file name", cxxopts::value(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; } @@ -247,7 +439,6 @@ void listener(sctp_params_t *params) { otSpan span = 0; #endif int num_of_SCTP_messages = 0; - int num_of_XAPP_messages = 0; auto totalTime = 0.0; mdclog_mdc_clean(); mdclog_level_set(params->logLevel); @@ -282,6 +473,14 @@ void listener(sctp_params_t *params) { 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++) { @@ -311,94 +510,15 @@ void listener(sctp_params_t *params) { clock_gettime(CLOCK_MONOTONIC, &message.message.time); start.tv_sec = message.message.time.tv_sec; start.tv_nsec = message.message.time.tv_nsec; - if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP)) { - if (events[i].data.fd != params->rmrListenFd) { - auto *peerInfo = (ConnectedCU_t *)events[i].data.ptr; - mdclog_write(MDCLOG_ERR, "epoll error, events %0x on fd %d, RAN NAME : %s", - events[i].events, peerInfo->fileDescriptor, peerInfo->enodbName); - - rmrMessageBuffer.sendMessage->len = snprintf((char *)rmrMessageBuffer.sendMessage->payload, 256, - "%s|Failed SCTP Connection", - peerInfo->enodbName); - message.message.asndata = rmrMessageBuffer.sendMessage->payload; - message.message.asnLength = rmrMessageBuffer.sendMessage->len; - memcpy(message.message.enodbName, peerInfo->enodbName, sizeof(peerInfo->enodbName)); - message.message.direction = 'N'; - if (sendRequestToXapp(message, RIC_SCTP_CONNECTION_FAILURE, rmrMessageBuffer, &span) != 0) { - mdclog_write(MDCLOG_ERR, "SCTP_CONNECTION_FAIL message failed to send to xAPP"); - } - close(peerInfo->fileDescriptor); - cleanHashEntry((ConnectedCU_t *) events[i].data.ptr, params->sctpMap, &span); - } else { - mdclog_write(MDCLOG_ERR, "epoll error, events %0x on RMR FD", events[i].events); - } + if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP)) { + handlepoll_error(events[i], message, rmrMessageBuffer, params, &span); } else if (events[i].events & EPOLLOUT) { - // this need to send waiting message from connection EINPROGRESS - auto *peerInfo = (ConnectedCU_t *) events[i].data.ptr; - - memcpy(message.message.enodbName, peerInfo->enodbName, sizeof(peerInfo->enodbName)); - - mdclog_write(MDCLOG_INFO, "file descriptor %d got EPOLLOUT", peerInfo->fileDescriptor); - auto retVal = 0; - socklen_t retValLen = 0; - auto rc = getsockopt(peerInfo->fileDescriptor, SOL_SOCKET, SO_ERROR, &retVal, &retValLen); - if (rc != 0 || retVal != 0) { - if (rc != 0) { - rmrMessageBuffer.sendMessage->len = snprintf((char *)rmrMessageBuffer.sendMessage->payload, 256, - "%s|Failed SCTP Connection, after EINPROGRESS the getsockopt%s", - peerInfo->enodbName, strerror(errno)); - } else if (retVal != 0) { - rmrMessageBuffer.sendMessage->len = snprintf((char *)rmrMessageBuffer.sendMessage->payload, 256, - "%s|Failed SCTP Connection after EINPROGRESS, SO_ERROR", - peerInfo->enodbName); - } - - message.message.asndata = rmrMessageBuffer.sendMessage->payload; - message.message.asnLength = rmrMessageBuffer.sendMessage->len; - mdclog_write(MDCLOG_ERR, "%s", rmrMessageBuffer.sendMessage->payload); - message.message.direction = 'N'; - if (sendRequestToXapp(message, RIC_SCTP_CONNECTION_FAILURE, rmrMessageBuffer, &span) != 0) { - mdclog_write(MDCLOG_ERR, "SCTP_CONNECTION_FAIL message failed to send to xAPP"); - } - memset(peerInfo->asnData, 0, peerInfo->asnLength); - peerInfo->asnLength = 0; - peerInfo->mtype = 0; - continue; - } - - peerInfo->isConnected = true; - - if (modifyToEpoll(params->epoll_fd, peerInfo, (EPOLLIN | EPOLLET), params->sctpMap, peerInfo->enodbName, - peerInfo->mtype, &span) != 0) { - mdclog_write(MDCLOG_ERR, "epoll_ctl EPOLL_CTL_MOD"); - continue; - } - - message.message.asndata = (unsigned char *)peerInfo->asnData; - message.message.asnLength = peerInfo->asnLength; - message.message.messageType = peerInfo->mtype; - memcpy(message.message.enodbName, peerInfo->enodbName, sizeof(peerInfo->enodbName)); - num_of_messages.fetch_add(1, std::memory_order_release); - if (mdclog_level_get() >= MDCLOG_DEBUG) { - mdclog_write(MDCLOG_DEBUG, "send the delayed SETUP/ENDC SETUP to sctp for %s", - message.message.enodbName); - } - if (sendSctpMsg(peerInfo, message, params->sctpMap, &span) != 0) { - if (mdclog_level_get() >= MDCLOG_DEBUG) { - mdclog_write(MDCLOG_DEBUG, "Error write to SCTP %s %d", __func__, __LINE__); - } - continue; - } - - memset(peerInfo->asnData, 0, peerInfo->asnLength); - peerInfo->asnLength = 0; - peerInfo->mtype = 0; - + handleEinprogressMessages(events[i], message, rmrMessageBuffer, params, &span); } else if (params->rmrListenFd == events[i].data.fd) { // got message from XAPP - num_of_XAPP_messages++; + num_of_XAPP_messages.fetch_add(1, std::memory_order_release); num_of_messages.fetch_add(1, std::memory_order_release); if (mdclog_level_get() >= MDCLOG_DEBUG) { mdclog_write(MDCLOG_DEBUG, "new message from RMR"); @@ -410,6 +530,9 @@ void listener(sctp_params_t *params) { &span) != 0) { mdclog_write(MDCLOG_ERR, "Error handling Xapp message"); } + } else if (params->inotifyFD == events[i].data.fd) { + mdclog_write(MDCLOG_INFO, "Got event from inotify (configuration update)"); + handleConfigChange(params); } else { /* We RMR_ERR_RETRY have data on the fd waiting to be read. Read and display it. * We must read whatever data is available completely, as we are running @@ -445,6 +568,247 @@ void listener(sctp_params_t *params) { #endif } +/** + * + * @param sctpParams + */ +void handleConfigChange(sctp_params_t *sctpParams) { + char buf[4096] __attribute__ ((aligned(__alignof__(struct inotify_event)))); + const struct inotify_event *event; + char *ptr; + + path p = (sctpParams->configFilePath + "/" + sctpParams->configFileName).c_str(); + auto endlessLoop = true; + while (endlessLoop) { + auto len = read(sctpParams->inotifyFD, buf, sizeof buf); + if (len == -1) { + if (errno != EAGAIN) { + mdclog_write(MDCLOG_ERR, "read %s ", strerror(errno)); + endlessLoop = false; + continue; + } + else { + endlessLoop = false; + continue; + } + } + + for (ptr = buf; ptr < buf + len; ptr += sizeof(struct inotify_event) + event->len) { + event = (const struct inotify_event *)ptr; + if (event->mask & (uint32_t)IN_ISDIR) { + continue; + } + + // the directory name + if (sctpParams->inotifyWD == event->wd) { + // not the directory + } + if (event->len) { + if (!(sctpParams->configFileName.compare(event->name))) { + continue; + } + } + // only the file we want + if (event->mask & (uint32_t)IN_CLOSE_WRITE) { + if (exists(p)) { + const int size = 2048; + auto fileSize = file_size(p); + if (fileSize > size) { + mdclog_write(MDCLOG_ERR, "File %s larger than %d", p.string().c_str(), size); + return; + } + } else { + mdclog_write(MDCLOG_ERR, "Configuration File %s not exists", p.string().c_str()); + return; + } + + ReadConfigFile conf; + if (conf.openConfigFile(p.string()) == -1) { + mdclog_write(MDCLOG_ERR, "Filed to open config file %s, %s", + p.string().c_str(), strerror(errno)); + return; + } + + auto tmpStr = conf.getStringValue("loglevel"); + if (tmpStr.length() == 0) { + mdclog_write(MDCLOG_ERR, "illigal loglevel. Set loglevel to MDCLOG_INFO"); + tmpStr = "info"; + } + transform(tmpStr.begin(), tmpStr.end(), tmpStr.begin(), ::tolower); + + if ((tmpStr.compare("debug")) == 0) { + mdclog_write(MDCLOG_INFO, "Log level set to MDCLOG_DEBUG"); + sctpParams->logLevel = MDCLOG_DEBUG; + } else if ((tmpStr.compare("info")) == 0) { + mdclog_write(MDCLOG_INFO, "Log level set to MDCLOG_INFO"); + sctpParams->logLevel = MDCLOG_INFO; + } else if ((tmpStr.compare("warning")) == 0) { + mdclog_write(MDCLOG_INFO, "Log level set to MDCLOG_WARN"); + sctpParams->logLevel = MDCLOG_WARN; + } else if ((tmpStr.compare("error")) == 0) { + mdclog_write(MDCLOG_INFO, "Log level set to MDCLOG_ERR"); + sctpParams->logLevel = MDCLOG_ERR; + } else { + mdclog_write(MDCLOG_ERR, "illigal loglevel = %s. Set loglevel to MDCLOG_INFO", tmpStr.c_str()); + sctpParams->logLevel = MDCLOG_INFO; + } + mdclog_level_set(sctpParams->logLevel); + + + tmpStr = conf.getStringValue("trace"); + if (tmpStr.length() == 0) { + mdclog_write(MDCLOG_ERR, "illigal trace. Set trace to stop"); + tmpStr = "stop"; + } + + transform(tmpStr.begin(), tmpStr.end(), tmpStr.begin(), ::tolower); + if ((tmpStr.compare("start")) == 0) { + mdclog_write(MDCLOG_INFO, "Trace set to: start"); + sctpParams->trace = true; + } else if ((tmpStr.compare("stop")) == 0) { + mdclog_write(MDCLOG_INFO, "Trace set to: stop"); + sctpParams->trace = false; + } else { + mdclog_write(MDCLOG_ERR, "Trace was set to wrong value %s, set to stop", tmpStr.c_str()); + sctpParams->trace = false; + } + jsonTrace = sctpParams->trace; + endlessLoop = false; + } + } + } +} + +/** + * + * @param event + * @param message + * @param rmrMessageBuffer + * @param params + * @param pSpan + */ +void handleEinprogressMessages(struct epoll_event &event, + ReportingMessages_t &message, + RmrMessagesBuffer_t &rmrMessageBuffer, + sctp_params_t *params, + otSpan *pSpan) { +#ifdef __TRACING__ + auto lspan = opentracing::Tracer::Global()->StartSpan( + __FUNCTION__, { opentracing::ChildOf(&pSpan->get()->context()) }); +#else + otSpan lspan = 0; +#endif + auto *peerInfo = (ConnectedCU_t *)event.data.ptr; + memcpy(message.message.enodbName, peerInfo->enodbName, sizeof(peerInfo->enodbName)); + + mdclog_write(MDCLOG_INFO, "file descriptor %d got EPOLLOUT", peerInfo->fileDescriptor); + auto retVal = 0; + socklen_t retValLen = 0; + auto rc = getsockopt(peerInfo->fileDescriptor, SOL_SOCKET, SO_ERROR, &retVal, &retValLen); + if (rc != 0 || retVal != 0) { + if (rc != 0) { + rmrMessageBuffer.sendMessage->len = snprintf((char *)rmrMessageBuffer.sendMessage->payload, 256, + "%s|Failed SCTP Connection, after EINPROGRESS the getsockopt%s", + peerInfo->enodbName, strerror(errno)); + } else if (retVal != 0) { + rmrMessageBuffer.sendMessage->len = snprintf((char *)rmrMessageBuffer.sendMessage->payload, 256, + "%s|Failed SCTP Connection after EINPROGRESS, SO_ERROR", + peerInfo->enodbName); + } + + message.message.asndata = rmrMessageBuffer.sendMessage->payload; + message.message.asnLength = rmrMessageBuffer.sendMessage->len; + mdclog_write(MDCLOG_ERR, "%s", rmrMessageBuffer.sendMessage->payload); + message.message.direction = 'N'; + if (sendRequestToXapp(message, RIC_SCTP_CONNECTION_FAILURE, rmrMessageBuffer, &lspan) != 0) { + mdclog_write(MDCLOG_ERR, "SCTP_CONNECTION_FAIL message failed to send to xAPP"); + } + memset(peerInfo->asnData, 0, peerInfo->asnLength); + peerInfo->asnLength = 0; + peerInfo->mtype = 0; +#ifdef __TRACING__ + lspan->Finish(); +#endif + return; + } + + peerInfo->isConnected = true; + + if (modifyToEpoll(params->epoll_fd, peerInfo, (EPOLLIN | EPOLLET), params->sctpMap, peerInfo->enodbName, + peerInfo->mtype, &lspan) != 0) { + mdclog_write(MDCLOG_ERR, "epoll_ctl EPOLL_CTL_MOD"); +#ifdef __TRACING__ + lspan->Finish(); +#endif + return; + } + + message.message.asndata = (unsigned char *)peerInfo->asnData; + message.message.asnLength = peerInfo->asnLength; + message.message.messageType = peerInfo->mtype; + memcpy(message.message.enodbName, peerInfo->enodbName, sizeof(peerInfo->enodbName)); + num_of_messages.fetch_add(1, std::memory_order_release); + if (mdclog_level_get() >= MDCLOG_DEBUG) { + mdclog_write(MDCLOG_DEBUG, "send the delayed SETUP/ENDC SETUP to sctp for %s", + message.message.enodbName); + } + if (sendSctpMsg(peerInfo, message, params->sctpMap, &lspan) != 0) { + if (mdclog_level_get() >= MDCLOG_DEBUG) { + mdclog_write(MDCLOG_DEBUG, "Error write to SCTP %s %d", __func__, __LINE__); + } +#ifdef __TRACING__ + lspan->Finish(); +#endif + return; + } + + memset(peerInfo->asnData, 0, peerInfo->asnLength); + peerInfo->asnLength = 0; + peerInfo->mtype = 0; +#ifdef __TRACING__ + lspan->Finish(); +#endif +} + + +void handlepoll_error(struct epoll_event &event, + ReportingMessages_t &message, + RmrMessagesBuffer_t &rmrMessageBuffer, + sctp_params_t *params, + otSpan *pSpan) { +#ifdef __TRACING__ + auto lspan = opentracing::Tracer::Global()->StartSpan( + __FUNCTION__, { opentracing::ChildOf(&pSpan->get()->context()) }); +#else + otSpan lspan = 0; +#endif + if (event.data.fd != params->rmrListenFd) { + auto *peerInfo = (ConnectedCU_t *)event.data.ptr; + mdclog_write(MDCLOG_ERR, "epoll error, events %0x on fd %d, RAN NAME : %s", + event.events, peerInfo->fileDescriptor, peerInfo->enodbName); + + rmrMessageBuffer.sendMessage->len = snprintf((char *)rmrMessageBuffer.sendMessage->payload, 256, + "%s|Failed SCTP Connection", + peerInfo->enodbName); + message.message.asndata = rmrMessageBuffer.sendMessage->payload; + message.message.asnLength = rmrMessageBuffer.sendMessage->len; + + memcpy(message.message.enodbName, peerInfo->enodbName, sizeof(peerInfo->enodbName)); + message.message.direction = 'N'; + if (sendRequestToXapp(message, RIC_SCTP_CONNECTION_FAILURE, rmrMessageBuffer, &lspan) != 0) { + mdclog_write(MDCLOG_ERR, "SCTP_CONNECTION_FAIL message failed to send to xAPP"); + } + + close(peerInfo->fileDescriptor); + cleanHashEntry((ConnectedCU_t *) event.data.ptr, params->sctpMap, &lspan); + } else { + mdclog_write(MDCLOG_ERR, "epoll error, events %0x on RMR FD", event.events); + } +#ifdef __TRACING__ + lspan->Finish(); +#endif + +} /** * * @param socket @@ -1004,9 +1368,16 @@ void asnInitiatingRequest(E2AP_PDU_t *pdu, 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 { @@ -1181,7 +1552,9 @@ void asnSuccsesfulMsg(E2AP_PDU_t *pdu, ReportingMessages_t &message, Sctp_Map_t static unsigned char tx[32]; snprintf((char *) tx, sizeof tx, "%15ld", transactionCounter++); rmr_bytes2xact(rmrMessageBuffer.sendMessage, tx, strlen((const char *) tx)); - rmr_bytes2meid(rmrMessageBuffer.sendMessage, (unsigned char *)message.message.enodbName, strlen(message.message.enodbName)); + rmr_bytes2meid(rmrMessageBuffer.sendMessage, + (unsigned char *)message.message.enodbName, + strlen(message.message.enodbName)); sendRmrMessage(rmrMessageBuffer, message, &lspan); messageSent = true; @@ -1396,26 +1769,24 @@ int sendRequestToXapp(ReportingMessages_t &message, } -void *getRmrContext(char *rmrAddress, otSpan *pSpan) { +void getRmrContext(sctp_params_t &pSctpParams, otSpan *pSpan) { #ifdef __TRACING__ auto lspan = opentracing::Tracer::Global()->StartSpan( __FUNCTION__, { opentracing::ChildOf(&pSpan->get()->context()) }); #else // otSpan lspan = 0; #endif - void *rmrCtx = rmr_init(rmrAddress, RMR_MAX_RCV_BYTES, RMRFL_NONE); - - - if (rmrCtx == nullptr) { - mdclog_write(MDCLOG_ERR, "RMR failed to initialise : %s", strerror(errno)); + pSctpParams.rmrCtx = nullptr; + pSctpParams.rmrCtx = rmr_init(pSctpParams.rmrAddress, RMR_MAX_RCV_BYTES, RMRFL_NONE); + if (pSctpParams.rmrCtx == nullptr) { + mdclog_write(MDCLOG_ERR, "Failed to initialize RMR"); #ifdef __TRACING__ lspan->Finish(); #endif - - return (nullptr); + return; } - rmr_set_stimeout(rmrCtx, 0); // disable retries for any send operation + rmr_set_stimeout(pSctpParams.rmrCtx, 0); // disable retries for any send operation // we need to find that routing table exist and we can run if (mdclog_level_get() >= MDCLOG_INFO) { mdclog_write(MDCLOG_INFO, "We are after RMR INIT wait for RMR_Ready"); @@ -1423,7 +1794,7 @@ void *getRmrContext(char *rmrAddress, otSpan *pSpan) { int rmrReady = 0; int count = 0; while (!rmrReady) { - if ((rmrReady = rmr_ready(rmrCtx)) == 0) { + if ((rmrReady = rmr_ready(pSctpParams.rmrCtx)) == 0) { sleep(1); } count++; @@ -1437,8 +1808,20 @@ void *getRmrContext(char *rmrAddress, otSpan *pSpan) { #ifdef __TRACING__ lspan->Finish(); #endif - - return rmrCtx; + rmr_init_trace(pSctpParams.rmrCtx, 200); + // get the RMR fd for the epoll + pSctpParams.rmrListenFd = rmr_get_rcvfd(pSctpParams.rmrCtx); + struct epoll_event event{}; + // add RMR fd to epoll + event.events = (EPOLLIN); + event.data.fd = pSctpParams.rmrListenFd; + // add listening RMR FD to epoll + if (epoll_ctl(pSctpParams.epoll_fd, EPOLL_CTL_ADD, pSctpParams.rmrListenFd, &event)) { + mdclog_write(MDCLOG_ERR, "Failed to add RMR descriptor to epoll"); + close(pSctpParams.rmrListenFd); + rmr_close(pSctpParams.rmrCtx); + pSctpParams.rmrCtx = nullptr; + } } /** @@ -1739,6 +2122,28 @@ int receiveXappMessages(int epoll_fd, 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; @@ -2420,41 +2825,36 @@ int sendRmrMessage(RmrMessagesBuffer_t &rmrMessageBuffer, ReportingMessages_t &m } void buildJsonMessage(ReportingMessages_t &message) { - message.outLen = sizeof(message.base64Data); - base64::encode((const unsigned char *)message.message.asndata, - (const int)message.message.asnLength, - message.base64Data, - message.outLen); - if (mdclog_level_get() >= MDCLOG_DEBUG) { - mdclog_write(MDCLOG_DEBUG, "asn data length = %d, base64 message length = %d ", - (int)message.message.asnLength, - (int)message.outLen); - } - -// 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; + } } diff --git a/RIC-E2-TERMINATION/sctpThread.h b/RIC-E2-TERMINATION/sctpThread.h index 2149cd3..588f6a8 100644 --- a/RIC-E2-TERMINATION/sctpThread.h +++ b/RIC-E2-TERMINATION/sctpThread.h @@ -13,14 +13,13 @@ * 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 @@ -49,6 +48,8 @@ #include #include #include +#include +#include #include #include @@ -64,17 +65,20 @@ #include #include #include - +#include #include -#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" @@ -84,6 +88,8 @@ #include "base64.h" +#include "ReadConfigFile.h" + using namespace std; namespace logging = boost::log; namespace src = boost::log::sources; @@ -115,11 +121,20 @@ typedef struct sctp_params { uint16_t rmrPort = 0; int epoll_fd = 0; int rmrListenFd = 0; + int inotifyFD = 0; + int inotifyWD = 0; void *rmrCtx = nullptr; Sctp_Map_t *sctpMap = nullptr; + char 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; @@ -136,11 +151,13 @@ typedef struct ConnectedCU { #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 { @@ -154,17 +171,38 @@ 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); @@ -254,7 +292,7 @@ int receiveDataFromSctp(struct epoll_event *events, * @param pSpan * @return */ -void *getRmrContext(char *rmrAddress, otSpan *pSpan); +void getRmrContext(sctp_params_t &pSctpParams, otSpan *pSpan); /** * @@ -385,6 +423,12 @@ void buildJsonMessage(ReportingMessages_t &message); */ string translateRmrErrorMessages(int state); + +static inline uint64_t rdtscp(uint32_t &aux) { + uint64_t rax,rdx; + asm volatile ("rdtscp\n" : "=a" (rax), "=d" (rdx), "=c" (aux) : :); + return (rdx << 32) + rax; +} #ifndef RIC_SCTP_CONNECTION_FAILURE #define RIC_SCTP_CONNECTION_FAILURE 10080 #endif diff --git a/config/config.bad b/config/config.bad new file mode 100644 index 0000000..980bbd5 --- /dev/null +++ b/config/config.bad @@ -0,0 +1,10 @@ +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 diff --git a/config/config.sec b/config/config.sec new file mode 100644 index 0000000..bf7689f --- /dev/null +++ b/config/config.sec @@ -0,0 +1,9 @@ +[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 diff --git a/config/config.secbad b/config/config.secbad new file mode 100644 index 0000000..9b5db3d --- /dev/null +++ b/config/config.secbad @@ -0,0 +1,9 @@ +[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