Commit 0d2d98f0 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

First version for HTTP2 support

parent bf70df85
......@@ -74,6 +74,7 @@ COPY --from=oai-amf-builder /usr/lib/x86_64-linux-gnu/librtmp.so.1 .
COPY --from=oai-amf-builder /usr/lib/x86_64-linux-gnu/libpsl.so.5 .
WORKDIR /usr/local/lib
COPY --from=oai-amf-builder /usr/local/lib/libnghttp2_asio.so.1 .
COPY --from=oai-amf-builder /usr/lib/libboost_system.so.1.67.0 .
COPY --from=oai-amf-builder /usr/lib/libboost_thread.so.1.67.0 .
COPY --from=oai-amf-builder /usr/lib/libboost_chrono.so.1.67.0 .
......
......@@ -94,6 +94,7 @@ COPY --from=oai-amf-builder /openair-amf/build/amf/build/amf oai_amf
COPY --from=oai-amf-builder /usr/lib64/libconfig++.so.9 /usr/lib64/
COPY --from=oai-amf-builder /usr/lib64/libboost_system.so.1.66.0 /usr/lib64/
COPY --from=oai-amf-builder /usr/local/lib64/libpistache.so.0 /usr/lib64/
COPY --from=oai-amf-builder /usr/local/lib/libnghttp2_asio.so /usr/lib64/
COPY --from=oai-amf-builder /usr/lib64/mysql/libmysqlclient.so.21 /usr/lib64/
COPY --from=oai-amf-builder /usr/lib64/libsctp.so.1 /usr/lib64/
COPY --from=oai-amf-builder /usr/local/lib64/libcpprest.so.2.10 /usr/lib64/
......
......@@ -95,6 +95,7 @@ COPY --from=oai-amf-builder /usr/lib/x86_64-linux-gnu/librtmp.so.1 .
COPY --from=oai-amf-builder /usr/lib/x86_64-linux-gnu/libpsl.so.5 .
WORKDIR /usr/local/lib
COPY --from=oai-amf-builder /usr/local/lib/libnghttp2_asio.so.1 .
COPY --from=oai-amf-builder /usr/lib/libboost_system.so.1.67.0 .
COPY --from=oai-amf-builder /usr/lib/libboost_thread.so.1.67.0 .
COPY --from=oai-amf-builder /usr/lib/libboost_chrono.so.1.67.0 .
......
......@@ -73,10 +73,11 @@ AMF =
IPV4_ADDRESS = "read";
PORT = 80; # YOUR NETWORK CONFIG HERE
API_VERSION = "v1"; # YOUR AMF API VERSION CONFIG HERE
HTTP2_PORT = 8080; # YOUR NETWORK CONFIG HERE
SMF_INSTANCES_POOL = (
{SMF_INSTANCE_ID = @SMF_INSTANCE_ID_0@; IPV4_ADDRESS = "@SMF_IPV4_ADDR_0@"; PORT = "80"; VERSION = "@SMF_HTTP_VERSION_0@"; FQDN = "@SMF_FQDN_0@", SELECTED = "true"}, # YOUR SMF CONFIG HERE
{SMF_INSTANCE_ID = @SMF_INSTANCE_ID_1@; IPV4_ADDRESS = "@SMF_IPV4_ADDR_1@"; PORT = "80"; VERSION = "@SMF_HTTP_VERSION_1@"; FQDN = "@SMF_FQDN_1@", SELECTED = "false"} # YOUR SMF CONFIG HERE
{SMF_INSTANCE_ID = @SMF_INSTANCE_ID_0@; IPV4_ADDRESS = "@SMF_IPV4_ADDR_0@"; PORT = "80"; HTTP2_PORT = 8080, VERSION = "@SMF_HTTP_VERSION_0@"; FQDN = "@SMF_FQDN_0@", SELECTED = "true"}, # YOUR SMF CONFIG HERE
{SMF_INSTANCE_ID = @SMF_INSTANCE_ID_1@; IPV4_ADDRESS = "@SMF_IPV4_ADDR_1@"; PORT = "80"; HTTP2_PORT = 8080, VERSION = "@SMF_HTTP_VERSION_1@"; FQDN = "@SMF_FQDN_1@", SELECTED = "false"} # YOUR SMF CONFIG HERE
);
};
......@@ -106,7 +107,8 @@ AMF =
EXTERNAL_AUSF = "@EXTERNAL_AUSF@"; # Set to yes if AMF works with an external AUSF
EXTERNAL_UDM = "@EXTERNAL_UDM@"; # Set to yes if AMF works with an external UDM
USE_FQDN_DNS = "@USE_FQDN_DNS@"; # Set to yes if AMF relies on a DNS to resolve NRF/SMF/UDM/AUSF's FQDN
}
USE_HTTP2 = "yes"; # Set to yes to enable HTTP2 for AMF server
}
AUTHENTICATION:
{
......
......@@ -34,7 +34,6 @@
#include <iostream>
#include <stdexcept>
//#include "3gpp_conversions.hpp"
#include "DLNASTransport.hpp"
#include "amf_config.hpp"
#include "amf_n1.hpp"
......@@ -43,14 +42,13 @@
#include "amf_statistics.hpp"
#include "itti.hpp"
#include "ngap_app.hpp"
#include "comUt.hpp"
using namespace ngap;
using namespace nas;
using namespace amf_application;
using namespace config;
extern void print_buffer(
const std::string app, const std::string commit, uint8_t* buf, int len);
extern amf_app* amf_app_inst;
extern itti_mw* itti_inst;
amf_n2* amf_n2_inst = nullptr;
......@@ -89,7 +87,7 @@ amf_app::amf_app(const amf_config& amf_cfg)
}
// Register to NRF
if (amf_cfg.enable_nf_registration) register_to_nrf();
if (amf_cfg.support_features.enable_nf_registration) register_to_nrf();
timer_id_t tid = itti_inst->timer_setup(
amf_cfg.statistics_interval, 0, TASK_AMF_APP,
......@@ -270,7 +268,7 @@ void amf_app::handle_itti_message(
uint8_t nas[BUFFER_SIZE_1024];
int encoded_size = dl->encode2buffer(nas, BUFFER_SIZE_1024);
print_buffer("amf_app", "n1n2 transfer", nas, encoded_size);
comUt::print_buffer("amf_app", "n1n2 transfer", nas, encoded_size);
bstring dl_nas = blk2bstr(nas, encoded_size);
itti_downlink_nas_transfer* dl_msg =
......
......@@ -38,16 +38,11 @@
#include "amf_profile.hpp"
#include "itti.hpp"
#include "itti_msg_amf_app.hpp"
#include "itti_msg_sbi.hpp"
#include "ue_context.hpp"
#include "amf_subscription.hpp"
#include "ProblemDetails.h"
#include "uint_generator.hpp"
#include "itti_msg_sbi.hpp"
#include "amf_msg.hpp"
#include "uint_generator.hpp"
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include "ProblemDetails.h"
#include "uint_generator.hpp"
#include <boost/thread.hpp>
......@@ -270,7 +265,6 @@ class amf_app {
void trigger_process_response(uint32_t pid, std::string n2_sm);
private:
// context management
std::map<long, std::shared_ptr<ue_context>> amf_ue_ngap_id2ue_ctx;
mutable std::shared_mutex m_amf_ue_ngap_id2ue_ctx;
std::map<std::string, std::shared_ptr<ue_context>> ue_ctx_key;
......
This diff is collapsed.
......@@ -51,6 +51,7 @@
#define AMF_CONFIG_STRING_IPV4_ADDRESS "IPV4_ADDRESS"
#define AMF_CONFIG_STRING_PORT "PORT"
#define AMF_CONFIG_STRING_PPID "PPID"
#define AMF_CONFIG_STRING_SBI_HTTP2_PORT "HTTP2_PORT"
#define AMF_CONFIG_STRING_INTERFACE_N11 "N11"
#define AMF_CONFIG_STRING_SMF_INSTANCES_POOL "SMF_INSTANCES_POOL"
......@@ -105,6 +106,8 @@
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_EXTERNAL_AUSF "EXTERNAL_AUSF"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_EXTERNAL_UDM "EXTERNAL_UDM"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_USE_FQDN_DNS "USE_FQDN_DNS"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_USE_HTTP2 "USE_HTTP2"
#define AMF_CONFIG_STRING_FQDN_DNS "FQDN"
using namespace libconfig;
......@@ -166,6 +169,7 @@ typedef struct {
int id;
std::string ipv4;
std::string port;
uint32_t http2_port;
std::string version;
bool selected;
std::string fqdn;
......@@ -185,6 +189,8 @@ class amf_config {
interface_cfg_t n11;
itti_cfg_t itti;
std::string sbi_api_version;
unsigned int sbi_http2_port;
unsigned int statistics_interval;
std::string AMF_Name;
guami_t guami;
......@@ -195,11 +201,15 @@ class amf_config {
auth_conf auth_para;
nas_conf_t nas_cfg;
std::vector<smf_inst_t> smf_pool;
struct {
bool enable_nf_registration;
bool enable_smf_selection;
bool enable_external_ausf;
bool enable_external_udm;
bool use_fqdn_dns;
bool use_http2;
} support_features;
struct {
struct in_addr ipv4_addr;
......
This diff is collapsed.
This diff is collapsed.
......@@ -70,11 +70,11 @@ class amf_n11 {
void curl_http_client(
std::string remoteUri, std::string jsonData, std::string n1SmMsg,
std::string n2SmMsg, std::string supi, uint8_t pdu_session_id,
uint32_t promise_id = 0);
uint8_t http_version = 1, uint32_t promise_id = 0);
void curl_http_client(
std::string remoteUri, std::string Method, std::string msgBody,
std::string& response);
std::string& response, uint8_t http_version = 1);
bool discover_smf(
std::string& smf_addr, std::string& smf_api_version,
......
......@@ -20,6 +20,8 @@
################################################################################
include_directories(${SRC_TOP_DIR}/common)
include_directories(${SRC_TOP_DIR}/utils/)
include_directories(${SRC_TOP_DIR}/utils/bstr)
include_directories(${SRC_TOP_DIR}/../build/ext/spdlog/include)
include_directories(${SRC_TOP_DIR}/common/unicode)
file(GLOB COMMON_SRC ${SRC_TOP_DIR}/common/conversions.cpp)
......@@ -27,4 +29,5 @@ file(GLOB COMMON_SRC ${SRC_TOP_DIR}/common/conversions.cpp)
add_library(3GPP_COMMON_TYPES STATIC
${SRC_TOP_DIR}/common/logger.cpp
${SRC_TOP_DIR}/common/conversions.cpp
${SRC_TOP_DIR}/common/comUt.cpp
)
......@@ -57,4 +57,7 @@ constexpr uint64_t SECONDS_SINCE_FIRST_EPOCH = 2208988800;
#define UE_AGGREGATE_MAXIMUM_BIT_RATE_DL 300000000
#define UE_AGGREGATE_MAXIMUM_BIT_RATE_UL 200000000
#define NAMF_COMMUNICATION_BASE "/namf-comm/"
#define NAMF_COMMUNICATION_N1N2_MESSAGE_TRANSFER_URL \
"/ue-contexts/{}/n1-n2-messages" // context id
#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 comUt.cpp
\brief
\author Keliang DU, BUPT
\date 2020
\email: contact@openairinterface.org
*/
#include "comUt.hpp"
#include "logger.hpp"
//------------------------------------------------------------------------------
void comUt::print_buffer(
const std::string app, const std::string commit, uint8_t* buf, int len) {
if (!app.compare("amf_app")) Logger::amf_app().debug(commit.c_str());
if (!app.compare("amf_n1")) Logger::amf_n1().debug(commit.c_str());
if (!app.compare("amf_server")) Logger::amf_server().debug(commit.c_str());
if (!app.compare("amf_n11")) Logger::amf_n11().debug(commit.c_str());
#if DEBUG_IS_ON
for (int i = 0; i < len; i++) printf("%x ", buf[i]);
printf("\n");
#endif
}
//------------------------------------------------------------------------------
void comUt::hexStr2Byte(const char* src, unsigned char* dest, int len) {
short i;
unsigned char hBy, lBy;
for (i = 0; i < len; i += 2) {
hBy = toupper(src[i]);
lBy = toupper(src[i + 1]);
if (hBy > 0x39)
hBy -= 0x37;
else
hBy -= 0x30;
if (lBy > 0x39)
lBy -= 0x37;
else
lBy -= 0x30;
dest[i / 2] = (hBy << 4) | lBy;
}
}
......@@ -33,36 +33,11 @@
#include "logger.hpp"
//------------------------------------------------------------------------------
void print_buffer(
const std::string app, const std::string commit, uint8_t* buf, int len) {
if (!app.compare("amf_app")) Logger::amf_app().debug(commit.c_str());
if (!app.compare("amf_n1")) Logger::amf_n1().debug(commit.c_str());
if (!app.compare("amf_server")) Logger::amf_server().debug(commit.c_str());
if (!app.compare("amf_n11")) Logger::amf_n11().debug(commit.c_str());
#if DEBUG_IS_ON
for (int i = 0; i < len; i++) printf("%x ", buf[i]);
printf("\n");
#endif
}
//------------------------------------------------------------------------------
void hexStr2Byte(const char* src, unsigned char* dest, int len) {
short i;
unsigned char hBy, lBy;
for (i = 0; i < len; i += 2) {
hBy = toupper(src[i]);
lBy = toupper(src[i + 1]);
if (hBy > 0x39)
hBy -= 0x37;
else
hBy -= 0x30;
if (lBy > 0x39)
lBy -= 0x37;
else
lBy -= 0x30;
dest[i / 2] = (hBy << 4) | lBy;
}
}
class comUt {
public:
static void print_buffer(
const std::string app, const std::string commit, uint8_t* buf, int len);
static void hexStr2Byte(const char* src, unsigned char* dest, int len);
};
#endif
......@@ -153,3 +153,87 @@ std::string conv::toString(const struct in6_addr& in6addr) {
}
return s;
}
//------------------------------------------------------------------------------
void conv::convert_string_2_hex(
std::string& input_str, std::string& output_str) {
unsigned char* data = (unsigned char*) malloc(input_str.length() + 1);
memset(data, 0, input_str.length() + 1);
memcpy((void*) data, (void*) input_str.c_str(), input_str.length());
for (int i = 0; i < input_str.length(); i++) {
printf("%02x ", data[i]);
}
printf("\n");
char* datahex = (char*) malloc(input_str.length() * 2 + 1);
memset(datahex, 0, input_str.length() * 2 + 1);
for (int i = 0; i < input_str.length(); i++)
sprintf(datahex + i * 2, "%02x", data[i]);
output_str = reinterpret_cast<char*>(datahex);
}
//------------------------------------------------------------------------------
unsigned char* conv::format_string_as_hex(std::string str) {
unsigned int str_len = str.length();
unsigned char* datavalue = (unsigned char*) malloc(str_len / 2 + 1);
unsigned char* data = (unsigned char*) malloc(str_len + 1);
memset(data, 0, str_len + 1);
memcpy((void*) data, (void*) str.c_str(), str_len);
std::cout << "Data: " << data << " (" << str_len << " bytes)" << std::endl;
std::cout << "Data (formatted): \n";
for (int i = 0; i < str_len; i++) {
char datatmp[3] = {0};
memcpy(datatmp, &data[i], 2);
// Ensure both characters are hexadecimal
bool bBothDigits = true;
for (int j = 0; j < 2; ++j) {
if (!isxdigit(datatmp[j])) bBothDigits = false;
}
if (!bBothDigits) break;
// Convert two hexadecimal characters into one character
unsigned int nAsciiCharacter;
sscanf(datatmp, "%x", &nAsciiCharacter);
printf("%x ", nAsciiCharacter);
// Concatenate this character onto the output
datavalue[i / 2] = (unsigned char) nAsciiCharacter;
// Skip the next character
i++;
}
printf("\n");
free_wrapper((void**) &data);
return datavalue;
}
//------------------------------------------------------------------------------
char* conv::bstring2charString(bstring b) {
char* buf = (char*) calloc(1, blength(b) + 1);
uint8_t* value = (uint8_t*) bdata(b);
for (int i = 0; i < blength(b); i++) buf[i] = (char) value[i];
buf[blength(b)] = '\0';
free_wrapper((void**) &value);
return buf;
}
//------------------------------------------------------------------------------
void conv::msg_str_2_msg_hex(std::string msg, bstring& b) {
std::string msg_hex_str;
convert_string_2_hex(msg, msg_hex_str);
printf("tmp string: %s\n", msg_hex_str.c_str());
unsigned int msg_len = msg_hex_str.length();
char* data = (char*) malloc(msg_len + 1);
memset(data, 0, msg_len + 1);
memcpy((void*) data, (void*) msg_hex_str.c_str(), msg_len);
printf("data: %s\n", data);
uint8_t* msg_hex = (uint8_t*) malloc(msg_len / 2 + 1);
conv::ascii_to_hex(msg_hex, (const char*) data);
b = blk2bstr(msg_hex, (msg_len / 2));
}
......@@ -33,6 +33,14 @@
#include <string>
#include <iostream>
#include "bstrlib.h"
extern "C" {
#include "dynamic_memory_check.h"
}
/* Used to format an uint32_t containing an ipv4 address */
#define IN_ADDR_FMT "%u.%u.%u.%u"
#define PRI_IN_ADDR(aDDRESS) \
......@@ -55,5 +63,11 @@ class conv {
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);
static void msg_str_2_msg_hex(std::string msg, bstring& b);
static char* bstring2charString(bstring b);
static unsigned char* format_string_as_hex(std::string str);
static void convert_string_2_hex(
std::string& input_str, std::string& output_str);
};
#endif /* FILE_CONVERSIONS_HPP_SEEN */
......@@ -355,4 +355,4 @@ IF(STATIC_LINKING)
ENDIF(STATIC_LINKING)
target_link_libraries(amf ${ASAN}
-Wl,--start-group 3GPP_COMMON_TYPES AMF CONTEXTS AMF_SCTP AMF_SECU_5GAKA AMF_SECU_NAS AMF_UTILS AMF_SBI_CLIENT AMF_SBI_SERVER config++ sctp pthread ${NETTLE_LIBRARIES} ${MySQL_LIBRARY} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} boost_system boost_thread boost_chrono ssl crypt cpprest gmp pistache curl)
-Wl,--start-group 3GPP_COMMON_TYPES AMF CONTEXTS AMF_SCTP AMF_SECU_5GAKA AMF_SECU_NAS AMF_UTILS AMF_SBI_CLIENT AMF_SBI_SERVER config++ sctp pthread ${NETTLE_LIBRARIES} ${MySQL_LIBRARY} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} nghttp2_asio boost_system boost_thread boost_chrono ssl crypt cpprest gmp pistache curl)
......@@ -30,6 +30,7 @@
#include <thread>
#include "AMFApiServer.hpp"
#include "amf-http2-server.hpp"
#include "amf_app.hpp"
#include "amf_config.hpp"
#include "amf_module_from_config.hpp"
......@@ -43,11 +44,6 @@
#include "pistache/http.h"
#include "pistache/router.h"
extern void hexStr2Byte(const char* src, unsigned char* dest, int len);
extern void print_buffer(
const std::string app, const std::string commit, uint8_t* buf, int len);
extern void ue_gnb_simulator();
using namespace config;
using namespace amf_application;
......@@ -57,6 +53,38 @@ itti_mw* itti_inst = nullptr;
amf_app* amf_app_inst = nullptr;
statistics stacs;
AMFApiServer* amf_api_server_1 = nullptr;
amf_http2_server* amf_api_server_2 = nullptr;
//------------------------------------------------------------------------------
void my_app_signal_handler(int s) {
std::cout << "Caught signal " << s << std::endl;
Logger::system().startup("exiting");
itti_inst->send_terminate_msg(TASK_AMF_APP);
itti_inst->wait_tasks_end();
std::cout << "Freeing Allocated memory..." << std::endl;
if (amf_api_server_1) {
amf_api_server_1->shutdown();
delete amf_api_server_1;
amf_api_server_1 = nullptr;
}
if (amf_api_server_2) {
amf_api_server_2->stop();
delete amf_api_server_2;
amf_api_server_2 = nullptr;
}
std::cout << "AMF API Server memory done." << std::endl;
if (itti_inst) delete itti_inst;
itti_inst = nullptr;
std::cout << "ITTI memory done." << std::endl;
if (amf_app_inst) delete amf_app_inst;
amf_app_inst = nullptr;
std::cout << "AMF APP memory done." << std::endl;
std::cout << "Freeing Allocated memory done" << std::endl;
exit(0);
}
//------------------------------------------------------------------------------
int main(int argc, char** argv) {
srand(time(NULL));
......@@ -69,6 +97,12 @@ int main(int argc, char** argv) {
Logger::init("AMF", Options::getlogStdout(), Options::getlogRotFilelog());
Logger::amf_app().startup("Options parsed!");
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = my_app_signal_handler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
amf_cfg.load(Options::getlibconfigConfig());
amf_cfg.display();
modules.load(Options::getlibconfigConfig());
......@@ -81,14 +115,24 @@ int main(int argc, char** argv) {
amf_app_inst->allRegistredModulesInit(modules);
Logger::amf_app().debug("Initiating AMF server endpoints");
// AMF HTTP1 server
Pistache::Address addr(
std::string(inet_ntoa(*((struct in_addr*) &amf_cfg.n11.addr4))),
Pistache::Port(amf_cfg.n11.port));
AMFApiServer amfApiServer(addr, amf_app_inst);
amfApiServer.init(2);
std::thread amf_api_manager(&AMFApiServer::start, amfApiServer);
amf_api_server_1 = new AMFApiServer(addr, amf_app_inst);
amf_api_server_1->init(2);
std::thread amf_http1_manager(&AMFApiServer::start, amf_api_server_1);
// AMF HTTP2 server
amf_api_server_2 = new amf_http2_server(
conv::toString(amf_cfg.n11.addr4), amf_cfg.sbi_http2_port, amf_app_inst);
amf_api_server_2->init(1);
std::thread amf_http2_manager(&amf_http2_server::start, amf_api_server_2);
// amf_http1_manager.join();
// amf_http2_manager.join();
Logger::amf_app().debug("Initiating Done!");
Logger::amf_app().debug("Initiation Done!");
pause();
return 0;
}
......@@ -41,6 +41,7 @@ include_directories(${SRC_TOP_DIR}/sbi/amf_server/impl)
include_directories(${SRC_TOP_DIR}/sbi/amf_server/model)
file(GLOB AMF_API_SERVER_src_files
${AMF_API_SERVER_DIR}/amf-http2-server.cpp
${AMF_API_SERVER_DIR}/AMFApiServer.cpp
${AMF_API_SERVER_DIR}/model/*.cpp
${AMF_API_SERVER_DIR}/api/*.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 amf_http2-server.cpp
\brief
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2021
\email: tien-thinh.nguyen@eurecom.fr
*/
#include "amf-http2-server.hpp"
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include <nlohmann/json.hpp>
#include "conversions.hpp"
#include "amf.hpp"
#include "amf_config.hpp"
#include "3gpp_29.500.h"
#include "logger.hpp"
#include "mime_parser.hpp"
using namespace nghttp2::asio_http2;
using namespace nghttp2::asio_http2::server;
using namespace oai::amf::model;
extern config::amf_config amf_cfg;
extern itti_mw* itti_inst;
//------------------------------------------------------------------------------
void amf_http2_server::start() {
boost::system::error_code ec;
Logger::amf_server().info("HTTP2 server started");
// n1_n2_message_transfer request
server.handle(
NAMF_COMMUNICATION_BASE + amf_cfg.sbi_api_version +
NAMF_COMMUNICATION_N1N2_MESSAGE_TRANSFER_URL,
[&](const request& request, const response& res) {
request.on_data([&](const uint8_t* data, std::size_t len) {
if (len > 0) {
std::string msg((char*) data, len);
Logger::amf_server().debug("");
Logger::amf_server().info("Received N1N2MessageTransfer Request");
Logger::amf_server().debug("Message content \n %s", msg.c_str());
// Get the ueContextId and method
std::vector<std::string> split_result;
boost::split(
split_result, request.uri().path, boost::is_any_of("/"));
if (split_result.size() != 6) {
Logger::amf_server().warn("Requested URL is not implemented");
res.write_head(static_cast<uint32_t>(
http_response_codes_e::
HTTP_RESPONSE_CODE_NOT_IMPLEMENTED)); // TODO
res.end();
return;
}
std::string ue_context_id = split_result[split_result.size() - 2];
Logger::amf_server().info(
"ue_context_id %s", ue_context_id.c_str());
// simple parser
mime_parser sp = {};
if (!sp.parse(msg)) {
// send reply!!!
res.write_head(static_cast<uint32_t>(
http_response_codes_e::HTTP_RESPONSE_CODE_BAD_REQUEST));
res.end();
return;
}
std::vector<mime_part> parts = {};
sp.get_mime_parts(parts);
uint8_t size = parts.size();
Logger::amf_server().debug("Number of MIME parts %d", size);
// at least 2 parts for Json data and N1 (+ N2)
if (size < 2) {
res.write_head(static_cast<uint32_t>(
http_response_codes_e::HTTP_RESPONSE_CODE_BAD_REQUEST));
res.end();
Logger::amf_server().debug(
"Bad request: should have at least 2 MIME parts");
return;
}
Logger::amf_server().debug(
"Request body, part 1: \n%s", parts[0].body.c_str());
Logger::amf_server().debug(
"Request body, part 2: \n %s", parts[1].body.c_str());
bool is_ngap = false;
if (size > 2) {
is_ngap = true;
Logger::amf_server().debug(
"Request body, part 3: \n %s", parts[2].body.c_str());
}
N1N2MessageTransferReqData n1N2MessageTransferReqData = {};
try {
nlohmann::json::parse(parts[0].body.c_str())
.get_to(n1N2MessageTransferReqData);
if (!is_ngap)
this->n1_n2_message_transfer_handler(
ue_context_id, n1N2MessageTransferReqData, parts[1].body,
res);
else
this->n1_n2_message_transfer_handler(
ue_context_id, n1N2MessageTransferReqData, parts[1].body,
res, parts[2].body);
} catch (nlohmann::detail::exception& e) {
Logger::amf_server().warn(
"Can not parse the json data (error: %s)!", e.what());
res.write_head(static_cast<uint32_t>(
http_response_codes_e::HTTP_RESPONSE_CODE_BAD_REQUEST));
res.end();
return;
} catch (std::exception& e) {
Logger::amf_server().warn("Error: %s!", e.what());
res.write_head(static_cast<uint32_t>(
http_response_codes_e::
HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR));
res.end();
return;
}
}
});
});
if (server.listen_and_serve(ec, m_address, std::to_string(m_port))) {
std::cerr << "HTTP Server error: " << ec.message() << std::endl;
}
}
//------------------------------------------------------------------------------
void amf_http2_server::n1_n2_message_transfer_handler(
const std::string& ueContextId,
const N1N2MessageTransferReqData& n1N2MessageTransferReqData,
const std::string& n1sm_str, const response& res,
const std::string& n2sm_str) {
Logger::amf_server().debug(
"Receive N1N2MessageTransfer Request, handling...");
nlohmann::json response_json = {};
response_json["cause"] =
n1_n2_message_transfer_cause_e2str[N1_N2_TRANSFER_INITIATED];
uint32_t code =
static_cast<uint32_t>(http_response_codes_e::HTTP_RESPONSE_CODE_200_OK);
std::string supi = ueContextId;
Logger::amf_server().debug(
"Key for PDU Session context: SUPI (%s)", supi.c_str());
std::shared_ptr<pdu_session_context> psc = {};
if (!m_amf_app->find_pdu_session_context(
supi, (uint8_t) n1N2MessageTransferReqData.getPduSessionId(), psc)) {
Logger::amf_server().error(
"Cannot get pdu_session_context with SUPI (%s)", supi.c_str());
// Send response to the NF Service Consumer (e.g., SMF)
res.write_head(static_cast<uint32_t>(
http_response_codes_e::HTTP_RESPONSE_CODE_BAD_REQUEST));
res.end();
return;
}
bstring n1sm;
conv::msg_str_2_msg_hex(
n1sm_str.substr(0, n1sm_str.length()), n1sm); // TODO: verify n1sm_length
bstring n2sm;
Logger::amf_server().debug(
"n2sm size in amf_server(%d)", blength(psc.get()->n2sm));
if (!n2sm_str.empty()) {
conv::msg_str_2_msg_hex(n2sm_str, n2sm);
psc.get()->n2sm = n2sm;
psc.get()->isn2sm_avaliable = true;
} else {
psc.get()->isn2sm_avaliable = false;
}
psc.get()->n1sm = n1sm;
psc.get()->isn1sm_avaliable = true;
itti_n1n2_message_transfer_request* itti_msg =
new itti_n1n2_message_transfer_request(AMF_SERVER, TASK_AMF_APP);
itti_msg->supi = ueContextId;
itti_msg->n1sm = n1sm;
itti_msg->is_n1sm_set = true;
if (!n2sm_str.empty()) {
itti_msg->n2sm = n2sm;
itti_msg->is_n2sm_set = true;
} else {
itti_msg->is_n2sm_set = false;
}
itti_msg->pdu_session_id =
(uint8_t) n1N2MessageTransferReqData.getPduSessionId();
// For Paging
if (n1N2MessageTransferReqData.ppiIsSet()) {
itti_msg->is_ppi_set = true;
itti_msg->ppi = n1N2MessageTransferReqData.getPpi();
response_json["cause"] =
n1_n2_message_transfer_cause_e2str[ATTEMPTING_TO_REACH_UE];
code = static_cast<uint32_t>(
http_response_codes_e::HTTP_RESPONSE_CODE_202_ACCEPTED);
} else {
itti_msg->is_ppi_set = false;
}
// Send response to the NF Service Consumer (e.g., SMF)
res.write_head(code);
res.end(response_json.dump().c_str());
// Process N1N2 Message Transfer Request
std::shared_ptr<itti_n1n2_message_transfer_request> i =
std::shared_ptr<itti_n1n2_message_transfer_request>(itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_server().error(
"Could not send ITTI message %s to task TASK_AMF_N2",
i->get_msg_name());
}
}
//------------------------------------------------------------------------------
void amf_http2_server::stop() {
server.stop();
}
/*
* 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 amf_http2-server.h
\brief
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2021
\email: tien-thinh.nguyen@eurecom.fr
*/
#ifndef FILE_AMF_HTTP2_SERVER_SEEN
#define FILE_AMF_HTTP2_SERVER_SEEN
#include "amf_app.hpp"
#include <nghttp2/asio_http2_server.h>
#include "pistache/endpoint.h"
#include "pistache/http.h"
#include "pistache/router.h"
#include "uint_generator.hpp"
#include "amf.hpp"
#include "N1N2MessageTransferError.h"
#include "N1N2MessageTransferReqData.h"
#include "N1N2MessageTransferRspData.h"
using namespace nghttp2::asio_http2;
using namespace nghttp2::asio_http2::server;
using namespace oai::amf::model;
class amf_http2_server {
public:
amf_http2_server(
std::string addr, uint32_t port, amf_application::amf_app* amf_app_inst)
: m_address(addr), m_port(port), server(), m_amf_app(amf_app_inst) {}
virtual ~amf_http2_server(){};
void start();
void init(size_t thr) {}
void n1_n2_message_transfer_handler(
const std::string& ueContextId,
const N1N2MessageTransferReqData& n1N2MessageTransferReqData,
const std::string& n1sm_str, const response& res,
const std::string& n2sm_str = "");
void stop();
private:
util::uint_generator<uint32_t> m_promise_id_generator;
std::string m_address;
uint32_t m_port;
http2 server;
amf_application::amf_app* m_amf_app;
protected:
static uint64_t generate_promise_id() {
return util::uint_uid_generator<uint64_t>::get_instance().get_uid();
}
};
#endif
......@@ -17,14 +17,13 @@
#include "amf_app.hpp"
#include "amf_n11.hpp"
#include "pdu_session_context.hpp"
#include "conversions.hpp"
#include "comUt.hpp"
using namespace amf_application;
extern void msg_str_2_msg_hex(std::string msg, bstring& b);
extern void convert_string_2_hex(std::string& input, std::string& output);
extern itti_mw* itti_inst;
extern amf_app* amf_app_inst;
extern void print_buffer(
const std::string app, const std::string commit, uint8_t* buf, int len);
namespace oai {
namespace amf {
......@@ -56,8 +55,8 @@ void N1N2MessageCollectionDocumentApiImpl::n1_n2_message_transfer(
"Receive N1N2MessageTransfer Request, handling...");
bstring n1sm;
msg_str_2_msg_hex(n1sm_str, n1sm);
print_buffer(
conv::msg_str_2_msg_hex(n1sm_str, n1sm);
comUt::print_buffer(
"amf_server", "Received N1 SM", (uint8_t*) bdata(n1sm), blength(n1sm));
response.send(
Pistache::Http::Code::Ok,
......@@ -90,11 +89,11 @@ void N1N2MessageCollectionDocumentApiImpl::n1_n2_message_transfer(
}
bstring n1sm;
msg_str_2_msg_hex(
conv::msg_str_2_msg_hex(
n1sm_str.substr(0, n1sm_str.length()), n1sm); // TODO: verify n1sm_length
bstring n2sm;
msg_str_2_msg_hex(n2sm_str, n2sm);
conv::msg_str_2_msg_hex(n2sm_str, n2sm);
psc.get()->n1sm = n1sm;
psc.get()->isn1sm_avaliable = true;
......
......@@ -13,8 +13,8 @@
#include "SubscriptionsCollectionDocumentApiImplEventExposure.h"
#include "amf_msg.hpp"
#include "3gpp_conversions.hpp"
#include "amf_config.hpp"
#include "3gpp_conversions.hpp"
extern amf_config amf_cfg;
......
......@@ -31,10 +31,8 @@
#include "OCTET_STRING.h"
#include "logger.hpp"
#include "comUt.hpp"
extern void print_buffer(
const std::string app, const std::string commit, uint8_t* buf, int len);
extern void hexStr2Byte(const char* src, unsigned char* dest, int len);
/************ algorithm f1 **************/
/*
Computes network authentication code MAC-A from key K, random, challenge RAND,
......@@ -306,17 +304,18 @@ void Authentication_5gaka::derive_kseaf(
OCTET_STRING_t netName;
OCTET_STRING_fromBuf(
&netName, serving_network.c_str(), serving_network.length());
// print_buffer("amf_n1", "inputstring: snn(hex)", netName.buf, netName.size);
// comUt::print_buffer("amf_n1", "inputstring: snn(hex)", netName.buf,
// netName.size);
uint8_t S[100];
S[0] = 0x6C; // FC
memcpy(&S[1], netName.buf, netName.size);
// memcpy (&S[1+netName.size], &netName.size, 2);
S[1 + netName.size] = (uint8_t)((netName.size & 0xff00) >> 8);
S[2 + netName.size] = (uint8_t)(netName.size & 0x00ff);
// print_buffer("amf_n1", "inputstring S", S, 3+netName.size);
// print_buffer("amf_n1", "key KEY", kausf, 32);
// comUt::print_buffer("amf_n1", "inputstring S", S, 3+netName.size);
// comUt::print_buffer("amf_n1", "key KEY", kausf, 32);
kdf(kausf, 32, S, 3 + netName.size, kseaf, 32);
// print_buffer("amf_n1", "KDF out: Kseaf", kseaf, 32);
// comUt::print_buffer("amf_n1", "KDF out: Kseaf", kseaf, 32);
// Logger::amf_n1().debug("derive kseaf finished!");
}
......@@ -328,7 +327,8 @@ void Authentication_5gaka::derive_kausf(
OCTET_STRING_t netName;
OCTET_STRING_fromBuf(
&netName, serving_network.c_str(), serving_network.length());
// print_buffer("amf_n1", "inputstring: snn(hex)", netName.buf, netName.size);
// comUt::print_buffer("amf_n1", "inputstring: snn(hex)", netName.buf,
// netName.size);
uint8_t S[100];
uint8_t key[32];
memcpy(&key[0], ck, 16);
......@@ -343,10 +343,10 @@ void Authentication_5gaka::derive_kausf(
}
S[9 + netName.size] = 0x00;
S[10 + netName.size] = 0x06;
// print_buffer("amf_n1", "inputstring S", S, 11+netName.size);
// print_buffer("amf_n1", "key KEY", key, 32);
// comUt::print_buffer("amf_n1", "inputstring S", S, 11+netName.size);
// comUt::print_buffer("amf_n1", "key KEY", key, 32);
kdf(key, 32, S, 11 + netName.size, kausf, 32);
// print_buffer("amf_n1", "KDF out: Kausf", kausf, 32);
// comUt::print_buffer("amf_n1", "KDF out: Kausf", kausf, 32);
// Logger::amf_n1().debug("derive kausf finished!");
}
......@@ -362,7 +362,7 @@ void Authentication_5gaka::derive_kamf(
OCTET_STRING_fromBuf(&supi, ueSupi.c_str(), ueSupi.length());
// uint8_t supi[8] = {0x64, 0xf0, 0x11, 0x10, 0x32, 0x54, 0x76, 0x98};
int supiLen = supi.size;
// print_buffer("amf_n1", "inputstring: supi(hex)", supi.buf, supiLen);
// comUt::print_buffer("amf_n1", "inputstring: supi(hex)", supi.buf, supiLen);
uint8_t S[100];
S[0] = 0x6D; // FC = 0x6D
memcpy(&S[1], supi.buf, supiLen);
......@@ -373,10 +373,10 @@ void Authentication_5gaka::derive_kamf(
S[4 + supiLen] = (abba & 0xff00) >> 8;
S[5 + supiLen] = 0x00;
S[6 + supiLen] = 0x02;
// print_buffer("amf_n1", "inputstring S", S, 7+supiLen);
// print_buffer("amf_n1", "key KEY", kseaf, 32);
// comUt::print_buffer("amf_n1", "inputstring S", S, 7+supiLen);
// comUt::print_buffer("amf_n1", "key KEY", kseaf, 32);
kdf(kseaf, 32, S, 7 + supiLen, kamf, 32);
// print_buffer("amf_n1", "KDF out: Kamf", kamf, 32);
// comUt::print_buffer("amf_n1", "KDF out: Kamf", kamf, 32);
// Logger::amf_n1().debug("derive kamf finished!");
}
......@@ -393,12 +393,12 @@ void Authentication_5gaka::derive_knas(
S[4] = nas_alg_id;
S[5] = 0x00;
S[6] = 0x01;
// print_buffer("amf_n1", "inputstring S", S, 7);
// print_buffer("amf_n1", "key KEY", kamf, 32);
// comUt::print_buffer("amf_n1", "inputstring S", S, 7);
// comUt::print_buffer("amf_n1", "key KEY", kamf, 32);
kdf(kamf, 32, S, 7, out, 32);
// memcpy (knas, &out[31 - 16 + 1], 16);
for (int i = 0; i < 16; i++) knas[i] = out[16 + i];
// print_buffer("amf_n1", "knas", knas, 16);
// comUt::print_buffer("amf_n1", "knas", knas, 16);
// Logger::amf_n1().debug("derive knas finished!");
}
......@@ -413,10 +413,10 @@ void Authentication_5gaka::derive_kgnb(
S[7] = accessType;
S[8] = 0x00;
S[9] = 0x01;
// print_buffer("amf_n1", "inputstring S", S, 10);
// print_buffer("amf_n1", "key KEY", kamf, 32);
// comUt::print_buffer("amf_n1", "inputstring S", S, 10);
// comUt::print_buffer("amf_n1", "key KEY", kamf, 32);
kdf(kamf, 32, S, 10, kgnb, 32);
// print_buffer("amf_n1", "kgnb", kgnb, 32);
// comUt::print_buffer("amf_n1", "kgnb", kgnb, 32);
// Logger::amf_n1().debug("derive kgnb finished!");
}
void Authentication_5gaka::handover_ncc_derive_knh(
......@@ -446,8 +446,8 @@ void Authentication_5gaka::handover_ncc_derive_knh(
SS[i][34] = 0x20;
kdf(kamf, 32, SS[i], 35, knh, 32);
}
print_buffer("amf_n1", "SS", SS[i], 35);
print_buffer("amf_n1", "Knh", knh, 32);
comUt::print_buffer("amf_n1", "SS", SS[i], 35);
comUt::print_buffer("amf_n1", "Knh", knh, 32);
}
}
void Authentication_5gaka::derive_kasme(
......@@ -507,24 +507,24 @@ int Authentication_5gaka::generate_vector(
* Compute MAC
*/
f1(opc, key, vector->rand, sqn, amf, mac_a);
// print_buffer ("MAC_A : ", mac_a, 8);
// print_buffer ("SQN : ", sqn, 6);
// print_buffer ("RAND : ", vector->rand, 16);
// comUt::print_buffer ("MAC_A : ", mac_a, 8);
// comUt::print_buffer ("SQN : ", sqn, 6);
// comUt::print_buffer ("RAND : ", vector->rand, 16);
/*
* Compute XRES, CK, IK, AK
*/
f2345(opc, key, vector->rand, vector->xres, ck, ik, ak);
// print_buffer ("AK : ", ak, 6);
// print_buffer ("CK : ", ck, 16);
// print_buffer ("IK : ", ik, 16);
// print_buffer ("XRES : ", vector->xres, 8);
// comUt::print_buffer ("AK : ", ak, 6);
// comUt::print_buffer ("CK : ", ck, 16);
// comUt::print_buffer ("IK : ", ik, 16);
// comUt::print_buffer ("XRES : ", vector->xres, 8);
/*
* AUTN = SQN ^ AK || AMF || MAC
*/
generate_autn(sqn, ak, amf, mac_a, vector->autn);
// print_buffer ("AUTN : ", vector->autn, 16);
// comUt::print_buffer ("AUTN : ", vector->autn, 16);
derive_kasme(ck, ik, plmn, sqn, ak, vector->kasme);
// print_buffer ("KASME : ", vector->kasme, 32);
// comUt::print_buffer ("KASME : ", vector->kasme, 32);
return 0;
}
......@@ -560,14 +560,14 @@ uint8_t* Authentication_5gaka::sqn_ms_derive(
sqn_ms[i] = ak[i] ^ conc_sqn_ms[i];
}
print_buffer("amf_n1", "sqn_ms_derive() KEY : ", key, 16);
print_buffer("amf_n1", "sqn_ms_derive() RAND : ", rand_p, 16);
print_buffer("amf_n1", "sqn_ms_derive() AUTS : ", auts, 14);
print_buffer("amf_n1", "sqn_ms_derive() AK : ", ak, 6);
print_buffer("amf_n1", "sqn_ms_derive() SQN_MS : ", sqn_ms, 6);
print_buffer("amf_n1", "sqn_ms_derive() MAC_S : ", mac_s, 8);
comUt::print_buffer("amf_n1", "sqn_ms_derive() KEY : ", key, 16);
comUt::print_buffer("amf_n1", "sqn_ms_derive() RAND : ", rand_p, 16);
comUt::print_buffer("amf_n1", "sqn_ms_derive() AUTS : ", auts, 14);
comUt::print_buffer("amf_n1", "sqn_ms_derive() AK : ", ak, 6);
comUt::print_buffer("amf_n1", "sqn_ms_derive() SQN_MS : ", sqn_ms, 6);
comUt::print_buffer("amf_n1", "sqn_ms_derive() MAC_S : ", mac_s, 8);
f1star(opc, key, rand_p, sqn_ms, amf, mac_s_computed);
print_buffer("amf_n1", "MAC_S computed : ", mac_s_computed, 8);
comUt::print_buffer("amf_n1", "MAC_S computed : ", mac_s_computed, 8);
if (memcmp(mac_s_computed, mac_s, 8) != 0) {
// FPRINTF_ERROR ( "Failed to verify computed SQN_MS\n");
......
......@@ -22,7 +22,6 @@
#ifndef _5GAKA_H_
#define _5GAKA_H_
// extern "C"{
#include <gmp.h>
#include <pthread.h>
#include <stdint.h>
......@@ -30,7 +29,6 @@
#include <unistd.h>
#include <string>
//}
#define SQN_LENGTH_BITS (48)
#define SQN_LENGTH_OCTEST (SQN_LENGTH_BITS / 8)
......
......@@ -34,7 +34,6 @@ add_library (AMF_UTILS STATIC
${CMAKE_CURRENT_SOURCE_DIR}/backtrace.c
${CMAKE_CURRENT_SOURCE_DIR}/conversions.c
${CMAKE_CURRENT_SOURCE_DIR}/dynamic_memory_check.c
${CMAKE_CURRENT_SOURCE_DIR}/hex_string_convert.cpp
${CMAKE_CURRENT_SOURCE_DIR}/if.cpp
${CMAKE_CURRENT_SOURCE_DIR}/string.cpp
${CMAKE_CURRENT_SOURCE_DIR}/thread_sched.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
*/
#include <iostream>
#include <string>
#include "bstrlib.h"
#include "conversions.hpp"
extern "C" {
#include "dynamic_memory_check.h"
}
void convert_string_2_hex(std::string& input_str, std::string& output_str) {
unsigned char* data = (unsigned char*) malloc(input_str.length() + 1);
memset(data, 0, input_str.length() + 1);
memcpy((void*) data, (void*) input_str.c_str(), input_str.length());
for (int i = 0; i < input_str.length(); i++) {
printf("%02x ", data[i]);
}
printf("\n");
char* datahex = (char*) malloc(input_str.length() * 2 + 1);
memset(datahex, 0, input_str.length() * 2 + 1);
for (int i = 0; i < input_str.length(); i++)
sprintf(datahex + i * 2, "%02x", data[i]);
output_str = reinterpret_cast<char*>(datahex);
}
// extern std::size_t callback(const char* in, std::size_t size, std::size_t
// num, std::string* out);
unsigned char* format_string_as_hex(std::string str) {
unsigned int str_len = str.length();
unsigned char* datavalue = (unsigned char*) malloc(str_len / 2 + 1);
unsigned char* data = (unsigned char*) malloc(str_len + 1);
memset(data, 0, str_len + 1);
memcpy((void*) data, (void*) str.c_str(), str_len);
std::cout << "Data: " << data << " (" << str_len << " bytes)" << std::endl;
std::cout << "Data (formatted): \n";
for (int i = 0; i < str_len; i++) {
char datatmp[3] = {0};
memcpy(datatmp, &data[i], 2);
// Ensure both characters are hexadecimal
bool bBothDigits = true;
for (int j = 0; j < 2; ++j) {
if (!isxdigit(datatmp[j])) bBothDigits = false;
}
if (!bBothDigits) break;
// Convert two hexadecimal characters into one character
unsigned int nAsciiCharacter;
sscanf(datatmp, "%x", &nAsciiCharacter);
printf("%x ", nAsciiCharacter);
// Concatenate this character onto the output
datavalue[i / 2] = (unsigned char) nAsciiCharacter;
// Skip the next character
i++;
}
printf("\n");
free_wrapper((void**) &data);
return datavalue;
}
char* bstring2charString(bstring b) {
char* buf = (char*) calloc(1, blength(b) + 1);
uint8_t* value = (uint8_t*) bdata(b);
for (int i = 0; i < blength(b); i++) buf[i] = (char) value[i];
buf[blength(b)] = '\0';
free_wrapper((void**) &value);
return buf;
}
void msg_str_2_msg_hex(std::string msg, bstring& b) {
std::string msg_hex_str;
convert_string_2_hex(msg, msg_hex_str);
printf("tmp string: %s\n", msg_hex_str.c_str());
unsigned int msg_len = msg_hex_str.length();
char* data = (char*) malloc(msg_len + 1);
memset(data, 0, msg_len + 1);
memcpy((void*) data, (void*) msg_hex_str.c_str(), msg_len);
printf("data: %s\n", data);
uint8_t* msg_hex = (uint8_t*) malloc(msg_len / 2 + 1);
conv::ascii_to_hex(msg_hex, (const char*) data);
b = blk2bstr(msg_hex, (msg_len / 2));
}
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