Commit 5c24d6a5 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

add common/app

parent fcbb4bde
...@@ -32,3 +32,5 @@ set (BUILD_TOP_DIR ${OPENAIRCN_DIR}/build) ...@@ -32,3 +32,5 @@ set (BUILD_TOP_DIR ${OPENAIRCN_DIR}/build)
set (SRC_TOP_DIR $ENV{OPENAIRCN_DIR}/src) set (SRC_TOP_DIR $ENV{OPENAIRCN_DIR}/src)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../src/oai-nrf/CMakeLists.txt) include(${CMAKE_CURRENT_SOURCE_DIR}/../../src/oai-nrf/CMakeLists.txt)
ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/nrf_app ${CMAKE_CURRENT_BINARY_DIR}/nrf_app)
################################################################################
# Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The OpenAirInterface Software Alliance licenses this file to You under
# the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
#
# 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.
#-------------------------------------------------------------------------------
# For more information about the OpenAirInterface (OAI) Software Alliance:
# contact@openairinterface.org
################################################################################
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/msg)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/nas)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ngap)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common/utils)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
include_directories(${SRC_TOP_DIR}/../build/ext/spdlog/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
add_library(3GPP_COMMON_TYPES STATIC
${CMAKE_CURRENT_SOURCE_DIR}/logger.cpp
)
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file common_defs.h
\brief
\author Sebastien ROUX, Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_COMMON_DEFS_SEEN
#define FILE_COMMON_DEFS_SEEN
#include <arpa/inet.h>
#include <stdint.h>
#define RETURNclear (int)2
#define RETURNerror (int)1
#define RETURNok (int)0
typedef enum {
/* Fatal errors - received message should not be processed */
TLV_MAC_MISMATCH = -14,
TLV_BUFFER_NULL = -13,
TLV_BUFFER_TOO_SHORT = -12,
TLV_PROTOCOL_NOT_SUPPORTED = -11,
TLV_WRONG_MESSAGE_TYPE = -10,
TLV_OCTET_STRING_TOO_LONG_FOR_IEI = -9,
TLV_VALUE_DOESNT_MATCH = -4,
TLV_MANDATORY_FIELD_NOT_PRESENT = -3,
TLV_UNEXPECTED_IEI = -2,
// RETURNerror = -1,
// RETURNok = 0,
TLV_ERROR_OK = RETURNok,
/* Defines error code limit below which received message should be discarded
* because it cannot be further processed */
TLV_FATAL_ERROR = TLV_VALUE_DOESNT_MATCH
} error_code_e;
//------------------------------------------------------------------------------
#define DECODE_U8(bUFFER, vALUE, sIZE) \
vALUE = *(uint8_t*)(bUFFER); \
sIZE += sizeof(uint8_t)
#define DECODE_U16(bUFFER, vALUE, sIZE) \
vALUE = ntohs(*(uint16_t*)(bUFFER)); \
sIZE += sizeof(uint16_t)
#define DECODE_U24(bUFFER, vALUE, sIZE) \
vALUE = ntohl(*(uint32_t*)(bUFFER)) >> 8; \
sIZE += sizeof(uint8_t) + sizeof(uint16_t)
#define DECODE_U32(bUFFER, vALUE, sIZE) \
vALUE = ntohl(*(uint32_t*)(bUFFER)); \
sIZE += sizeof(uint32_t)
#if (BYTE_ORDER == LITTLE_ENDIAN)
# define DECODE_LENGTH_U16(bUFFER, vALUE, sIZE) \
vALUE = ((*(bUFFER)) << 8) | (*((bUFFER) + 1)); \
sIZE += sizeof(uint16_t)
#else
# define DECODE_LENGTH_U16(bUFFER, vALUE, sIZE) \
vALUE = (*(bUFFER)) | (*((bUFFER) + 1) << 8); \
sIZE += sizeof(uint16_t)
#endif
#define ENCODE_U8(buffer, value, size) \
*(uint8_t*)(buffer) = value; \
size += sizeof(uint8_t)
#define ENCODE_U16(buffer, value, size) \
*(uint16_t*)(buffer) = htons(value); \
size += sizeof(uint16_t)
#define ENCODE_U24(buffer, value, size) \
*(uint32_t*)(buffer) = htonl(value); \
size += sizeof(uint8_t) + sizeof(uint16_t)
#define ENCODE_U32(buffer, value, size) \
*(uint32_t*)(buffer) = htonl(value); \
size += sizeof(uint32_t)
#define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\
struct in_addr inp;\
if ( inet_aton(AdDr_StR, &inp ) < 0 ) {\
AssertFatal (0, MeSsAgE);\
} else {\
NwBo = inp.s_addr;\
}\
} while (0)
#define NIPADDR(addr) \
(uint8_t)(addr & 0x000000FF), \
(uint8_t)((addr & 0x0000FF00) >> 8), \
(uint8_t)((addr & 0x00FF0000) >> 16), \
(uint8_t)((addr & 0xFF000000) >> 24)
#define HIPADDR(addr) \
(uint8_t)((addr & 0xFF000000) >> 24),\
(uint8_t)((addr & 0x00FF0000) >> 16),\
(uint8_t)((addr & 0x0000FF00) >> 8), \
(uint8_t)(addr & 0x000000FF)
#define NIP6ADDR(addr) \
ntohs((addr)->s6_addr16[0]), \
ntohs((addr)->s6_addr16[1]), \
ntohs((addr)->s6_addr16[2]), \
ntohs((addr)->s6_addr16[3]), \
ntohs((addr)->s6_addr16[4]), \
ntohs((addr)->s6_addr16[5]), \
ntohs((addr)->s6_addr16[6]), \
ntohs((addr)->s6_addr16[7])
#define IN6_ARE_ADDR_MASKED_EQUAL(a,b,m) \
(((((__const uint32_t *) (a))[0] & (((__const uint32_t *) (m))[0])) == (((__const uint32_t *) (b))[0] & (((__const uint32_t *) (m))[0]))) \
&& ((((__const uint32_t *) (a))[1] & (((__const uint32_t *) (m))[1])) == (((__const uint32_t *) (b))[1] & (((__const uint32_t *) (m))[1]))) \
&& ((((__const uint32_t *) (a))[2] & (((__const uint32_t *) (m))[2])) == (((__const uint32_t *) (b))[2] & (((__const uint32_t *) (m))[2]))) \
&& ((((__const uint32_t *) (a))[3] & (((__const uint32_t *) (m))[3])) == (((__const uint32_t *) (b))[3] & (((__const uint32_t *) (m))[3]))))
////////////
#define IPV4_STR_ADDR_TO_INADDR(AdDr_StR,InAdDr,MeSsAgE ) do {\
if ( inet_aton(AdDr_StR, &InAdDr ) <= 0 ) {\
throw (MeSsAgE);\
}\
} while (0)
#ifndef UNUSED
#define UNUSED(x) (void)(x)
#endif
#endif /* FILE_COMMON_DEFS_SEEN */
/*
* Copyright (c) 2015, EURECOM (www.eurecom.fr)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the FreeBSD Project.
*/
#include <stdlib.h>
#include "dynamic_memory_check.h"
#include "assertions.h"
//------------------------------------------------------------------------------
void free_wrapper(void **ptr)
{
// for debug only
AssertFatal(ptr, "Trying to free NULL ptr");
if (ptr) {
free(*ptr);
*ptr = NULL;
}
}
//------------------------------------------------------------------------------
void bdestroy_wrapper(bstring *b)
{
if ((b) && (*b)) {
bdestroy(*b);
*b = NULL;
}
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file dynamic_memory_check.h
\brief
\author Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_DYNAMIC_MEMORY_CHECK_SEEN
#define FILE_DYNAMIC_MEMORY_CHECK_SEEN
# include "bstrlib.h"
void free_wrapper(void **ptr) __attribute__ ((hot));
void bdestroy_wrapper(bstring *b);
#endif /* FILE_DYNAMIC_MEMORY_CHECK_SEEN */
/*
* Copyright (c) 2017 Sprint
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "logger.hpp"
#include "spdlog/sinks/syslog_sink.h"
#include <iostream>
#include <sstream>
#include <string>
#include <memory>
Logger *Logger::m_singleton = NULL;
void Logger::_init(const char *app, const bool log_stdout,
bool const log_rot_file) {
int num_sinks = 0;
spdlog::set_async_mode(2048);
#if TRACE_IS_ON
spdlog::level::level_enum llevel = spdlog::level::trace;
#elif DEBUG_IS_ON
spdlog::level::level_enum llevel = spdlog::level::debug;
#elif INFO_IS_ON
spdlog::level::level_enum llevel = spdlog::level::info;
#else
spdlog::level::level_enum llevel = spdlog::level::warn;
#endif
if (log_stdout) {
std::string filename = fmt::format("./{}.log", app);
m_sinks.push_back(
std::make_shared<spdlog::sinks::ansicolor_stdout_sink_mt>());
m_sinks[num_sinks++].get()->set_level(llevel);
}
if (log_rot_file) {
std::string filename = fmt::format("./{}.log", app);
m_sinks.push_back(
std::make_shared<spdlog::sinks::rotating_file_sink_mt>(filename,
5 * 1024 * 1024,
3));
m_sinks[num_sinks++].get()->set_level(llevel);
}
std::stringstream ss;
ss << "[%Y-%m-%dT%H:%M:%S.%f] [" << app << "] [%n] [%l] %v";
m_async_cmd = new _Logger("async_c", m_sinks, ss.str().c_str());
m_itti = new _Logger("itti ", m_sinks, ss.str().c_str());
m_smf_app = new _Logger("smf_app", m_sinks, ss.str().c_str());
m_system = new _Logger("system ", m_sinks, ss.str().c_str());
m_udp = new _Logger("udp ", m_sinks, ss.str().c_str());
m_pfcp = new _Logger("pfcp ", m_sinks, ss.str().c_str());
m_pfcp_switch = new _Logger("pfcp_sw ", m_sinks, ss.str().c_str());
m_smf_n1 = new _Logger("smf_n1 ", m_sinks, ss.str().c_str());
m_smf_n2 = new _Logger("smf_n2 ", m_sinks, ss.str().c_str());
m_smf_n4 = new _Logger("smf_n4 ", m_sinks, ss.str().c_str());
m_smf_n10 = new _Logger("smf_n10", m_sinks, ss.str().c_str());
m_smf_n11 = new _Logger("smf_n11", m_sinks, ss.str().c_str());
m_smf_api_server = new _Logger("sbi_srv", m_sinks, ss.str().c_str());
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
_Logger::_Logger(const char *category, std::vector<spdlog::sink_ptr> &sinks,
const char *pattern)
:
m_log(category, sinks.begin(), sinks.end()) {
m_log.set_pattern(pattern);
#if TRACE_IS_ON
m_log.set_level( spdlog::level::trace );
#elif DEBUG_IS_ON
m_log.set_level( spdlog::level::debug );
#elif INFO_IS_ON
m_log.set_level( spdlog::level::info );
#else
m_log.set_level(spdlog::level::warn);
#endif
}
void _Logger::trace(const char *format, ...) {
#if TRACE_IS_ON
va_list args;
va_start( args, format );
log( _ltTrace, format, args );
va_end( args );
#endif
}
void _Logger::debug(const char *format, ...) {
#if DEBUG_IS_ON
va_list args;
va_start( args, format );
log( _ltDebug, format, args );
va_end( args );
#endif
}
void _Logger::info(const char *format, ...) {
#if INFO_IS_ON
va_list args;
va_start( args, format );
log( _ltInfo, format, args );
va_end( args );
#endif
}
void _Logger::startup(const char *format, ...) {
va_list args;
va_start(args, format);
log(_ltStartup, format, args);
va_end(args);
}
void _Logger::warn(const char *format, ...) {
va_list args;
va_start(args, format);
log(_ltWarn, format, args);
va_end(args);
}
void _Logger::error(const char *format, ...) {
va_list args;
va_start(args, format);
log(_ltError, format, args);
va_end(args);
}
void _Logger::log(_LogType lt, const char *format, va_list &args) {
char buffer[2048];
vsnprintf(buffer, sizeof(buffer), format, args);
switch (lt) {
case _ltTrace:
m_log.trace(buffer);
break;
case _ltDebug:
m_log.debug(buffer);
break;
case _ltInfo:
m_log.info(buffer);
break;
case _ltStartup:
m_log.warn(buffer);
break;
case _ltWarn:
m_log.error(buffer);
break;
case _ltError:
m_log.critical(buffer);
break;
}
}
/*
* Copyright (c) 2017 Sprint
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __LOGGER_H
#define __LOGGER_H
#include <cstdarg>
#include <stdexcept>
#include <vector>
//#define SPDLOG_LEVEL_NAMES { "trace", "debug", "info", "warning", "error", "critical", "off" };
#define SPDLOG_LEVEL_NAMES { "trace", "debug", "info ", "start", "warn ", "error", "off " };
#define SPDLOG_ENABLE_SYSLOG
#include "spdlog/spdlog.h"
class LoggerException : public std::runtime_error {
public:
explicit LoggerException(const char *m)
:
std::runtime_error(m) {
}
explicit LoggerException(const std::string &m)
:
std::runtime_error(m) {
}
};
class _Logger {
public:
_Logger(const char *category, std::vector<spdlog::sink_ptr> &sinks,
const char *pattern);
void trace(const char *format, ...);
void trace(const std::string &format, ...);
void debug(const char *format, ...);
void debug(const std::string &format, ...);
void info(const char *format, ...);
void info(const std::string &format, ...);
void startup(const char *format, ...);
void startup(const std::string &format, ...);
void warn(const char *format, ...);
void warn(const std::string &format, ...);
void error(const char *format, ...);
void error(const std::string &format, ...);
private:
_Logger();
enum _LogType {
_ltTrace,
_ltDebug,
_ltInfo,
_ltStartup,
_ltWarn,
_ltError
};
void log(_LogType lt, const char *format, va_list &args);
spdlog::logger m_log;
};
class Logger {
public:
static void init(const char *app, const bool log_stdout,
const bool log_rot_file) {
singleton()._init(app, log_stdout, log_rot_file);
}
static void init(const std::string &app, const bool log_stdout,
const bool log_rot_file) {
init(app.c_str(), log_stdout, log_rot_file);
}
static _Logger& async_cmd() {
return *singleton().m_async_cmd;
}
static _Logger& itti() {
return *singleton().m_itti;
}
static _Logger& smf_app() {
return *singleton().m_smf_app;
}
static _Logger& system() {
return *singleton().m_system;
}
static _Logger& udp() {
return *singleton().m_udp;
}
static _Logger& pfcp() {
return *singleton().m_pfcp;
}
static _Logger& pfcp_switch() {
return *singleton().m_pfcp_switch;
}
static _Logger& smf_n1() {
return *singleton().m_smf_n1;
}
static _Logger& smf_n2() {
return *singleton().m_smf_n2;
}
static _Logger& smf_n4() {
return *singleton().m_smf_n4;
}
static _Logger& smf_n10() {
return *singleton().m_smf_n10;
}
static _Logger& smf_n11() {
return *singleton().m_smf_n11;
}
static _Logger& smf_api_server() {
return *singleton().m_smf_api_server;
}
private:
static Logger *m_singleton;
static Logger& singleton() {
if (!m_singleton)
m_singleton = new Logger();
return *m_singleton;
}
Logger() {
}
~Logger() {
}
void _init(const char *app, const bool log_stdout, const bool log_rot_file);
std::vector<spdlog::sink_ptr> m_sinks;
std::string m_pattern;
_Logger *m_async_cmd;
_Logger *m_itti;
_Logger *m_smf_app;
_Logger *m_system;
_Logger *m_udp;
_Logger *m_pfcp;
_Logger *m_pfcp_switch;
_Logger *m_smf_n1;
_Logger *m_smf_n2;
_Logger *m_smf_n4;
_Logger *m_smf_n10;
_Logger *m_smf_n11;
_Logger *m_smf_api_server;
};
#endif // __LOGGER_H
################################################################################
# Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The OpenAirInterface Software Alliance licenses this file to You under
# the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
#
# 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.
#-------------------------------------------------------------------------------
# For more information about the OpenAirInterface (OAI) Software Alliance:
# contact@openairinterface.org
################################################################################
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${SRC_TOP_DIR}/common)
include_directories(${SRC_TOP_DIR}/common/utils)
include_directories(${SRC_TOP_DIR}/../build/ext/spdlog/include)
set(CN_UTILS_SRC STATIC
${CMAKE_CURRENT_SOURCE_DIR}/async_shell_cmd.cpp
${CMAKE_CURRENT_SOURCE_DIR}/conversions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/get_gateway_netlink.cpp
${CMAKE_CURRENT_SOURCE_DIR}/if.cpp
${CMAKE_CURRENT_SOURCE_DIR}/pid_file.cpp
${CMAKE_CURRENT_SOURCE_DIR}/string.cpp
${CMAKE_CURRENT_SOURCE_DIR}/thread_sched.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mime_parser.cpp
)
add_library(CN_UTILS ${CN_UTILS_SRC})
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file async_shell_cmd.cpp
\brief
\author Lionel GAUTHIER
\date 2017
\email: lionel.gauthier@eurecom.fr
*/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include <inttypes.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
//#include "itti.hpp"
#include "async_shell_cmd.hpp"
//#include "itti_async_shell_cmd.hpp"
#include "logger.hpp"
//#include "common_defs.h"
#include <stdexcept>
using namespace util;
//extern itti_mw *itti_inst;
void async_cmd_task(void*);
//------------------------------------------------------------------------------
void async_cmd_task(void *args_p) {
// const task_id_t task_id = TASK_ASYNC_SHELL_CMD;
/*
const thread_sched_params *const sched_params =
(const util::thread_sched_params* const ) args_p;
sched_params->apply(task_id, Logger::async_cmd());
itti_inst->notify_task_ready(task_id);
do {
std::shared_ptr<itti_msg> shared_msg = itti_inst->receive_msg(task_id);
auto *msg = shared_msg.get();
switch (msg->msg_type) {
case ASYNC_SHELL_CMD:
if (itti_async_shell_cmd *to = dynamic_cast<itti_async_shell_cmd*>(msg)) {
int rc = system((const char*) to->system_command.c_str());
if (rc) {
Logger::async_cmd().error("Failed cmd from %d: %s ", to->origin,
(const char*) to->system_command.c_str());
if (to->is_abort_on_error) {
Logger::async_cmd().error(
"Terminate cause failed cmd %s at %s:%d",
to->system_command.c_str(), to->src_file.c_str(),
to->src_line);
itti_inst->send_terminate_msg(to->origin);
}
}
}
break;
case TIME_OUT:
if (itti_msg_timeout *to = dynamic_cast<itti_msg_timeout*>(msg)) {
Logger::async_cmd().info("TIME-OUT event timer id %d", to->timer_id);
}
break;
case TERMINATE:
if (itti_msg_terminate *terminate =
dynamic_cast<itti_msg_terminate*>(msg)) {
Logger::async_cmd().info("Received terminate message");
return;
}
break;
case HEALTH_PING:
break;
default:
Logger::smf_app().info("no handler for msg type %d", msg->msg_type);
}
} while (true);
*/
}
//------------------------------------------------------------------------------
async_shell_cmd::async_shell_cmd(util::thread_sched_params &sched_params) {
Logger::async_cmd().startup("Starting...");
/*
if (itti_inst->create_task(TASK_ASYNC_SHELL_CMD, async_cmd_task,
&sched_params)) {
Logger::async_cmd().error("Cannot create task TASK_ASYNC_SHELL_CMD");
throw std::runtime_error("Cannot create task TASK_ASYNC_SHELL_CMD");
}
*/
Logger::async_cmd().startup("Started");
}
/*
//------------------------------------------------------------------------------
int async_shell_cmd::run_command(const task_id_t sender_itti_task,
const bool is_abort_on_error,
const char *src_file, const int src_line,
const std::string &cmd_str) {
itti_async_shell_cmd cmd(sender_itti_task, TASK_ASYNC_SHELL_CMD, cmd_str,
is_abort_on_error, src_file, src_line);
std::shared_ptr<itti_async_shell_cmd> msg = std::make_shared<
itti_async_shell_cmd>(cmd);
int ret = itti_inst->send_msg(msg);
if (RETURNok != ret) {
Logger::async_cmd().error(
"Could not send ITTI message to task TASK_ASYNC_SHELL_CMD");
return RETURNerror ;
}
return RETURNok ;
}
*/
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file async_shell_cmd.hpp
\brief We still use some unix commands for convenience, and we did not have to replace them by system calls
\ Instead of calling C system(...) that can take a lot of time (creation of a process, etc), in many cases
\ it doesn't hurt to do this asynchronously, may be we must tweak thread priority, pin it to a CPU, etc (TODO later)
\author Lionel GAUTHIER
\date 2017
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_ASYNC_SHELL_CMD_HPP_SEEN
#define FILE_ASYNC_SHELL_CMD_HPP_SEEN
//#include "itti_msg.hpp"
#include "thread_sched.hpp"
#include <string>
#include <thread>
namespace util {
class async_shell_cmd {
private:
std::thread::id thread_id;
std::thread thread;
public:
explicit async_shell_cmd(util::thread_sched_params &sched_params);
~async_shell_cmd() {
}
async_shell_cmd(async_shell_cmd const&) = delete;
void operator=(async_shell_cmd const&) = delete;
// int run_command(const task_id_t sender_itti_task,
// const bool is_abort_on_error, const char *src_file,
// const int src_line, const std::string &cmd_str);
};
}
#endif /* FILE_ASYNC_SHELL_CMD_HPP_SEEN */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file conversions.cpp
\brief
\author Sebastien ROUX
\company Eurecom
*/
#include "conversions.hpp"
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <ctype.h>
#include <inttypes.h>
#include <arpa/inet.h>
static const char hex_to_ascii_table[16] = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', };
static const signed char ascii_to_hex_table[0x100] = { -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1,
10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1 };
void conv::hexa_to_ascii(uint8_t *from, char *to, size_t length) {
size_t i;
for (i = 0; i < length; i++) {
uint8_t upper = (from[i] & 0xf0) >> 4;
uint8_t lower = from[i] & 0x0f;
to[2 * i] = hex_to_ascii_table[upper];
to[2 * i + 1] = hex_to_ascii_table[lower];
}
}
int conv::ascii_to_hex(uint8_t *dst, const char *h) {
const unsigned char *hex = (const unsigned char*) h;
unsigned i = 0;
for (;;) {
int high, low;
while (*hex && isspace(*hex))
hex++;
if (!*hex)
return 1;
high = ascii_to_hex_table[*hex++];
if (high < 0)
return 0;
while (*hex && isspace(*hex))
hex++;
if (!*hex)
return 0;
low = ascii_to_hex_table[*hex++];
if (low < 0)
return 0;
dst[i++] = (high << 4) | low;
}
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file conversions.hpp
\brief
\author Sebastien ROUX, Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_CONVERSIONS_HPP_SEEN
#define FILE_CONVERSIONS_HPP_SEEN
#include <stdint.h>
#include <string>
#include <netinet/in.h>
/* Used to format an uint32_t containing an ipv4 address */
#define IN_ADDR_FMT "%u.%u.%u.%u"
#define PRI_IN_ADDR(aDDRESS) \
(uint8_t)((aDDRESS.s_addr) & 0x000000ff), \
(uint8_t)(((aDDRESS.s_addr) & 0x0000ff00) >> 8 ), \
(uint8_t)(((aDDRESS.s_addr) & 0x00ff0000) >> 16), \
(uint8_t)(((aDDRESS.s_addr) & 0xff000000) >> 24)
#define IPV4_ADDR_DISPLAY_8(aDDRESS) \
(aDDRESS)[0], (aDDRESS)[1], (aDDRESS)[2], (aDDRESS)[3]
/* Convert an integer on 32 bits to the given bUFFER */
#define INT32_TO_BUFFER(x, buf) \
(buf)[0] = (x) >> 24, \
(buf)[1] = (x) >> 16, \
(buf)[2] = (x) >> 8, \
(buf)[3] = (x)
class conv {
public:
static void hexa_to_ascii(uint8_t *from, char *to, size_t length);
static int ascii_to_hex(uint8_t *dst, const char *h);
static struct in_addr fromString(const std::string addr4);
static std::string toString(const struct in_addr &inaddr);
static std::string toString(const struct in6_addr &in6addr);
static std::string mccToString(const uint8_t digit1, const uint8_t digit2,
const uint8_t digit3);
static std::string mncToString(const uint8_t digit1, const uint8_t digit2,
const uint8_t digit3);
};
#endif /* FILE_CONVERSIONS_HPP_SEEN */
/* From https://gist.github.com/javiermon/6272065#file-gateway_netlink-c */
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <net/if.h>
#include <fstream> // std::ifstream
#include <string>
#include "common_defs.h"
#include "get_gateway_netlink.hpp"
#include "logger.hpp"
#define BUFFER_SIZE 4096
using namespace std;
//------------------------------------------------------------------------------
bool util::get_iface_l2_addr(const std::string &iface, std::string &mac) {
std::string mac_address_path = fmt::format("/sys/class/net/{}/address",
iface);
std::ifstream mac_address_in(mac_address_path.c_str(),
ios_base::in | ios_base::binary);
char wb[32];
mac_address_in.get(wb, 32);
mac.assign(wb);
Logger::pfcp_switch().error("Found IFace %s MAC %s", iface.c_str(),
mac.c_str());
mac.erase(std::remove(mac.begin(), mac.end(), ':'), mac.end());
return true;
// ifr = {};
// strncpy ((char *) ifr.ifr_name, ifname, IFNAMSIZ);
// if (ioctl(sd, SIOCGIFFLAGS, &ifr) == 0) {
// if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback
// if (ioctl(sd, SIOCGIFHWADDR, &ifr) == 0) {
// memcpy(pdn_mac_address, ifr.ifr_hwaddr.sa_data, 6);
// }
// }
// }
}
//------------------------------------------------------------------------------
bool util::get_gateway_and_iface(std::string &gw, std::string &iface) {
int received_bytes = 0, msg_len = 0, route_attribute_len = 0;
int sock = -1, msgseq = 0;
struct nlmsghdr *nlh, *nlmsg;
struct rtmsg *route_entry;
// This struct contain route attributes (route type)
struct rtattr *route_attribute;
char gateway_address[INET_ADDRSTRLEN], interface[IF_NAMESIZE + 1];
char msgbuf[BUFFER_SIZE], buffer[BUFFER_SIZE];
char *ptr = buffer;
struct timeval tv;
int rv = 0; //RETURNok;
if ((sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) {
perror("socket failed");
return false;
}
memset(msgbuf, 0, sizeof(msgbuf));
memset(gateway_address, 0, sizeof(gateway_address));
memset(interface, 0, sizeof(interface));
memset(buffer, 0, sizeof(buffer));
/* point the header and the msg structure pointers into the buffer */
nlmsg = (struct nlmsghdr*) msgbuf;
/* Fill in the nlmsg header*/
nlmsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
nlmsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
nlmsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump.
nlmsg->nlmsg_seq = msgseq++; // Sequence of the message packet.
nlmsg->nlmsg_pid = getpid(); // PID of process sending the request.
/* 1 Sec Timeout to avoid stall */
tv.tv_sec = 1;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (struct timeval*) &tv,
sizeof(struct timeval));
/* send msg */
if (send(sock, nlmsg, nlmsg->nlmsg_len, 0) < 0) {
perror("send failed");
return false;
}
/* receive response */
do {
received_bytes = recv(sock, ptr, sizeof(buffer) - msg_len, 0);
if (received_bytes < 0) {
perror("Error in recv");
return false;
}
nlh = (struct nlmsghdr*) ptr;
/* Check if the header is valid */
if ((NLMSG_OK(nlmsg, received_bytes) == 0)
|| (nlmsg->nlmsg_type == NLMSG_ERROR)) {
perror("Error in received packet");
return false;
}
/* If we received all data break */
if (nlh->nlmsg_type == NLMSG_DONE)
break;
else {
ptr += received_bytes;
msg_len += received_bytes;
}
/* Break if its not a multi part message */
if ((nlmsg->nlmsg_flags & NLM_F_MULTI) == 0)
break;
} while ((nlmsg->nlmsg_seq != msgseq) || (nlmsg->nlmsg_pid != getpid()));
/* parse response */
for (; NLMSG_OK(nlh, received_bytes); nlh = NLMSG_NEXT(nlh, received_bytes)) {
/* Get the route data */
route_entry = (struct rtmsg*) NLMSG_DATA(nlh);
/* We are just interested in main routing table */
if (route_entry->rtm_table != RT_TABLE_MAIN)
continue;
route_attribute = (struct rtattr*) RTM_RTA(route_entry);
route_attribute_len = RTM_PAYLOAD(nlh);
/* Loop through all attributes */
for (; RTA_OK(route_attribute, route_attribute_len); route_attribute =
RTA_NEXT(route_attribute, route_attribute_len)) {
switch (route_attribute->rta_type) {
case RTA_OIF:
if_indextoname(*(int*) RTA_DATA(route_attribute), interface);
break;
case RTA_GATEWAY:
inet_ntop(AF_INET, RTA_DATA(route_attribute), gateway_address,
sizeof(gateway_address));
break;
default:
break;
}
}
if ((*gateway_address) && (*interface)) {
gw.assign(gateway_address);
iface.assign(interface);
break;
} else {
rv = false;
}
}
close(sock);
return true;
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file get_gateway_netlink.hpp
\brief
\author Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_GET_GATEWAY_NETLINK_HPP_SEEN
#define FILE_GET_GATEWAY_NETLINK_HPP_SEEN
#include <string>
namespace util {
bool get_iface_l2_addr(const std::string &iface, std::string &mac);
bool get_gateway_and_iface(std::string &gw, std::string &iface);
}
#endif /* FILE_GET_GATEWAY_NETLINK_HPP_SEEN */
/* From https://gist.github.com/javiermon/6272065#file-gateway_netlink-c */
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common_defs.h"
#include "if.hpp"
#include "logger.hpp"
#include <errno.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#define BUFFER_SIZE 4096
//------------------------------------------------------------------------------
int get_gateway_and_iface(std::string *gw, std::string *iface) {
int received_bytes = 0, msg_len = 0, route_attribute_len = 0;
int sock = -1, msgseq = 0;
struct nlmsghdr *nlh, *nlmsg;
struct rtmsg *route_entry;
// This struct contain route attributes (route type)
struct rtattr *route_attribute;
char gateway_address[INET_ADDRSTRLEN], interface[IF_NAMESIZE];
char msgbuf[BUFFER_SIZE], buffer[BUFFER_SIZE];
char *ptr = buffer;
struct timeval tv;
int rv = RETURNok;
if ((sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) {
Logger::system().error("socket raw/NETLINK_ROUTE failed");
return EXIT_FAILURE;
}
memset(msgbuf, 0, sizeof(msgbuf));
memset(gateway_address, 0, sizeof(gateway_address));
memset(interface, 0, sizeof(interface));
memset(buffer, 0, sizeof(buffer));
/* point the header and the msg structure pointers into the buffer */
nlmsg = (struct nlmsghdr*) msgbuf;
/* Fill in the nlmsg header*/
nlmsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
nlmsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
nlmsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump.
nlmsg->nlmsg_seq = msgseq++; // Sequence of the message packet.
nlmsg->nlmsg_pid = getpid(); // PID of process sending the request.
/* 1 Sec Timeout to avoid stall */
tv.tv_sec = 1;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (struct timeval*) &tv,
sizeof(struct timeval));
/* send msg */
if (send(sock, nlmsg, nlmsg->nlmsg_len, 0) < 0) {
Logger::system().error("send socket raw/NETLINK_ROUTE failed");
return EXIT_FAILURE;
}
/* receive response */
do {
received_bytes = recv(sock, ptr, sizeof(buffer) - msg_len, 0);
if (received_bytes < 0) {
Logger::system().error("recv socket raw/NETLINK_ROUTE failed");
return EXIT_FAILURE;
}
nlh = (struct nlmsghdr*) ptr;
/* Check if the header is valid */
if ((NLMSG_OK(nlmsg, received_bytes) == 0)
|| (nlmsg->nlmsg_type == NLMSG_ERROR)) {
Logger::system().error("recv msg raw/NETLINK_ROUTE failed");
return EXIT_FAILURE;
}
/* If we received all data break */
if (nlh->nlmsg_type == NLMSG_DONE)
break;
else {
ptr += received_bytes;
msg_len += received_bytes;
}
/* Break if its not a multi part message */
if ((nlmsg->nlmsg_flags & NLM_F_MULTI) == 0)
break;
} while ((nlmsg->nlmsg_seq != msgseq) || (nlmsg->nlmsg_pid != getpid()));
/* parse response */
for (; NLMSG_OK(nlh, received_bytes); nlh = NLMSG_NEXT(nlh, received_bytes)) {
/* Get the route data */
route_entry = (struct rtmsg*) NLMSG_DATA(nlh);
/* We are just interested in main routing table */
if (route_entry->rtm_table != RT_TABLE_MAIN)
continue;
route_attribute = (struct rtattr*) RTM_RTA(route_entry);
route_attribute_len = RTM_PAYLOAD(nlh);
/* Loop through all attributes */
for (; RTA_OK(route_attribute, route_attribute_len); route_attribute =
RTA_NEXT(route_attribute, route_attribute_len)) {
switch (route_attribute->rta_type) {
case RTA_OIF:
if_indextoname(*(int*) RTA_DATA(route_attribute), interface);
break;
case RTA_GATEWAY:
inet_ntop(AF_INET, RTA_DATA(route_attribute), gateway_address,
sizeof(gateway_address));
break;
default:
break;
}
}
if ((*gateway_address) && (*interface)) {
*gw = std::string(gateway_address);
if (iface) {
*iface = std::string(interface);
}
break;
} else {
rv = RETURNerror;
}
}
close(sock);
return rv;
}
//------------------------------------------------------------------------------
int get_inet_addr_from_iface(const std::string &if_name,
struct in_addr &inet_addr) {
struct ifreq ifr;
char str[INET_ADDRSTRLEN];
memset(&ifr, 0, sizeof(ifr));
int fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
//strncpy(ifr.ifr_name, (const char *)if_name.c_str(), IFNAMSIZ-1);
strcpy(ifr.ifr_name, (const char*) if_name.c_str());
if (ioctl(fd, SIOCGIFADDR, &ifr)) {
close(fd);
Logger::system().error("Failed to probe %s inet addr: error %s\n",
if_name.c_str(), strerror(errno));
return RETURNerror ;
}
close(fd);
struct sockaddr_in *ipaddr = (struct sockaddr_in*) &ifr.ifr_addr;
// check
if (inet_ntop(AF_INET, (const void*) &ipaddr->sin_addr, str,
INET_ADDRSTRLEN) == NULL) {
return RETURNerror ;
}
inet_addr.s_addr = ipaddr->sin_addr.s_addr;
return RETURNok ;
}
//------------------------------------------------------------------------------
int get_mtu_from_iface(const std::string &if_name, uint32_t &mtu) {
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
int fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
//strncpy(ifr.ifr_name, (const char *)if_name.c_str(), IFNAMSIZ-1);
strcpy(ifr.ifr_name, (const char*) if_name.c_str());
if (ioctl(fd, SIOCGIFMTU, &ifr)) {
close(fd);
Logger::system().error("Failed to probe %s MTU: error %s\n",
if_name.c_str(), strerror(errno));
return RETURNerror ;
}
close(fd);
mtu = ifr.ifr_mtu;
return RETURNok ;
}
//------------------------------------------------------------------------------
int get_inet_addr_infos_from_iface(const std::string &if_name,
struct in_addr &inet_addr,
struct in_addr &inet_network,
unsigned int &mtu) {
struct ifreq ifr;
char str[INET_ADDRSTRLEN];
inet_addr.s_addr = INADDR_ANY;
inet_network.s_addr = INADDR_ANY;
mtu = 0;
memset(&ifr, 0, sizeof(ifr));
int fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
//strncpy(ifr.ifr_name, (const char *)if_name.c_str(), IFNAMSIZ-1);
strcpy(ifr.ifr_name, (const char*) if_name.c_str());
if (ioctl(fd, SIOCGIFADDR, &ifr)) {
close(fd);
Logger::system().error("Failed to probe %s inet addr: error %s\n",
if_name.c_str(), strerror(errno));
return RETURNerror ;
}
struct sockaddr_in *ipaddr = (struct sockaddr_in*) &ifr.ifr_addr;
// check
if (inet_ntop(AF_INET, (const void*) &ipaddr->sin_addr, str,
INET_ADDRSTRLEN) == NULL) {
close(fd);
return RETURNerror ;
}
inet_addr.s_addr = ipaddr->sin_addr.s_addr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_addr.sa_family = AF_INET;
//strncpy(ifr.ifr_name, (const char *)if_name.c_str(), IFNAMSIZ-1);
strcpy(ifr.ifr_name, (const char*) if_name.c_str());
if (ioctl(fd, SIOCGIFNETMASK, &ifr)) {
close(fd);
Logger::system().error("Failed to probe %s inet netmask: error %s\n",
if_name.c_str(), strerror(errno));
return RETURNerror ;
}
ipaddr = (struct sockaddr_in*) &ifr.ifr_netmask;
// check
if (inet_ntop(AF_INET, (const void*) &ipaddr->sin_addr, str,
INET_ADDRSTRLEN) == NULL) {
close(fd);
return RETURNerror ;
}
inet_network.s_addr = ipaddr->sin_addr.s_addr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_addr.sa_family = AF_INET;
//strncpy(ifr.ifr_name, (const char *)if_name.c_str(), IFNAMSIZ-1);
strcpy(ifr.ifr_name, (const char*) if_name.c_str());
if (ioctl(fd, SIOCGIFMTU, &ifr)) {
Logger::system().error("Failed to probe %s MTU: error %s\n",
if_name.c_str(), strerror(errno));
} else {
mtu = ifr.ifr_mtu;
}
close(fd);
return RETURNok ;
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file get_gateway_netlink.h
\brief
\author Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_IF_HPP_SEEN
#define FILE_IF_HPP_SEEN
# include <string>
int get_gateway_and_iface(std::string *gw /*OUT*/, std::string *iface /*OUT*/);
int get_inet_addr_from_iface(const std::string &if_name,
struct in_addr &inet_addr);
int get_mtu_from_iface(const std::string &if_name, uint32_t &mtu);
int get_inet_addr_infos_from_iface(const std::string &if_name,
struct in_addr &inet_addr,
struct in_addr &inet_netmask,
unsigned int &mtu);
#endif /* FILE_IF_HPP_SEEN */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "mime_parser.hpp"
#include "logger.hpp"
#include "conversions.hpp"
bool mime_parser::parse(const std::string &str) {
std::string CRLF = "\r\n";
Logger::smf_app().debug("Parsing the message with Simple Parser");
//find boundary
std::size_t content_type_pos = str.find("Content-Type"); //first part
if ((content_type_pos <= 4) or (content_type_pos == std::string::npos))
return false;
std::string boundary_str = str.substr(2, content_type_pos - 4); // 2 for -- and 2 for CRLF
Logger::smf_app().debug("Boundary: %s", boundary_str.c_str());
std::string boundary_full = "--" + boundary_str + CRLF;
std::string last_boundary = "--" + boundary_str + "--" + CRLF;
std::size_t crlf_pos = str.find(CRLF, content_type_pos);
std::size_t boundary_pos = str.find(boundary_full);
std::size_t boundary_last_post = str.find(last_boundary);
while (boundary_pos < boundary_last_post) {
mime_part p = { };
content_type_pos = str.find("Content-Type", boundary_pos);
crlf_pos = str.find(CRLF, content_type_pos);
if ((content_type_pos == std::string::npos)
or (crlf_pos == std::string::npos))
break;
p.content_type = str.substr(content_type_pos + 14,
crlf_pos - (content_type_pos + 14));
Logger::smf_app().debug("Content Type: %s", p.content_type.c_str());
crlf_pos = str.find(CRLF + CRLF, content_type_pos); //beginning of content
boundary_pos = str.find(boundary_full, crlf_pos);
if (boundary_pos == std::string::npos) {
boundary_pos = str.find(last_boundary, crlf_pos);
}
if (boundary_pos > 0) {
p.body = str.substr(crlf_pos + 4, boundary_pos - 2 - (crlf_pos + 4));
Logger::smf_app().debug("Body: %s", p.body.c_str());
mime_parts.push_back(p);
}
}
return true;
}
void mime_parser::get_mime_parts(std::vector<mime_part> &parts) const {
for (auto it : mime_parts) {
parts.push_back(it);
}
}
//---------------------------------------------------------------------------------------------
unsigned char* mime_parser::format_string_as_hex(const std::string &str) {
unsigned int str_len = str.length();
char *data = (char*) malloc(str_len + 1);
memset(data, 0, str_len + 1);
memcpy((void*) data, (void*) str.c_str(), str_len);
unsigned char *data_hex = (uint8_t*) malloc(str_len / 2 + 1);
conv::ascii_to_hex(data_hex, (const char*) data);
Logger::smf_app().debug("[Format string as Hex] Input string (%d bytes): %s ",
str_len, str.c_str());
Logger::smf_app().debug("Data (formatted):");
#if DEBUG_IS_ON
for (int i = 0; i < str_len / 2; i++)
printf(" %02x ", data_hex[i]);
printf("\n");
#endif
//free memory
//free_wrapper((void**) &data);
free(data);
data = NULL;
return data_hex;
}
//------------------------------------------------------------------------------
void mime_parser::create_multipart_related_content(std::string &body,
const std::string &json_part,
const std::string boundary,
const std::string &n1_message,
const std::string &n2_message,
std::string json_format) {
//TODO: provide Content-Ids as function parameters
//format string as hex
unsigned char *n1_msg_hex = format_string_as_hex(n1_message);
unsigned char *n2_msg_hex = format_string_as_hex(n2_message);
std::string CRLF = "\r\n";
body.append("--" + boundary + CRLF);
body.append("Content-Type: "+ json_format + CRLF);
body.append(CRLF);
body.append(json_part + CRLF);
body.append("--" + boundary + CRLF);
body.append(
"Content-Type: application/vnd.3gpp.5gnas" + CRLF + "Content-Id: n1SmMsg"
+ CRLF);
body.append(CRLF);
body.append(std::string((char*) n1_msg_hex, n1_message.length() / 2) + CRLF);
body.append("--" + boundary + CRLF);
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2msg"
+ CRLF);
body.append(CRLF);
body.append(std::string((char*) n2_msg_hex, n2_message.length() / 2) + CRLF);
body.append("--" + boundary + "--" + CRLF);
}
//------------------------------------------------------------------------------
void mime_parser::create_multipart_related_content(
std::string &body, const std::string &json_part, const std::string boundary,
const std::string &message, const multipart_related_content_part_e content_type,
std::string json_format) {
//TODO: provide Content-Id as function parameters
//format string as hex
unsigned char *msg_hex = format_string_as_hex(message);
std::string CRLF = "\r\n";
body.append("--" + boundary + CRLF);
body.append("Content-Type: " + json_format + CRLF);
body.append(CRLF);
body.append(json_part + CRLF);
body.append("--" + boundary + CRLF);
if (content_type == multipart_related_content_part_e::NAS) { //NAS
body.append(
"Content-Type: application/vnd.3gpp.5gnas" + CRLF
+ "Content-Id: n1SmMsg" + CRLF);
} else if (content_type == multipart_related_content_part_e::NGAP) { //NGAP
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2msg"
+ CRLF);
}
body.append(CRLF);
body.append(std::string((char*) msg_hex, message.length() / 2) + CRLF);
body.append("--" + boundary + "--" + CRLF);
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file mime_parser.hpp
\brief
\author
\company Eurecom
\email:
*/
#ifndef FILE_MIME_PARSER_HPP_SEEN
#define FILE_MIME_PARSER_HPP_SEEN
# include <string>
#include <map>
#include <vector>
enum class multipart_related_content_part_e {
JSON = 0,
NAS = 1,
NGAP = 2
};
static const std::vector<std::string> multipart_related_content_part_e2str = {
"JSON", "NAS", "NGAP" };
typedef struct mime_part {
std::string content_type;
std::string body;
} mime_part;
class mime_parser {
public:
/*
* Parse the input string into different Mime parts
* @param [const std::string &] str: input string
* @return void
*/
bool parse(const std::string &str);
/*
* Get vector of Mime parts
* @param [std::vector<mime_part> &] parts: store vector of Mime parts
* @return void
*/
void get_mime_parts(std::vector<mime_part> &parts) const;
/*
* Represent a string as hex
* @param [const std::string&] str: input string
* @return String represents string in hex format
*/
unsigned char* format_string_as_hex(const std::string &str);
/*
* Create HTTP body content for multipart/related message
* @param [std::string] body: Body of the created message
* @param [std::string] json_part: Json part of multipart/related msg
* @param [std::string] boundary: Boundary of multipart/related msg
* @param [std::string] n1_message: N1 (NAS) part
* @param [std::string] n2_message: N2 (NGAP) part
* @return void
*/
void create_multipart_related_content(std::string &body,
const std::string &json_part,
const std::string boundary,
const std::string &n1_message,
const std::string &n2_message,
std::string json_format="application/json");
/*
* Create HTTP body content for multipart/related message
* @param [std::string] body: Body of the created message
* @param [std::string] json_part: Json part of multipart/related msg
* @param [std::string] boundary: Boundary of multipart/related msg
* @param [std::string] message: N1 (NAS) or N2 (NGAP) part
* @param [uint8_t] content_type: 1 for NAS content, else NGAP content
* @return void
*/
void create_multipart_related_content(
std::string &body, const std::string &json_part,
const std::string boundary, const std::string &message,
const multipart_related_content_part_e content_type,
std::string json_format="application/json");
private:
std::vector<mime_part> mime_parts;
};
#endif /* FILE_MIME_PARSER_HPP_SEEN */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file pid_file.cpp
\brief
\author Lionel GAUTHIER
\date 2016
\email: lionel.gauthier@eurecom.fr
*/
#include "logger.hpp"
#include "pid_file.hpp"
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <libgen.h>
int g_fd_pid_file = -1;
__pid_t g_pid = -1;
//------------------------------------------------------------------------------
std::string util::get_exe_absolute_path(const std::string &basepath,
const unsigned int instance) {
#define MAX_FILE_PATH_LENGTH 255
char pid_file_name[MAX_FILE_PATH_LENGTH + 1] = { 0 };
char *exe_basename = NULL;
int rv = 0;
int num_chars = 0;
// get executable name
rv = readlink("/proc/self/exe", pid_file_name, 256);
if (-1 == rv) {
return NULL;
}
pid_file_name[rv] = 0;
exe_basename = basename(pid_file_name);
// Add 6 for the other 5 characters in the path + null terminator + 2 chars for instance.
num_chars = basepath.size() + strlen(exe_basename) + 6 + 2;
if (num_chars > MAX_FILE_PATH_LENGTH) {
num_chars = MAX_FILE_PATH_LENGTH;
}
snprintf(pid_file_name, num_chars, "%s/%s%02u.pid", basepath.c_str(),
exe_basename, instance);
return std::string(pid_file_name);
}
//------------------------------------------------------------------------------
int util::lockfile(int fd, int lock_type) {
// lock on fd only, not on file on disk (do not prevent another process from modifying the file)
return lockf(fd, F_TLOCK, 0);
}
//------------------------------------------------------------------------------
bool util::is_pid_file_lock_success(const char *pid_file_name) {
char pid_dec[64] = { 0 };
g_fd_pid_file = open(pid_file_name,
O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* Read/write by owner, read by grp, others */
if (0 > g_fd_pid_file) {
Logger::smf_app().error("open filename %s failed %d:%s\n", pid_file_name,
errno, strerror(errno));
return false;
}
if (0 > util::lockfile(g_fd_pid_file, F_TLOCK)) {
Logger::smf_app().error("lockfile filename %s failed %d:%s\n",
pid_file_name, errno, strerror(errno));
if ( EACCES == errno || EAGAIN == errno) {
close(g_fd_pid_file);
}
return false;
}
// fruncate file content
if (ftruncate(g_fd_pid_file, 0)) {
Logger::smf_app().error("truncate %s failed %d:%s\n", pid_file_name, errno,
strerror(errno));
close(g_fd_pid_file);
return false;
}
// write PID in file
g_pid = getpid();
snprintf(pid_dec, 64 /* should be big enough */, "%ld", (long) g_pid);
if ((ssize_t) -1 == write(g_fd_pid_file, pid_dec, strlen(pid_dec))) {
Logger::smf_app().error("write PID to filename %s failed %d:%s\n",
pid_file_name, errno, strerror(errno));
return false;
}
return true;
}
//------------------------------------------------------------------------------
void util::pid_file_unlock(void) {
util::lockfile(g_fd_pid_file, F_ULOCK);
close(g_fd_pid_file);
g_fd_pid_file = -1;
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file pid_file.hpp
\brief
\author Lionel GAUTHIER
\date 2016
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_PID_FILE_SEEN
#define FILE_PID_FILE_SEEN
#include <string>
namespace util {
/*
* Generate the exe absolute path using a specified base_path.
*
* @param base_path
* the root directory to use.
*
* @return a string for the exe absolute path.
*/
std::string get_exe_absolute_path(const std::string &base_path,
const unsigned int instance);
bool is_pid_file_lock_success(const char *pid_file_name);
void pid_file_unlock(void);
int lockfile(int fd, int lock_type);
}
#endif
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "string.hpp"
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <stdarg.h>
template<class T>
class Buffer {
public:
explicit Buffer(size_t size) {
msize = size;
mbuf = new T[msize];
}
~Buffer() {
if (mbuf)
delete[] mbuf;
}
T* get() {
return mbuf;
}
private:
Buffer();
size_t msize;
T *mbuf;
};
std::string util::string_format(const char *format, ...) {
va_list args;
va_start(args, format);
size_t size = vsnprintf( NULL, 0, format, args) + 1; // Extra space for '\0'
va_end(args);
Buffer<char> buf(size);
va_start(args, format);
vsnprintf(buf.get(), size, format, args);
va_end(args);
return std::string(buf.get(), size - 1); // We don't want the '\0' inside
}
// Licence : https://creativecommons.org/licenses/by-sa/4.0/legalcode
//https://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring#217605
// trim from start
std::string& util::ltrim(std::string &s) {
s.erase(
s.begin(),
std::find_if(s.begin(), s.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}
// trim from end
std::string& util::rtrim(std::string &s) {
s.erase(
std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(),
s.end());
return s;
}
// trim from both ends
std::string& util::trim(std::string &s) {
return util::ltrim(util::rtrim(s));
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file string.hpp
\brief
\author Lionel GAUTHIER
\date 2018
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_STRING_HPP_FILE_SEEN
#define FILE_STRING_HPP_FILE_SEEN
#include <string>
namespace util {
std::string string_format(const char *format, ...);
std::string& ltrim(std::string &s);
// trim from end
std::string& rtrim(std::string &s);
// trim from both ends
std::string& trim(std::string &s);
}
#endif
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file thread_sched.cpp
\brief
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#include "thread_sched.hpp"
//------------------------------------------------------------------------------
void util::thread_sched_params::apply(const int task_id,
_Logger &logger) const {
if (cpu_id >= 0) {
cpu_set_t cpuset;
CPU_SET(cpu_id, &cpuset);
if (int rc = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t),
&cpuset)) {
logger.warn("Could not set affinity to ITTI task %d, err=%d", task_id,
rc);
}
}
struct sched_param sparam;
memset(&sparam, 0, sizeof(sparam));
sparam.sched_priority = sched_priority;
if (int rc = pthread_setschedparam(pthread_self(), sched_policy, &sparam)) {
logger.warn("Could not set schedparam to ITTI task %d, err=%d", task_id,
rc);
}
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file thread_sched.hpp
\brief
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_THREAD_SCHED_HPP_SEEN
#define FILE_THREAD_SCHED_HPP_SEEN
#include <sched.h>
#include "logger.hpp"
namespace util {
class thread_sched_params {
public:
thread_sched_params()
:
cpu_id(0),
sched_policy(SCHED_FIFO),
sched_priority(84) {
}
int cpu_id;
int sched_policy;
int sched_priority;
void apply(const int task_id, _Logger &logger) const;
};
}
#endif /* FILE_THREAD_SCHED_HPP_SEEN */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file uint_uid_generator.hpp
\author Lionel GAUTHIER
\date 2019
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_UINT_GENERATOR_HPP_SEEN
#define FILE_UINT_GENERATOR_HPP_SEEN
#include <mutex>
#include <set>
namespace util {
template<class UINT> class uint_generator {
private:
UINT uid_generator;
std::mutex m_uid_generator;
std::set<UINT> uid_generated;
std::mutex m_uid_generated;
public:
uint_generator()
:
m_uid_generator(),
m_uid_generated() {
uid_generator = 0;
uid_generated = { };
}
;
uint_generator(uint_generator const&) = delete;
void operator=(uint_generator const&) = delete;
UINT get_uid() {
std::unique_lock<std::mutex> lr(m_uid_generator);
UINT uid = ++uid_generator;
while (true) {
// may happen race conditions here
std::unique_lock<std::mutex> ld(m_uid_generated);
if (uid_generated.count(uid) == 0) {
uid_generated.insert(uid);
ld.unlock();
lr.unlock();
return uid;
}
uid = ++uid_generator;
}
}
void free_uid(UINT uid) {
std::unique_lock<std::mutex> l(m_uid_generated);
uid_generated.erase(uid);
l.unlock();
}
};
template<class UINT> class uint_uid_generator {
private:
UINT uid_generator;
std::mutex m_uid_generator;
std::set<UINT> uid_generated;
std::mutex m_uid_generated;
uint_uid_generator()
:
m_uid_generator(),
m_uid_generated() {
uid_generator = 0;
uid_generated = { };
}
;
public:
static uint_uid_generator& get_instance() {
static uint_uid_generator instance;
return instance;
}
uint_uid_generator(uint_uid_generator const&) = delete;
void operator=(uint_uid_generator const&) = delete;
UINT get_uid() {
std::unique_lock<std::mutex> lr(m_uid_generator);
UINT uid = ++uid_generator;
while (true) {
// may happen race conditions here
std::unique_lock<std::mutex> ld(m_uid_generated);
if (uid_generated.count(uid) == 0) {
uid_generated.insert(uid);
lr.unlock();
ld.unlock();
return uid;
}
uid = ++uid_generator;
}
}
void free_uid(UINT uid) {
std::unique_lock<std::mutex> l(m_uid_generated);
uid_generated.erase(uid);
l.unlock();
}
};
}
#endif // FILE_UINT_GENERATOR_HPP_SEEN
################################################################################
# Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The OpenAirInterface Software Alliance licenses this file to You under
# the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
#
# 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.
#-------------------------------------------------------------------------------
# For more information about the OpenAirInterface (OAI) Software Alliance:
# contact@openairinterface.org
################################################################################
include_directories(${SRC_TOP_DIR}/../build/ext/spdlog/include)
include_directories(${SRC_TOP_DIR}/api-server/api)
include_directories(${SRC_TOP_DIR}/api-server/impl)
include_directories(${SRC_TOP_DIR}/api-server/model)
include_directories(${SRC_TOP_DIR}/api-server/)
add_library (NRF STATIC
nrf_config.cpp
)
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file smf_config.cpp
\brief
\author Lionel GAUTHIER, Tien-Thinh NGUYEN
\company Eurecom
\date 2019
\email: lionel.gauthier@eurecom.fr, tien-thinh.nguyen@eurecom.fr
*/
#include "nrf_config.hpp"
#include <cstdlib>
#include <iomanip>
#include <iostream>
//#include "string.hpp"
// C includes
#include <arpa/inet.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
using namespace std;
//using namespace libconfig;
using namespace nrf;
//extern smf_config smf_cfg;
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file smf_config.hpp
* \brief
\author Lionel GAUTHIER, Tien-Thinh NGUYEN
\company Eurecom
\date 2019
\email: lionel.gauthier@eurecom.fr, tien-thinh.nguyen@eurecom.fr
*/
#ifndef FILE_NRF_CONFIG_HPP_SEEN
#define FILE_NRF_CONFIG_HPP_SEEN
#include <arpa/inet.h>
#include <libconfig.h++>
#include <netinet/in.h>
#include <sys/socket.h>
#include <mutex>
#include <vector>
//#include "thread_sched.hpp"
namespace nrf {} // namespace nrf
#endif /* FILE_NRF_CONFIG_HPP_SEEN */
...@@ -262,8 +262,8 @@ else(STATIC_LINKING) ...@@ -262,8 +262,8 @@ else(STATIC_LINKING)
SET(BUILD_SHARED_LIBS ON) SET(BUILD_SHARED_LIBS ON)
endif(STATIC_LINKING) endif(STATIC_LINKING)
#ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/common ${CMAKE_CURRENT_BINARY_DIR}/common) ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/common ${CMAKE_CURRENT_BINARY_DIR}/common)
#ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/common/utils ${CMAKE_CURRENT_BINARY_DIR}/utils) ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/common/utils ${CMAKE_CURRENT_BINARY_DIR}/utils)
#ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/pfcp ${CMAKE_CURRENT_BINARY_DIR}/pfcp) #ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/pfcp ${CMAKE_CURRENT_BINARY_DIR}/pfcp)
#ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/udp ${CMAKE_CURRENT_BINARY_DIR}/udp) #ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/udp ${CMAKE_CURRENT_BINARY_DIR}/udp)
ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/api-server ${CMAKE_CURRENT_BINARY_DIR}/api-server) ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/api-server ${CMAKE_CURRENT_BINARY_DIR}/api-server)
...@@ -274,15 +274,12 @@ ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/api-server ${CMAKE_CURREN ...@@ -274,15 +274,12 @@ ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/api-server ${CMAKE_CURREN
################################################################################ ################################################################################
# Specific part for oai_nrf folder # Specific part for oai_nrf folder
add_definitions("-DPACKAGE_NAME=\"SMF\"") add_definitions("-DPACKAGE_NAME=\"NRF\"")
#include_directories(${SRC_TOP_DIR}/nrf_app) include_directories(${SRC_TOP_DIR}/nrf_app)
#include_directories(${SRC_TOP_DIR}/oai_nrf) include_directories(${SRC_TOP_DIR}/oai_nrf)
#include_directories(${SRC_TOP_DIR}/itti) include_directories(${SRC_TOP_DIR}/common)
#include_directories(${SRC_TOP_DIR}/common) include_directories(${SRC_TOP_DIR}/common/utils)
#include_directories(${SRC_TOP_DIR}/common/msg)
#include_directories(${SRC_TOP_DIR}/common/nas)
#include_directories(${SRC_TOP_DIR}/common/utils)
#include_directories(${SRC_TOP_DIR}/common/utils/bstr) #include_directories(${SRC_TOP_DIR}/common/utils/bstr)
#include_directories(${SRC_TOP_DIR}/pfcp) #include_directories(${SRC_TOP_DIR}/pfcp)
#include_directories(${SRC_TOP_DIR}/udp) #include_directories(${SRC_TOP_DIR}/udp)
...@@ -317,5 +314,5 @@ IF(STATIC_LINKING) ...@@ -317,5 +314,5 @@ IF(STATIC_LINKING)
ENDIF(STATIC_LINKING) ENDIF(STATIC_LINKING)
target_link_libraries (nrf ${ASAN} target_link_libraries (nrf ${ASAN}
-Wl,--start-group -lnettle ${NETTLE_LIBRARIES} ${CRYPTO_LIBRARIES} -lnghttp2_asio -lboost_system -lboost_thread -lssl -lcrypto gflags glog dl double-conversion folly -Wl,--end-group pthread m rt config++ event boost_system pistache curl) -Wl,--start-group NRF 3GPP_COMMON_TYPES CN_UTILS -lnettle ${NETTLE_LIBRARIES} ${CRYPTO_LIBRARIES} -lnghttp2_asio -lboost_system -lboost_thread -lssl -lcrypto gflags glog dl double-conversion folly -Wl,--end-group pthread m rt config++ event boost_system pistache curl)
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment