Commit 4b74e26c authored by dukl's avatar dukl

version 1.0

parent 8b5c84e5
......@@ -19,21 +19,24 @@ function help()
echo_error " -b, --build-type Build type as defined in cmake, allowed values are: Debug Release RelWithDebInfo MinSizeRel"
echo_error " -c, --clean Clean the build generated files: config, object, executable files (build from scratch)"
echo_error " -f, --force No interactive script for installation of software packages."
#echo_error " -h, --help Print this help."
echo_error " -h, --help Print this help."
echo_error " -I, --install-deps Check installed software necessary to build and run AMF (support $SUPPORTED_DISTRO)."
#echo_error " -i, --install-min-deps Check installed software necessary to run a statically linked AMF (support $SUPPORTED_DISTRO)."
#echo_error " -j, --jobs Multiple jobs for compiling."
#echo_error " -v, --verbose Build process verbose."
#echo_error " -V, --Verbose CMake only build process verbose, display compilation warnings and errors."
#echo_error " "
echo_error " -j, --jobs Multiple jobs for compiling."
echo_error " -v, --verbose Build process verbose."
echo_error " -V, --Verbose CMake only build process verbose, display compilation warnings and errors."
echo_error " "
}
function main()
{
local -i clean=0
local -i force=0
local -i debug=0
local -i verbose=0
local -i var_check_install_deps=0
local -i cmake_args=" "
local cmake_args=" "
export make_args=" "
until [ -z "$1" ]
do
......@@ -41,7 +44,9 @@ function main()
-b | --build-type)
list_include_item "Debug Release RelWithDebInfo MinSizeRel" $2
[[ $? -ne 0 ]] && echo_error "Build type $2 not recognized" && return $?
echo ${cmake_args}
cmake_args="$cmake_args -DCMAKE_BUILD_TYPE=$2"
echo ${cmake_args}
list_include_item "Debug" $2
[[ $? -ne 0 ]] && debug=1
shift 2;
......@@ -55,6 +60,11 @@ function main()
force=1
echo "when install deps, no interaction"
shift;
;;
-h | --help)
help
shift;
return 0
;;
-I | --install-deps)
echo "check istalled software necessary to build and run AMF(support $SUPPORTED_DISTRO)"
......@@ -62,6 +72,22 @@ function main()
var_check_install_deps=1
shift;
;;
-j | --jobs)
make_args="$make_args -j`nproc`"
shift;
;;
-v | --verbose)
echo "Make build process verbose"
cmake_args="$cmake_args -DCMAKE_VERBOSE_MAKEFILE=ON"
make_args="VERBOSE=1 $make_args"
verbose=1
shift;
;;
-V | --Verbose)
echo "CMake build process verbose"
verbose=1
shift;
;;
*)
echo "unknown option $1"
help
......
......@@ -5,6 +5,7 @@ AMF =
PID_DIRECTORY = "/var/run";
######################################################################## NG SETUP RESPONSE IEs ############################################################
AMF_NAME = "bupt-amf";
GUAMI:{MCC = "460"; MNC = "11"; RegionID = "128"; AMFSetID = "4"; AMFPointer = "1"}
ServedGUAMIList = (
{MCC = "460"; MNC = "11"; RegionID = "10"; AMFSetID = "1"; AMFPointer = "0"}, #48bits <MCC><MNC><RegionID><AMFSetID><AMFPointer>
{MCC = "460"; MNC = "11"; RegionID = "10"; AMFSetID = "1"; AMFPointer = "1"} #48bits <MCC><MNC><RegionID><AMFSetID><AMFPointer>
......@@ -19,7 +20,7 @@ AMF =
}
);
##################################################################### clause 9.2.6.2, 3gpp ts38.413 ####################################################
STATISTICS_TIMER_INTERVAL = 2; #second
STATISTICS_TIMER_INTERVAL = 20; #second
INTERFACES:{
NGAP_AMF:{
INTERFACE_NAME = "ens33";
......@@ -29,8 +30,8 @@ AMF =
};
N11:{
SMF_INSTANCES_POOL = (
{SMF_INSTANCE_ID = 1; IPV4_ADDRESS = "10.103.238.20"},
{SMF_INSTANCE_ID = 2; IPV4_ADDRESS = "10.103.238.21"}
{SMF_INSTANCE_ID = 1; IPV4_ADDRESS = "192.168.2.189"; PORT = "8889"; VERSION = "v1"; SELECTED = "true"},
{SMF_INSTANCE_ID = 2; IPV4_ADDRESS = "10.103.238.21"; PORT = "8181"; VERSION = "v1"; SELECTED = "false"}
);
};
};
......@@ -46,8 +47,10 @@ AMF =
RANDOM = "true";
};
NAS:{
ORDERED_SUPPORTED_INTEGRITY_ALGORITHM_LIST = [ "NIA2" , "NIA1" , "NIA0" ];
#ORDERED_SUPPORTED_INTEGRITY_ALGORITHM_LIST = [ "NIA2" , "NIA1" , "NIA0" ];
ORDERED_SUPPORTED_INTEGRITY_ALGORITHM_LIST = [ "NIA1" , "NIA1" , "NIA1" ];
ORDERED_SUPPORTED_CIPHERING_ALGORITHM_LIST = [ "NEA0" , "NEA1" , "NEA2" ];
#ORDERED_SUPPORTED_CIPHERING_ALGORITHM_LIST = [ "NEA1" , "NEA1" , "NEA1" ];
};
};
......
......@@ -4,19 +4,25 @@
#include "amf_config.hpp"
#include "amf_n2.hpp"
#include "amf_n1.hpp"
#include "amf_n11.hpp"
#include <stdexcept>
#include <iostream>
#include <cstdlib>
#include "amf_statistics.hpp"
#include "DLNASTransport.hpp"
using namespace ngap;
using namespace amf;
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;
amf_n1 * amf_n1_inst = nullptr;
amf_n11 * amf_n11_inst = nullptr;
extern amf_config amf_cfg;
extern statistics stacs;
......@@ -39,6 +45,11 @@ amf_app::amf_app(const amf_config &amf_cfg){
}catch(std::exception& e){
Logger::amf_app().error( "Cannot create amf n1 interface: %s", e.what() );
}
try{
amf_n11_inst = new amf_n11();
}catch(std::exception& e){
Logger::amf_app().error( "Cannot create amf n11 interface: %s", e.what() );
}
timer_id_t tid = itti_inst->timer_setup(amf_cfg.statistics_interval,0,TASK_AMF_APP,TASK_AMF_APP_PERIODIC_STATISTICS,0);
Logger::amf_app().startup( "Started timer(%d)", tid);
}
......@@ -60,6 +71,13 @@ void amf_app_task(void*){
itti_nas_signalling_establishment_request *m = dynamic_cast<itti_nas_signalling_establishment_request*>(msg);
amf_app_inst->handle_itti_message(ref(*m));
}break;
case N1N2_MESSAGE_TRANSFER_REQ:{
Logger::amf_app().debug("Received N1N2_MESSAGE_TRANSFER_REQ");
itti_n1n2_message_transfer_request *m = dynamic_cast<itti_n1n2_message_transfer_request*>(msg);
amf_app_inst->handle_itti_message(ref(*m));
}break;
case TIME_OUT:
if (itti_msg_timeout* to = dynamic_cast<itti_msg_timeout*>(msg)) {
switch(to->arg1_user){
......@@ -102,6 +120,36 @@ void amf_app::set_amf_ue_ngap_id_2_ue_context(const long & amf_ue_ngap_id, std::
}
/****************************** itti handlers *******************************/
void amf_app::handle_itti_message(itti_n1n2_message_transfer_request & itti_msg){
//1. encode DL NAS TRANSPORT message(NAS message)
DLNASTransport * dl = new DLNASTransport();
dl->setHeader(PLAIN_5GS_MSG);
dl->setPayload_Container_Type(N1_SM_INFORMATION);
dl->setPayload_Container((uint8_t*)bdata(itti_msg.n1sm), blength(itti_msg.n1sm));
dl->setPDUSessionId(itti_msg.pdu_session_id);
uint8_t nas[1024];
int encoded_size = dl->encode2buffer(nas, 1024);
print_buffer("amf_app", "n1n2 transfer", nas, encoded_size);
bstring dl_nas = blk2bstr(nas,encoded_size);
itti_downlink_nas_transfer * dl_msg = new itti_downlink_nas_transfer(TASK_AMF_APP, TASK_AMF_N1);
dl_msg->dl_nas = dl_nas;
if(!itti_msg.is_n2sm_set){
dl_msg->is_n2sm_set = false;
}else{
dl_msg->n2sm = itti_msg.n2sm;
dl_msg->pdu_session_id = itti_msg.pdu_session_id;
dl_msg->is_n2sm_set = true;
}
dl_msg->amf_ue_ngap_id = amf_n1_inst->supi2amfId.at(itti_msg.supi);
dl_msg->ran_ue_ngap_id = amf_n1_inst->supi2ranId.at(itti_msg.supi);
std::shared_ptr<itti_downlink_nas_transfer> i = std::shared_ptr<itti_downlink_nas_transfer>(dl_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_app().error( "Could not send ITTI message %s to task TASK_AMF_N1", i->get_msg_name());
}
}
void amf_app::handle_itti_message(itti_nas_signalling_establishment_request & itti_msg){
//1. generate amf_ue_ngap_id
//2. establish ue_context associated with amf_ue_ngap_id
......@@ -126,18 +174,31 @@ void amf_app::handle_itti_message(itti_nas_signalling_establishment_request & it
uc.get()->tai = itti_msg.tai;
if(itti_msg.rrc_cause != -1)
uc.get()->rrc_estb_cause = (e_Ngap_RRCEstablishmentCause)itti_msg.rrc_cause;
if(itti_msg.ueCtxReq == 0)
if(itti_msg.ueCtxReq == -1)
uc.get()->isUeContextRequest = false;
else
uc.get()->isUeContextRequest = true;
uc.get()->ran_ue_ngap_id = itti_msg.ran_ue_ngap_id;
uc.get()->amf_ue_ngap_id = amf_ue_ngap_id;
std::string guti; bool is_guti_valid = false;
if(itti_msg.is_5g_s_tmsi_present){
guti = itti_msg.tai.mcc + itti_msg.tai.mnc + amf_cfg.guami.regionID + itti_msg._5g_s_tmsi;
is_guti_valid = true;
Logger::amf_app().debug("Receiving guti: %s", guti.c_str());
}
itti_uplink_nas_data_ind * itti_n1_msg = new itti_uplink_nas_data_ind(TASK_AMF_APP, TASK_AMF_N1);
itti_n1_msg->amf_ue_ngap_id = amf_ue_ngap_id;
itti_n1_msg->ran_ue_ngap_id = itti_msg.ran_ue_ngap_id;
itti_n1_msg->is_nas_signalling_estab_req = true;
itti_n1_msg->nas_msg = itti_msg.nas_buf;
itti_n1_msg->mcc = itti_msg.tai.mcc;
itti_n1_msg->mnc = itti_msg.tai.mnc;
itti_n1_msg->is_guti_valid = is_guti_valid;
if(is_guti_valid){
itti_n1_msg->guti = guti;
}
std::shared_ptr<itti_uplink_nas_data_ind> i = std::shared_ptr<itti_uplink_nas_data_ind>(itti_n1_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
......@@ -147,3 +208,9 @@ void amf_app::handle_itti_message(itti_nas_signalling_establishment_request & it
}
}
/************************ SMF Client response handlers *****************************/
void amf_app::handle_post_sm_context_response_error_400(){
Logger::amf_app().error("post sm context response error 400");
}
......@@ -15,7 +15,7 @@ using namespace config;
static uint32_t amf_app_ue_ngap_id_generator = 1;
namespace amf{
namespace amf_application{
#define TASK_AMF_APP_PERIODIC_STATISTICS (0)
......@@ -28,6 +28,7 @@ public:
long generate_amf_ue_ngap_id();
public://itti handlers
void handle_itti_message(itti_nas_signalling_establishment_request & itti_msg);
void handle_itti_message(itti_n1n2_message_transfer_request & itti_msg);
public://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;
......@@ -35,6 +36,8 @@ public://context management
bool is_amf_ue_id_2_ue_context(const long & amf_ue_ngap_id) const;
std::shared_ptr<ue_context> amf_ue_id_2_ue_context(const long & amf_ue_ngap_id) const;
void set_amf_ue_ngap_id_2_ue_context(const long & amf_ue_ngap_id, std::shared_ptr<ue_context> uc);
public:/*** SMF Client response handlers ****/
void handle_post_sm_context_response_error_400();
};
......
......@@ -20,7 +20,7 @@ extern "C"{
using namespace libconfig;
using namespace std;
using namespace amf;
using namespace amf_application;
namespace config{
......@@ -69,6 +69,16 @@ namespace config{
}catch(const SettingNotFoundException &nfex){
Logger::amf_app().error("%s : %s, using defaults", nfex.what(), nfex.getPath());
}
try{
const Setting &guami_cfg = amf_cfg[AMF_CONFIG_STRING_GUAMI];
guami_cfg.lookupValue(AMF_CONFIG_STRING_MCC, guami.mcc);
guami_cfg.lookupValue(AMF_CONFIG_STRING_MNC, guami.mnc);
guami_cfg.lookupValue(AMF_CONFIG_STRING_RegionID, guami.regionID);
guami_cfg.lookupValue(AMF_CONFIG_STRING_AMFSetID, guami.AmfSetID);
guami_cfg.lookupValue(AMF_CONFIG_STRING_AMFPointer, guami.AmfPointer);
}catch(const SettingNotFoundException &nfex){
Logger::amf_app().error("%s : %s, using defaults", nfex.what(), nfex.getPath());
}
try{
const Setting &guami_list_cfg = amf_cfg[AMF_CONFIG_STRING_ServedGUAMIList];
int count = guami_list_cfg.getLength();
......@@ -117,6 +127,23 @@ namespace config{
const Setting &new_if_cfg = amf_cfg[AMF_CONFIG_STRING_INTERFACES];
const Setting &n2_amf_cfg = new_if_cfg[AMF_CONFIG_STRING_INTERFACE_NGAP_AMF];
load_interface(n2_amf_cfg, n2);
const Setting &n11_cfg = new_if_cfg[AMF_CONFIG_STRING_INTERFACE_N11];
const Setting &smf_addr_pool = n11_cfg[AMF_CONFIG_STRING_SMF_INSTANCES_POOL];
int count = smf_addr_pool.getLength();
for(int i=0; i< count; i++){
const Setting & smf_addr_item = smf_addr_pool[i];
smf_inst_t smf_inst; string selected;
smf_addr_item.lookupValue(AMF_CONFIG_STRING_SMF_INSTANCE_ID, smf_inst.id);
smf_addr_item.lookupValue(AMF_CONFIG_STRING_IPV4_ADDRESS, smf_inst.ipv4);
smf_addr_item.lookupValue(AMF_CONFIG_STRING_SMF_INSTANCE_PORT, smf_inst.port);
smf_addr_item.lookupValue(AMF_CONFIG_STRING_SMF_INSTANCE_VERSION, smf_inst.version);
smf_addr_item.lookupValue(AMF_CONFIG_STRING_SMF_INSTANCE_SELECTED, selected);
if(!selected.compare("true"))
smf_inst.selected = true;
else
smf_inst.selected = false;
smf_pool.push_back(smf_inst);
}
}catch(const SettingNotFoundException &nfex){
Logger::amf_app().error("%s : %s, using defaults", nfex.what(), nfex.getPath());
return -1;
......@@ -184,6 +211,8 @@ namespace config{
Logger::config().info( "- Instance .......................: %d", instance);
Logger::config().info( "- PID dir ........................: %s", pid_dir.c_str());
Logger::config().info( "- AMF NAME........................: %s", AMF_Name.c_str());
Logger::config().info( "- GUAMI...........................: ");
Logger::config().info( " [%s] [%s] [%s] [%s] [%s]", guami.mcc.c_str(),guami.mnc.c_str(),guami.regionID.c_str(),guami.AmfSetID.c_str(),guami.AmfPointer.c_str());
Logger::config().info( "- ServedGUAMIList ................: ");
for(int i=0;i<guami_list.size();i++){
Logger::config().info( " [%s] [%s] [%s] [%s] [%s]", guami_list[i].mcc.c_str(),guami_list[i].mnc.c_str(),guami_list[i].regionID.c_str(),guami_list[i].AmfSetID.c_str(),guami_list[i].AmfPointer.c_str());
......@@ -205,6 +234,13 @@ namespace config{
Logger::config().info( "- MYSQL db ........................: %s", auth_para.mysql_db.c_str());
Logger::config().info( "- operator key ....................: %s", auth_para.operator_key.c_str());
Logger::config().info( "- random ..........................: %s", auth_para.random.c_str());
Logger::config().info( "- Remote SMF Pool..................: ");
for(int i=0; i<smf_pool.size(); i++){
string selected;
if(smf_pool[i].selected) selected = "true";
else selected = "false";
Logger::config().info( " SMF_INSTANCE_ID(%d) : (%s:%s) version(%s) is selected(%s)", smf_pool[i].id, smf_pool[i].ipv4.c_str(), smf_pool[i].port.c_str(), smf_pool[i].version.c_str(), selected.c_str());
}
}
int amf_config::load_interface(const libconfig::Setting& if_cfg, interface_cfg_t& cfg){
......
......@@ -28,12 +28,20 @@
#define AMF_CONFIG_STRING_SCTP_PORT "SCTP_PORT"
#define AMF_CONFIG_STRING_PPID "PPID"
#define AMF_CONFIG_STRING_INTERFACE_N11 "N11"
#define AMF_CONFIG_STRING_SMF_INSTANCES_POOL "SMF_INSTANCES_POOL"
#define AMF_CONFIG_STRING_SMF_INSTANCE_ID "SMF_INSTANCE_ID"
#define AMF_CONFIG_STRING_SMF_INSTANCE_PORT "PORT"
#define AMF_CONFIG_STRING_SMF_INSTANCE_VERSION "VERSION"
#define AMF_CONFIG_STRING_SMF_INSTANCE_SELECTED "SELECTED"
#define AMF_CONFIG_STRING_SCHED_PARAMS "SCHED_PARAMS"
#define AMF_CONFIG_STRING_THREAD_RD_CPU_ID "CPU_ID"
#define AMF_CONFIG_STRING_THREAD_RD_SCHED_POLICY "SCHED_POLICY"
#define AMF_CONFIG_STRING_THREAD_RD_SCHED_PRIORITY "SCHED_PRIORITY"
#define AMF_CONFIG_STRING_AMF_NAME "AMF_NAME"
#define AMF_CONFIG_STRING_GUAMI "GUAMI"
#define AMF_CONFIG_STRING_ServedGUAMIList "ServedGUAMIList"
#define AMF_CONFIG_STRING_TAC "TAC"
#define AMF_CONFIG_STRING_MCC "MCC"
......@@ -117,6 +125,14 @@ typedef struct{
uint8_t prefered_ciphering_algorithm[8];
}nas_conf_t;
typedef struct{
int id;
string ipv4;
string port;
string version;
bool selected;
}smf_inst_t;
class amf_config{
public:
amf_config();
......@@ -132,12 +148,14 @@ public:
itti_cfg_t itti;
unsigned int statistics_interval;
string AMF_Name;
guami_t guami;
vector<guami_t> guami_list;
unsigned int relativeAMFCapacity;
vector<plmn_item_t> plmn_list;
string is_emergency_support;
auth_conf auth_para;
nas_conf_t nas_cfg;
vector<smf_inst_t> smf_pool;
};
......
This diff is collapsed.
......@@ -4,6 +4,7 @@
#include <map>
#include <shared_mutex>
#include "nas_context.hpp"
#include "pdu_session_context.hpp"
#include "itti_msg_n1.hpp"
#include "bstrlib.h"
#include "3gpp_ts24501.hpp"
......@@ -21,7 +22,7 @@
#include "mysql_db.hpp"
namespace amf{
namespace amf_application{
#define NAS_MESSAGE_DOWNLINK 1
#define NAS_MESSAGE_UPLINK 0
......@@ -39,13 +40,23 @@ public:
amf_n1();
~amf_n1();
void handle_itti_message(itti_uplink_nas_data_ind&);
void handle_itti_message(itti_downlink_nas_transfer & itti_msg);
public: // nas message decode
void nas_signalling_establishment_request_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg);
void nas_signalling_establishment_request_handle(std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg, std::string snn);
void uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg);
bool check_security_header_type(SecurityHeaderType & type, uint8_t *buffer);
private:
public:
std::map<long, std::shared_ptr<nas_context>> amfueid2nas_context; // amf ue ngap id
std::map<std::string, long> supi2amfId;
std::map<std::string, uint32_t> supi2ranId;
std::map<std::string, std::shared_ptr<nas_context>> guti2nas_context;
mutable std::shared_mutex m_guti2nas_context;
bool is_guti_2_nas_context(const std::string & guti) const;
std::shared_ptr<nas_context> guti_2_nas_context(const std::string & guti) const;
void set_guti_2_nas_context(const std::string & guti, std::shared_ptr<nas_context>nc);
mutable std::shared_mutex m_amfueid2nas_context;
bool is_amf_ue_id_2_nas_context(const long & amf_ue_ngap_id) const;
std::shared_ptr<nas_context> amf_ue_id_2_nas_context(const long & amf_ue_ngap_id) const;
......@@ -53,9 +64,14 @@ private:
database_t *db_desc;
private://nas message handlers
void registration_request_handle(bool isNasSig, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring reg);
void registration_request_handle(bool isNasSig, std::shared_ptr<nas_context>nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring reg);
void authentication_response_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg);
void authentication_failure_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg);
void security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas_msg);
void security_mode_reject_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas_msg);
void ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas);
void sha256(unsigned char * message, int msg_len, unsigned char * output);
void service_request_handle(bool isNasSig, std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas);
private://authentication vector
bool generate_authentication_vector();
......@@ -66,6 +82,7 @@ private://response message
public://procedures
void run_registration_procedure(std::shared_ptr<nas_context>&nc);
void run_initial_registration_procedure();
void run_mobility_registration_update_procedure(std::shared_ptr<nas_context>nc);
public://authentication
bool auth_vectors_generator(std::shared_ptr<nas_context>&nc);
bool authentication_vectors_generator_in_ausf(std::shared_ptr<nas_context>&nc);
......@@ -77,14 +94,22 @@ public://mysql handlers in mysql_db.cpp
bool connect_to_mysql();
void generate_random(uint8_t *random_p, ssize_t length);
void generate_5g_he_av_in_udm(const uint8_t opc[16], std::string imsi, uint8_t key[16], uint8_t sqn[6], std::string serving_network, _5G_HE_AV_t &vector);
void test_generate_5g_he_av_in_udm(const uint8_t opc[16], uint8_t key[16], uint8_t sqnak[6], std::string serving_network, _5G_HE_AV_t &vector);
void handle_auth_vector_successful_result(std::shared_ptr<nas_context> nc);
bool start_authentication_procedure(std::shared_ptr<nas_context> nc, int vindex, uint8_t ngksi);
bool check_nas_common_procedure_on_going(std::shared_ptr<nas_context> nc);
int security_select_algorithms(uint8_t nea, uint8_t nia, uint8_t amf_nea, uint8_t amf_nia);
int security_select_algorithms(uint8_t nea, uint8_t nia, uint8_t &amf_nea, uint8_t &amf_nia);
bool start_security_mode_control_procedure(std::shared_ptr<nas_context>nc);
void encode_nas_message_protected(nas_secu_ctx * nsc, bool is_secu_ctx_new, uint8_t security_header_type, uint8_t direction, uint8_t *input_nas_buf, int input_nas_len, bstring & encrypted_nas);
bool nas_message_integrity_protected(nas_secu_ctx *nsc, uint8_t direction, uint8_t *input_nas, int input_nas_len, uint32_t &mac);
bool nas_message_cipher_protected(nas_secu_ctx *nsc, uint8_t direction, bstring input_nas, bstring &output_nas);
public:
void dump_nas_message(uint8_t *buf, int len);
public:
void ue_authentication_simulator(uint8_t *rand, uint8_t *autn);
void annex_a_4_33501(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], std::string serving_network, uint8_t *output);
public:
void send_itti_to_smf_services_consumer(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, uint8_t request_type, uint8_t pdu_session_id, bstring dnn, bstring sm_msg);
};
}
......
This diff is collapsed.
#ifndef _AMF_N11_H_
#define _AMF_N11_H_
#include "itti_msg_n11.hpp"
#include <map>
#include <shared_mutex>
#include "pdu_session_context.hpp"
#include <string>
using namespace std;
namespace amf_application{
class amf_n11{
public:
amf_n11();
~amf_n11();
public:
void handle_itti_message(itti_smf_services_consumer &);
void handle_pdu_session_initial_request(string supi, std::shared_ptr<pdu_session_context> psc, string smf_addr, bstring sm_msg, string dnn);
void handle_itti_message(itti_pdu_session_resource_setup_response &itti_msg);
public:
std::map<string, std::shared_ptr<pdu_session_context>> supi2pdu; // amf ue ngap id
mutable std::shared_mutex m_supi2pdu;
bool is_supi_to_pdu_ctx(const string &supi) const;
std::shared_ptr<pdu_session_context> supi_to_pdu_ctx(const string & supi) const;
void set_supi_to_pdu_ctx(const string &supi, std::shared_ptr<pdu_session_context> psc);
public:
std::map<uint8_t, string> pduid2supi;
public:
bool smf_selection_from_configuration(string & smf_addr);
bool smf_selection_from_context(string & smf_addr);
public:
void handle_post_sm_context_response_error_400();
void handle_post_sm_context_response_error(long code, string cause, bstring n1sm, string supi, uint8_t pdu_session_id);
public:
void curl_http_client(string remoteUri, string jsonData, string n1SmMsg, string n2SmMsg, string supi, uint8_t pdu_session_id);
};
}
#endif
This diff is collapsed.
......@@ -5,7 +5,7 @@
#include "itti_msg_n2.hpp"
#include "ue_ngap_context.hpp"
namespace amf{
namespace amf_application{
class amf_n2 : public ngap::ngap_app{
public:
......@@ -17,6 +17,10 @@ public:
void handle_itti_message(itti_initial_ue_message &init_ue_msg);
void handle_itti_message(itti_ul_nas_transport &ul_nas_transport);
void handle_itti_message(itti_dl_nas_transport &dl_nas_transport);
void handle_itti_message(itti_initial_context_setup_request &itti_msg);
void handle_itti_message(itti_pdu_session_resource_setup_request &itti_msg);
void handle_itti_message(itti_ue_context_release_request &itti_msg);
void handle_itti_message(itti_ue_radio_capability_indication &itti_msg);
bool verifyPlmn(vector<SupportedItem_t> list);
private:
std::map<uint32_t, std::shared_ptr<ue_ngap_context>> ranid2uecontext;// ran ue ngap id
......
#include "amf_n1.hpp"
#include "logger.hpp"
#include "amf_config.hpp"
using namespace amf;
using namespace amf_application;
using namespace config;
extern amf_config amf_cfg;
......
#ifndef _PRINT_BUFFER_H
#define _PRINT_BUFFER_H
#include "logger.hpp"
#include <string>
using namespace std;
void print_buffer(const string app, const 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());
for(int i=0; i<len; i++)
printf("%x ",buf[i]);
printf("\n");
}
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;
}
}
#endif
......@@ -46,6 +46,9 @@ void Logger::_init(const char *app, const bool log_stdout, const bool log_rot_fi
m_task_amf_n2 = new _Logger("TASK_AMF_N2", m_sinks, ss.str().c_str());
m_amf_n1 = new _Logger("amf_n1", m_sinks, ss.str().c_str());
m_task_amf_n1 = new _Logger("TASK_AMF_N1", m_sinks, ss.str().c_str());
m_amf_n11 = new _Logger("amf_n11", m_sinks, ss.str().c_str());
m_task_amf_n11 = new _Logger("TASK_AMF_N11", m_sinks, ss.str().c_str());
m_amf_server = new _Logger("amf_server", m_sinks, ss.str().c_str());
}
......
......@@ -70,6 +70,9 @@ public:
static _Logger &task_amf_n2(){return *singleton().m_task_amf_n2;}
static _Logger &amf_n1(){return *singleton().m_amf_n1;}
static _Logger &task_amf_n1(){return *singleton().m_task_amf_n1;}
static _Logger &amf_n11(){return *singleton().m_amf_n11;}
static _Logger &task_amf_n11(){return *singleton().m_task_amf_n11;}
static _Logger &amf_server(){return *singleton().m_amf_server;}
private:
static Logger *m_singleton;
......@@ -96,6 +99,9 @@ private:
_Logger *m_task_amf_n2;
_Logger *m_amf_n1;
_Logger *m_task_amf_n1;
_Logger *m_amf_n11;
_Logger *m_task_amf_n11;
_Logger *m_amf_server;
};
......
#ifndef UNF_TRIE_CHAR_STREAM_HH
#define UNF_TRIE_CHAR_STREAM_HH
#include <vector>
#include <string>
#include "util.hh"
namespace UNF {
namespace Trie {
class CharStream {
public:
CharStream(const char* str) : cur_(str) {}
unsigned char read() { return eos() ? '\0' : *cur_++; }
unsigned char prev() const { return cur_[-1]; }
unsigned char peek() const { return *cur_; }
const char* cur() const { return cur_; }
bool eos() const { return *cur_ == '\0'; }
void setCur(const char* new_cur) { cur_ = new_cur; }
private:
const char* cur_;
};
class RangeCharStream {
public:
RangeCharStream(const char* beg, const char* end) : cur_(beg), end_(end) {}
unsigned char read() { return eos() ? '\0' : *cur_++; }
unsigned char prev() const { return cur_[-1]; }
unsigned char peek() const { return *cur_; }
const char* cur() const { return cur_; }
const char* end() const { return end_; }
bool eos() const { return cur_ == end_; }
private:
const char* cur_;
const char* end_;
};
class CompoundCharStream {
public:
CompoundCharStream(const char* first, const char* second)
: beg1(first), beg2(second), cur1(beg1), cur2(beg2) {}
unsigned char read() { return !eos1() ? read1() : read2(); }
unsigned char peek() const { return !eos1() ? *cur1 : *cur2; }
unsigned char prev() const { return !eos1() || beg2==cur2 ? cur1[-1] : cur2[-1]; }
const char* cur() const { return !eos1() ? cur1 : cur2; }
bool eos() const { return eos1() && eos2(); }
bool within_first() const { return !eos1(); }
unsigned offset() const { return cur1-beg1 + cur2-beg2; }
void setCur(const char* p) {
if(beg1 <= p && p <= cur1) {
cur1=p;
cur2=beg2;
} else {
cur2=p;
}
}
protected:
unsigned char read1() { return eos1() ? '\0' : *cur1++; }
unsigned char read2() { return eos2() ? '\0' : *cur2++; }
bool eos1() const { return *cur1=='\0'; }
bool eos2() const { return *cur2=='\0'; }
protected:
const char* beg1;
const char* beg2;
const char* cur1;
const char* cur2;
};
class CharStreamForComposition : public CompoundCharStream {
public:
CharStreamForComposition (const char* first, const char* second,
const std::vector<unsigned char>& canonical_classes,
std::string& buf)
: CompoundCharStream(first, second), classes(canonical_classes), skipped(buf)
{}
void init_skipinfo() {
skipped.clear();
skipped_tail = 0;
}
void mark_as_last_valid_point() {
skipped_tail = skipped.size();
marked_point = cur();
}
void reset_at_marked_point() {
setCur(marked_point);
}
void append_read_char_to_str(std::string& s, const char* beg) const {
if(eos1()==false) {
s.append(beg, cur());
} else {
s.append(beg, cur1);
s.append(beg2, cur());
}
}
void append_skipped_chars_to_str(std::string& s) const {
s.append(skipped.begin(), skipped.begin()+skipped_tail);
}
unsigned char get_canonical_class() const {
return offset() < classes.size() ? classes[offset()] : 0;
}
bool next_combining_char(unsigned char prev_class, const char* ppp) {
while(Util::is_utf8_char_start_byte(peek()) == false)
read();
unsigned char mid_class = get_prev_canonical_class();
unsigned char cur_class = get_canonical_class();
if(prev_class==0 && mid_class==0 && cur_class!=0)
return false;
if(prev_class < cur_class && mid_class < cur_class) {
skipped.append(ppp, cur());
return true;
} else {
if(cur_class != 0) {
read();
return next_combining_char(prev_class,ppp);
}
return false;
}
}
private:
unsigned char get_prev_canonical_class() const {
return offset()-1 < classes.size() ? classes[offset()-1] : 0;
}
private:
const std::vector<unsigned char>& classes;
std::string& skipped;
unsigned skipped_tail;
const char* marked_point;
};
}
}
#endif
#ifndef UNF_TRIE_NODE_HH
#define UNF_TRIE_NODE_HH
namespace UNF {
namespace Trie {
class Node {
public:
unsigned jump(unsigned char ch) const { return base() + ch; }
unsigned value() const { return base(); }
unsigned check_char() const { return data>>24; }
unsigned to_uint() const { return data; }
static const Node* from_uint_array(const unsigned* node_uints)
{ return reinterpret_cast<const Node*>(node_uints); }
private:
unsigned base() const { return data & 0xFFFFFF; }
private:
unsigned data;
};
}
}
#endif
#ifndef UNF_NORMALIZER_HH
#define UNF_NORMALIZER_HH
#include <vector>
#include <string>
#include <algorithm>
#include <cstring>
#include "searcher.hh"
#include "char_stream.hh"
#include "table.hh"
#include "util.hh"
namespace UNF {
class Normalizer {
public:
enum Form { FORM_NFD, FORM_NFC, FORM_NFKD, FORM_NFKC };
public:
Normalizer()
: nf_d(TABLE::NODES, TABLE::CANONICAL_DECOM_ROOT, (const char *)TABLE::STRINGS),
nf_kd(TABLE::NODES, TABLE::COMPATIBILITY_DECOM_ROOT, (const char *)TABLE::STRINGS),
nf_c(TABLE::NODES, TABLE::CANONICAL_COM_ROOT, (const char *)TABLE::STRINGS),
nf_c_qc(TABLE::NODES, TABLE::NFC_ILLEGAL_ROOT),
nf_kc_qc(TABLE::NODES, TABLE::NFKC_ILLEGAL_ROOT),
ccc(TABLE::NODES, TABLE::CANONICAL_CLASS_ROOT)
{}
const char* normalize(const char* src, Form form) {
switch(form) {
case FORM_NFD: return nfd(src);
case FORM_NFC: return nfc(src);
case FORM_NFKD: return nfkd(src);
case FORM_NFKC: return nfkc(src);
default: return src;
}
}
const char* nfd(const char* src) { return decompose(src, nf_d); }
const char* nfkd(const char* src) { return decompose(src, nf_kd); }
const char* nfc(const char* src) { return compose(src, nf_c_qc, nf_d); }
const char* nfkc(const char* src) { return compose(src, nf_kc_qc, nf_kd); }
private:
const char* decompose(const char* src, const Trie::NormalizationForm& nf) {
const char* beg = next_invalid_char(src, nf);
if(*beg=='\0')
return src;
buffer.assign(src, beg);
do {
const char* end = next_valid_starter(beg, nf);
decompose_one(beg, end, nf, buffer);
beg = next_invalid_char(end, nf);
buffer.append(end, beg);
} while(*beg!='\0');
return buffer.c_str();
}
void decompose_one(const char* beg, const char* end, const Trie::NormalizationForm& nf, std::string& buf) {
unsigned last = buf.size();
nf.decompose(Trie::RangeCharStream(beg,end), buf);
char* bufbeg = const_cast<char*>(buf.data());
canonical_combining_class_ordering(bufbeg+last, bufbeg+buf.size());
}
const char* compose(const char* src, const Trie::NormalizationForm& nf, const Trie::NormalizationForm& nf_decomp) {
const char* beg = next_invalid_char(src, nf);
if(*beg=='\0')
return src;
buffer.assign(src, beg);
while(*beg!='\0') {
const char* end = next_valid_starter(beg, nf);
buffer2.clear();
decompose_one(beg, end, nf_decomp, buffer2);
end = compose_one(buffer2.c_str(), end, buffer);
beg = next_invalid_char(end, nf);
buffer.append(end, beg);
}
return buffer.c_str();
}
const char* compose_one(const char* starter, const char* rest_starter, std::string& buf) {
Trie::CharStreamForComposition in(starter, rest_starter, canonical_classes, buffer3);
while(in.within_first())
nf_c.compose(in, buf);
return in.cur();
}
void canonical_combining_class_ordering(char* beg, const char* end) {
canonical_classes.assign(end-beg+1, 0); // +1 is for sentinel value
ccc.sort(beg, canonical_classes);
}
const char* next_invalid_char(const char* src, const Trie::NormalizationForm& nf) const {
int last_canonical_class = 0;
const char* cur = Util::nearest_utf8_char_start_point(src);
const char* starter = cur;
for(; *cur != '\0'; cur = Util::nearest_utf8_char_start_point(cur+1)) {
int canonical_class = ccc.get_class(cur);
if(last_canonical_class > canonical_class && canonical_class != 0)
return starter;
if(nf.quick_check(cur)==false)
return starter;
if(canonical_class==0)
starter=cur;
last_canonical_class = canonical_class;
}
return cur;
}
const char* next_valid_starter(const char* src, const Trie::NormalizationForm& nf) const {
const char* cur = Util::nearest_utf8_char_start_point(src+1);
while(ccc.get_class(cur)!=0 || nf.quick_check(cur)==false)
cur = Util::nearest_utf8_char_start_point(cur+1);
return cur;
}
private:
const Trie::NormalizationForm nf_d;
const Trie::NormalizationForm nf_kd;
const Trie::NormalizationForm nf_c;
const Trie::NormalizationForm nf_c_qc;
const Trie::NormalizationForm nf_kc_qc;
const Trie::CanonicalCombiningClass ccc;
std::string buffer;
std::string buffer2;
std::string buffer3;
std::vector<unsigned char> canonical_classes;
};
}
#endif
#ifndef UNF_TRIE_SEARCHER_HH
#define UNF_TRIE_SEARCHER_HH
#include "char_stream.hh"
#include "node.hh"
#include "util.hh"
namespace UNF {
namespace Trie {
class Searcher {
public:
Searcher(const Node* nodes, unsigned root, const char* value=NULL)
: nodes(nodes), root(root), value(value) {}
unsigned find_value(const char* key, int default_value) const {
unsigned node_index=root;
for(CharStream in(key);; in.read()) {
node_index = nodes[node_index].jump(in.peek());
if(nodes[node_index].check_char()==in.peek()) {
unsigned terminal_index = nodes[node_index].jump('\0');
if(nodes[terminal_index].check_char()=='\0') {
return nodes[terminal_index].value();
}
} else
return default_value;
}
}
protected:
const Node* nodes;
const unsigned root;
const char* value;
};
class CanonicalCombiningClass : private Searcher {
public:
CanonicalCombiningClass(const unsigned* node_uints, unsigned root)
: Searcher(Node::from_uint_array(node_uints), root) {}
unsigned get_class(const char* str) const { return find_value(str,0); }
void sort(char* str, std::vector<unsigned char>& classes) const {
CharStream in(str);
unsigned sort_beg=0;
unsigned sort_end=0;
unsigned unicode_char_count=0;
loop_head:
unsigned beg = in.cur()-str;
for(unsigned node_index=root;;){
node_index = nodes[node_index].jump(in.read());
if(nodes[node_index].check_char()==in.prev()) {
unsigned terminal_index = nodes[node_index].jump('\0');
if(nodes[terminal_index].check_char()=='\0') {
if((unicode_char_count++)==0)
sort_beg = beg;
sort_end = in.cur()-str;
unsigned char klass = nodes[terminal_index].value();
for(unsigned i=beg; i < sort_end; i++)
classes[i] = klass;
break;
}
} else {
if(unicode_char_count > 1)
bubble_sort(str, classes, sort_beg, sort_end);
unicode_char_count = 0;
break;
}
}
Util::eat_until_utf8_char_start_point(in);
if(in.eos()==false)
goto loop_head;
if(unicode_char_count > 1)
bubble_sort(str, classes, sort_beg, sort_end);
}
private:
void bubble_sort(char* str, std::vector<unsigned char>& canonical_classes, unsigned beg, unsigned end) const {
for(unsigned limit=beg, next=end; limit != next;) {
limit = next;
for(unsigned i=beg+1; i < limit; i++)
if(canonical_classes[i-1] > canonical_classes[i]) {
std::swap(canonical_classes[i-1], canonical_classes[i]);
std::swap(str[i-1], str[i]);
next = i;
}
}
}
};
class NormalizationForm : private Searcher {
public:
NormalizationForm(const unsigned* node_uints, unsigned root, const char* value=NULL)
: Searcher(Node::from_uint_array(node_uints), root, value) {}
bool quick_check(const char* key) const { return find_value(key,0xFFFFFFFF)==0xFFFFFFFF; }
void decompose(RangeCharStream in, std::string& buffer) const {
loop_head:
const char* beg = in.cur();
for(unsigned node_index=root;;) {
node_index = nodes[node_index].jump(in.read());
if(nodes[node_index].check_char()==in.prev()) {
unsigned terminal_index = nodes[node_index].jump('\0');
if(nodes[terminal_index].check_char()=='\0') {
word_append(buffer, value, nodes[terminal_index].value());
beg = in.cur();
break;
}
} else {
Util::eat_until_utf8_char_start_point(in);
buffer.append(beg, in.cur());
break;
}
}
if(in.eos()==false)
goto loop_head;
}
void compose(CharStreamForComposition& in, std::string& buf) const {
in.init_skipinfo();
const char* const beg = in.cur();
const char* current_char_head = in.cur();
unsigned composed_char_info = 0;
unsigned node_index = root;
unsigned retry_root_node = root;
unsigned char retry_root_class = 0;
for(bool first=true;;) {
if(Util::is_utf8_char_start_byte(in.peek())) {
if(node_index != root)
first=false;
current_char_head = in.cur();
retry_root_node = node_index;
retry_root_class = in.get_canonical_class();
}
retry:
unsigned next_index = nodes[node_index].jump(in.peek());
if(nodes[next_index].check_char()==in.read()) {
// succeeded
node_index = next_index;
unsigned terminal_index = nodes[node_index].jump('\0');
if(nodes[terminal_index].check_char()=='\0') {
composed_char_info = nodes[terminal_index].value();
in.mark_as_last_valid_point();
if(in.eos() || retry_root_class > in.get_canonical_class())
break;
}
} else if (first==true) {
// no retry if current point is a part of first starter
break;
} else if (in.next_combining_char(retry_root_class, current_char_head)==true) {
// back previous code-point and retry
node_index = retry_root_node;
current_char_head = in.cur();
goto retry;
} else {
break;
}
}
if(composed_char_info != 0) {
// append composed unicode-character and skipped combining-characters
word_append(buf, value, composed_char_info);
in.append_skipped_chars_to_str(buf);
in.reset_at_marked_point();
} else {
// append one unicode-character
in.setCur(Util::nearest_utf8_char_start_point(beg+1));
in.append_read_char_to_str(buf, beg);
}
}
private:
static void word_append(std::string& buffer, const char* base, unsigned pos_info) {
buffer.append(base+(pos_info&0x3FFFF), pos_info>>18);
}
};
}
}
#endif
This diff is collapsed.
#ifndef UNF_UTIL_HH
#define UNF_UTIL_HH
namespace UNF {
namespace Util {
inline bool is_utf8_char_start_byte(char byte) {
if(!(byte&0x80)) return true; // ascii
else if (byte&0x40) return true; // start of a UTF-8 character byte sequence
return false;
}
inline const char* nearest_utf8_char_start_point(const char* s) {
for(; is_utf8_char_start_byte(*s)==false; s++);
return s;
}
template <class CharStream>
inline void eat_until_utf8_char_start_point(CharStream& in) {
for(; is_utf8_char_start_byte(in.peek())==false; in.read());
}
}
}
#endif
......@@ -8,6 +8,7 @@
#include "NgapIEsStruct.hpp"
extern "C"{
#include "Ngap_PagingDRX.h"
#include "bstrlib.h"
}
using namespace sctp;
......@@ -28,6 +29,7 @@ public:
long globalRanNodeId;
e_Ngap_PagingDRX default_paging_drx; //v32, v64, v128, v256
vector<SupportedItem_t> s_ta_list;
bstring ue_radio_cap_ind;
sctp_assoc_id_t sctp_assoc_id;
sctp_stream_id_t next_sctp_stream;
......
......@@ -3,6 +3,13 @@
nas_context::nas_context(){
is_imsi_present = false;
is_auth_vectors_present = false;
is_specific_procedure_for_registration_running = false;
is_specific_procedure_for_deregistration_running = false;
is_specific_procedure_for_eCell_inactivity_running = false;
is_common_procedure_for_authentication_running = false;
is_common_procedure_for_identification_running = false;
is_common_procedure_for_security_mode_control_running = false;
is_common_procedure_for_nas_transport_running = false;
auts = NULL;
}
......
......@@ -6,7 +6,8 @@
#include "authentication_algorithms_with_5gaka.hpp"
#include <string>
#include "nas_security_context.hpp"
#include "ies/NSSAI.hpp"
//#include "ies/NSSAI.hpp"
#include "struct.hpp"
class nas_context{
public:
......@@ -28,7 +29,7 @@ public:
uint8_t ueSecurityCapInt;
std::vector<nas::SNSSAI_t> requestedNssai;
std::string serving_network;
uint8_t *auts;
bstring auts;
/************ NAS EP(s) ****************/
bool is_specific_procedure_for_registration_running;
bool is_specific_procedure_for_deregistration_running;
......
#include "pdu_session_context.hpp"
pdu_session_context::pdu_session_context(){
smf_avaliable = false;
}
pdu_session_context::~pdu_session_context(){}
#ifndef _PDU_SESSION_CONTEXT_H_
#define _PDU_SESSION_CONTEXT_H_
#include <string>
#include "bstrlib.h"
using namespace std;
class pdu_session_context{
public:
pdu_session_context();
~pdu_session_context();
public:
uint32_t ran_ue_ngap_id;
long amf_ue_ngap_id;
uint8_t req_type;
uint8_t pdu_session_id;
bstring n2sm;
string dnn;
string remote_smf_addr[0];//"192.168.12.10:8080"
bool smf_avaliable;
};
#endif
......@@ -37,7 +37,9 @@ typedef enum {
TASK_NGAP,
TASK_AMF_N2,
TASK_AMF_N1,
TASK_AMF_N11,
TASK_AMF_APP,
AMF_SERVER,
TASK_MAX,
TASK_NONE,
TASK_ALL = 255
......@@ -62,8 +64,16 @@ typedef enum {
INITIAL_UE_MSG,
ITTI_UL_NAS_TRANSPORT,
ITTI_DL_NAS_TRANSPORT,
INITIAL_CONTEXT_SETUP_REQUEST,
PDU_SESSION_RESOURCE_SETUP_REQUEST,
UE_CONTEXT_RELEASE_REQUEST,
UE_RADIO_CAP_IND,
UL_NAS_DATA_IND,//task amf_n1 message id
DOWNLINK_NAS_TRANSFER,
NAS_SIG_ESTAB_REQ,//task amf_app
N1N2_MESSAGE_TRANSFER_REQ,
SMF_SERVICES_CONSUMER,
PDU_SESS_RES_SET_RESP,
TIME_OUT,
HEALTH_PING,
TERMINATE,
......
......@@ -3,6 +3,7 @@
#include "itti_msg.hpp"
#include "NgapIEsStruct.hpp"
#include <string>
using namespace ngap;
#include "bstrlib.h"
......@@ -28,9 +29,24 @@ public:
NrCgi_t cgi;
Tai_t tai;
bstring nas_buf;
bool is_5g_s_tmsi_present;
std::string _5g_s_tmsi;
};
class itti_n1n2_message_transfer_request : public itti_msg_amf_app{
public:
itti_n1n2_message_transfer_request(const task_id_t origin, const task_id_t destination) : itti_msg_amf_app(N1N2_MESSAGE_TRANSFER_REQ, origin, destination){}
itti_n1n2_message_transfer_request(const itti_n1n2_message_transfer_request & i) : itti_msg_amf_app(i){}
std::string supi;
bstring n1sm;
bstring n2sm;
bool is_n2sm_set;
bool is_n1sm_set;
uint8_t pdu_session_id;
//other parameters
};
......
......@@ -26,10 +26,23 @@ public:
public:
bstring nas_msg;
std::string mcc;
std::string mnc;
bool is_guti_valid;
std::string guti;
};
class itti_downlink_nas_transfer : public itti_msg_n1{
public:
itti_downlink_nas_transfer(const task_id_t origin, const task_id_t destination) : itti_msg_n1(DOWNLINK_NAS_TRANSFER, origin,destination){}
itti_downlink_nas_transfer(const itti_downlink_nas_transfer &i) : itti_msg_n1(i){}
public:
bstring dl_nas;
bstring n2sm;
bool is_n2sm_set;
uint8_t pdu_session_id;
};
......
#ifndef _ITTI_N11_MSG_H_
#define _ITTI_N11_MSG_H_
#include "bstrlib.h"
#include "itti_msg.hpp"
class itti_msg_n11 : public itti_msg{
public:
itti_msg_n11(const itti_msg_type_t msg_type, const task_id_t origin, const task_id_t destination):itti_msg(msg_type,origin,destination){}
itti_msg_n11(const itti_msg_n11& i) : itti_msg(i){
ran_ue_ngap_id = i.ran_ue_ngap_id;
amf_ue_ngap_id = i.amf_ue_ngap_id;
}
public:
long amf_ue_ngap_id;
uint32_t ran_ue_ngap_id;
};
class itti_smf_services_consumer : public itti_msg_n11{
public:
itti_smf_services_consumer(const task_id_t origin, const task_id_t destination):itti_msg_n11(SMF_SERVICES_CONSUMER, origin, destination){
}
itti_smf_services_consumer(const itti_smf_services_consumer& i) : itti_msg_n11(i){
}
public:
uint8_t req_type;
uint8_t pdu_sess_id;
bstring dnn;
bstring sm_msg;
};
class itti_pdu_session_resource_setup_response : public itti_msg_n11{
public:
itti_pdu_session_resource_setup_response(const task_id_t origin, const task_id_t destination) : itti_msg_n11(PDU_SESS_RES_SET_RESP, origin, destination){}
itti_pdu_session_resource_setup_response(const itti_pdu_session_resource_setup_response &i) : itti_msg_n11(i){}
public:
uint8_t pdu_session_id;
bstring n2sm;
};
#endif
......@@ -6,6 +6,8 @@
#include "NGSetupRequest.hpp"
#include "InitialUEMessage.hpp"
#include "UplinkNASTransport.hpp"
#include "UEContextReleaseRequest.hpp"
#include "UERadioCapabilityInfoIndication.hpp"
#include "sctp_server.hpp"
using namespace ngap;
......@@ -63,11 +65,44 @@ public:
bstring nas;
};
class itti_initial_context_setup_request : public itti_msg_n2{
public:
itti_initial_context_setup_request(const task_id_t origin, const task_id_t destination):itti_msg_n2(INITIAL_CONTEXT_SETUP_REQUEST,origin,destination){}
itti_initial_context_setup_request(const itti_initial_context_setup_request &i):itti_msg_n2(i){}
uint32_t ran_ue_ngap_id;
long amf_ue_ngap_id;
bstring kgnb;
bstring nas;
bool is_sr;
bstring n2sm;
uint8_t pdu_session_id;
};
class itti_pdu_session_resource_setup_request : public itti_msg_n2{
public:
itti_pdu_session_resource_setup_request(const task_id_t origin, const task_id_t destination) : itti_msg_n2(PDU_SESSION_RESOURCE_SETUP_REQUEST,origin,destination){}
itti_pdu_session_resource_setup_request(const itti_pdu_session_resource_setup_request &i) : itti_msg_n2(i){}
bstring nas;
bstring n2sm;
uint32_t ran_ue_ngap_id;
long amf_ue_ngap_id;
uint8_t pdu_session_id;
};
class itti_ue_context_release_request : public itti_msg_n2{
public:
itti_ue_context_release_request(const task_id_t origin, const task_id_t destination) : itti_msg_n2(UE_CONTEXT_RELEASE_REQUEST, origin,destination){}
itti_ue_context_release_request(const itti_ue_context_release_request &i) : itti_msg_n2(i){}
UEContextReleaseRequestMsg * ueCtxRel;
};
class itti_ue_radio_capability_indication : public itti_msg_n2{
public:
itti_ue_radio_capability_indication(const task_id_t origin, const task_id_t destination) : itti_msg_n2(UE_RADIO_CAP_IND, origin, destination){}
itti_ue_radio_capability_indication(const itti_ue_radio_capability_indication &i) : itti_msg_n2(i){}
UeRadioCapabilityInfoIndicationMsg * ueRadioCap;
};
#endif
......@@ -33,6 +33,9 @@
#define IDENTITY_RESPONSE 0b01011100
#define UL_NAS_TRANSPORT 0b01100111
#define DL_NAS_TRANSPORT 0b01101000
#define SERVICE_REQUEST 0b01001100
#define SERVICE_REJECT 0b01001101
#define SERVICE_ACCEPT 0b01001110
/********* registration type ***************/
......@@ -55,9 +58,9 @@
#define NO_IDENTITY 0b000
#define SUCI 0b001
#define _5G_GUTI 0b110
#define _5G_GUTI 0b010
#define IMEI 0b011
#define _5G-S-TMSI 0b100
#define _5G_S_TMSI 0b100
#define IMEISVI 0b101
#define MAC_ADDRESS 0b110
......@@ -85,7 +88,7 @@
/************************** cause value for 5g mobility management(Annex A) ********************************/
#define _5GMM_CAUSE_ILLEGAL_UE 3
#define _5GMM_CAUSE_SYNCH_FAILURE 0b00010101
// A.5 Causes related to invalid messages
......@@ -99,8 +102,21 @@
#define _5GMM_CAUSE_MESSAGE_NOT_COMPATIBLE 101
#define _5GMM_CAUSE_PROTOCOL_ERROR 111
/********************* UL NAS TRANSPORT payload container type **************************/
#define N1_SM_INFORMATION 0x01
#define SMS_CONTAINER 0x02
#define LTE_POSITIONING_PROTOCOL 0x03
#define SOR_TRANSPARENT_CONTAINER 0x04
#define UE_POLICY_CONTAINER 0x05
#define UE_PARAMETERS_UPDATE 0x06
#define MULTIPLE_PAYLOADS 0x0f
#define PDU_SESSION_INITIAL_REQUEST 0b001
#define EXISTING_PDU_SESSION 0b010
#define PDU_SESSION_INITIAL_EMERGENCY_REQUEST 0b011
#define EXISTING_EMERGENCY_PDU_SESSION 0b100
#define PDU_SESSION_MODIFICATION_REQUEST 0b101
#define MA_PDU_REQUEST 0b110
......
......@@ -55,3 +55,6 @@
#include "MA_PDU_Session_Information.hpp"
#include "Release_Assistance_Indication.hpp"
#include "Extended_DRX_Parameters.hpp"
#include "struct.hpp"
#include "ServiceType.hpp"
#include "_5GSTrackingAreaIdList.hpp"
This diff is collapsed.
#ifndef _5GSMobilityIdentity_H_
#define _5GSMobilityIdentity_H_
#include <string>
#include <iostream>
#include <stdint.h>
#include "struct.hpp"
extern "C" {
#include "bstrlib.h"
#include "TLVEncoder.h"
#include "TLVDecoder.h"
}
using namespace std;
namespace nas{
......@@ -12,8 +17,8 @@ typedef struct _5G_GUTI_s{
string mnc;
uint8_t amf_region_id;
uint8_t amf_set_id;
uint8_t amf_pointer;
string _5g_tmsi;
uint16_t amf_pointer;
uint32_t _5g_tmsi;
}_5G_GUTI_t;
typedef struct IMEI_or_IMEISV_s{
......@@ -42,6 +47,7 @@ typedef struct _5G_S_TMSI_s{
class _5GSMobilityIdentity{
public:
_5GSMobilityIdentity(uint8_t _iei, const uint16_t amfSetId, const uint8_t amfPointer, const string tmsi);
_5GSMobilityIdentity(const string mcc, const string mnc, const string routingInd, uint8_t protection_sch_id, const string msin);
_5GSMobilityIdentity();
~_5GSMobilityIdentity();
......@@ -52,16 +58,24 @@ public:
int encodeMssMnc2buffer(string mcc, string mnc, uint8_t *buf);
int encodeRoutid2buffer(string routid, uint8_t *buf);
int encodeMSIN2buffer(string msinstr, uint8_t *buf);
int _5g_s_tmsi_encode2buffer(uint8_t *buf, int len);
int _5g_s_tmsi_decodefrombuffer(uint8_t *buf, int len);
int decodefrombuffer(uint8_t *buf, int len, bool is_option);
int suci_decodefrombuffer(uint8_t *buf, int len);
int suci_decodefrombuffer(uint8_t *buf, int len, int length);
int _5g_guti_decodefrombuffer(uint8_t *buf, int len);
void set5GGUTI(const string mcc, const string mnc, uint8_t amf_region_id, uint8_t amf_set_id, uint8_t amf_pointer, const string _5g_tmsi);
void set5GGUTI(const string mcc, const string mnc, uint8_t amf_region_id, uint16_t amf_set_id, uint8_t amf_pointer, const uint32_t _5g_tmsi);
void setSuciWithSupiImsi(const string &mcc, const string &mnc, const string &routingInd, uint8_t protecSchId ,uint8_t home_pki, const string &msin_digits);
void setSuciWithSupiImsi(const string &mcc, const string &mnc, const string &routingInd, uint8_t protecSchId ,const string &msin_digits);
void getSuciWithSupiImsi(SUCI_imsi_t &);
void get5GGUTI(_5G_GUTI_t &);
uint8_t gettypeOfIdentity() { return typeOfIdentity; };
bool get5G_S_TMSI(uint16_t &amfSetId, uint8_t &amfPointer, string &tmsi);
void setIMEISV(IMEISV_t imeisv);
void getIMEISV(IMEISV_t &imeisv);
int imeisv_encode2buffer(uint8_t *buf, int len);
int imeisv_decodefrombuffer(uint8_t *buf, int len);
private:
uint8_t iei;
_5G_GUTI_t *_5g_guti;
......@@ -71,6 +85,7 @@ private:
bool is_no_identity;
uint16_t length;
uint8_t typeOfIdentity:3;
IMEISV_t _IMEISV;
};
......
......@@ -47,7 +47,7 @@ int _5GSRegistrationType::encode2buffer(uint8_t *buf, int len){
int _5GSRegistrationType::decodefrombuffer(uint8_t *buf, int len, bool is_option){
if(is_option){
return 0;
return -1;
}
Logger::nas_mm().debug("decoding 5GSRegistrationType");
uint8_t octet = *buf;
......
......@@ -37,9 +37,10 @@ int ABBA::encode2buffer(uint8_t *buf, int len) {
}
}
else {
*(buf + encoded_size) = _length - 1; encoded_size++;
Logger::nas_mm().debug("length(%d)", _length);
*(buf + encoded_size) = _length; encoded_size++;
int i = 0;
while ((_length - 1) != 0) {
while (_length != 0) {
*(buf + encoded_size) = _value[i]; encoded_size++;
_length--; i++;
}
......
......@@ -34,7 +34,10 @@ int Additional_5G_Security_Information::encode2buffer(uint8_t *buf, int len) {
}
uint8_t octet = 0;
int encoded_size=0;
octet = (_iei << 4) | (RINMR<<1)|HDP;
if(RINMR)
octet |= 0x02;
if(HDP)
octet |= 0x01;
*(buf + encoded_size) = _iei; encoded_size++;
*(buf + encoded_size) = 1; encoded_size++;
*(buf + encoded_size) = octet; encoded_size++;
......
......@@ -5,33 +5,29 @@ using namespace nas;
Authentication_Failure_Parameter::Authentication_Failure_Parameter(uint8_t iei) {
_iei = iei;
}
Authentication_Failure_Parameter::Authentication_Failure_Parameter(const uint8_t iei,uint8_t *value) {
Authentication_Failure_Parameter::Authentication_Failure_Parameter(const uint8_t iei, bstring auts) {
_iei = iei;
for(int i=0;i<14;i++){
this->_value[i] =value[i];}
value = bstrcpy(auts);
length = blength(auts) + 2;
}
Authentication_Failure_Parameter::Authentication_Failure_Parameter() {}
Authentication_Failure_Parameter::~Authentication_Failure_Parameter() {}
uint8_t Authentication_Failure_Parameter::getValue() {
for (int j = 0; j < 14; j++) {
Logger::nas_mm().debug("decoded Authentication_Failure_Parameter value(0x%2x)", _value[j]);
}
return 1;
void Authentication_Failure_Parameter::getValue(bstring &auts) {
auts = bstrcpy(value);
}
int Authentication_Failure_Parameter::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().debug("encoding Authentication_Failure_Parameter iei(0x%x)", _iei);
if (len < 16) {
Logger::nas_mm().error("len is less than 16");
if (len < length) {
Logger::nas_mm().error("len is less than %x",length);
return 0;
}
int encoded_size = 0;
if (_iei) {
*(buf + encoded_size) = _iei; encoded_size++;
*(buf + encoded_size) = 16; encoded_size++;
for (int i = 0; i < 14;i++) {
*(buf + encoded_size) = _value[i]; encoded_size++;
}
*(buf + encoded_size) = length-2; encoded_size++;
int size = encode_bstring(value, (buf + encoded_size), len - encoded_size);
encoded_size += size;
return encoded_size;
}
else {
......@@ -45,16 +41,16 @@ int Authentication_Failure_Parameter::encode2buffer(uint8_t *buf, int len) {
int Authentication_Failure_Parameter::decodefrombuffer(uint8_t *buf, int len, bool is_option) {
Logger::nas_mm().debug("decoding Authentication_Failure_Parameter iei(0x%x)", *buf);
int decoded_size = 0;
//if (is_option) {
// decoded_size++;
//}
decoded_size++;
decoded_size++;
for(int i=0;i<14;i++) {
_value[i] = *(buf + decoded_size); decoded_size++;
if (is_option) {
decoded_size++;
}
length = *(buf + decoded_size); decoded_size++;
Logger::nas_mm().debug("decoded IE Authentication_Failure_Parameter length(%d)", length);
decode_bstring(&value, length, (buf + decoded_size), len - decoded_size);
decoded_size += length;
for (int i = 0; i < length; i++) {
Logger::nas_mm().debug("decoded Authentication_Failure_Parameter value(0x%x)", (uint8_t*)value->data[i]);
}
for(int j=0;j<14;j++){
Logger::nas_mm().debug("decoded Authentication_Failure_Parameter value(0x%2x)", _value[j]);}
Logger::nas_mm().debug("decoded Authentication_Failure_Parameter len(%d)", decoded_size);
return decoded_size;
}
......@@ -64,3 +60,4 @@ int Authentication_Failure_Parameter::decodefrombuffer(uint8_t *buf, int len, bo
#ifndef __Authentication_Failure_Parameter_H_
#define __Authentication_Failure_Parameter_H_
#include <iostream>
#include <stdint.h>
extern "C" {
#include "bstrlib.h"
#include "TLVEncoder.h"
#include "TLVDecoder.h"
}
namespace nas {
class Authentication_Failure_Parameter {
public:
Authentication_Failure_Parameter();
Authentication_Failure_Parameter(uint8_t iei);
Authentication_Failure_Parameter(const uint8_t iei, uint8_t *value);
Authentication_Failure_Parameter(const uint8_t iei, bstring auts);
~Authentication_Failure_Parameter();
//void setValue(uint8_t iei, uint8_t value);
int encode2buffer(uint8_t *buf, int len);
int decodefrombuffer(uint8_t *buf, int len, bool is_option);
uint8_t getValue();
void getValue(bstring &auts);
private:
uint8_t _iei;
uint8_t _value[14];
uint8_t length;
bstring value;
};
......@@ -41,3 +46,4 @@ namespace nas {
......@@ -13,11 +13,11 @@ Authentication_Parameter_AUTN::Authentication_Parameter_AUTN(const uint8_t iei,u
Authentication_Parameter_AUTN::Authentication_Parameter_AUTN() {}
Authentication_Parameter_AUTN::~Authentication_Parameter_AUTN() {}
uint8_t Authentication_Parameter_AUTN::getValue() {
for (int j = 0; j < 16; j++) {
Logger::nas_mm().debug("decoded Authentication_Response_Parameter value(0x%2x)", _value[j]);
}
return 1;}
uint8_t *Authentication_Parameter_AUTN::getValue() {
//for (int j = 0; j < 16; j++) {
// Logger::nas_mm().debug("decoded Authentication_Response_Parameter value(0x%2x)", _value[j]);
//}
return _value;}
int Authentication_Parameter_AUTN::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().debug("encoding Authentication_Parameter_AUTN iei(0x%x)", _iei);
......
......@@ -14,7 +14,7 @@ namespace nas {
//void setValue(uint8_t iei, uint8_t value);
int encode2buffer(uint8_t *buf, int len);
int decodefrombuffer(uint8_t *buf, int len, bool is_option);
uint8_t getValue();
uint8_t *getValue();
private:
uint8_t _iei;
uint8_t _value[16];
......
......@@ -12,8 +12,8 @@ Authentication_Parameter_RAND::Authentication_Parameter_RAND(const uint8_t iei,
Authentication_Parameter_RAND::Authentication_Parameter_RAND() {}
Authentication_Parameter_RAND::~Authentication_Parameter_RAND() {}
uint8_t Authentication_Parameter_RAND::getValue() {
return *_value;
uint8_t *Authentication_Parameter_RAND::getValue() {
return _value;
}
int Authentication_Parameter_RAND::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().debug("encoding Authentication_Parameter_RAND iei(0x%x)", _iei);
......@@ -24,10 +24,11 @@ int Authentication_Parameter_RAND::encode2buffer(uint8_t *buf, int len) {
int encoded_size = 0;
if (_iei) {
*(buf + encoded_size) = _iei; encoded_size++;
int i = 0;
for (int i = 0; i < 16; i++) {
*(buf + encoded_size) = _value[i]; encoded_size++;
}
memcpy((void*)(buf+encoded_size), (void*)_value, 16); encoded_size += 16;
//int i = 0;
//for (int i = 0; i < 16; i++) {
// *(buf + encoded_size) = _value[i]; encoded_size++;
//}
return encoded_size;
}
else {
......
......@@ -14,7 +14,7 @@ namespace nas {
//void setValue(uint8_t iei, uint8_t value);
int encode2buffer(uint8_t *buf, int len);
int decodefrombuffer(uint8_t *buf, int len, bool is_option);
uint8_t getValue();
uint8_t *getValue();
private:
uint8_t _iei;
uint8_t _value[16];
......
......@@ -5,20 +5,20 @@ using namespace nas;
DNN::DNN(uint8_t iei) {
_iei = iei;
}
DNN::DNN(const uint8_t iei, uint8_t _length, uint8_t value) {
DNN::DNN(const uint8_t iei, bstring dnn) {
_iei = iei;
_value = value;
length = _length;
_DNN = bstrcpy(dnn);
length = blength(dnn) + 2;
}
DNN::DNN() {}
DNN::~DNN() {}
void DNN::setValue(uint8_t iei, uint8_t value) {
/*void DNN::setValue(uint8_t iei, uint8_t value) {
_iei = iei;
_value = value;
}
uint8_t DNN::getValue() {
return _value;
}*/
void DNN::getValue(bstring &dnn) {
dnn = bstrcpy(_DNN);
}
int DNN::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().debug("encoding DNN iei(0x%x)", _iei);
......@@ -30,12 +30,14 @@ int DNN::encode2buffer(uint8_t *buf, int len) {
if (_iei) {
*(buf + encoded_size) = _iei; encoded_size++;
*(buf + encoded_size) = (length - 2); encoded_size++;
*(buf + encoded_size) = _value; encoded_size++;
int size = encode_bstring(_DNN, (buf + encoded_size), len - encoded_size);
encoded_size += size;
}
else {
*(buf + encoded_size) = (length - 1); encoded_size++;
*(buf + encoded_size) = _value; encoded_size++;
int size = encode_bstring(_DNN, (buf + encoded_size), len - encoded_size);
encoded_size += size;
}
Logger::nas_mm().debug("encoded DNN len(%d)", encoded_size);
return encoded_size;
......@@ -47,11 +49,14 @@ int DNN::decodefrombuffer(uint8_t *buf, int len, bool is_option) {
if (is_option) {
decoded_size++;
}
_value = 0x00;
length = *(buf + decoded_size); decoded_size++;
_value = *(buf + decoded_size); decoded_size++;
Logger::nas_mm().debug("decoded DNN value(0x%x)", _value);
decode_bstring(&_DNN, length, (buf + decoded_size), len - decoded_size);
decoded_size += length;
for (int i = 0; i < length; i++) {
Logger::nas_mm().debug("decoded DNN value(0x%x)", (uint8_t*)_DNN->data[i]);
}
Logger::nas_mm().debug("decoded DNN len(%d)", decoded_size);
return decoded_size;
}
#ifndef __DNN_H_
#define __DNN_H_
#include <iostream>
#include <stdint.h>
extern "C" {
#include "bstrlib.h"
#include "TLVEncoder.h"
#include "TLVDecoder.h"
}
namespace nas {
class DNN {
public:
DNN();
DNN(uint8_t iei);
DNN(const uint8_t iei, uint8_t _length, uint8_t value);
DNN(const uint8_t iei, bstring dnn);
~DNN();
void setValue(uint8_t iei, uint8_t value);
//void setValue(uint8_t iei, uint8_t value);
int encode2buffer(uint8_t *buf, int len);
int decodefrombuffer(uint8_t *buf, int len, bool is_option);
uint8_t getValue();
void getValue(bstring &dnn);
private:
uint8_t _iei;
uint8_t length;
uint8_t _value;
bstring _DNN;
};
......@@ -37,3 +41,4 @@ namespace nas {
#endif
......@@ -53,8 +53,8 @@ int NAS_Message_Container::decodefrombuffer(uint8_t *buf, int len, bool is_optio
decoded_size++;
}
length = 0;
length |= *(buf + decoded_size); decoded_size++;
length |= (*(buf + decoded_size)) << 8; decoded_size++;
length |= (*(buf + decoded_size))<<8; decoded_size++;
length |= *(buf + decoded_size); decoded_size++;
decode_bstring(&_value, length, (buf + decoded_size), len - decoded_size);
decoded_size += length;
for (int i = 0; i < length; i++) {
......
......@@ -8,16 +8,15 @@ NSSAI::NSSAI(uint8_t iei) {
_iei = iei;
}
NSSAI::NSSAI(const uint8_t iei, std::vector<struct SNSSAI_s> nssai) {
_iei = iei;
length = 2;
S_NSSAI.assign(nssai.begin(), nssai.end());
for(int i =0;i< nssai.size(); i++){
length = length + 1 + 1;
if (nssai.at(i).sd != -1)
{
length++;
}
}
_iei = iei;
length = 0;
S_NSSAI.assign(nssai.begin(), nssai.end());
for(int i=0; i<nssai.size(); i++){
length += 2;//for sst
if(nssai[i].sd != -1) length += 3;
if(nssai[i].mHplmnSst != -1) length += 1;
if(nssai[i].mHplmnSd != -1) length += 3;
}
}
NSSAI::NSSAI() {}
NSSAI::~NSSAI() {}
......@@ -38,21 +37,35 @@ int NSSAI::encode2buffer(uint8_t *buf, int len) {
int encoded_size = 0;
if (_iei) {
*(buf + encoded_size) = _iei; encoded_size++;
*(buf + encoded_size) = length - 2; encoded_size++;
*(buf + encoded_size) = length; encoded_size++;
for(int i =0;i< S_NSSAI.size(); i++){
if (S_NSSAI.at(i).sd != -1)
{
*(buf + encoded_size) = 2; encoded_size++;
}
else { *(buf + encoded_size) = 1; encoded_size++; }
int len_s_nssai = 1; encoded_size ++;
*(buf + encoded_size) = S_NSSAI.at(i).sst; encoded_size++;
if (S_NSSAI.at(i).sd != -1)
{
*(buf + encoded_size) = S_NSSAI.at(i).sd; encoded_size++;
len_s_nssai += 3;
*(buf + encoded_size) = (S_NSSAI.at(i).sd & 0x00ff0000)>> 16; encoded_size++;
Logger::nas_mm().debug("decoded NSSAI len(%x)", *(buf + encoded_size-1));
*(buf + encoded_size) = (S_NSSAI.at(i).sd & 0x0000ff00)>>8; encoded_size++;
Logger::nas_mm().debug("decoded NSSAI len(%x)", *(buf + encoded_size-1));
*(buf + encoded_size) = S_NSSAI.at(i).sd & 0x000000ff; encoded_size++;
Logger::nas_mm().debug("decoded NSSAI len(%x)", *(buf + encoded_size-1));
}
if (S_NSSAI.at(i).mHplmnSst != -1)
{
len_s_nssai += 1;
*(buf + encoded_size) = S_NSSAI.at(i).mHplmnSst; encoded_size++;
}
if (S_NSSAI.at(i).mHplmnSd != -1)
{
len_s_nssai += 3;
*(buf + encoded_size) = (S_NSSAI.at(i).mHplmnSd & 0x00ff0000) >> 16; encoded_size++;
*(buf + encoded_size) = (S_NSSAI.at(i).mHplmnSd & 0x0000ff00) >> 8; encoded_size++;
*(buf + encoded_size) = S_NSSAI.at(i).mHplmnSd & 0x000000ff; encoded_size++;
}
*(buf + encoded_size - len_s_nssai - 1) = len_s_nssai;
}
}
else {
......@@ -66,37 +79,72 @@ int NSSAI::encode2buffer(uint8_t *buf, int len) {
int NSSAI::decodefrombuffer(uint8_t *buf, int len, bool is_option) {
Logger::nas_mm().debug("decoding NSSAI iei(0x%x)", *buf);
int decoded_size = 0;
SNSSAI_s a;
SNSSAI_s a = {0,0,0,0};
if (is_option) {
decoded_size++;
}
length = *(buf + decoded_size); decoded_size++;
int LEAGTH = length;
while (LEAGTH) {
if (*(buf + decoded_size) == 1) //通过snssai的length检测有无sd
switch (*(buf + decoded_size))
{
case 1: {
decoded_size++;//snssai—leagth
LEAGTH--;
a.sst = *(buf + decoded_size); decoded_size++;//无 sd
LEAGTH--;
a.sd = -1;
a.mHplmnSst = -1;
a.mHplmnSd = -1;
}break;
case 4: {
decoded_size++; LEAGTH--;
a.sst = *(buf + decoded_size); decoded_size++; LEAGTH--;
a.sd |= *(buf + decoded_size); decoded_size++; LEAGTH--;//有 sd
a.sd << 8;
a.sd |= *(buf + decoded_size); decoded_size++; LEAGTH--;//有 sd
a.sd << 8;
a.sd |= *(buf + decoded_size); decoded_size++; LEAGTH--;//有 sd
a.mHplmnSst = -1;
a.mHplmnSd = -1;
}break;
case 5: {
decoded_size++; LEAGTH--;
a.sst = *(buf + decoded_size); decoded_size++; LEAGTH--;
a.sd |= *(buf + decoded_size); decoded_size++; LEAGTH--;//有 sd
a.sd << 8;
a.sd |= *(buf + decoded_size); decoded_size++; LEAGTH--;//有 sd
a.sd << 8;
a.sd |= *(buf + decoded_size); decoded_size++; LEAGTH--;//有 sd
a.mHplmnSst = *(buf + decoded_size); decoded_size++; LEAGTH--;
a.mHplmnSd = -1;
}break;
case 8: {
decoded_size++; LEAGTH--;
a.sst = *(buf + decoded_size); decoded_size++; LEAGTH--;
a.sd |= *(buf + decoded_size); decoded_size++; LEAGTH--;//有 sd
a.sd << 8;
a.sd |= *(buf + decoded_size); decoded_size++; LEAGTH--;//有 sd
a.sd << 8;
a.sd |= *(buf + decoded_size); decoded_size++; LEAGTH--;//有 sd
a.mHplmnSst = *(buf + decoded_size); decoded_size++; LEAGTH--;
a.mHplmnSd |= *(buf + decoded_size); decoded_size++; LEAGTH--;//有 sd
a.mHplmnSd << 16;
a.mHplmnSd |= *(buf + decoded_size); decoded_size++; LEAGTH--;//有 sd
a.mHplmnSd << 8;
a.mHplmnSd |= *(buf + decoded_size); decoded_size++; LEAGTH--;//有 sd
}break;
}
else
{
decoded_size++;
LEAGTH--;
a.sst = *(buf + decoded_size); decoded_size++;
LEAGTH--;
a.sd = *(buf + decoded_size); decoded_size++;//有 sd
LEAGTH--;
}
S_NSSAI.insert(S_NSSAI.end(),a);
a={0,0,0,0};
}
for(int i =0;i< S_NSSAI.size(); i++){
Logger::nas_mm().debug("decoded NSSAI SST(0x%x) SD(%d) ",S_NSSAI.at(i).sst,S_NSSAI.at(i).sd); }
Logger::nas_mm().debug("decoded NSSAI SST(0x%x) SD(0x%x) hplmnSST(0x%x) hplmnSD(%d)",S_NSSAI.at(i).sst,S_NSSAI.at(i).sd, S_NSSAI.at(i).mHplmnSst, S_NSSAI.at(i).mHplmnSd); }
Logger::nas_mm().debug("decoded NSSAI len(%d)", decoded_size);
return decoded_size;
}
#ifndef __NSSAI_H_
#define __NSSAI_H_
#include <vector>
#include "nas_ie_header.hpp"
#include <stdint.h>
namespace nas {
typedef struct SNSSAI_s {
uint8_t sst;
int8_t sd;//若sd不存在,则sd设置为-1
}SNSSAI_t;
class NSSAI{
public:
NSSAI();
......
......@@ -32,7 +32,7 @@ int NasKeySetIdentifier::encode2buffer(uint8_t *buf, int len){
octet = (0x0f) & ((tsc<<3) | key_id);
*buf = octet;
Logger::nas_mm().debug("encoded NasKeySetIdentifier IE tsc(0x%x),key_id(0x%x)", tsc, key_id);
return 0;
return 1;
}else{
octet = (iei<<4) | (tsc<<3) | key_id;
*buf = octet;
......@@ -43,11 +43,11 @@ int NasKeySetIdentifier::encode2buffer(uint8_t *buf, int len){
}
}
int NasKeySetIdentifier::decodefrombuffer(uint8_t *buf, int len, bool is_option){
int NasKeySetIdentifier::decodefrombuffer(uint8_t *buf, int len, bool is_option, bool is_high){
Logger::nas_mm().debug("decoding NasKeySetIdentifier IE");
if(len < 1){
Logger::nas_mm().error("len is less than one");
return 0;
return -1;
}else{
uint8_t octet = (*buf);
if(is_option){
......@@ -55,10 +55,16 @@ int NasKeySetIdentifier::decodefrombuffer(uint8_t *buf, int len, bool is_option)
}else{
iei = 0;
}
tsc = octet&0x08;
key_id = octet&0x07;
Logger::nas_mm().debug("decoded NasKeySetIdentifier IE tsc(0x%x),key_id(0x%x)", tsc, key_id);
return 1;
if(!is_high){
tsc = octet&0x08;
key_id = octet&0x07;
}else{
tsc = (octet&0x80)>>4;
key_id = (octet&0x70)>>4;
}
Logger::nas_mm().debug("decoded NasKeySetIdentifier IE tsc(0x%x),key_id(0x%x)", tsc, key_id);
if(iei) return 1;
else return 0;
}
}
......
......@@ -13,7 +13,7 @@ public:
~NasKeySetIdentifier();
int encode2buffer(uint8_t *buf, int len);
int decodefrombuffer(uint8_t *buf, int len, bool is_option);
int decodefrombuffer(uint8_t *buf, int len, bool is_option, bool is_high);
void setTypeOfSecurityContext(uint8_t type);
void setNasKeyIdentifier(uint8_t id);
......
......@@ -31,8 +31,8 @@ int PDU_Session_Status::encode2buffer(uint8_t *buf, int len) {
if (_iei) {
*(buf + encoded_size) = _iei; encoded_size++;
*(buf + encoded_size) = length - 2; encoded_size++;
*(buf + encoded_size) = (_value&0x00ff); encoded_size++;
*(buf + encoded_size) = (_value&0xff00)>>8; encoded_size++;
*(buf + encoded_size) = (_value&0x00ff); encoded_size++;
}
else {
//*(buf + encoded_size) = length - 1; encoded_size++;
......
......@@ -5,9 +5,16 @@ using namespace nas;
Payload_Container::Payload_Container(uint8_t iei) {
_iei = iei;
}
Payload_Container::Payload_Container(uint8_t iei, bstring b) {
_iei = iei;
content = b;
}
Payload_Container::Payload_Container(const uint8_t iei, std::vector<PayloadContainerEntry> content) {
_iei = iei;
length = 4 + content.size() * 2;
if (_iei) {
length = 4 + content.size() * 2;
}
else { length = 3+ content.size() * 2; }
CONTENT.assign(content.begin(), content.end());
for (int i = 0; i < content.size(); i++) {
length = length + content.at(i).optionalIE.size() * 2;
......@@ -27,13 +34,25 @@ void Payload_Container::getValue(std::vector<PayloadContainerEntry> &content) {
content.assign(CONTENT.begin(), CONTENT.end());
}
void Payload_Container::getValue(bstring &cnt){
cnt = content;
}
int Payload_Container::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().debug("encoding Payload_Container iei(0x%x)", _iei);
if (len < length) {
Logger::nas_mm().error("len is less than %d", length);
return 0;
//Logger::nas_mm().error("len is less than %d", length);
//return 0;
}
int encoded_size = 0;
if(_iei){
*(buf + encoded_size) = _iei; encoded_size++;
}
*(buf+encoded_size) = (blength(content) & 0xff00)>>8; encoded_size ++;
*(buf+encoded_size) = (blength(content) & 0x00ff); encoded_size ++;
memcpy(buf+encoded_size, (uint8_t*)bdata(content), blength(content)); encoded_size += blength(content);
#if 0
if (_iei) {
*(buf + encoded_size) = _iei; encoded_size++;
*(buf + encoded_size) = (length - 2)&0x00ff; encoded_size++;
......@@ -58,24 +77,54 @@ int Payload_Container::encode2buffer(uint8_t *buf, int len) {
}
}
else {
*(buf + encoded_size) = (length - 2) & 0x00ff; encoded_size++;
*(buf + encoded_size) = (length - 2)&0x00ff; encoded_size++;
*(buf + encoded_size) = (length - 2) & 0xff00; encoded_size++;
//*(buf + encoded_size) = _value; encoded_size++;
*(buf + encoded_size) = CONTENT.size(); encoded_size++;
for (int i = 0; i < CONTENT.size(); i++) {
/*Length of Payload container entry*/
*(buf + encoded_size) = CONTENT.at(i).optionalIE.size() * 2 + 1;
for (int j = 0; j < CONTENT.at(i).optionalIE.size(); j++) {
*(buf + encoded_size) += blength(CONTENT.at(i).optionalIE.at(j).ie_value);
}
encoded_size++;
/*Length of Payload container entry*/
*(buf + encoded_size) = ((CONTENT.at(i).optionalIE.size()&0x0f)<<4)| CONTENT.at(i).payloadContainerType;
encoded_size++;
for (int j = 0; j < CONTENT.at(i).optionalIE.size(); j++) {
*(buf + encoded_size) += CONTENT.at(i).optionalIE.at(j).ie_type; encoded_size++;
*(buf + encoded_size) += CONTENT.at(i).optionalIE.at(j).ie_len; encoded_size++;
int size = encode_bstring(CONTENT.at(i).optionalIE.at(j).ie_value, (buf + encoded_size), len - encoded_size);
encoded_size += size;
}
}
}
#endif
Logger::nas_mm().debug("encoded Payload_Container len(%d)", encoded_size);
return encoded_size;
}
int Payload_Container::decodefrombuffer(uint8_t *buf, int len, bool is_option) {
Logger::nas_mm().debug("decoding Payload_Container iei(0x%x)", *buf);
}
int Payload_Container::decodefrombuffer(uint8_t *buf, int len, bool is_option, uint8_t type) {
Logger::nas_mm().debug("decoding Payload_Container iei(0x%x)", _iei);
int decoded_size = 0;
if (is_option) {
decoded_size++;
}
if(type != 0x0f){//not multiple payload
uint8_t octet = *(buf+decoded_size); decoded_size++;
length = 0;
length |= (octet<<8);
octet = *(buf+decoded_size); decoded_size++;
length |= octet;
content = blk2bstr(buf+decoded_size, length); decoded_size += length;
return decoded_size;
}
uint8_t num_entries;
uint8_t num_optional;
IE_t value;
PayloadContainerEntry payloadcontainerentry;
if (is_option) {
decoded_size++;
}
length = 0x00;
length |= *(buf + decoded_size); decoded_size++;
length |= (*(buf + decoded_size)) << 8; decoded_size++;
......
......@@ -3,39 +3,30 @@
#include <iostream>
#include <stdint.h>
#include <vector>
#include "nas_ie_header.hpp"
extern "C" {
#include "bstrlib.h"
#include "TLVEncoder.h"
#include "TLVDecoder.h"
}
namespace nas {
typedef struct {
uint8_t ie_type;
uint8_t ie_len;
bstring ie_value;
}IE_t;
typedef struct {
uint8_t ie_type;
uint16_t ie_len;
bstring ie_value;
}IE_t_E;
typedef struct {
uint8_t payloadContainerType : 4;
std::vector<IE_t> optionalIE;
}PayloadContainerEntry;
class Payload_Container {
public:
Payload_Container();
Payload_Container(uint8_t iei);
Payload_Container(uint8_t iei, bstring b);
Payload_Container(const uint8_t iei, std::vector<PayloadContainerEntry> content);
~Payload_Container();
void setValue(uint8_t iei, uint8_t value);
int encode2buffer(uint8_t *buf, int len);
int decodefrombuffer(uint8_t *buf, int len, bool is_option, uint8_t type);
int decodefrombuffer(uint8_t *buf, int len, bool is_option);
void getValue(std::vector<PayloadContainerEntry> &content);
void getValue(bstring &cnt);
private:
uint8_t _iei;
uint16_t length;
bstring content;
std::vector<PayloadContainerEntry> CONTENT;
};
......
......@@ -6,19 +6,31 @@ using namespace nas;
S_NSSAI::S_NSSAI(uint8_t iei) {
_iei = iei;
}
S_NSSAI::S_NSSAI(const uint8_t iei, uint8_t SST) {
S_NSSAI::S_NSSAI(const uint8_t iei, SNSSAI_s snssai) {
_iei = iei;
length = 3;
_SST = SST;
length = 3;
SNSSAI = snssai;
if (SNSSAI.sd != -1)
{
length += 3;
}
if (SNSSAI.mHplmnSst != -1)
{
length += 1;
}
if (SNSSAI.mHplmnSd != -1)
{
length += 3;
};
}
S_NSSAI::S_NSSAI() {}
S_NSSAI::~S_NSSAI() {}
void S_NSSAI::setS_NSSAI(uint8_t SST) {
_SST = SST;
void S_NSSAI::setS_NSSAI(SNSSAI_s snssai) {
SNSSAI = snssai;
}
uint8_t S_NSSAI::getValue() {
return _SST;
void S_NSSAI::getValue(SNSSAI_s &snssai) {
snssai=SNSSAI;
}
int S_NSSAI::encode2buffer(uint8_t *buf, int len) {
......@@ -31,7 +43,23 @@ int S_NSSAI::encode2buffer(uint8_t *buf, int len) {
if (_iei) {
*(buf + encoded_size) = _iei; encoded_size++;
*(buf + encoded_size) = length - 2; encoded_size++;
*(buf + encoded_size) = _SST; encoded_size++;
*(buf + encoded_size) = SNSSAI.sst; encoded_size++;
if (SNSSAI.sd != -1)
{
*(buf + encoded_size) = (SNSSAI.sd & 0x00ff0000) >> 16; encoded_size++;
*(buf + encoded_size) = (SNSSAI.sd & 0x0000ff00) >> 8; encoded_size++;
*(buf + encoded_size) = SNSSAI.sd & 0x000000ff; encoded_size++;
}
if (SNSSAI.mHplmnSst != -1)
{
*(buf + encoded_size) = SNSSAI.mHplmnSst; encoded_size++;
}
if (SNSSAI.mHplmnSd != -1)
{
*(buf + encoded_size) = (SNSSAI.mHplmnSd & 0x00ff0000) >> 16; encoded_size++;
*(buf + encoded_size) = (SNSSAI.mHplmnSd & 0x0000ff00) >> 8; encoded_size++;
*(buf + encoded_size) = SNSSAI.mHplmnSd & 0x000000ff; encoded_size++;
}
}
else {
// *(buf + encoded_size) = length - 1; encoded_size++;
......@@ -44,14 +72,59 @@ int S_NSSAI::encode2buffer(uint8_t *buf, int len) {
int S_NSSAI::decodefrombuffer(uint8_t *buf, int len, bool is_option) {
Logger::nas_mm().debug("decoding S_NSSAI iei(0x%x)", *buf);
int decoded_size = 0;
SNSSAI_s a={0,0,0,0};
if (is_option) {
decoded_size++;
}
length = *(buf + decoded_size); decoded_size++;
_SST = *(buf + decoded_size); decoded_size++;
Logger::nas_mm().debug("decoded S_NSSAI value_SST(0x%x)",_SST);
switch (*(buf + decoded_size-1))
{
case 1: {
a.sst = *(buf + decoded_size); decoded_size++;//无 sd
a.sd = -1;
a.mHplmnSst = -1;
a.mHplmnSd = -1;
}break;
case 4: {
a.sst = *(buf + decoded_size); decoded_size++;
a.sd |= *(buf + decoded_size); decoded_size++; //有 sd
a.sd << 8;
a.sd |= *(buf + decoded_size); decoded_size++; //有 sd
a.sd << 8;
a.sd |= *(buf + decoded_size); decoded_size++; //有 sd
a.mHplmnSst = -1;
a.mHplmnSd = -1;
}break;
case 5: {
a.sst = *(buf + decoded_size); decoded_size++;
a.sd |= *(buf + decoded_size); decoded_size++; //有 sd
a.sd << 8;
a.sd |= *(buf + decoded_size); decoded_size++; //有 sd
a.sd << 8;
a.sd |= *(buf + decoded_size); decoded_size++; //有 sd
a.mHplmnSst = *(buf + decoded_size); decoded_size++;
a.mHplmnSd = -1;
}break;
case 8: {
a.sst = *(buf + decoded_size); decoded_size++;
a.sd |= *(buf + decoded_size); decoded_size++; //有 sd
a.sd << 8;
a.sd |= *(buf + decoded_size); decoded_size++; //有 sd
a.sd << 8;
a.sd |= *(buf + decoded_size); decoded_size++; //有 sd
a.mHplmnSst = *(buf + decoded_size); decoded_size++;
a.mHplmnSd |= *(buf + decoded_size); decoded_size++; //有 sd
a.mHplmnSd << 16;
a.mHplmnSd |= *(buf + decoded_size); decoded_size++; //有 sd
a.mHplmnSd << 8;
a.mHplmnSd |= *(buf + decoded_size); decoded_size++; //有 sd
}break;
}
SNSSAI=a;
Logger::nas_mm().debug("decoded S_NSSAI SST(0x%x) SD(0x%x) hplmnSST(0x%x) hplmnSD(0x%x)",a.sst, a.sd, a.mHplmnSst, a.mHplmnSd);
Logger::nas_mm().debug("decoded S_NSSAI len(%d)", decoded_size);
return decoded_size;
}
......@@ -2,23 +2,23 @@
#define __S_NSSAI_H_
#include <stdint.h>
#include "nas_ie_header.hpp"
namespace nas {
class S_NSSAI {
public:
S_NSSAI();
S_NSSAI(uint8_t iei);
S_NSSAI(const uint8_t iei, uint8_t SST);
S_NSSAI(const uint8_t iei, SNSSAI_s snssai);
~S_NSSAI();
void setS_NSSAI(uint8_t SST);
void setS_NSSAI(SNSSAI_s snssai);
int encode2buffer(uint8_t *buf, int len);
int decodefrombuffer(uint8_t *buf, int len, bool is_option);
uint8_t getValue();
void getValue(SNSSAI_s &snssai);
private:
uint8_t _iei;
uint8_t length;
uint8_t _SST;
SNSSAI_s SNSSAI;
};
......@@ -38,3 +38,4 @@ namespace nas {
#endif
#include "ServiceType.hpp"
using namespace nas;
ServiceType::ServiceType(){}
ServiceType::~ServiceType(){}
ServiceType::ServiceType(uint8_t iei, uint8_t stp){
_iei = iei;
value = stp;
}
int ServiceType::encode2buffer(uint8_t *buf, int len){
if(len < 1) return -1;
int encoded_size = 0;
if(_iei){ *buf = _iei; encoded_size++; *(buf+encoded_size) = value; encoded_size++; return encoded_size;}
else{ *buf = 0x00 | ((value & 0x0f)<<4); return 0;}
}
int ServiceType::decodefrombuffer(uint8_t *buf, int len, bool is_optional, bool is_high){
if(len < 1) return -1;
if(is_optional){
_iei = *buf;
}else{
if(is_high)
value = ((*buf)&0xf0)>>4;
else
value = (*buf)&0x0f;
return 0;
}
}
uint8_t ServiceType::getValue(){
return value;
}
#ifndef _SERVICE_TYPE_H_
#define _SERVICE_TYPE_H_
#include <stdint.h>
namespace nas{
class ServiceType{
public:
ServiceType();
~ServiceType();
ServiceType(uint8_t iei, uint8_t stp);
public:
int encode2buffer(uint8_t *buf, int len);
int decodefrombuffer(uint8_t *nuf, int len, bool is_optional, bool is_high);
uint8_t getValue();
private:
uint8_t _iei;
uint8_t value;
};
}
#endif
......@@ -44,7 +44,7 @@ int UESecurityCapability::encode2buffer(uint8_t *buf, int len) {
*(buf + encoded_size) = _5g_IASel; encoded_size++;
}
else {
*(buf + encoded_size) = length - 1; encoded_size++;
*(buf + encoded_size) = length - 2; encoded_size++;
*(buf + encoded_size) = _5g_EASel; encoded_size++;
*(buf + encoded_size) = _5g_IASel; encoded_size++;
}
......
#include "_5GSTrackingAreaIdList.hpp"
#include "String2Value.hpp"
using namespace nas;
_5GSTrackingAreaIdList::_5GSTrackingAreaIdList(uint8_t iei, std::vector<p_tai_t> tai_list){
m_tai_list = tai_list;
m_iei = iei;
}
int _5GSTrackingAreaIdList::encode2buffer(uint8_t *buf, int len){
int encoded_size = 0, length = 0;
if(m_iei){
*(buf+encoded_size) = m_iei; encoded_size ++;
}
encoded_size ++;//for length octet
for(int i=0; i<m_tai_list.size(); i++){
int item_len = 0;
switch(m_tai_list[i].type){
case 0x00:{
item_len += encode_00_type(m_tai_list[i], buf+encoded_size, len-encoded_size);
}break;
case 0x01:{
item_len += encode_01_type(m_tai_list[i], buf+encoded_size, len-encoded_size);
}break;
case 0x10:{
item_len += encode_10_type(m_tai_list[i], buf+encoded_size, len-encoded_size);
}break;
}
encoded_size += item_len; length += item_len;
}
*(buf + encoded_size - length -1) = length;
return encoded_size;
}
int _5GSTrackingAreaIdList::encode_00_type(p_tai_t item, uint8_t *buf, int len){
int encoded_size = 0;
uint8_t octet = 0x00 | ((item.tac_list.size()-1) & 0x1f);
*(buf+encoded_size) = octet; encoded_size++;
encoded_size += encode_mcc_mnc(item.plmn_list[0], buf+encoded_size, len-encoded_size);
for(int i=0; i<item.tac_list.size(); i++){
octet = (item.tac_list[i] & 0x00ff0000) >> 16; *(buf+encoded_size) = octet; encoded_size++;
octet = (item.tac_list[i] & 0x0000ff00) >> 8; *(buf+encoded_size) = octet; encoded_size++;
octet = (item.tac_list[i] & 0x000000ff) >> 0; *(buf+encoded_size) = octet; encoded_size++;
}
return encoded_size;
}
int _5GSTrackingAreaIdList::encode_01_type(p_tai_t item, uint8_t *buf, int len){
}
int _5GSTrackingAreaIdList::encode_10_type(p_tai_t item, uint8_t *buf, int len){
}
int _5GSTrackingAreaIdList::encode_mcc_mnc(nas_plmn_t plmn, uint8_t *buf, int len){
int encoded_size = 0;
int mcc = fromString<int>(plmn.mcc);
int mnc = fromString<int>(plmn.mnc);
*(buf+encoded_size) = (0x0f & (mcc/100)) | ((0x0f & ((mcc%100)/10))<<4);
encoded_size += 1;
if(!(mnc/100)){
*(buf+encoded_size) = (0x0f & (mcc%10)) | 0xf0;
encoded_size += 1;
*(buf+encoded_size) = (0x0f & ((mnc%100)/10)) | ((0x0f & (mnc%10))<<4);
encoded_size += 1;
}else{
*(buf+encoded_size) = (0x0f & (mcc%10)) | ((0x0f & (mnc%10))<<4);
encoded_size += 1;
*(buf+encoded_size) = ((0x0f & ((mnc%100)/10))<<4) | (0x0f & (mnc/100));
encoded_size += 1;
}
return encoded_size;
}
#ifndef __5GSTrackingAreaIdList_H_
#define __5GSTrackingAreaIdList_H_
#include <vector>
#include "struct.hpp"
namespace nas{
class _5GSTrackingAreaIdList{
public:
_5GSTrackingAreaIdList(uint8_t iei, std::vector<p_tai_t> tai_list);
int encode2buffer(uint8_t *buf, int len);
private:
uint8_t m_iei;
std::vector<p_tai_t> m_tai_list;
private:
int encode_00_type(p_tai_t item, uint8_t *buf, int len);
int encode_01_type(p_tai_t item, uint8_t *buf, int len);
int encode_10_type(p_tai_t item, uint8_t *buf, int len);
int encode_mcc_mnc(nas_plmn_t plmn, uint8_t *buf, int len);
};
}
#endif
......@@ -8,11 +8,12 @@ _5GS_Network_Feature_Support::_5GS_Network_Feature_Support(uint8_t iei){
_5GS_Network_Feature_Support::_5GS_Network_Feature_Support() {}
_5GS_Network_Feature_Support::~_5GS_Network_Feature_Support(){}
_5GS_Network_Feature_Support::_5GS_Network_Feature_Support(const uint8_t iei, uint8_t value)
_5GS_Network_Feature_Support::_5GS_Network_Feature_Support(const uint8_t iei, uint8_t value, uint8_t value2)
{
_iei = iei;
_value=value;
length = 3;
_value2 = value2;
length = 4;
}
void _5GS_Network_Feature_Support::setValue(uint8_t value) {
......@@ -32,6 +33,7 @@ int _5GS_Network_Feature_Support::encode2buffer(uint8_t *buf, int len) {
*(buf + encoded_size) = _iei; encoded_size++;
*(buf + encoded_size) = length - 2; encoded_size++;
*(buf + encoded_size) = _value; encoded_size++;
*(buf + encoded_size) = _value2; encoded_size++;
}
else {
*(buf + encoded_size) = length - 1; encoded_size++;
......
......@@ -10,7 +10,7 @@ public:
_5GS_Network_Feature_Support(uint8_t iei);
_5GS_Network_Feature_Support();
~_5GS_Network_Feature_Support();
_5GS_Network_Feature_Support(const uint8_t iei, uint8_t value);
_5GS_Network_Feature_Support(const uint8_t iei, uint8_t value, uint8_t value2);
void setValue(uint8_t value);
uint8_t getValue();
int encode2buffer(uint8_t *buf, int len);
......@@ -19,6 +19,7 @@ private:
uint8_t _iei;
uint8_t length;
uint8_t _value;
uint8_t _value2;
};
......
#ifndef _STRUCT_H_
#define _STRUCT_H_
#include <iostream>
#include <stdint.h>
#include <vector>
extern "C" {
#include "bstrlib.h"
#include "TLVEncoder.h"
#include "TLVDecoder.h"
}
using namespace std;
namespace nas{
typedef struct SNSSAI_s {
uint8_t sst;
int32_t sd;//若sd不存在,则sd设置为-1
int32_t mHplmnSst;//若sd不存在,则sd设置为-1
int32_t mHplmnSd;//若sd不存在,则sd设置为-1
}SNSSAI_t;
typedef struct {
uint8_t ie_type;
uint8_t ie_len;
bstring ie_value;
}IE_t;
typedef struct {
uint8_t ie_type;
uint16_t ie_len;
bstring ie_value;
}IE_t_E;
typedef struct {
uint8_t payloadContainerType : 4;
std::vector<IE_t> optionalIE;
}PayloadContainerEntry;
typedef struct IMEISV_s{
bstring identity;
}IMEISV_t;
typedef struct{
string mcc;
string mnc;
}nas_plmn_t;
typedef struct{
uint8_t type;
std::vector<nas_plmn_t> plmn_list;
std::vector<uint32_t> tac_list;
}p_tai_t;
}
#endif
......@@ -20,10 +20,22 @@ void AuthenticationFailure::setHeader(uint8_t security_header_type) {
void AuthenticationFailure::set_5GMM_Cause(uint8_t value) {
ie_5gmm_cause = new _5GMM_Cause(0x00,value);
}
void AuthenticationFailure::setAuthentication_Failure_Parameter(uint8_t *value) {
ie_authentication_failure_parameter = new Authentication_Failure_Parameter(0x30, value);
uint8_t AuthenticationFailure::get5GMmCause() {
if (ie_5gmm_cause) {
return ie_5gmm_cause->getValue();
}
else { return -1; }
}
void AuthenticationFailure::setAuthentication_Failure_Parameter(bstring auts) {
ie_authentication_failure_parameter = new Authentication_Failure_Parameter(0x30, auts);
}
bool AuthenticationFailure::getAutsInAuthFailPara(bstring &auts) {
if (ie_authentication_failure_parameter) {
ie_authentication_failure_parameter->getValue(auts);
return true;
}
else { return false; }
}
int AuthenticationFailure::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().debug("encoding AuthenticationFailure message");
......
......@@ -13,8 +13,10 @@ namespace nas {
int decodefrombuffer(NasMmPlainHeader * header, uint8_t *buf, int len);
void setHeader(uint8_t security_header_type);
void set_5GMM_Cause(uint8_t value);
void setAuthentication_Failure_Parameter(uint8_t *value);
void setAuthentication_Failure_Parameter(bstring auts);
uint8_t get5GMmCause();
bool getAutsInAuthFailPara(bstring &auts);
public:
NasMmPlainHeader *plain_header;
_5GMM_Cause *ie_5gmm_cause;
......
......@@ -50,7 +50,8 @@ int AuthenticationRequest::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().warn("IE ie_ngKSI is not avaliable");
}
else {
if (int size = ie_ngKSI->encode2buffer(buf + encoded_size, len - encoded_size)) {
int size = ie_ngKSI->encode2buffer(buf + encoded_size, len - encoded_size);
if (size != -1) {
encoded_size += size;
}
else {
......@@ -62,7 +63,9 @@ int AuthenticationRequest::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().warn("IE ie_abba is not avaliable");
}
else {
if (int size = ie_abba->encode2buffer(buf + encoded_size, len - encoded_size)) {
int size = ie_abba->encode2buffer(buf + encoded_size, len - encoded_size);
if (size != 0) {
Logger::nas_mm().debug("0x%x, 0x%x, 0x%x", (buf+encoded_size)[0],(buf+encoded_size)[1],(buf+encoded_size)[2]);
encoded_size += size;
}
else {
......@@ -74,7 +77,8 @@ int AuthenticationRequest::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().warn("IE ie_authentication_parameter_rand is not avaliable");
}
else {
if (int size = ie_authentication_parameter_rand->encode2buffer(buf + encoded_size, len - encoded_size)) {
int size = ie_authentication_parameter_rand->encode2buffer(buf + encoded_size, len - encoded_size);
if (size != 0) {
encoded_size += size;
}
else {
......@@ -86,7 +90,8 @@ int AuthenticationRequest::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().warn("IE ie_authentication_parameter_autn is not avaliable");
}
else {
if (int size = ie_authentication_parameter_autn->encode2buffer(buf + encoded_size, len - encoded_size)) {
int size = ie_authentication_parameter_autn->encode2buffer(buf + encoded_size, len - encoded_size);
if (size != 0) {
encoded_size += size;
}
else {
......@@ -98,7 +103,8 @@ int AuthenticationRequest::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().warn("IE ie_eap_message is not avaliable");
}
else {
if (int size = ie_eap_message->encode2buffer(buf + encoded_size, len - encoded_size)) {
int size = ie_eap_message->encode2buffer(buf + encoded_size, len - encoded_size);
if (size != 0) {
encoded_size += size;
}
else {
......@@ -108,7 +114,7 @@ int AuthenticationRequest::encode2buffer(uint8_t *buf, int len) {
}
Logger::nas_mm().debug("encoded AuthenticationRequest message len(%d)", encoded_size);
return 1;
return encoded_size;
}
int AuthenticationRequest::decodefrombuffer(NasMmPlainHeader * header, uint8_t *buf, int len) {
......@@ -116,7 +122,8 @@ int AuthenticationRequest::decodefrombuffer(NasMmPlainHeader * header, uint8_t *
int decoded_size = 3;
plain_header = header;
ie_ngKSI = new NasKeySetIdentifier();
decoded_size += ie_ngKSI->decodefrombuffer(buf + decoded_size, len - decoded_size, false);
decoded_size += ie_ngKSI->decodefrombuffer(buf + decoded_size, len - decoded_size, false, false);
decoded_size ++;
ie_abba = new ABBA();
decoded_size += ie_abba->decodefrombuffer(buf + decoded_size, len - decoded_size, false);
Logger::nas_mm().debug("decoded_size(%d)", decoded_size);
......
......@@ -24,9 +24,9 @@ void AuthenticationResponse::setAuthentication_Response_Parameter(bstring para)
bool AuthenticationResponse::getAuthenticationResponseParameter(bstring &para) {
if (ie_authentication_response_parameter) {
ie_authentication_response_parameter->getValue(para);
return 0;
return true;
}
else { return -1; }
else { return false; }
}
void AuthenticationResponse::setEAP_Message(bstring eap) {
ie_eap_message = new EAP_Message(0x78, eap);
......
......@@ -84,7 +84,8 @@ int AuthenticationResult::decodefrombuffer(NasMmPlainHeader * header, uint8_t *b
int decoded_size = 3;
plain_header = header;
ie_ngKSI = new NasKeySetIdentifier();
decoded_size += ie_ngKSI->decodefrombuffer(buf + decoded_size, len - decoded_size, false);
decoded_size += ie_ngKSI->decodefrombuffer(buf + decoded_size, len - decoded_size, false, false);
decoded_size ++;
ie_eap_message = new EAP_Message();
decoded_size += ie_eap_message->decodefrombuffer(buf + decoded_size, len - decoded_size, false);
Logger::nas_mm().debug("decoded_size(%d)", decoded_size);
......
This diff is collapsed.
......@@ -14,7 +14,8 @@ namespace nas {
void setHeader(uint8_t security_header_type);
void setPayload_Container_Type(uint8_t value);
void setPayload_Container(std::vector<PayloadContainerEntry> content);
void setPDU_Session_Identity_2(uint8_t value);
void setPayload_Container(uint8_t *buf, int len);
void setPDUSessionId(uint8_t value);
void setAdditional_Information(uint8_t _length, uint8_t value);
void set_5GMM_Cause(uint8_t value);
void setBack_off_timer_value(uint8_t unit, uint8_t value);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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