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;
......
......@@ -64,13 +64,11 @@ amf_config::amf_config() {
ausf_addr.ipv4_addr.s_addr = INADDR_ANY;
ausf_addr.port = 80;
ausf_addr.api_version = "v1";
enable_nf_registration = false;
enable_smf_selection = false;
enable_external_ausf = false;
enable_external_udm = false;
instance = 0;
n2 = {};
n11 = {};
sbi_api_version = "v1";
sbi_http2_port = 8080;
statistics_interval = 0;
guami = {};
guami_list = {};
......@@ -79,24 +77,12 @@ amf_config::amf_config() {
auth_conf auth_para = {};
nas_cfg = {};
smf_pool = {};
enable_nf_registration = false;
enable_smf_selection = false;
enable_external_ausf = false;
enable_external_udm = false;
use_fqdn_dns = false;
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} nrf_addr;
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} ausf_addr;
support_features.enable_nf_registration = false;
support_features.enable_smf_selection = false;
support_features.enable_external_ausf = false;
support_features.enable_external_udm = false;
support_features.use_fqdn_dns = false;
support_features.use_http2 = false;
// TODO:
}
......@@ -240,47 +226,55 @@ int amf_config::load(const std::string& config_file) {
// Supported features
try {
const Setting& support_features =
const Setting& support_features_cfg =
amf_cfg[AMF_CONFIG_STRING_SUPPORT_FEATURES];
string opt;
support_features.lookupValue(
support_features_cfg.lookupValue(
AMF_CONFIG_STRING_SUPPORT_FEATURES_NF_REGISTRATION, opt);
if (boost::iequals(opt, "yes")) {
enable_nf_registration = true;
support_features.enable_nf_registration = true;
} else {
enable_nf_registration = false;
support_features.enable_nf_registration = false;
}
support_features.lookupValue(
support_features_cfg.lookupValue(
AMF_CONFIG_STRING_SUPPORT_FEATURES_SMF_SELECTION, opt);
if (boost::iequals(opt, "yes")) {
enable_smf_selection = true;
support_features.enable_smf_selection = true;
} else {
enable_smf_selection = false;
support_features.enable_smf_selection = false;
}
support_features.lookupValue(
support_features_cfg.lookupValue(
AMF_CONFIG_STRING_SUPPORT_FEATURES_EXTERNAL_AUSF, opt);
if (boost::iequals(opt, "yes")) {
enable_external_ausf = true;
support_features.enable_external_ausf = true;
} else {
enable_external_ausf = false;
support_features.enable_external_ausf = false;
}
support_features.lookupValue(
support_features_cfg.lookupValue(
AMF_CONFIG_STRING_SUPPORT_FEATURES_EXTERNAL_UDM, opt);
if (boost::iequals(opt, "yes")) {
enable_external_udm = true;
support_features.enable_external_udm = true;
} else {
enable_external_udm = false;
support_features.enable_external_udm = false;
}
support_features.lookupValue(
support_features_cfg.lookupValue(
AMF_CONFIG_STRING_SUPPORT_FEATURES_USE_FQDN_DNS, opt);
if (boost::iequals(opt, "yes")) {
use_fqdn_dns = true;
support_features.use_fqdn_dns = true;
} else {
support_features.use_fqdn_dns = false;
}
support_features_cfg.lookupValue(
AMF_CONFIG_STRING_SUPPORT_FEATURES_USE_HTTP2, opt);
if (boost::iequals(opt, "yes")) {
support_features.use_http2 = true;
} else {
use_fqdn_dns = false;
support_features.use_http2 = false;
}
} catch (const SettingNotFoundException& nfex) {
......@@ -310,6 +304,13 @@ int amf_config::load(const std::string& config_file) {
throw(AMF_CONFIG_STRING_API_VERSION "failed");
}
// HTTP2 port
if (!(n11_cfg.lookupValue(
AMF_CONFIG_STRING_SBI_HTTP2_PORT, sbi_http2_port))) {
Logger::amf_app().error(AMF_CONFIG_STRING_SBI_HTTP2_PORT "failed");
throw(AMF_CONFIG_STRING_SBI_HTTP2_PORT "failed");
}
// SMF
const Setting& smf_addr_pool =
n11_cfg[AMF_CONFIG_STRING_SMF_INSTANCES_POOL];
......@@ -319,11 +320,12 @@ int amf_config::load(const std::string& config_file) {
smf_inst_t smf_inst = {};
struct in_addr smf_ipv4_addr = {};
unsigned int smf_port = {};
uint32_t smf_http2_port = {};
std::string smf_api_version = {};
std::string selected = {};
smf_addr_item.lookupValue(AMF_CONFIG_STRING_SMF_INSTANCE_ID, smf_inst.id);
if (!use_fqdn_dns) {
if (!support_features.use_fqdn_dns) {
smf_addr_item.lookupValue(
AMF_CONFIG_STRING_IPV4_ADDRESS, smf_inst.ipv4);
IPV4_STR_ADDR_TO_INADDR(
......@@ -334,6 +336,11 @@ int amf_config::load(const std::string& config_file) {
Logger::amf_app().error(AMF_CONFIG_STRING_SMF_INSTANCE_PORT "failed");
throw(AMF_CONFIG_STRING_SMF_INSTANCE_PORT "failed");
}
if (!(smf_addr_item.lookupValue(
AMF_CONFIG_STRING_SBI_HTTP2_PORT, smf_inst.http2_port))) {
Logger::amf_app().error(AMF_CONFIG_STRING_SBI_HTTP2_PORT "failed");
throw(AMF_CONFIG_STRING_SBI_HTTP2_PORT "failed");
}
smf_addr_item.lookupValue(
AMF_CONFIG_STRING_SMF_INSTANCE_VERSION, smf_inst.version);
if (!(smf_addr_item.lookupValue(
......@@ -364,7 +371,7 @@ int amf_config::load(const std::string& config_file) {
std::string nrf_api_version = {};
string address = {};
if (!use_fqdn_dns) {
if (!support_features.use_fqdn_dns) {
nrf_cfg.lookupValue(AMF_CONFIG_STRING_NRF_IPV4_ADDRESS, address);
IPV4_STR_ADDR_TO_INADDR(
util::trim(address).c_str(), nrf_ipv4_addr,
......@@ -393,19 +400,27 @@ int amf_config::load(const std::string& config_file) {
util::trim(address).c_str(), nrf_ipv4_addr,
"BAD IPv4 ADDRESS FORMAT FOR NRF !");
nrf_addr.ipv4_addr = nrf_ipv4_addr;
// nrf_addr.port = nrf_port;
// We hardcode nrf port from config for the moment
if (!(nrf_cfg.lookupValue(AMF_CONFIG_STRING_NRF_PORT, nrf_port))) {
Logger::amf_app().error(AMF_CONFIG_STRING_NRF_PORT "failed");
throw(AMF_CONFIG_STRING_NRF_PORT "failed");
}
nrf_addr.port = nrf_port;
//
nrf_addr.api_version = "v1"; // TODO: get API version
}
}
// AUSF
if (enable_external_ausf) {
if (support_features.enable_external_ausf) {
const Setting& ausf_cfg = new_if_cfg[AMF_CONFIG_STRING_AUSF];
struct in_addr ausf_ipv4_addr = {};
unsigned int ausf_port = {};
std::string ausf_api_version = {};
if (!use_fqdn_dns) {
if (!support_features.use_fqdn_dns) {
ausf_cfg.lookupValue(AMF_CONFIG_STRING_IPV4_ADDRESS, address);
IPV4_STR_ADDR_TO_INADDR(
util::trim(address).c_str(), ausf_ipv4_addr,
......@@ -581,7 +596,8 @@ void amf_config::display() {
Logger::config().info(
" API version............: %s", sbi_api_version.c_str());
if (enable_nf_registration or enable_smf_selection) {
if (support_features.enable_nf_registration or
support_features.enable_smf_selection) {
Logger::config().info("- NRF:");
Logger::config().info(
" IP Addr ...............: %s", inet_ntoa(nrf_addr.ipv4_addr));
......@@ -590,7 +606,7 @@ void amf_config::display() {
" API version ...........: %s", nrf_addr.api_version.c_str());
}
if (enable_external_ausf) {
if (support_features.enable_external_ausf) {
Logger::config().info("- AUSF:");
Logger::config().info(
" IP Addr ...............: %s", inet_ntoa(ausf_addr.ipv4_addr));
......@@ -599,12 +615,13 @@ void amf_config::display() {
" API version ...........: %s", ausf_addr.api_version.c_str());
}
if (!enable_smf_selection) {
if (!support_features.enable_smf_selection) {
Logger::config().info("- SMF Pool.........: ");
for (int i = 0; i < smf_pool.size(); i++) {
std::string selected = smf_pool[i].selected ? "true" : "false";
std::string smf_info =
use_fqdn_dns ? smf_pool[i].fqdn : smf_pool[i].ipv4.c_str();
std::string smf_info = support_features.use_fqdn_dns ?
smf_pool[i].fqdn :
smf_pool[i].ipv4.c_str();
Logger::config().info(
" SMF_INSTANCE_ID %d (%s:%s, version %s) is selected: %s",
smf_pool[i].id, smf_info.c_str(), smf_pool[i].port.c_str(),
......@@ -614,15 +631,23 @@ void amf_config::display() {
Logger::config().info("- Supported Features:");
Logger::config().info(
" NF Registration .......: %s", enable_nf_registration ? "Yes" : "No");
" NF Registration .......: %s",
support_features.enable_nf_registration ? "Yes" : "No");
Logger::config().info(
" SMF Selection .........: %s",
support_features.enable_smf_selection ? "Yes" : "No");
Logger::config().info(
" SMF Selection .........: %s", enable_smf_selection ? "Yes" : "No");
" External AUSF .........: %s",
support_features.enable_external_ausf ? "Yes" : "No");
Logger::config().info(
" External AUSF .........: %s", enable_external_ausf ? "Yes" : "No");
" External UDM ..........: %s",
support_features.enable_external_udm ? "Yes" : "No");
Logger::config().info(
" External UDM ..........: %s", enable_external_udm ? "Yes" : "No");
" Use FQDN ..............: %s",
support_features.use_fqdn_dns ? "Yes" : "No");
Logger::config().info(
" Use FQDN ..............: %s", use_fqdn_dns ? "Yes" : "No");
" Use HTTP2..............: %s",
support_features.use_http2 ? "Yes" : "No");
}
//------------------------------------------------------------------------------
......
......@@ -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;
......
......@@ -62,6 +62,7 @@
#include "logger.hpp"
#include "nas_algorithms.hpp"
#include "sha256.hpp"
#include "comUt.hpp"
extern "C" {
#include "bstrlib.h"
......@@ -81,8 +82,6 @@ extern amf_config amf_cfg;
extern amf_app* amf_app_inst;
extern amf_n2* amf_n2_inst;
extern statistics stacs;
extern void convert_string_2_hex(std::string& input, std::string& output);
extern unsigned char* format_string_as_hex(std::string str);
Sha256 ctx;
random_state_t random_state;
......@@ -261,7 +260,7 @@ void amf_n1::handle_itti_message(itti_downlink_nas_transfer& itti_msg) {
uint32_t ulcount =
secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Authentication_5gaka::derive_kgnb(0, 0x01, kamf, kgnb);
print_buffer("amf_n1", "kamf", kamf, 32);
comUt::print_buffer("amf_n1", "kamf", kamf, 32);
// Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
bstring kgnb_bs = blk2bstr(kgnb, 32);
......@@ -431,7 +430,7 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind& nas_data_ind) {
if (nas_data_ind.is_nas_signalling_estab_req) {
Logger::amf_n1().debug("Received NAS signalling establishment request...");
print_buffer(
comUt::print_buffer(
"amf_n1", "Decoded plain NAS Message buffer",
(uint8_t*) bdata(decoded_plain_msg), blength(decoded_plain_msg));
nas_signalling_establishment_request_handle(
......@@ -439,7 +438,7 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind& nas_data_ind) {
decoded_plain_msg, snn, ulCount);
} else {
Logger::amf_n1().debug("Received uplink NAS message...");
print_buffer(
comUt::print_buffer(
"amf_n1", "Decoded NAS message buffer",
(uint8_t*) bdata(decoded_plain_msg), blength(decoded_plain_msg));
uplink_nas_msg_handle(
......@@ -803,7 +802,7 @@ void amf_n1::service_request_handle(
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Logger::amf_n1().debug("uplink count(%d)", secu->ul_count.seq_num);
print_buffer("amf_n1", "kamf", kamf, 32);
comUt::print_buffer("amf_n1", "kamf", kamf, 32);
Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
bstring kgnb_bs = blk2bstr(kgnb, 32);
......@@ -852,7 +851,7 @@ void amf_n1::service_request_handle(
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Logger::amf_n1().debug("uplink count(%d)", secu->ul_count.seq_num);
print_buffer("amf_n1", "kamf", kamf, 32);
comUt::print_buffer("amf_n1", "kamf", kamf, 32);
Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
bstring kgnb_bs = blk2bstr(kgnb, 32);
itti_initial_context_setup_request* itti_msg =
......@@ -1255,7 +1254,7 @@ void amf_n1::response_registration_reject_msg(
registrationRej->set_5GMM_Cause(cause_value);
uint8_t buffer[BUFFER_SIZE_1024] = {0};
int encoded_size = registrationRej->encode2buffer(buffer, BUFFER_SIZE_1024);
print_buffer(
comUt::print_buffer(
"amf_n1", "Registration-Reject message buffer", buffer, encoded_size);
if (!encoded_size) {
Logger::nas_mm().error("Encode Registration-Reject message error");
......@@ -1339,7 +1338,7 @@ void amf_n1::run_registration_procedure(std::shared_ptr<nas_context>& nc) {
// locally)
bool amf_n1::auth_vectors_generator(std::shared_ptr<nas_context>& nc) {
Logger::amf_n1().debug("Start to generate authentication vectors");
if (amf_cfg.enable_external_ausf) {
if (amf_cfg.support_features.enable_external_ausf) {
// get authentication vectors from AUSF
if (!get_authentication_vectors_from_ausf(nc)) return false;
} else {
......@@ -1383,7 +1382,8 @@ bool amf_n1::get_authentication_vectors_from_ausf(
}
authenticationinfo_auts = auts_s;
print_buffer("amf_n1", "********** ausf ***********", auts_value, auts_len);
comUt::print_buffer(
"amf_n1", "********** ausf ***********", auts_value, auts_len);
Logger::amf_n1().info("********** ausf_s (%s) ***********", auts_s);
// generate_random(rand_value, RAND_LENGTH);
std::map<std::string, std::string>::iterator iter;
......@@ -1402,8 +1402,8 @@ bool amf_n1::get_authentication_vectors_from_ausf(
// sprintf(&rand_s[i*2],"%02X",rand_value[i]);
// }
// authenticationinfo_rand = rand_s;
// print_buffer("amf_n1", "********** rand ***********", rand_value,
// RAND_LENGTH);
// comUt::print_buffer("amf_n1", "********** rand ***********",
// rand_value, RAND_LENGTH);
resynchronizationInfo.setAuts(authenticationinfo_auts);
resynchronizationInfo.setRand(authenticationinfo_rand);
......@@ -1414,24 +1414,25 @@ bool amf_n1::get_authentication_vectors_from_ausf(
if (amf_n11_inst->send_ue_authentication_request(
authenticationinfo, ueauthenticationctx, 1)) {
unsigned char* r5gauthdata_rand =
format_string_as_hex(ueauthenticationctx.getR5gAuthData().getRand());
unsigned char* r5gauthdata_rand = conv::format_string_as_hex(
ueauthenticationctx.getR5gAuthData().getRand());
memcpy(nc.get()->_5g_av[0].rand, r5gauthdata_rand, 16);
rand_record[nc.get()->imsi] =
ueauthenticationctx.getR5gAuthData().getRand();
print_buffer("amf_n1", "5G AV: rand", nc.get()->_5g_av[0].rand, 16);
comUt::print_buffer("amf_n1", "5G AV: rand", nc.get()->_5g_av[0].rand, 16);
free_wrapper((void**) &r5gauthdata_rand);
unsigned char* r5gauthdata_autn =
format_string_as_hex(ueauthenticationctx.getR5gAuthData().getAutn());
unsigned char* r5gauthdata_autn = conv::format_string_as_hex(
ueauthenticationctx.getR5gAuthData().getAutn());
memcpy(nc.get()->_5g_av[0].autn, r5gauthdata_autn, 16);
print_buffer("amf_n1", "5G AV: autn", nc.get()->_5g_av[0].autn, 16);
comUt::print_buffer("amf_n1", "5G AV: autn", nc.get()->_5g_av[0].autn, 16);
free_wrapper((void**) &r5gauthdata_autn);
unsigned char* r5gauthdata_hxresstar = format_string_as_hex(
unsigned char* r5gauthdata_hxresstar = conv::format_string_as_hex(
ueauthenticationctx.getR5gAuthData().getHxresStar());
memcpy(nc.get()->_5g_av[0].hxresStar, r5gauthdata_hxresstar, 16);
print_buffer("amf_n1", "5G AV: hxres*", nc.get()->_5g_av[0].hxresStar, 16);
comUt::print_buffer(
"amf_n1", "5G AV: hxres*", nc.get()->_5g_av[0].hxresStar, 16);
free_wrapper((void**) &r5gauthdata_hxresstar);
std::map<std::string, LinksValueSchema>::iterator iter;
......@@ -1474,7 +1475,7 @@ bool amf_n1::_5g_aka_confirmation_from_ausf(
sprintf(&resStar_s[i * 2], "%02X", resStar_value[i]);
}
resStar_string = resStar_s;
print_buffer(
comUt::print_buffer(
"amf_n1", "********** resStar ***********", resStar_value, resStar_len);
Logger::amf_n1().info("********** resStar_s (%s) ***********", resStar_s);
......@@ -1493,9 +1494,10 @@ bool amf_n1::_5g_aka_confirmation_from_ausf(
ConfirmationDataResponse confirmationdataresponse;
nlohmann::json::parse(response.c_str()).get_to(confirmationdataresponse);
unsigned char* kseaf_hex =
format_string_as_hex(confirmationdataresponse.getKseaf());
conv::format_string_as_hex(confirmationdataresponse.getKseaf());
memcpy(nc.get()->_5g_av[0].kseaf, kseaf_hex, 32);
print_buffer("amf_n1", "5G AV: kseaf", nc.get()->_5g_av[0].kseaf, 32);
comUt::print_buffer(
"amf_n1", "5G AV: kseaf", nc.get()->_5g_av[0].kseaf, 32);
free_wrapper((void**) &kseaf_hex);
Logger::amf_n1().debug("Deriving kamf");
......@@ -1503,7 +1505,7 @@ bool amf_n1::_5g_aka_confirmation_from_ausf(
Authentication_5gaka::derive_kamf(
nc.get()->imsi, nc.get()->_5g_av[i].kseaf, nc.get()->kamf[i],
0x0000); // second parameter: abba
print_buffer("amf_n1", "kamf", nc.get()->kamf[i], 32);
comUt::print_buffer("amf_n1", "kamf", nc.get()->kamf[i], 32);
}
} catch (nlohmann::json::exception& e) {
Logger::amf_n1().info("Could not get Json content from AUSF response");
......@@ -1535,11 +1537,11 @@ bool amf_n1::authentication_vectors_generator_in_ausf(
Authentication_5gaka::derive_kseaf(
nc.get()->serving_network, nc.get()->_5g_he_av[i].kausf, kseaf);
memcpy(nc.get()->_5g_av[i].kseaf, kseaf, 32);
// print_buffer("amf_n1", "5G AV: rand", nc.get()->_5g_av[i].rand, 16);
// print_buffer("amf_n1", "5G AV: autn", nc.get()->_5g_av[i].autn, 16);
// print_buffer("amf_n1", "5G AV: kseaf", nc.get()->_5g_av[i].kseaf, 32);
// print_buffer("amf_n1", "5G AV: hxres*", nc.get()->_5g_av[i].hxresStar,
// 16);
// comUt::print_buffer("amf_n1", "5G AV: rand", nc.get()->_5g_av[i].rand,
// 16); comUt::print_buffer("amf_n1", "5G AV: autn",
// nc.get()->_5g_av[i].autn, 16); comUt::print_buffer("amf_n1", "5G AV:
// kseaf", nc.get()->_5g_av[i].kseaf, 32); comUt::print_buffer("amf_n1", "5G
// AV: hxres*", nc.get()->_5g_av[i].hxresStar, 16);
}
return true;
}
......@@ -1576,7 +1578,7 @@ bool amf_n1::authentication_vectors_generator_in_udm(
sqn = mysql_resp.sqn;
for (int i = 0; i < MAX_5GS_AUTH_VECTORS; i++) {
generate_random(vector[i].rand, RAND_LENGTH);
print_buffer(
comUt::print_buffer(
"amf_n1", "Generated random rand (5G HE AV)", vector[i].rand, 16);
generate_5g_he_av_in_udm(
mysql_resp.opc, nc.get()->imsi, mysql_resp.key, sqn,
......@@ -1590,11 +1592,12 @@ bool amf_n1::authentication_vectors_generator_in_udm(
Logger::amf_n1().debug(
"Receive information from MySQL with IMSI %s",
nc.get()->imsi.c_str());
// print_buffer("amf_n1", "Received from MYSQL: rand", mysql_resp.rand,
// 16); print_buffer("amf_n1", "Received from MYSQL: opc", mysql_resp.opc,
// 16); print_buffer("amf_n1", "Received from MYSQL: key", mysql_resp.key,
// 16); print_buffer("amf_n1", "Received from MYSQL: sqn", mysql_resp.sqn,
// 6);
// comUt::print_buffer("amf_n1", "Received from MYSQL: rand",
// mysql_resp.rand, 16); comUt::print_buffer("amf_n1", "Received from
// MYSQL: opc", mysql_resp.opc, 16); comUt::print_buffer("amf_n1",
// "Received from MYSQL: key", mysql_resp.key, 16);
// comUt::print_buffer("amf_n1", "Received from MYSQL: sqn",
// mysql_resp.sqn, 6);
for (int i = 0; i < MAX_5GS_AUTH_VECTORS; i++) {
generate_random(vector[i].rand, RAND_LENGTH);
sqn = mysql_resp.sqn;
......@@ -1631,9 +1634,9 @@ void amf_n1::test_generate_5g_he_av_in_udm(
Authentication_5gaka::f1(
opc, key, vector.rand, sqn, amf,
mac_a); // to compute MAC, Figure 7, ts33.102
print_buffer("amf_n1", "sqn^ak", sqnak, 6);
print_buffer("amf_n1", "rand", vector.rand, 16);
print_buffer("amf_n1", "mac_a", mac_a, 8);
comUt::print_buffer("amf_n1", "sqn^ak", sqnak, 6);
comUt::print_buffer("amf_n1", "rand", vector.rand, 16);
comUt::print_buffer("amf_n1", "mac_a", mac_a, 8);
annex_a_4_33501(
ck, ik, vector.xres, vector.rand, serving_network, vector.xresStar);
Authentication_5gaka::generate_autn(
......@@ -1691,23 +1694,23 @@ void amf_n1::generate_5g_he_av_in_udm(
Authentication_5gaka::f1(
opc, key, vector.rand, sqn, amf,
mac_a); // to compute MAC, Figure 7, ts33.102
// print_buffer("amf_n1", "Result For F1-Alg: mac_a", mac_a, 8);
// comUt::print_buffer("amf_n1", "Result For F1-Alg: mac_a", mac_a, 8);
Authentication_5gaka::f2345(
opc, key, vector.rand, vector.xres, ck, ik,
ak); // to compute XRES, CK, IK, AK
annex_a_4_33501(
ck, ik, vector.xres, vector.rand, serving_network, vector.xresStar);
// print_buffer("amf_n1", "Result For KDF: xres*(5G HE AV)", vector.xresStar,
// 16);
// comUt::print_buffer("amf_n1", "Result For KDF: xres*(5G HE AV)",
// vector.xresStar, 16);
Authentication_5gaka::generate_autn(
sqn, ak, amf, mac_a,
vector.autn); // generate AUTN
// print_buffer("amf_n1", "Generated autn(5G HE AV)", vector.autn, 16);
// comUt::print_buffer("amf_n1", "Generated autn(5G HE AV)", vector.autn, 16);
Authentication_5gaka::derive_kausf(
ck, ik, serving_network, sqn, ak,
vector.kausf); // derive Kausf
// print_buffer("amf_n1", "Result For KDF: Kausf(5G HE AV)", vector.kausf,
// 32);
// comUt::print_buffer("amf_n1", "Result For KDF: Kausf(5G HE AV)",
// vector.kausf, 32);
Logger::amf_n1().debug("Generate_5g_he_av_in_udm finished!");
// ue_authentication_simulator(vector.rand, vector.autn);
return;
......@@ -1744,7 +1747,7 @@ void amf_n1::annex_a_4_33501(
for (int i = 0; i < 8; i++) oldS[24 + i] = input[i];
oldS[32] = 0x00;
oldS[33] = 0x08;
print_buffer("amf_n1", "Input string: ", S, 31 + netName.size);
comUt::print_buffer("amf_n1", "Input string: ", S, 31 + netName.size);
uint8_t key[32];
memcpy(&key[0], ck, 16);
memcpy(&key[16], ik, 16); // KEY
......@@ -1752,7 +1755,7 @@ void amf_n1::annex_a_4_33501(
uint8_t out[32];
Authentication_5gaka::kdf(key, 32, S, 31 + netName.size, out, 32);
for (int i = 0; i < 16; i++) output[i] = out[16 + i];
print_buffer("amf_n1", "XRES*(new)", out, 32);
comUt::print_buffer("amf_n1", "XRES*(new)", out, 32);
}
//------------------------------------------------------------------------------
......@@ -1820,7 +1823,7 @@ bool amf_n1::start_authentication_procedure(
}
bstring b = blk2bstr(buffer, encoded_size);
print_buffer(
comUt::print_buffer(
"amf_n1", "Authentication-Request message buffer", (uint8_t*) bdata(b),
blength(b));
Logger::amf_n1().debug("amf_ue_ngap_id 0x%x", nc.get()->amf_ue_ngap_id);
......@@ -1883,7 +1886,7 @@ void amf_n1::authentication_response_handle(
Logger::amf_n1().warn(
"Cannot receive AuthenticationResponseParameter (RES*)");
} else {
if (amf_cfg.enable_external_ausf) {
if (amf_cfg.support_features.enable_external_ausf) {
// std::string data = bdata(resStar);
if (!_5g_aka_confirmation_from_ausf(nc, resStar)) isAuthOk = false;
} else {
......@@ -1901,16 +1904,17 @@ void amf_n1::authentication_response_handle(
sha256((unsigned char*) inputstring, 16 + blength(resStar), sha256Out);
uint8_t hres[16];
for (int i = 0; i < 16; i++) hres[i] = (uint8_t) sha256Out[i];
print_buffer(
comUt::print_buffer(
"amf_n1", "Received RES* From Authentication-Response", res, 16);
print_buffer(
comUt::print_buffer(
"amf_n1", "Stored XRES* in 5G HE AV",
nc.get()->_5g_he_av[secu_index].xresStar, 16);
print_buffer(
comUt::print_buffer(
"amf_n1", "Stored XRES in 5G HE AV",
nc.get()->_5g_he_av[secu_index].xres, 8);
print_buffer("amf_n1", "Computed HRES* from RES*", hres, 16);
print_buffer("amf_n1", "Computed HXRES* from XRES*", hxresStar, 16);
comUt::print_buffer("amf_n1", "Computed HRES* from RES*", hres, 16);
comUt::print_buffer(
"amf_n1", "Computed HXRES* from XRES*", hxresStar, 16);
for (int i = 0; i < 16; i++) {
if (hxresStar[i] != hres[i]) isAuthOk = false;
}
......@@ -2065,13 +2069,13 @@ bool amf_n1::start_security_mode_control_procedure(
smc->setAdditional_5G_Security_Information(true, false);
uint8_t buffer[1024];
int encoded_size = smc->encode2buffer(buffer, 1024);
print_buffer(
comUt::print_buffer(
"amf_n1", "Security-Mode-Command message buffer", buffer, encoded_size);
bstring intProtctedNas;
encode_nas_message_protected(
secu_ctx, security_context_is_new, INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size, intProtctedNas);
print_buffer(
comUt::print_buffer(
"amf_n1", "Encrypted Security-Mode-Command message buffer",
(uint8_t*) bdata(intProtctedNas), blength(intProtctedNas));
itti_send_dl_nas_buffer_to_task_n2(
......@@ -2175,7 +2179,7 @@ void amf_n1::security_mode_complete_handle(
regAccept->setT3512_Value(0x5, 0x1e);
uint8_t buffer[BUFFER_SIZE_1024] = {0};
int encoded_size = regAccept->encode2buffer(buffer, BUFFER_SIZE_1024);
print_buffer(
comUt::print_buffer(
"amf_n1", "Registration-Accept message buffer", buffer, encoded_size);
if (!encoded_size) {
Logger::nas_mm().error("Encode Registration-Accept message error");
......@@ -2249,7 +2253,7 @@ void amf_n1::security_mode_complete_handle(
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Authentication_5gaka::derive_kgnb(0, 0x01, kamf, kgnb);
print_buffer("amf_n1", "kamf", kamf, 32);
comUt::print_buffer("amf_n1", "kamf", kamf, 32);
// Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
bstring kgnb_bs = blk2bstr(kgnb, 32);
......@@ -2416,7 +2420,7 @@ bool amf_n1::nas_message_integrity_protected(
nas_stream_cipher_t stream_cipher = {0};
uint8_t mac[4];
stream_cipher.key = nsc->knas_int;
print_buffer(
comUt::print_buffer(
"amf_n1", "Parameters for NIA: knas_int", nsc->knas_int,
AUTH_KNAS_INT_SIZE);
stream_cipher.key_length = AUTH_KNAS_INT_SIZE;
......@@ -2433,7 +2437,7 @@ bool amf_n1::nas_message_integrity_protected(
stream_cipher.direction = direction; // "1" for downlink
Logger::amf_n1().debug("Parameters for NIA, direction: 0x%x", direction);
stream_cipher.message = (uint8_t*) input_nas;
print_buffer(
comUt::print_buffer(
"amf_n1", "Parameters for NIA, message: ", input_nas, input_nas_len);
stream_cipher.blength = input_nas_len * 8;
......@@ -2446,7 +2450,7 @@ bool amf_n1::nas_message_integrity_protected(
case IA1_128_5G: {
Logger::amf_n1().debug("Integrity with algorithms: 128-5G-IA1");
nas_algorithms::nas_stream_encrypt_nia1(&stream_cipher, mac);
print_buffer("amf_n1", "Result for NIA1, mac: ", mac, 4);
comUt::print_buffer("amf_n1", "Result for NIA1, mac: ", mac, 4);
mac32 = ntohl(*((uint32_t*) mac));
Logger::amf_n1().debug("Result for NIA1, mac32: 0x%x", mac32);
return true;
......@@ -2455,7 +2459,7 @@ bool amf_n1::nas_message_integrity_protected(
case IA2_128_5G: {
Logger::amf_n1().debug("Integrity with algorithms: 128-5G-IA2");
nas_algorithms::nas_stream_encrypt_nia2(&stream_cipher, mac);
print_buffer("amf_n1", "Result for NIA2, mac: ", mac, 4);
comUt::print_buffer("amf_n1", "Result for NIA2, mac: ", mac, 4);
mac32 = ntohl(*((uint32_t*) mac));
Logger::amf_n1().debug("Result for NIA2, mac32: 0x%x", mac32);
return true;
......@@ -2501,7 +2505,8 @@ bool amf_n1::nas_message_cipher_protected(
Logger::amf_n1().debug("stream_cipher.blength %d", stream_cipher.blength);
Logger::amf_n1().debug(
"stream_cipher.message %x", stream_cipher.message[0]);
print_buffer("amf_n1", "stream_cipher.key ", stream_cipher.key, 16);
comUt::print_buffer(
"amf_n1", "stream_cipher.key ", stream_cipher.key, 16);
Logger::amf_n1().debug("stream_cipher.count %x", stream_cipher.count);
uint8_t* ciphered =
......@@ -2574,7 +2579,7 @@ void amf_n1::ue_initiate_de_registration_handle(
uint8_t buffer[BUFFER_SIZE_512] = {0};
int encoded_size = deregAccept->encode2buffer(buffer, BUFFER_SIZE_512);
print_buffer(
comUt::print_buffer(
"amf_n1", "De-registration Accept message buffer", buffer, encoded_size);
if (encoded_size < 1) {
Logger::nas_mm().error("Encode De-registration Accept message error!");
......@@ -2631,7 +2636,7 @@ void amf_n1::ul_nas_transport_handle(
} else {
dnn = bfromcstr("default");
}
print_buffer(
comUt::print_buffer(
"amf_n1", "Decoded DNN bitstring", (uint8_t*) bdata(dnn), blength(dnn));
switch (payload_type) {
case N1_SM_INFORMATION: {
......@@ -2680,7 +2685,7 @@ void amf_n1::ul_nas_transport_handle(
} else {
dnn = bfromcstr("default");
}
print_buffer(
comUt::print_buffer(
"amf_n1", "Decoded DNN bitstring", (uint8_t*) bdata(dnn), blength(dnn));
switch (payload_type) {
case N1_SM_INFORMATION: {
......@@ -2721,37 +2726,37 @@ void amf_n1::dump_nas_message(uint8_t* buf, int len) {
//------------------------------------------------------------------------------
void amf_n1::ue_authentication_simulator(uint8_t* rand, uint8_t* autn) {
print_buffer("amf_n1", "[ue] received rand", rand, 16);
print_buffer("amf_n1", "[ue] received autn", autn, 16);
comUt::print_buffer("amf_n1", "[ue] received rand", rand, 16);
comUt::print_buffer("amf_n1", "[ue] received autn", autn, 16);
uint8_t opc[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
uint8_t key[16] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
string serving_network = "5G:mnc011.mcc460.3gppnetwork.org";
print_buffer("amf_n1", "[ue] local opc", opc, 16);
print_buffer("amf_n1", "[ue] local key", key, 16);
comUt::print_buffer("amf_n1", "[ue] local opc", opc, 16);
comUt::print_buffer("amf_n1", "[ue] local key", key, 16);
uint8_t res[8], resStar[16];
uint8_t ck[16], ik[16], ak[6];
Authentication_5gaka::f2345(
opc, key, rand, res, ck, ik,
ak); // to compute XRES, CK, IK, AK
print_buffer("amf_n1", "[ue] Result for f2345: res", res, 8);
print_buffer("amf_n1", "[ue] Result for f2345: ck", ck, 16);
print_buffer("amf_n1", "[ue] Result for f2345: ik", ik, 16);
print_buffer("amf_n1", "[ue] Result for f2345: ak", ak, 6);
comUt::print_buffer("amf_n1", "[ue] Result for f2345: res", res, 8);
comUt::print_buffer("amf_n1", "[ue] Result for f2345: ck", ck, 16);
comUt::print_buffer("amf_n1", "[ue] Result for f2345: ik", ik, 16);
comUt::print_buffer("amf_n1", "[ue] Result for f2345: ak", ak, 6);
annex_a_4_33501(ck, ik, res, rand, serving_network, resStar);
print_buffer("amf_n1", "[ue] computed RES*", resStar, 16);
comUt::print_buffer("amf_n1", "[ue] computed RES*", resStar, 16);
uint8_t sqn[6];
for (int i = 0; i < 6; i++) sqn[i] = ak[i] ^ autn[i];
print_buffer("amf_n1", "[ue] sqn", sqn, 6);
comUt::print_buffer("amf_n1", "[ue] sqn", sqn, 6);
uint8_t amf[2];
amf[0] = autn[6];
amf[1] = autn[7];
Logger::amf_n1().debug("[ue] amf 0x%x%x", amf[0], amf[1]);
uint8_t mac_s[8];
Authentication_5gaka::f1(opc, key, rand, sqn, amf, mac_s);
print_buffer("amf_n1", "[ue] mas_s", mac_s, 8);
print_buffer("amf_n1", "[ue] mas_a", autn + 8, 8);
comUt::print_buffer("amf_n1", "[ue] mas_s", mac_s, 8);
comUt::print_buffer("amf_n1", "[ue] mas_a", autn + 8, 8);
}
//------------------------------------------------------------------------------
......@@ -2804,7 +2809,7 @@ void amf_n1::run_mobility_registration_update_procedure(
regAccept->set_5GS_Network_Feature_Support(0x00, 0x00);
uint8_t buffer[1024] = {0};
int encoded_size = regAccept->encode2buffer(buffer, 1024);
print_buffer(
comUt::print_buffer(
"amf_n1", "Registration-Accept Message Buffer", buffer, encoded_size);
if (!encoded_size) {
Logger::nas_mm().error("Encode Registration-Accept message error");
......@@ -2865,7 +2870,7 @@ void amf_n1::run_mobility_registration_update_procedure(
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
print_buffer("amf_n1", "kamf", kamf, 32);
comUt::print_buffer("amf_n1", "kamf", kamf, 32);
bstring kgnb_bs = blk2bstr(kgnb, 32);
itti_initial_context_setup_request* itti_msg =
new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
......@@ -2936,7 +2941,7 @@ void amf_n1::run_periodic_registration_update_procedure(
regAccept->set_5GS_Network_Feature_Support(0x01, 0x00);
uint8_t buffer[BUFFER_SIZE_1024] = {0};
int encoded_size = regAccept->encode2buffer(buffer, BUFFER_SIZE_1024);
print_buffer(
comUt::print_buffer(
"amf_n1", "Registration-Accept Message Buffer", buffer, encoded_size);
if (!encoded_size) {
Logger::nas_mm().error("Encode Registration-Accept message error");
......@@ -3023,7 +3028,7 @@ void amf_n1::run_periodic_registration_update_procedure(
regAccept->set_5GS_Network_Feature_Support(0x01, 0x00);
uint8_t buffer[BUFFER_SIZE_1024] = {0};
int encoded_size = regAccept->encode2buffer(buffer, BUFFER_SIZE_1024);
print_buffer(
comUt::print_buffer(
"amf_n1", "Registration-Accept Message Buffer", buffer, encoded_size);
if (!encoded_size) {
Logger::nas_mm().error("Encode Registration-Accept message error");
......
......@@ -50,6 +50,9 @@
#include "ue_context.hpp"
#include "fqdn.hpp"
#include "conversions.hpp"
#include "comUt.hpp"
extern "C" {
#include "dynamic_memory_check.h"
}
......@@ -69,13 +72,6 @@ extern amf_n1* amf_n1_inst;
extern amf_app* amf_app_inst;
extern statistics stacs;
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 void print_buffer(
const std::string app, const std::string commit, uint8_t* buf, int len);
extern unsigned char* format_string_as_hex(std::string str);
extern char* bstring2charString(bstring b);
//------------------------------------------------------------------------------
std::size_t callback(
const char* in, std::size_t size, std::size_t num, std::string* out) {
......@@ -248,9 +244,12 @@ void amf_n11::handle_itti_message(
std::string json_part = pdu_session_update_request.dump();
uint8_t http_version = 1;
if (amf_cfg.support_features.use_http2) http_version = 2;
curl_http_client(
remote_uri, json_part, "", n2SmMsg, supi, itti_msg.pdu_session_id,
itti_msg.promise_id);
http_version, itti_msg.promise_id);
// stacs.display();
}
......@@ -313,7 +312,7 @@ void amf_n11::handle_itti_message(itti_nsmf_pdusession_create_sm_context& smf) {
// parse binary dnn and store
std::string dnn = "default"; // If DNN doesn't available, use "default"
if ((smf.dnn != nullptr) && (blength(smf.dnn) > 0)) {
char* tmp = bstring2charString(smf.dnn);
char* tmp = conv::bstring2charString(smf.dnn);
dnn = tmp;
free_wrapper((void**) &tmp);
}
......@@ -324,7 +323,7 @@ void amf_n11::handle_itti_message(itti_nsmf_pdusession_create_sm_context& smf) {
std::string smf_addr = {};
std::string smf_api_version = {};
if (!psc.get()->smf_available) {
if (amf_cfg.enable_smf_selection) {
if (amf_cfg.support_features.enable_smf_selection) {
// use NRF to find suitable SMF based on snssai, plmn and dnn
if (!discover_smf(
smf_addr, smf_api_version, psc.get()->snssai, psc.get()->plmn,
......@@ -404,8 +403,13 @@ void amf_n11::send_pdu_session_update_sm_context_request(
std::string n1SmMsg = {};
octet_stream_2_hex_stream((uint8_t*) bdata(sm_msg), blength(sm_msg), n1SmMsg);
uint8_t http_version = 1;
if (amf_cfg.support_features.use_http2) http_version = 2;
curl_http_client(
remote_uri, json_part, n1SmMsg, "", supi, psc.get()->pdu_session_id);
remote_uri, json_part, n1SmMsg, "", supi, psc.get()->pdu_session_id,
http_version);
}
//------------------------------------------------------------------------------
......@@ -451,8 +455,12 @@ void amf_n11::handle_pdu_session_initial_request(
std::string n1SmMsg = {};
octet_stream_2_hex_stream((uint8_t*) bdata(sm_msg), blength(sm_msg), n1SmMsg);
uint8_t http_version = 1;
if (amf_cfg.support_features.use_http2) http_version = 2;
curl_http_client(
remote_uri, json_part, n1SmMsg, "", supi, psc.get()->pdu_session_id);
remote_uri, json_part, n1SmMsg, "", supi, psc.get()->pdu_session_id,
http_version);
}
//------------------------------------------------------------------------------
......@@ -488,8 +496,12 @@ void amf_n11::handle_itti_message(
pdu_session_release_request["cause"] = "REL_DUE_TO_REACTIVATION";
pdu_session_release_request["ngApCause"] = "radioNetwork";
std::string json_part = pdu_session_release_request.dump();
uint8_t http_version = 1;
if (amf_cfg.support_features.use_http2) http_version = 2;
curl_http_client(
remote_uri, json_part, "", "", itti_msg.supi, psc.get()->pdu_session_id);
remote_uri, json_part, "", "", itti_msg.supi, psc.get()->pdu_session_id,
http_version);
}
//------------------------------------------------------------------------------
......@@ -540,8 +552,12 @@ bool amf_n11::smf_selection_from_configuration(
std::string& smf_addr, std::string& smf_api_version) {
for (int i = 0; i < amf_cfg.smf_pool.size(); i++) {
if (amf_cfg.smf_pool[i].selected) {
if (!amf_cfg.use_fqdn_dns) {
if (!amf_cfg.support_features.use_fqdn_dns) {
if (!amf_cfg.support_features.use_http2)
smf_addr = amf_cfg.smf_pool[i].ipv4 + ":" + amf_cfg.smf_pool[i].port;
else
smf_addr = amf_cfg.smf_pool[i].ipv4 + ":" +
std::to_string(amf_cfg.smf_pool[i].http2_port);
smf_api_version = amf_cfg.smf_pool[i].version;
return true;
} else {
......@@ -551,6 +567,8 @@ bool amf_n11::smf_selection_from_configuration(
fqdn::resolve(
amf_cfg.smf_pool[i].fqdn, amf_cfg.smf_pool[i].ipv4, smf_port,
addr_type);
// TODO for HTTP2
if (amf_cfg.support_features.use_http2) smf_port = 8080;
if (addr_type != 0) { // IPv6: TODO
Logger::amf_n11().warn("Do not support IPv6 Addr for SMF");
return false;
......@@ -573,7 +591,8 @@ void amf_n11::handle_post_sm_context_response_error_400() {}
void amf_n11::handle_post_sm_context_response_error(
long code, std::string cause, bstring n1sm, std::string supi,
uint8_t pdu_session_id) {
print_buffer("amf_n11", "n1 sm", (uint8_t*) bdata(n1sm), blength(n1sm));
comUt::print_buffer(
"amf_n11", "n1 sm", (uint8_t*) bdata(n1sm), blength(n1sm));
itti_n1n2_message_transfer_request* itti_msg =
new itti_n1n2_message_transfer_request(TASK_AMF_N11, TASK_AMF_APP);
itti_msg->n1sm = n1sm;
......@@ -595,7 +614,7 @@ void amf_n11::handle_post_sm_context_response_error(
void amf_n11::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) {
uint8_t http_version, uint32_t promise_id) {
Logger::amf_n11().debug("Call SMF service: %s", remoteUri.c_str());
uint8_t number_parts = 0;
......@@ -608,6 +627,7 @@ void amf_n11::curl_http_client(
Logger::amf_n11().warn(
"PDU Session context for SUPI %s doesn't exit!", supi.c_str());
// TODO:
return;
}
if ((n1SmMsg.size() > 0) and (n2SmMsg.size() > 0)) {
......@@ -657,6 +677,15 @@ void amf_n11::curl_http_client(
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT_MS);
curl_easy_setopt(curl, CURLOPT_INTERFACE, amf_cfg.n11.if_name.c_str());
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
// we use a self-signed test server, skip verification during debugging
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
}
// Response information
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
......@@ -738,8 +767,8 @@ void amf_n11::curl_http_client(
Logger::amf_n11().debug(
"Get response with jsonData: %s", json_data_response.c_str());
msg_str_2_msg_hex(n1sm, n1sm_hex);
print_buffer(
conv::msg_str_2_msg_hex(n1sm, n1sm_hex);
comUt::print_buffer(
"amf_n11", "Get response with n1sm:", (uint8_t*) bdata(n1sm_hex),
blength(n1sm_hex));
......@@ -816,16 +845,16 @@ void amf_n11::curl_http_client(
itti_msg->is_ppi_set = false;
if (n1sm.size() > 0) {
msg_str_2_msg_hex(n1sm, n1sm_hex);
print_buffer(
conv::msg_str_2_msg_hex(n1sm, n1sm_hex);
comUt::print_buffer(
"amf_n11", "Get response n1sm:", (uint8_t*) bdata(n1sm_hex),
blength(n1sm_hex));
itti_msg->n1sm = n1sm_hex;
itti_msg->is_n1sm_set = true;
}
if (n2sm.size() > 0) {
msg_str_2_msg_hex(n2sm, n2sm_hex);
print_buffer(
conv::msg_str_2_msg_hex(n2sm, n2sm_hex);
comUt::print_buffer(
"amf_n11", "Get response n2sm:", (uint8_t*) bdata(n2sm_hex),
blength(n2sm_hex));
itti_msg->n2sm = n2sm_hex;
......@@ -863,6 +892,9 @@ bool amf_n11::discover_smf(
"Send NFDiscovery to NRF to discover the available SMFs");
bool result = true;
uint8_t http_version = 1;
if (amf_cfg.support_features.use_http2) http_version = 2;
nlohmann::json json_data = {};
// TODO: remove hardcoded values
std::string url =
......@@ -885,6 +917,15 @@ bool amf_n11::discover_smf(
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT_MS);
curl_easy_setopt(curl, CURLOPT_INTERFACE, amf_cfg.n11.if_name.c_str());
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
// we use a self-signed test server, skip verification during debugging
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
}
// Response information
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
......@@ -985,6 +1026,9 @@ void amf_n11::register_nf_instance(
curl_global_init(CURL_GLOBAL_ALL);
CURL* curl = curl = curl_easy_init();
uint8_t http_version = 1;
if (amf_cfg.support_features.use_http2) http_version = 2;
if (curl) {
CURLcode res = {};
struct curl_slist* headers = nullptr;
......@@ -997,6 +1041,15 @@ void amf_n11::register_nf_instance(
curl_easy_setopt(curl, CURLOPT_INTERFACE, amf_cfg.n11.if_name.c_str());
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
// we use a self-signed test server, skip verification during debugging
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
}
// Response information.
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
......@@ -1125,7 +1178,7 @@ bool amf_n11::send_ue_authentication_request(
// From AMF_N1, need to be reworked
void amf_n11::curl_http_client(
std::string remoteUri, std::string Method, std::string msgBody,
std::string& response) {
std::string& response, uint8_t http_version) {
Logger::amf_n11().info("Send HTTP message with body %s", msgBody.c_str());
uint32_t str_len = msgBody.length();
......@@ -1158,6 +1211,15 @@ void amf_n11::curl_http_client(
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1);
curl_easy_setopt(curl, CURLOPT_INTERFACE, amf_cfg.n11.if_name.c_str());
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
// we use a self-signed test server, skip verification during debugging
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
}
// Response information.
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
......
......@@ -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