Commit 058c666e authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Apply Google style format

parent 7b5b106a
......@@ -82,13 +82,15 @@ void amf_n1_task(void*) {
switch (msg->msg_type) {
case UL_NAS_DATA_IND: { //receive nas message buffer from amf_n2
Logger::amf_n1().info("Received UL_NAS_DATA_IND");
itti_uplink_nas_data_ind *m = dynamic_cast<itti_uplink_nas_data_ind*>(msg);
itti_uplink_nas_data_ind *m =
dynamic_cast<itti_uplink_nas_data_ind*>(msg);
amf_n1_inst->handle_itti_message(ref(*m));
}
break;
case DOWNLINK_NAS_TRANSFER: {
Logger::amf_n1().info("Received DOWNLINK_NAS_TRANSFER");
itti_downlink_nas_transfer *m = dynamic_cast<itti_downlink_nas_transfer*>(msg);
itti_downlink_nas_transfer *m =
dynamic_cast<itti_downlink_nas_transfer*>(msg);
amf_n1_inst->handle_itti_message(ref(*m));
}
break;
......@@ -119,33 +121,45 @@ void amf_n1::handle_itti_message(itti_downlink_nas_transfer &itti_msg) {
if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id))
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
else {
Logger::amf_n1().warn("No existed nas_context with amf_ue_ngap_id(0x%x)", amf_ue_ngap_id);
Logger::amf_n1().warn("No existed nas_context with amf_ue_ngap_id(0x%x)",
amf_ue_ngap_id);
return;
}
nas_secu_ctx *secu = nc.get()->security_ctx;
bstring protected_nas;
encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK, (uint8_t*) bdata(itti_msg.dl_nas), blength(itti_msg.dl_nas), protected_nas);
encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK,
(uint8_t*) bdata(itti_msg.dl_nas),
blength(itti_msg.dl_nas), protected_nas);
if (itti_msg.is_n2sm_set) {
itti_pdu_session_resource_setup_request *psrsr = new itti_pdu_session_resource_setup_request(TASK_AMF_N1, TASK_AMF_N2);
itti_pdu_session_resource_setup_request *psrsr =
new itti_pdu_session_resource_setup_request(TASK_AMF_N1, TASK_AMF_N2);
psrsr->nas = protected_nas;
psrsr->n2sm = itti_msg.n2sm;
psrsr->amf_ue_ngap_id = amf_ue_ngap_id;
psrsr->ran_ue_ngap_id = ran_ue_ngap_id;
psrsr->pdu_session_id = itti_msg.pdu_session_id;
std::shared_ptr<itti_pdu_session_resource_setup_request> i = std::shared_ptr < itti_pdu_session_resource_setup_request > (psrsr);
std::shared_ptr<itti_pdu_session_resource_setup_request> i = std::shared_ptr
< itti_pdu_session_resource_setup_request > (psrsr);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2", i->get_msg_name());
Logger::amf_n1().error(
"Could not send ITTI message %s to task TASK_AMF_N2",
i->get_msg_name());
}
} else {
itti_dl_nas_transport *dnt = new itti_dl_nas_transport(TASK_AMF_N1, TASK_AMF_N2);
itti_dl_nas_transport *dnt = new itti_dl_nas_transport(TASK_AMF_N1,
TASK_AMF_N2);
dnt->nas = protected_nas;
dnt->amf_ue_ngap_id = amf_ue_ngap_id;
dnt->ran_ue_ngap_id = ran_ue_ngap_id;
std::shared_ptr<itti_dl_nas_transport> i = std::shared_ptr < itti_dl_nas_transport > (dnt);
std::shared_ptr<itti_dl_nas_transport> i = std::shared_ptr
< itti_dl_nas_transport > (dnt);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2", i->get_msg_name());
Logger::amf_n1().error(
"Could not send ITTI message %s to task TASK_AMF_N2",
i->get_msg_name());
}
}
}
......@@ -154,14 +168,17 @@ void amf_n1::handle_itti_message(itti_downlink_nas_transfer &itti_msg) {
void amf_n1::handle_itti_message(itti_uplink_nas_data_ind &nas_data_ind) {
long amf_ue_ngap_id = nas_data_ind.amf_ue_ngap_id;
uint32_t ran_ue_ngap_id = nas_data_ind.ran_ue_ngap_id;
std::string nas_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id) + ":amfid_" + to_string(amf_ue_ngap_id); // key for nas_context, option 1
std::string nas_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id)
+ ":amfid_" + to_string(amf_ue_ngap_id); // key for nas_context, option 1
std::string snn;
if (nas_data_ind.mnc.length() == 2)
snn = "5G:mnc0" + nas_data_ind.mnc + ".mcc" + nas_data_ind.mcc + ".3gppnetwork.org";
snn = "5G:mnc0" + nas_data_ind.mnc + ".mcc" + nas_data_ind.mcc
+ ".3gppnetwork.org";
else
snn = "5G:mnc" + nas_data_ind.mnc + ".mcc" + nas_data_ind.mcc + ".3gppnetwork.org";
snn = "5G:mnc" + nas_data_ind.mnc + ".mcc" + nas_data_ind.mcc
+ ".3gppnetwork.org";
Logger::amf_n1().debug("Serving network name %s", snn.c_str());
plmn_t plmn = {};
plmn_t plmn = { };
plmn.mnc = nas_data_ind.mnc;
plmn.mcc = nas_data_ind.mcc;
......@@ -174,17 +191,19 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind &nas_data_ind) {
if (is_guti_2_nas_context(guti))
nc = guti_2_nas_context(guti);
else {
Logger::amf_n1().error("No existing nas_context with GUTI %s", nas_data_ind.guti.c_str());
Logger::amf_n1().error("No existing nas_context with GUTI %s",
nas_data_ind.guti.c_str());
return;
}
} else {
if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id))
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
else
Logger::amf_n1().warn("No existing nas_context with amf_ue_ngap_id 0x%x", amf_ue_ngap_id);
Logger::amf_n1().warn("No existing nas_context with amf_ue_ngap_id 0x%x",
amf_ue_ngap_id);
}
SecurityHeaderType type = {};
SecurityHeaderType type = { };
if (!check_security_header_type(type, (uint8_t*) bdata(recved_nas_msg))) {
Logger::amf_n1().error("Not 5GS MOBILITY MANAGEMENT message");
return;
......@@ -199,24 +218,34 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind &nas_data_ind) {
case IntegrityProtected: {
Logger::amf_n1().debug("Received integrity protected NAS message");
ulCount = *((uint8_t*) bdata(recved_nas_msg) + 6);
Logger::amf_n1().info("Integrity protected message: ulCount(%d)", ulCount);
decoded_plain_msg = blk2bstr((uint8_t*) bdata(recved_nas_msg) + 7, blength(recved_nas_msg) - 7);
Logger::amf_n1().info("Integrity protected message: ulCount(%d)",
ulCount);
decoded_plain_msg = blk2bstr((uint8_t*) bdata(recved_nas_msg) + 7,
blength(recved_nas_msg) - 7);
}
break;
case IntegrityProtectedAndCiphered: {
Logger::amf_n1().debug("Received integrity protected and ciphered NAS message");
Logger::amf_n1().debug(
"Received integrity protected and ciphered NAS message");
} //break;
case IntegrityProtectedWithNew5GNASSecurityContext: {
Logger::amf_n1().debug("Received integrity protected with new security context NAS message");
Logger::amf_n1().debug(
"Received integrity protected with new security context NAS message");
} //break;
case IntegrityProtectedAndCipheredWithNew5GNASSecurityContext: {
Logger::amf_n1().debug("Received integrity protected and ciphered with new security context NAS message");
Logger::amf_n1().debug(
"Received integrity protected and ciphered with new security context NAS message");
if (nc.get() == nullptr) {
Logger::amf_n1().debug("Abnormal condition: no existed nas_context. exit...");
Logger::amf_n1().debug(
"Abnormal condition: no existed nas_context. exit...");
return;
}
uint32_t mac32 = 0;
if (!nas_message_integrity_protected(nc.get()->security_ctx, NAS_MESSAGE_UPLINK, (uint8_t*) bdata(recved_nas_msg) + 6, blength(recved_nas_msg) - 6, mac32)) {
if (!nas_message_integrity_protected(nc.get()->security_ctx,
NAS_MESSAGE_UPLINK,
(uint8_t*) bdata(recved_nas_msg) + 6,
blength(recved_nas_msg) - 6,
mac32)) {
//IA0_5G
//TODO:
} else {
......@@ -224,7 +253,8 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind &nas_data_ind) {
uint8_t *buf = (uint8_t*) bdata(recved_nas_msg);
int buf_len = blength(recved_nas_msg);
uint32_t mac32_recv = ntohl((((uint32_t*) (buf + 2))[0]));
Logger::amf_n1().debug("Received mac32 (0x%x) from the message", mac32_recv);
Logger::amf_n1().debug("Received mac32 (0x%x) from the message",
mac32_recv);
if (mac32 == mac32_recv) {
isMatched = true;
Logger::amf_n1().error("Integrity matched");
......@@ -235,7 +265,9 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind &nas_data_ind) {
return;
} else {
bstring ciphered = blk2bstr(buf + 7, buf_len - 7);
if (!nas_message_cipher_protected(nc.get()->security_ctx, NAS_MESSAGE_UPLINK, ciphered, decoded_plain_msg)) {
if (!nas_message_cipher_protected(nc.get()->security_ctx,
NAS_MESSAGE_UPLINK, ciphered,
decoded_plain_msg)) {
Logger::amf_n1().error("Decrypt NAS message failure");
return;
}
......@@ -247,24 +279,39 @@ 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...");
//dump_nas_message((uint8_t*)bdata(decoded_plain_msg), blength(decoded_plain_msg));
print_buffer("amf_n1", "Decoded plain NAS Message buffer", (uint8_t*) bdata(decoded_plain_msg), blength(decoded_plain_msg));
nas_signalling_establishment_request_handle(type, nc, nas_data_ind.ran_ue_ngap_id, nas_data_ind.amf_ue_ngap_id, decoded_plain_msg, snn, ulCount);
print_buffer("amf_n1", "Decoded plain NAS Message buffer",
(uint8_t*) bdata(decoded_plain_msg),
blength(decoded_plain_msg));
nas_signalling_establishment_request_handle(type, nc,
nas_data_ind.ran_ue_ngap_id,
nas_data_ind.amf_ue_ngap_id,
decoded_plain_msg, snn,
ulCount);
} else {
Logger::amf_n1().debug("Received uplink NAS message...");
print_buffer("amf_n1", "Decoded NAS message buffer", (uint8_t*) bdata(decoded_plain_msg), blength(decoded_plain_msg));
uplink_nas_msg_handle(nas_data_ind.ran_ue_ngap_id, nas_data_ind.amf_ue_ngap_id, decoded_plain_msg, plmn);
print_buffer("amf_n1", "Decoded NAS message buffer",
(uint8_t*) bdata(decoded_plain_msg),
blength(decoded_plain_msg));
uplink_nas_msg_handle(nas_data_ind.ran_ue_ngap_id,
nas_data_ind.amf_ue_ngap_id, decoded_plain_msg, plmn);
}
}
// handlers for lower layer
//------------------------------------------------------------------------------
void amf_n1::nas_signalling_establishment_request_handle(SecurityHeaderType type, std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg, std::string snn, uint8_t ulCount) {
void amf_n1::nas_signalling_establishment_request_handle(
SecurityHeaderType type, std::shared_ptr<nas_context> nc,
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg,
std::string snn, uint8_t ulCount) {
//1. Create nas context, or update nas context
if ((nc.get() == nullptr) && (type == PlainNasMsg)) {
Logger::amf_n1().debug("No existing nas_context with amf_ue_ngap_id 0x%x --> Create a new one", amf_ue_ngap_id);
Logger::amf_n1().debug(
"No existing nas_context with amf_ue_ngap_id 0x%x --> Create a new one",
amf_ue_ngap_id);
nc = std::shared_ptr < nas_context > (new nas_context);
if (!nc.get()) {
Logger::amf_n1().error("Cannot allocate memory for new nas_context, exit...");
Logger::amf_n1().error(
"Cannot allocate memory for new nas_context, exit...");
return;
}
set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
......@@ -285,14 +332,17 @@ void amf_n1::nas_signalling_establishment_request_handle(SecurityHeaderType type
Logger::amf_n1().debug("NAS message type 0x%x", message_type);
switch (message_type) {
case REGISTRATION_REQUEST: {
Logger::amf_n1().debug("Received registration request message, handling...");
registration_request_handle(true, nc, ran_ue_ngap_id, amf_ue_ngap_id, snn, plain_msg);
Logger::amf_n1().debug(
"Received registration request message, handling...");
registration_request_handle(true, nc, ran_ue_ngap_id, amf_ue_ngap_id, snn,
plain_msg);
}
break;
case SERVICE_REQUEST: {
Logger::amf_n1().debug("Received service request message, handling...");
nc.get()->security_ctx->ul_count.seq_num = ulCount;
service_request_handle(true, nc, ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
service_request_handle(true, nc, ran_ue_ngap_id, amf_ue_ngap_id,
plain_msg);
}
break;
default:
......@@ -301,27 +351,32 @@ void amf_n1::nas_signalling_establishment_request_handle(SecurityHeaderType type
}
//------------------------------------------------------------------------------
void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg) {
void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
bstring plain_msg) {
uint8_t *buf = (uint8_t*) bdata(plain_msg);
uint8_t message_type = *(buf + 2);
switch (message_type) {
case AUTHENTICATION_RESPONSE: {
Logger::amf_n1().debug("Received authentication response message, handling...");
Logger::amf_n1().debug(
"Received authentication response message, handling...");
authentication_response_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
}
break;
case AUTHENTICATION_FAILURE: {
Logger::amf_n1().debug("Received authentication failure message, handling...");
Logger::amf_n1().debug(
"Received authentication failure message, handling...");
authentication_failure_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
}
break;
case SECURITY_MODE_COMPLETE: {
Logger::amf_n1().debug("Received security mode complete message, handling...");
Logger::amf_n1().debug(
"Received security mode complete message, handling...");
security_mode_complete_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
}
break;
case SECURITY_MODE_REJECT: {
Logger::amf_n1().debug("Received security mode reject message, handling...");
Logger::amf_n1().debug(
"Received security mode reject message, handling...");
security_mode_reject_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
}
break;
......@@ -331,12 +386,15 @@ void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
}
break;
case UE_INIT_DEREGISTER: {
Logger::amf_n1().debug("Received de-registration request message, handling...");
ue_initiate_de_registration_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
Logger::amf_n1().debug(
"Received de-registration request message, handling...");
ue_initiate_de_registration_handle(ran_ue_ngap_id, amf_ue_ngap_id,
plain_msg);
}
break;
case REGISTRATION_COMPLETE: {
Logger::amf_n1().debug("Received registration complete message, handling...");
Logger::amf_n1().debug(
"Received registration complete message, handling...");
//TODO
}
break;
......@@ -346,29 +404,33 @@ void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
}
}
//------------------------------------------------------------------------------
void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg, plmn_t plmn) {
void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
bstring plain_msg, plmn_t plmn) {
uint8_t *buf = (uint8_t*) bdata(plain_msg);
uint8_t message_type = *(buf + 2);
switch (message_type) {
case AUTHENTICATION_RESPONSE: {
Logger::amf_n1().debug("Received authentication response message, handling...");
Logger::amf_n1().debug(
"Received authentication response message, handling...");
authentication_response_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
}
break;
case AUTHENTICATION_FAILURE: {
Logger::amf_n1().debug("Received authentication failure message, handling...");
Logger::amf_n1().debug(
"Received authentication failure message, handling...");
authentication_failure_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
}
break;
case SECURITY_MODE_COMPLETE: {
Logger::amf_n1().debug("Received security mode complete message, handling...");
Logger::amf_n1().debug(
"Received security mode complete message, handling...");
security_mode_complete_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
}
break;
case SECURITY_MODE_REJECT: {
Logger::amf_n1().debug("Received security mode reject message, handling...");
Logger::amf_n1().debug(
"Received security mode reject message, handling...");
security_mode_reject_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
}
break;
......@@ -378,12 +440,15 @@ void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
}
break;
case UE_INIT_DEREGISTER: {
Logger::amf_n1().debug("Received de-registration request message, handling...");
ue_initiate_de_registration_handle(ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
Logger::amf_n1().debug(
"Received de-registration request message, handling...");
ue_initiate_de_registration_handle(ran_ue_ngap_id, amf_ue_ngap_id,
plain_msg);
}
break;
case REGISTRATION_COMPLETE: {
Logger::amf_n1().debug("Received registration complete message, handling...");
Logger::amf_n1().debug(
"Received registration complete message, handling...");
//TODO
}
break;
......@@ -395,7 +460,8 @@ void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
// nas message decode
//------------------------------------------------------------------------------
bool amf_n1::check_security_header_type(SecurityHeaderType &type, uint8_t *buffer) {
bool amf_n1::check_security_header_type(SecurityHeaderType &type,
uint8_t *buffer) {
uint8_t octet = 0, decoded_size = 0;
octet = *(buffer + decoded_size);
decoded_size++;
......@@ -425,7 +491,10 @@ bool amf_n1::check_security_header_type(SecurityHeaderType &type, uint8_t *buffe
//nas message handlers
//------------------------------------------------------------------------------
void amf_n1::service_request_handle(bool isNasSig, std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas) {
void amf_n1::service_request_handle(bool isNasSig,
std::shared_ptr<nas_context> nc,
uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, bstring nas) {
set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
nas_secu_ctx *secu = nc.get()->security_ctx;
ServiceRequest *serReq = new ServiceRequest();
......@@ -437,7 +506,9 @@ void amf_n1::service_request_handle(bool isNasSig, std::shared_ptr<nas_context>
uint8_t buffer[100];
int encoded_size = serApt->encode2buffer(buffer, 100);
bstring protectedNas;
encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK, buffer, encoded_size, protectedNas);
encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
protectedNas);
uint8_t *kamf = nc.get()->kamf[secu->vector_pointer];
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
......@@ -451,7 +522,8 @@ void amf_n1::service_request_handle(bool isNasSig, std::shared_ptr<nas_context>
/* by liuyu */
supi2amfId[supi] = amf_ue_ngap_id;
supi2ranId[supi] = ran_ue_ngap_id;
Logger::amf_n1().debug("amf_ue_ngap_id %d, ran_ue_ngap_id %d", amf_ue_ngap_id, ran_ue_ngap_id);
Logger::amf_n1().debug("amf_ue_ngap_id %d, ran_ue_ngap_id %d", amf_ue_ngap_id,
ran_ue_ngap_id);
Logger::amf_n1().debug("Key for pdu session context: SUPI %s", supi.c_str());
std::shared_ptr<pdu_session_context> psc;
if (amf_n11_inst->is_supi_to_pdu_ctx(supi)) {
......@@ -461,10 +533,12 @@ void amf_n1::service_request_handle(bool isNasSig, std::shared_ptr<nas_context>
return;
}
} else {
Logger::amf_n1().error("Cannot get pdu_session_context with SUPI %s", supi.c_str());
Logger::amf_n1().error("Cannot get pdu_session_context with SUPI %s",
supi.c_str());
}
itti_initial_context_setup_request *itti_msg = new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
itti_initial_context_setup_request *itti_msg =
new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
itti_msg->nas = protectedNas;
......@@ -472,15 +546,21 @@ void amf_n1::service_request_handle(bool isNasSig, std::shared_ptr<nas_context>
itti_msg->is_sr = true; //service request indicator
itti_msg->pdu_session_id = psc.get()->pdu_session_id;
itti_msg->n2sm = psc.get()->n2sm;
std::shared_ptr<itti_initial_context_setup_request> i = std::shared_ptr < itti_initial_context_setup_request > (itti_msg);
std::shared_ptr<itti_initial_context_setup_request> i = std::shared_ptr
< itti_initial_context_setup_request > (itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2", i->get_msg_name());
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2",
i->get_msg_name());
}
}
//------------------------------------------------------------------------------
void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, std::string snn, bstring reg) {
void amf_n1::registration_request_handle(bool isNasSig,
std::shared_ptr<nas_context> nc,
uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, std::string snn,
bstring reg) {
//Decode registration request message
RegistrationRequest *regReq = new RegistrationRequest();
regReq->decodefrombuffer(nullptr, (uint8_t*) bdata(reg), blength(reg));
......@@ -499,14 +579,18 @@ void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_cont
supi2amfId[("imsi-" + nc.get()->imsi)] = amf_ue_ngap_id;
supi2ranId[("imsi-" + nc.get()->imsi)] = ran_ue_ngap_id;
imsi2nas_context[("imsi-" + nc.get()->imsi)] = nc;
Logger::amf_n1().info("Associating IMSI %s with nas_context %p", ("imsi-" + nc.get()->imsi).c_str(), nc.get());
Logger::amf_n1().info("Associating IMSI %s with nas_context %p",
("imsi-" + nc.get()->imsi).c_str(), nc.get());
if (!nc.get()->is_stacs_available) {
string ue_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id) + ":amfid_" + to_string(amf_ue_ngap_id);
string ue_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id)
+ ":amfid_" + to_string(amf_ue_ngap_id);
std::shared_ptr<ue_context> uc;
Logger::amf_n1().info("Try to find ue_context in amf_app using ran_amf_id %s", ue_context_key.c_str());
Logger::amf_n1().info(
"Try to find ue_context in amf_app using ran_amf_id %s",
ue_context_key.c_str());
uc = amf_app_inst->ran_amf_id_2_ue_context(ue_context_key);
ue_info_t ueItem;
ueItem.connStatus = "5GMM-CONNECTED";//"CM-CONNECTED";
ueItem.connStatus = "5GMM-CONNECTED"; //"CM-CONNECTED";
ueItem.registerStatus = "5GMM-REG-INITIATED"; //5GMM-COMMON-PROCEDURE-INITIATED
ueItem.ranid = ran_ue_ngap_id;
ueItem.amfid = amf_ue_ngap_id;
......@@ -542,7 +626,8 @@ void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_cont
supi2ranId[("imsi-" + nc.get()->imsi)] = ran_ue_ngap_id;
} else {
Logger::amf_n1().error("No nas_context with GUTI %s", guti.c_str());
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id, amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
amf_ue_ngap_id);
return;
}
} else {
......@@ -560,7 +645,8 @@ void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_cont
bool is_follow_on_req_pending;
if (!regReq->get5GSRegistrationType(is_follow_on_req_pending, reg_type)) {
Logger::amf_n1().error("Missing Mandatory IE 5GS Registration type...");
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO, ran_ue_ngap_id, amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
ran_ue_ngap_id, amf_ue_ngap_id);
return;
}
nc.get()->registration_type = reg_type;
......@@ -570,7 +656,8 @@ void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_cont
uint8_t ngKSI = regReq->getngKSI();
if (ngKSI == -1) {
Logger::amf_n1().error("Missing Mandatory IE ngKSI...");
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO, ran_ue_ngap_id, amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
ran_ue_ngap_id, amf_ue_ngap_id);
return;
}
nc.get()->ngKsi = ngKSI;
......@@ -584,8 +671,8 @@ void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_cont
nc.get()->mmCapability = _5g_mm_cap;
//Get UE Security Capability IE (optional), not included for periodic registration updating procedure
uint8_t encrypt_alg = {0};
uint8_t integrity_alg = {0};
uint8_t encrypt_alg = { 0 };
uint8_t integrity_alg = { 0 };
if (!regReq->getUeSecurityCapability(encrypt_alg, integrity_alg)) {
Logger::amf_n1().warn("No Optional IE UESecurityCapability available");
}
......@@ -593,7 +680,7 @@ void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_cont
nc.get()->ueSecurityCapInt = integrity_alg;
//Get Requested NSSAI (Optional IE), if provided
std::vector<SNSSAI_t> requestedNssai = {};
std::vector<SNSSAI_t> requestedNssai = { };
if (!regReq->getRequestedNssai(requestedNssai)) {
Logger::amf_n1().warn("No Optional IE RequestedNssai available");
}
......@@ -619,13 +706,16 @@ void amf_n1::registration_request_handle(bool isNasSig, std::shared_ptr<nas_cont
}
break;
case PERIODIC_REGISTRATION_UPDATING: {
Logger::amf_n1().error("Network doesn't support periodic registration, reject ...");
Logger::amf_n1().error(
"Network doesn't support periodic registration, reject ...");
}
break;
case EMERGENCY_REGISTRATION: {
if (!amf_cfg.is_emergency_support.compare("false")) {
Logger::amf_n1().error("Network doesn't support emergency registration, reject ...");
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id, amf_ue_ngap_id); //cause?
Logger::amf_n1().error(
"Network doesn't support emergency registration, reject ...");
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
amf_ue_ngap_id); //cause?
return;
}
}
......@@ -646,13 +736,15 @@ bool amf_n1::is_amf_ue_id_2_nas_context(const long &amf_ue_ngap_id) const {
}
//------------------------------------------------------------------------------
std::shared_ptr<nas_context> amf_n1::amf_ue_id_2_nas_context(const long &amf_ue_ngap_id) const {
std::shared_ptr<nas_context> amf_n1::amf_ue_id_2_nas_context(
const long &amf_ue_ngap_id) const {
std::shared_lock lock(m_amfueid2nas_context);
return amfueid2nas_context.at(amf_ue_ngap_id);
}
//------------------------------------------------------------------------------
void amf_n1::set_amf_ue_ngap_id_2_nas_context(const long &amf_ue_ngap_id, std::shared_ptr<nas_context> nc) {
void amf_n1::set_amf_ue_ngap_id_2_nas_context(const long &amf_ue_ngap_id,
std::shared_ptr<nas_context> nc) {
std::shared_lock lock(m_amfueid2nas_context);
amfueid2nas_context[amf_ue_ngap_id] = nc;
}
......@@ -664,41 +756,51 @@ bool amf_n1::is_guti_2_nas_context(const std::string &guti) const {
}
//------------------------------------------------------------------------------
std::shared_ptr<nas_context> amf_n1::guti_2_nas_context(const std::string &guti) const {
std::shared_ptr<nas_context> amf_n1::guti_2_nas_context(
const std::string &guti) const {
std::shared_lock lock(m_guti2nas_context);
return guti2nas_context.at(guti);
}
//------------------------------------------------------------------------------
void amf_n1::set_guti_2_nas_context(const std::string &guti, std::shared_ptr<nas_context> nc) {
void amf_n1::set_guti_2_nas_context(const std::string &guti,
std::shared_ptr<nas_context> nc) {
std::shared_lock lock(m_guti2nas_context);
guti2nas_context[guti] = nc;
}
// to lower layer TASK_N2
//------------------------------------------------------------------------------
void amf_n1::itti_send_dl_nas_buffer_to_task_n2(bstring &b, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id) {
itti_dl_nas_transport *msg = new itti_dl_nas_transport(TASK_AMF_N1, TASK_AMF_N2);
void amf_n1::itti_send_dl_nas_buffer_to_task_n2(bstring &b,
uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id) {
itti_dl_nas_transport *msg = new itti_dl_nas_transport(TASK_AMF_N1,
TASK_AMF_N2);
msg->ran_ue_ngap_id = ran_ue_ngap_id;
msg->amf_ue_ngap_id = amf_ue_ngap_id;
msg->nas = b;
std::shared_ptr<itti_dl_nas_transport> i = std::shared_ptr < itti_dl_nas_transport > (msg);
std::shared_ptr<itti_dl_nas_transport> i = std::shared_ptr
< itti_dl_nas_transport > (msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2", i->get_msg_name());
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2",
i->get_msg_name());
}
}
//------------------------------------------------------------------------------
// response messages
void amf_n1::response_registration_reject_msg(uint8_t cause_value, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id) {
void amf_n1::response_registration_reject_msg(uint8_t cause_value,
uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id) {
RegistrationReject *registrationRej = new RegistrationReject();
registrationRej->setHeader(PLAIN_5GS_MSG);
registrationRej->set_5GMM_Cause(cause_value);
uint8_t buffer[1024] = { 0 };
int encoded_size = registrationRej->encode2buffer(buffer, 1024);
//dump_nas_message(buffer, encoded_size);
print_buffer("amf_n1", "Registration-Reject message buffer", buffer, encoded_size);
print_buffer("amf_n1", "Registration-Reject message buffer", buffer,
encoded_size);
if (!encoded_size) {
Logger::nas_mm().error("Encode Registration-Reject message error");
return;
......@@ -721,22 +823,28 @@ void amf_n1::run_registration_procedure(std::shared_ptr<nas_context> &nc) {
if (nc.get()->is_imsi_present) {
Logger::amf_n1().debug("SUCI SUPI format IMSI is available");
if (!nc.get()->is_auth_vectors_present) {
Logger::amf_n1().debug("Authentication vector in nas_context is not available");
Logger::amf_n1().debug(
"Authentication vector in nas_context is not available");
if (auth_vectors_generator(nc)) { // all authentication in one(AMF)
ngksi_t ngksi = 0;
if (nc.get()->security_ctx && nc.get()->ngKsi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE) {
if (nc.get()->security_ctx
&& nc.get()->ngKsi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE) {
ngksi = (nc.get()->ngKsi + 1) % (NGKSI_MAX_VALUE + 1);
}
nc.get()->ngKsi = ngksi;
handle_auth_vector_successful_result(nc);
} else {
Logger::amf_n1().error("Request authentication vectors failure");
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, nc.get()->ran_ue_ngap_id, nc.get()->amf_ue_ngap_id); //cause?
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE,
nc.get()->ran_ue_ngap_id,
nc.get()->amf_ue_ngap_id); //cause?
}
} else {
Logger::amf_n1().debug("Authentication vector in nas_context is available");
Logger::amf_n1().debug(
"Authentication vector in nas_context is available");
ngksi_t ngksi = 0;
if (nc.get()->security_ctx && nc.get()->ngKsi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE) {
if (nc.get()->security_ctx
&& nc.get()->ngKsi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE) {
ngksi = (nc.get()->ngKsi + 1) % (NGKSI_MAX_VALUE + 1);
Logger::amf_n1().debug("New ngKsi (%d)", ngksi);
// ... how to handle?
......@@ -759,13 +867,15 @@ bool amf_n1::auth_vectors_generator(std::shared_ptr<nas_context> &nc) {
authentication_vectors_generator_in_ausf(nc);
Logger::amf_n1().debug("Deriving kamf");
for (int i = 0; i < MAX_5GS_AUTH_VECTORS; i++) {
Authentication_5gaka::derive_kamf(nc.get()->imsi, nc.get()->_5g_av[i].kseaf, nc.get()->kamf[i], 0x0000); //second parameter: abba
Authentication_5gaka::derive_kamf(nc.get()->imsi, nc.get()->_5g_av[i].kseaf,
nc.get()->kamf[i], 0x0000); //second parameter: abba
}
return true;
}
//------------------------------------------------------------------------------
bool amf_n1::authentication_vectors_generator_in_ausf(std::shared_ptr<nas_context> &nc) { // A.5, 3gpp ts33.501
bool amf_n1::authentication_vectors_generator_in_ausf(
std::shared_ptr<nas_context> &nc) { // A.5, 3gpp ts33.501
Logger::amf_n1().debug("Authentication_vectors_generator_in_ausf");
uint8_t inputString[MAX_5GS_AUTH_VECTORS][40];
uint8_t *xresStar[MAX_5GS_AUTH_VECTORS];
......@@ -782,7 +892,8 @@ bool amf_n1::authentication_vectors_generator_in_ausf(std::shared_ptr<nas_contex
memcpy(nc.get()->_5g_av[i].rand, nc.get()->_5g_he_av[i].rand, 16);
memcpy(nc.get()->_5g_av[i].autn, nc.get()->_5g_he_av[i].autn, 16);
uint8_t kseaf[32];
Authentication_5gaka::derive_kseaf(nc.get()->serving_network, nc.get()->_5g_he_av[i].kausf, kseaf);
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);
......@@ -794,7 +905,8 @@ bool amf_n1::authentication_vectors_generator_in_ausf(std::shared_ptr<nas_contex
//------------------------------------------------------------------------------
//TODO: Get from UDM
bool amf_n1::authentication_vectors_generator_in_udm(std::shared_ptr<nas_context> &nc) {
bool amf_n1::authentication_vectors_generator_in_udm(
std::shared_ptr<nas_context> &nc) {
Logger::amf_n1().debug("Generate authentication vectors");
uint8_t *sqn = NULL;
uint8_t *auts = (uint8_t*) bdata(nc.get()->auts);
......@@ -805,10 +917,11 @@ bool amf_n1::authentication_vectors_generator_in_udm(std::shared_ptr<nas_context
return false;
}
Logger::amf_n1().debug("Connected to MySQL successfully");
mysql_auth_info_t mysql_resp = {};
mysql_auth_info_t mysql_resp = { };
if (get_mysql_auth_info(nc.get()->imsi, mysql_resp)) {
if (auts) {
sqn = Authentication_5gaka::sqn_ms_derive(mysql_resp.opc, mysql_resp.key, auts, mysql_resp.rand);
sqn = Authentication_5gaka::sqn_ms_derive(mysql_resp.opc, mysql_resp.key,
auts, mysql_resp.rand);
if (sqn) {
generate_random(vector[0].rand, RAND_LENGTH);
mysql_push_rand_sqn(nc.get()->imsi, vector[0].rand, sqn);
......@@ -822,13 +935,17 @@ bool amf_n1::authentication_vectors_generator_in_udm(std::shared_ptr<nas_context
sqn = mysql_resp.sqn;
for (int i = 0; i < MAX_5GS_AUTH_VECTORS; i++) {
generate_random(vector[i].rand, RAND_LENGTH);
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, nc.get()->serving_network, vector[i]); //serving network name
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, nc.get()->serving_network, vector[i]); //serving network name
}
mysql_push_rand_sqn(nc.get()->imsi, vector[MAX_5GS_AUTH_VECTORS - 1].rand, sqn);
mysql_push_rand_sqn(nc.get()->imsi, vector[MAX_5GS_AUTH_VECTORS - 1].rand,
sqn);
} else {
Logger::amf_n1().debug("No auts ...");
Logger::amf_n1().debug("Receive information from MySQL with IMSI %s", nc.get()->imsi.c_str());
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);
......@@ -837,9 +954,11 @@ bool amf_n1::authentication_vectors_generator_in_udm(std::shared_ptr<nas_context
generate_random(vector[i].rand, RAND_LENGTH);
//print_buffer("amf_n1", "generated random: rand(5G HE AV)", vector[i].rand, 16);
sqn = mysql_resp.sqn;
generate_5g_he_av_in_udm(mysql_resp.opc, nc.get()->imsi, mysql_resp.key, sqn, nc.get()->serving_network, vector[i]); //serving network name
generate_5g_he_av_in_udm(mysql_resp.opc, nc.get()->imsi, mysql_resp.key,
sqn, nc.get()->serving_network, vector[i]); //serving network name
}
mysql_push_rand_sqn(nc.get()->imsi, vector[MAX_5GS_AUTH_VECTORS - 1].rand, sqn);
mysql_push_rand_sqn(nc.get()->imsi, vector[MAX_5GS_AUTH_VECTORS - 1].rand,
sqn);
}
mysql_increment_sqn(nc.get()->imsi);
} else {
......@@ -849,7 +968,10 @@ bool amf_n1::authentication_vectors_generator_in_udm(std::shared_ptr<nas_context
}
//------------------------------------------------------------------------------
void amf_n1::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 amf_n1::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) {
uint8_t amf[] = { 0x90, 0x01 };
uint8_t mac_a[8];
uint8_t ck[16];
......@@ -863,9 +985,11 @@ void amf_n1::test_generate_5g_he_av_in_udm(const uint8_t opc[16], uint8_t key[16
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);
annex_a_4_33501(ck, ik, vector.xres, vector.rand, serving_network, vector.xresStar);
annex_a_4_33501(ck, ik, vector.xres, vector.rand, serving_network,
vector.xresStar);
Authentication_5gaka::generate_autn(sqn, ak, amf, mac_a, vector.autn); // generate AUTN
Authentication_5gaka::derive_kausf(ck, ik, serving_network, sqn, ak, vector.kausf); //derive Kausf
Authentication_5gaka::derive_kausf(ck, ik, serving_network, sqn, ak,
vector.kausf); //derive Kausf
}
//------------------------------------------------------------------------------
......@@ -902,7 +1026,10 @@ void amf_n1::generate_random(uint8_t *random_p, ssize_t length) {
//------------------------------------------------------------------------------
//TODO: read from UDM
void amf_n1::generate_5g_he_av_in_udm(const uint8_t opc[16], string imsi, uint8_t key[16], uint8_t sqn[6], std::string serving_network, _5G_HE_AV_t &vector) {
void amf_n1::generate_5g_he_av_in_udm(const uint8_t opc[16], string imsi,
uint8_t key[16], uint8_t sqn[6],
std::string serving_network,
_5G_HE_AV_t &vector) {
Logger::amf_n1().debug("Generate 5g_he_av as in UDM");
uint8_t amf[] = { 0x90, 0x01 };
uint8_t mac_a[8];
......@@ -914,11 +1041,13 @@ void amf_n1::generate_5g_he_av_in_udm(const uint8_t opc[16], string imsi, uint8_
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);
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);
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);
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);
Authentication_5gaka::derive_kausf(ck, ik, serving_network, sqn, ak, vector.kausf); //derive Kausf
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);
Logger::amf_n1().debug("Generate_5g_he_av_in_udm finished!");
//ue_authentication_simulator(vector.rand, vector.autn);
......@@ -926,9 +1055,12 @@ void amf_n1::generate_5g_he_av_in_udm(const uint8_t opc[16], string imsi, uint8_
}
//------------------------------------------------------------------------------
void amf_n1::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) {
void amf_n1::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) {
OCTET_STRING_t netName;
OCTET_STRING_fromBuf(&netName, serving_network.c_str(), serving_network.length());
OCTET_STRING_fromBuf(&netName, serving_network.c_str(),
serving_network.length());
uint8_t S[100];
S[0] = 0x6B;
memcpy(&S[1], netName.buf, netName.size);
......@@ -970,13 +1102,16 @@ void amf_n1::annex_a_4_33501(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uin
}
//------------------------------------------------------------------------------
void amf_n1::handle_auth_vector_successful_result(std::shared_ptr<nas_context> nc) {
Logger::amf_n1().debug("Received security vectors, try to setup security with the UE");
void amf_n1::handle_auth_vector_successful_result(
std::shared_ptr<nas_context> nc) {
Logger::amf_n1().debug(
"Received security vectors, try to setup security with the UE");
nc.get()->is_auth_vectors_present = true;
ngksi_t ngksi = 0;
if (!nc.get()->security_ctx) {
nc.get()->security_ctx = new nas_secu_ctx();
if (nc.get()->security_ctx && nc.get()->ngKsi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE)
if (nc.get()->security_ctx
&& nc.get()->ngKsi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE)
ngksi = (nc.get()->security_ctx->ngksi + 1) % (NGKSI_MAX_VALUE + 1);
// ensure which vector is available?
nc.get()->ngKsi = ngksi;
......@@ -985,18 +1120,23 @@ void amf_n1::handle_auth_vector_successful_result(std::shared_ptr<nas_context> n
if (!start_authentication_procedure(nc, vindex, nc.get()->ngKsi)) {
Logger::amf_n1().error("Start authentication procedure failure, reject...");
Logger::amf_n1().error("Ran_ue_ngap_id 0x%x", nc.get()->ran_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO, nc.get()->ran_ue_ngap_id, nc.get()->amf_ue_ngap_id); //cause?
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
nc.get()->ran_ue_ngap_id,
nc.get()->amf_ue_ngap_id); //cause?
} else {
//update mm state -> COMMON-PROCEDURE-INITIATED
}
}
//------------------------------------------------------------------------------
bool amf_n1::start_authentication_procedure(std::shared_ptr<nas_context> nc, int vindex, uint8_t ngksi) {
bool amf_n1::start_authentication_procedure(std::shared_ptr<nas_context> nc,
int vindex, uint8_t ngksi) {
Logger::amf_n1().debug("****Starting authentication procedure****");
if (check_nas_common_procedure_on_going(nc)) {
Logger::amf_n1().error("Existed NAS common procedure on going, reject...");
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO, nc.get()->ran_ue_ngap_id, nc.get()->amf_ue_ngap_id); //cause?
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
nc.get()->ran_ue_ngap_id,
nc.get()->amf_ue_ngap_id); //cause?
return false;
}
......@@ -1029,14 +1169,17 @@ bool amf_n1::start_authentication_procedure(std::shared_ptr<nas_context> nc, int
delete authReq;
}
bstring b = blk2bstr(buffer, encoded_size);
print_buffer("amf_n1", "Authentication-Request message buffer", (uint8_t*) bdata(b), blength(b));
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);
itti_send_dl_nas_buffer_to_task_n2(b, nc.get()->ran_ue_ngap_id, nc.get()->amf_ue_ngap_id);
itti_send_dl_nas_buffer_to_task_n2(b, nc.get()->ran_ue_ngap_id,
nc.get()->amf_ue_ngap_id);
return true;
}
//------------------------------------------------------------------------------
bool amf_n1::check_nas_common_procedure_on_going(std::shared_ptr<nas_context> nc) {
bool amf_n1::check_nas_common_procedure_on_going(
std::shared_ptr<nas_context> nc) {
if (nc.get()->is_common_procedure_for_authentication_running) {
Logger::amf_n1().debug("Existed authentication procedure is running");
return true;
......@@ -1057,27 +1200,35 @@ bool amf_n1::check_nas_common_procedure_on_going(std::shared_ptr<nas_context> nc
}
//------------------------------------------------------------------------------
void amf_n1::authentication_response_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg) {
void amf_n1::authentication_response_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id,
bstring plain_msg) {
std::shared_ptr<nas_context> nc;
if (!is_amf_ue_id_2_nas_context(amf_ue_ngap_id)) {
Logger::amf_n1().error("No existed NAS context for UE with amf_ue_ngap_id (0x%x)", amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id, amf_ue_ngap_id); //cause?
Logger::amf_n1().error(
"No existed NAS context for UE with amf_ue_ngap_id (0x%x)",
amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
amf_ue_ngap_id); //cause?
return;
}
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
Logger::amf_n1().info("Found nas_context(%p) with amf_ue_ngap_id (0x%x)", nc.get(), amf_ue_ngap_id);
Logger::amf_n1().info("Found nas_context(%p) with amf_ue_ngap_id (0x%x)",
nc.get(), amf_ue_ngap_id);
//Stop timer? common procedure finished!
nc.get()->is_common_procedure_for_authentication_running = false;
// MM state: COMMON-PROCEDURE-INITIATED -> DEREGISTRED
//Decode AUTHENTICATION RESPONSE message
AuthenticationResponse *auth = new AuthenticationResponse();
auth->decodefrombuffer(nullptr, (uint8_t*) bdata(plain_msg), blength(plain_msg));
auth->decodefrombuffer(nullptr, (uint8_t*) bdata(plain_msg),
blength(plain_msg));
bstring resStar;
bool isAuthOk = true;
//Get response RES*
if (!auth->getAuthenticationResponseParameter(resStar)) {
Logger::amf_n1().warn("Cannot receive AuthenticationResponseParameter (RES*)");
Logger::amf_n1().warn(
"Cannot receive AuthenticationResponseParameter (RES*)");
} else {
//Get stored XRES*
int secu_index = nc.get()->security_ctx->vector_pointer;
......@@ -1093,9 +1244,12 @@ void amf_n1::authentication_response_handle(uint32_t ran_ue_ngap_id, long amf_ue
uint8_t hres[16];
for (int i = 0; i < 16; i++)
hres[i] = (uint8_t) sha256Out[i];
print_buffer("amf_n1", "Received RES* From Authentication-Response", res, 16);
print_buffer("amf_n1", "Stored XRES* in 5G HE AV", nc.get()->_5g_he_av[secu_index].xresStar, 16);
print_buffer("amf_n1", "Stored XRES in 5G HE AV", nc.get()->_5g_he_av[secu_index].xres, 8);
print_buffer("amf_n1", "Received RES* From Authentication-Response", res,
16);
print_buffer("amf_n1", "Stored XRES* in 5G HE AV",
nc.get()->_5g_he_av[secu_index].xresStar, 16);
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);
for (int i = 0; i < 16; i++) {
......@@ -1105,8 +1259,11 @@ void amf_n1::authentication_response_handle(uint32_t ran_ue_ngap_id, long amf_ue
}
//If success, start SMC procedure; else if failure, response registration reject message with corresponding cause
if (!isAuthOk) {
Logger::amf_n1().error("Authentication failed for UE with amf_ue_ngap_id 0x%x", amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id, amf_ue_ngap_id); //cause?
Logger::amf_n1().error(
"Authentication failed for UE with amf_ue_ngap_id 0x%x",
amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
amf_ue_ngap_id); //cause?
return;
} else {
Logger::amf_n1().debug("Authentication successful by network!");
......@@ -1121,22 +1278,29 @@ void amf_n1::authentication_response_handle(uint32_t ran_ue_ngap_id, long amf_ue
}
//------------------------------------------------------------------------------
void amf_n1::authentication_failure_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg) {
void amf_n1::authentication_failure_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id,
bstring plain_msg) {
std::shared_ptr<nas_context> nc;
if (!is_amf_ue_id_2_nas_context(amf_ue_ngap_id)) {
Logger::amf_n1().error("No existed NAS context for UE with amf_ue_ngap_id(0x%x)", amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id, amf_ue_ngap_id); //cause?
Logger::amf_n1().error(
"No existed NAS context for UE with amf_ue_ngap_id(0x%x)",
amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
amf_ue_ngap_id); //cause?
return;
}
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
nc.get()->is_common_procedure_for_authentication_running = false;
//1. decode AUTHENTICATION FAILURE message
AuthenticationFailure *authFail = new AuthenticationFailure();
authFail->decodefrombuffer(NULL, (uint8_t*) bdata(plain_msg), blength(plain_msg));
authFail->decodefrombuffer(NULL, (uint8_t*) bdata(plain_msg),
blength(plain_msg));
uint8_t mm_cause = authFail->get5GMmCause();
if (mm_cause == -1) {
Logger::amf_n1().error("Missing mandatory IE 5G_MM_CAUSE");
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO, ran_ue_ngap_id, amf_ue_ngap_id); //cause?
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
ran_ue_ngap_id, amf_ue_ngap_id); //cause?
return;
}
switch (mm_cause) {
......@@ -1144,7 +1308,8 @@ void amf_n1::authentication_failure_handle(uint32_t ran_ue_ngap_id, long amf_ue_
Logger::amf_n1().debug("Initial new authentication procedure");
bstring auts;
if (!authFail->getAutsInAuthFailPara(auts)) {
Logger::amf_n1().warn("IE Authentication Failure Parameter (auts) not received");
Logger::amf_n1().warn(
"IE Authentication Failure Parameter (auts) not received");
}
nc.get()->auts = auts;
printf("Received auts: 0x ");
......@@ -1155,7 +1320,9 @@ void amf_n1::authentication_failure_handle(uint32_t ran_ue_ngap_id, long amf_ue_
handle_auth_vector_successful_result(nc);
} else {
Logger::amf_n1().error("Request authentication vectors failure");
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, nc.get()->ran_ue_ngap_id, nc.get()->amf_ue_ngap_id); //cause?
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE,
nc.get()->ran_ue_ngap_id,
nc.get()->amf_ue_ngap_id); //cause?
}
//authentication_failure_synch_failure_handle(nc, auts);
}
......@@ -1165,7 +1332,8 @@ void amf_n1::authentication_failure_handle(uint32_t ran_ue_ngap_id, long amf_ue_
}
//------------------------------------------------------------------------------
bool amf_n1::start_security_mode_control_procedure(std::shared_ptr<nas_context> nc) {
bool amf_n1::start_security_mode_control_procedure(
std::shared_ptr<nas_context> nc) {
Logger::amf_n1().debug("Start Security Mode Control procedure");
nc.get()->is_common_procedure_for_security_mode_control_running = true;
bool security_context_is_new = false;
......@@ -1177,8 +1345,10 @@ bool amf_n1::start_security_mode_control_procedure(std::shared_ptr<nas_context>
if (!data)
Logger::amf_n1().error("Cannot allocate memory for security_data_t");
if (secu_ctx->sc_type == SECURITY_CTX_TYPE_NOT_AVAILABLE && nc.get()->is_common_procedure_for_security_mode_control_running) {
Logger::amf_n1().debug("Using INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX for SecurityModeControl message");
if (secu_ctx->sc_type == SECURITY_CTX_TYPE_NOT_AVAILABLE
&& nc.get()->is_common_procedure_for_security_mode_control_running) {
Logger::amf_n1().debug(
"Using INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX for SecurityModeControl message");
data->saved_selected_nea = secu_ctx->nas_algs.encryption; //emm_ctx->_security.selected_algorithms.encryption;
data->saved_selected_nia = secu_ctx->nas_algs.integrity;
data->saved_ngksi = secu_ctx->ngksi;
......@@ -1190,12 +1360,19 @@ bool amf_n1::start_security_mode_control_procedure(std::shared_ptr<nas_context>
secu_ctx->dl_count.seq_num = 0;
secu_ctx->ul_count.overflow = 0;
secu_ctx->ul_count.seq_num = 0;
int rc = security_select_algorithms(nc.get()->ueSecurityCapEnc, nc.get()->ueSecurityCapInt, amf_nea, amf_nia);
int rc = security_select_algorithms(nc.get()->ueSecurityCapEnc,
nc.get()->ueSecurityCapInt, amf_nea,
amf_nia);
secu_ctx->nas_algs.integrity = amf_nia;
secu_ctx->nas_algs.encryption = amf_nea;
secu_ctx->sc_type = SECURITY_CTX_TYPE_FULL_NATIVE;
Authentication_5gaka::derive_knas(NAS_INT_ALG, secu_ctx->nas_algs.integrity, nc.get()->kamf[secu_ctx->vector_pointer], secu_ctx->knas_int);
Authentication_5gaka::derive_knas(NAS_ENC_ALG, secu_ctx->nas_algs.encryption, nc.get()->kamf[secu_ctx->vector_pointer], secu_ctx->knas_enc);
Authentication_5gaka::derive_knas(NAS_INT_ALG, secu_ctx->nas_algs.integrity,
nc.get()->kamf[secu_ctx->vector_pointer],
secu_ctx->knas_int);
Authentication_5gaka::derive_knas(NAS_ENC_ALG,
secu_ctx->nas_algs.encryption,
nc.get()->kamf[secu_ctx->vector_pointer],
secu_ctx->knas_enc);
security_context_is_new = true;
nc.get()->is_current_security_available = true;
}
......@@ -1205,22 +1382,30 @@ bool amf_n1::start_security_mode_control_procedure(std::shared_ptr<nas_context>
smc->setNAS_Security_Algorithms(amf_nea, amf_nia);
Logger::amf_n1().debug("Encoded ngKSI 0x%x", nc.get()->ngKsi);
smc->setngKSI(NAS_KEY_SET_IDENTIFIER_NATIVE, nc.get()->ngKsi & 0x07);
smc->setUE_Security_Capability(nc.get()->ueSecurityCapEnc, nc.get()->ueSecurityCapInt);
smc->setUE_Security_Capability(nc.get()->ueSecurityCapEnc,
nc.get()->ueSecurityCapInt);
smc->setIMEISV_Request(0xe1);
smc->setAdditional_5G_Security_Information(true, false);
uint8_t buffer[1024];
int encoded_size = smc->encode2buffer(buffer, 1024);
print_buffer("amf_n1", "Security-Mode-Command message buffer", buffer, encoded_size);
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("amf_n1", "Encrypted Security-Mode-Command message buffer", (uint8_t*) bdata(intProtctedNas), blength(intProtctedNas));
itti_send_dl_nas_buffer_to_task_n2(intProtctedNas, nc.get()->ran_ue_ngap_id, nc.get()->amf_ue_ngap_id);
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("amf_n1", "Encrypted Security-Mode-Command message buffer",
(uint8_t*) bdata(intProtctedNas), blength(intProtctedNas));
itti_send_dl_nas_buffer_to_task_n2(intProtctedNas, nc.get()->ran_ue_ngap_id,
nc.get()->amf_ue_ngap_id);
//secu_ctx->dl_count.seq_num ++;
return true;
}
//------------------------------------------------------------------------------
int amf_n1::security_select_algorithms(uint8_t nea, uint8_t nia, uint8_t &amf_nea, uint8_t &amf_nia) {
int amf_n1::security_select_algorithms(uint8_t nea, uint8_t nia,
uint8_t &amf_nea, uint8_t &amf_nia) {
for (int i = 0; i < 8; i++) {
if (nea & (0x80 >> amf_cfg.nas_cfg.prefered_ciphering_algorithm[i])) {
amf_nea = amf_cfg.nas_cfg.prefered_ciphering_algorithm[i];
......@@ -1239,16 +1424,23 @@ int amf_n1::security_select_algorithms(uint8_t nea, uint8_t nia, uint8_t &amf_ne
}
//------------------------------------------------------------------------------
void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas_msg) {
void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id,
bstring nas_msg) {
Logger::amf_n1().debug("Handling security mode complete ...");
string ue_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id) + ":amfid_" + to_string(amf_ue_ngap_id);
string ue_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id)
+ ":amfid_" + to_string(amf_ue_ngap_id);
std::shared_ptr<ue_context> uc;
uc = amf_app_inst->ran_amf_id_2_ue_context(ue_context_key);
if (uc.get() == nullptr) {
//TODO:
Logger::amf_n1().error("ue_context in amf_app using ran_amf_id (%s) does not existed!", ue_context_key.c_str());
Logger::amf_n1().error(
"ue_context in amf_app using ran_amf_id (%s) does not existed!",
ue_context_key.c_str());
}
Logger::amf_n1().info("Found ue_context (%p) in amf_app using ran_amf_id (%s)", uc.get(), ue_context_key.c_str());
Logger::amf_n1().info(
"Found ue_context (%p) in amf_app using ran_amf_id (%s)", uc.get(),
ue_context_key.c_str());
// encoding REGISTRATION ACCEPT
RegistrationAccept *regAccept = new RegistrationAccept();
......@@ -1257,15 +1449,17 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_
std::string mcc;
std::string mnc;
uint32_t tmsi = 0;
if (!amf_app_inst->generate_5g_guti(ran_ue_ngap_id, amf_ue_ngap_id, mcc, mnc, tmsi)) {
if (!amf_app_inst->generate_5g_guti(ran_ue_ngap_id, amf_ue_ngap_id, mcc, mnc,
tmsi)) {
Logger::amf_n1().error("Generate 5G GUTI error! exit");
//TODO:
return;
}
regAccept->set5G_GUTI(mcc, mnc, amf_cfg.guami.regionID, amf_cfg.guami.AmfSetID, amf_cfg.guami.AmfPointer, tmsi);
regAccept->set5G_GUTI(mcc, mnc, amf_cfg.guami.regionID,
amf_cfg.guami.AmfSetID, amf_cfg.guami.AmfPointer, tmsi);
std::vector<p_tai_t> tai_list = {};
p_tai_t item0 = {};
std::vector<p_tai_t> tai_list = { };
p_tai_t item0 = { };
item0.type = 0x00;
nas_plmn_t plmn;
plmn.mcc = amf_cfg.plmn_list[0].mcc;
......@@ -1275,8 +1469,8 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_
tai_list.push_back(item0);
regAccept->setTaiList(tai_list);
std::vector<struct SNSSAI_s> nssai = {};
SNSSAI_t snssai = {};
std::vector<struct SNSSAI_s> nssai = { };
SNSSAI_t snssai = { };
snssai.sst = 1;
snssai.sd = -1;
snssai.mHplmnSst = -1;
......@@ -1284,7 +1478,8 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_
nssai.push_back(snssai);
regAccept->setALLOWED_NSSAI(nssai);
std::string guti = mcc + mnc + amf_cfg.guami.regionID + amf_cfg.guami.AmfSetID + amf_cfg.guami.AmfPointer + std::to_string(tmsi);
std::string guti = mcc + mnc + amf_cfg.guami.regionID + amf_cfg.guami.AmfSetID
+ amf_cfg.guami.AmfPointer + std::to_string(tmsi);
Logger::amf_n1().debug("Allocated GUTI %s", guti.c_str());
//TODO: remove hardcoded values
......@@ -1292,7 +1487,8 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_
regAccept->setT3512_Value(0x5, 0x1e);
uint8_t buffer[1024] = { 0 };
int encoded_size = regAccept->encode2buffer(buffer, 1024);
print_buffer("amf_n1", "Registration-Accept message buffer", buffer, encoded_size);
print_buffer("amf_n1", "Registration-Accept message buffer", buffer,
encoded_size);
if (!encoded_size) {
Logger::nas_mm().error("Encode Registration-Accept message error");
return;
......@@ -1301,15 +1497,19 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_
}
if (!uc.get()->isUeContextRequest) {
Logger::amf_n1().debug("UE Context is not requested, UE with ran_ue_ngap_id %d, amf_ue_ngap_id %d attached", ran_ue_ngap_id, amf_ue_ngap_id);
Logger::amf_n1().debug(
"UE Context is not requested, UE with ran_ue_ngap_id %d, amf_ue_ngap_id %d attached",
ran_ue_ngap_id, amf_ue_ngap_id);
//send registration accept back
} else {
//encoding InitialContextSetupRequest(NGAP message) back
std::shared_ptr<nas_context> nc;
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
Logger::amf_n1().info("UE (IMSI %s, GUTI %s, current RAN ID %d, current AMF ID %d) has been registered to the network", nc.get()->imsi.c_str(), guti.c_str(), ran_ue_ngap_id, amf_ue_ngap_id);
Logger::amf_n1().info(
"UE (IMSI %s, GUTI %s, current RAN ID %d, current AMF ID %d) has been registered to the network",
nc.get()->imsi.c_str(), guti.c_str(), ran_ue_ngap_id, amf_ue_ngap_id);
if (nc.get()->is_stacs_available) {
stacs.update_5gmm_state(nc.get()->imsi,"5GMM-REGISTERED");
stacs.update_5gmm_state(nc.get()->imsi, "5GMM-REGISTERED");
}
set_5gmm_state(nc, _5GMM_REGISTERED);
......@@ -1318,7 +1518,9 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_
nas_secu_ctx *secu = nc.get()->security_ctx;
//protect nas message
bstring protectedNas;
encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK, buffer, encoded_size, protectedNas);
encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
protectedNas);
uint8_t *kamf = nc.get()->kamf[secu->vector_pointer];
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
......@@ -1326,27 +1528,39 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id, long amf_ue_
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 = new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
itti_initial_context_setup_request *itti_msg =
new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
itti_msg->kgnb = kgnb_bs;
itti_msg->nas = protectedNas;
itti_msg->is_sr = false; //TODO: for Setup Request procedure
std::shared_ptr<itti_initial_context_setup_request> i = std::shared_ptr < itti_initial_context_setup_request > (itti_msg);
std::shared_ptr<itti_initial_context_setup_request> i = std::shared_ptr
< itti_initial_context_setup_request > (itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2", i->get_msg_name());
Logger::amf_n1().error(
"Could not send ITTI message %s to task TASK_AMF_N2",
i->get_msg_name());
}
}
}
//------------------------------------------------------------------------------
void amf_n1::security_mode_reject_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas_msg) {
Logger::amf_n1().debug("Receiving security mode reject message, handling ...");
void amf_n1::security_mode_reject_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, bstring nas_msg) {
Logger::amf_n1().debug(
"Receiving security mode reject message, handling ...");
}
//------------------------------------------------------------------------------
void amf_n1::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 &protected_nas) {
void amf_n1::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 &protected_nas) {
Logger::amf_n1().debug("Encoding nas_message_protected...");
uint8_t protected_nas_buf[1024];
int encoded_size = 0;
......@@ -1361,9 +1575,12 @@ void amf_n1::encode_nas_message_protected(nas_secu_ctx *nsc, bool is_secu_ctx_ne
protected_nas_buf[0] = EPD_5GS_MM_MSG;
protected_nas_buf[1] = INTEGRITY_PROTECTED_AND_CIPHERED;
protected_nas_buf[6] = (uint8_t) nsc->dl_count.seq_num;
memcpy(&protected_nas_buf[7], (uint8_t*) bdata(ciphered), blength(ciphered));
memcpy(&protected_nas_buf[7], (uint8_t*) bdata(ciphered),
blength(ciphered));
uint32_t mac32;
if (!(nas_message_integrity_protected(nsc, NAS_MESSAGE_DOWNLINK, protected_nas_buf + 6, input_nas_len + 1, mac32))) {
if (!(nas_message_integrity_protected(nsc, NAS_MESSAGE_DOWNLINK,
protected_nas_buf + 6,
input_nas_len + 1, mac32))) {
memcpy(protected_nas_buf, input_nas_buf, input_nas_len);
encoded_size = input_nas_len;
} else {
......@@ -1381,7 +1598,9 @@ void amf_n1::encode_nas_message_protected(nas_secu_ctx *nsc, bool is_secu_ctx_ne
protected_nas_buf[6] = (uint8_t) nsc->dl_count.seq_num;
memcpy(&protected_nas_buf[7], input_nas_buf, input_nas_len);
uint32_t mac32;
if (!(nas_message_integrity_protected(nsc, NAS_MESSAGE_DOWNLINK, protected_nas_buf + 6, input_nas_len + 1, mac32))) {
if (!(nas_message_integrity_protected(nsc, NAS_MESSAGE_DOWNLINK,
protected_nas_buf + 6,
input_nas_len + 1, mac32))) {
memcpy(protected_nas_buf, input_nas_buf, input_nas_len);
encoded_size = input_nas_len;
} else {
......@@ -1400,16 +1619,23 @@ void amf_n1::encode_nas_message_protected(nas_secu_ctx *nsc, bool is_secu_ctx_ne
}
//------------------------------------------------------------------------------
bool amf_n1::nas_message_integrity_protected(nas_secu_ctx *nsc, uint8_t direction, uint8_t *input_nas, int input_nas_len, uint32_t &mac32) {
bool amf_n1::nas_message_integrity_protected(nas_secu_ctx *nsc,
uint8_t direction,
uint8_t *input_nas,
int input_nas_len,
uint32_t &mac32) {
uint32_t count = 0x00000000;
if (direction)
count = 0x00000000 | ((nsc->dl_count.overflow & 0x0000ffff) << 8) | ((nsc->dl_count.seq_num & 0x000000ff));
count = 0x00000000 | ((nsc->dl_count.overflow & 0x0000ffff) << 8)
| ((nsc->dl_count.seq_num & 0x000000ff));
else
count = 0x00000000 | ((nsc->ul_count.overflow & 0x0000ffff) << 8) | ((nsc->ul_count.seq_num & 0x000000ff));
count = 0x00000000 | ((nsc->ul_count.overflow & 0x0000ffff) << 8)
| ((nsc->ul_count.seq_num & 0x000000ff));
nas_stream_cipher_t stream_cipher = { 0 };
uint8_t mac[4];
stream_cipher.key = nsc->knas_int;
print_buffer("amf_n1", "Parameters for NIA: knas_int", nsc->knas_int, AUTH_KNAS_INT_SIZE);
print_buffer("amf_n1", "Parameters for NIA: knas_int", nsc->knas_int,
AUTH_KNAS_INT_SIZE);
stream_cipher.key_length = AUTH_KNAS_INT_SIZE;
stream_cipher.count = *(input_nas);
//stream_cipher.count = count;
......@@ -1419,11 +1645,13 @@ bool amf_n1::nas_message_integrity_protected(nas_secu_ctx *nsc, uint8_t directio
}
Logger::amf_n1().debug("Parameters for NIA, count: 0x%x", count);
stream_cipher.bearer = 0x01; //33.501 section 8.1.1
Logger::amf_n1().debug("Parameters for NIA, bearer: 0x%x", stream_cipher.bearer);
Logger::amf_n1().debug("Parameters for NIA, bearer: 0x%x",
stream_cipher.bearer);
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("amf_n1", "Parameters for NIA, message: ", input_nas, input_nas_len);
print_buffer("amf_n1", "Parameters for NIA, message: ", input_nas,
input_nas_len);
stream_cipher.blength = input_nas_len * 8;
switch (nsc->nas_algs.integrity & 0x0f) {
case IA0_5G: {
......@@ -1453,14 +1681,18 @@ bool amf_n1::nas_message_integrity_protected(nas_secu_ctx *nsc, uint8_t directio
}
//------------------------------------------------------------------------------
bool amf_n1::nas_message_cipher_protected(nas_secu_ctx *nsc, uint8_t direction, bstring input_nas, bstring &output_nas) {
bool amf_n1::nas_message_cipher_protected(nas_secu_ctx *nsc, uint8_t direction,
bstring input_nas,
bstring &output_nas) {
uint8_t *buf = (uint8_t*) bdata(input_nas);
int buf_len = blength(input_nas);
uint32_t count = 0x00000000;
if (direction)
count = 0x00000000 | ((nsc->dl_count.overflow & 0x0000ffff) << 8) | ((nsc->dl_count.seq_num & 0x000000ff));
count = 0x00000000 | ((nsc->dl_count.overflow & 0x0000ffff) << 8)
| ((nsc->dl_count.seq_num & 0x000000ff));
else
count = 0x00000000 | ((nsc->ul_count.overflow & 0x0000ffff) << 8) | ((nsc->ul_count.seq_num & 0x000000ff));
count = 0x00000000 | ((nsc->ul_count.overflow & 0x0000ffff) << 8)
| ((nsc->ul_count.seq_num & 0x000000ff));
nas_stream_cipher_t stream_cipher = { 0 };
uint8_t mac[4];
stream_cipher.key = nsc->knas_enc;
......@@ -1479,12 +1711,14 @@ bool amf_n1::nas_message_cipher_protected(nas_secu_ctx *nsc, uint8_t direction,
break;
case EA1_128_5G: {
Logger::amf_n1().debug("Cipher protected with EA1_128_5G");
nas_algorithms::nas_stream_encrypt_nea1(&stream_cipher, (uint8_t*) bdata(output_nas));
nas_algorithms::nas_stream_encrypt_nea1(&stream_cipher,
(uint8_t*) bdata(output_nas));
}
break;
case EA2_128_5G: {
Logger::amf_n1().debug("Cipher protected with EA2_128_5G");
nas_algorithms::nas_stream_encrypt_nea2(&stream_cipher, (uint8_t*) bdata(output_nas));
nas_algorithms::nas_stream_encrypt_nea2(&stream_cipher,
(uint8_t*) bdata(output_nas));
}
break;
}
......@@ -1495,14 +1729,17 @@ void amf_n1::run_initial_registration_procedure() {
}
//------------------------------------------------------------------------------
void amf_n1::ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas) {
void amf_n1::ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id,
bstring nas) {
Logger::amf_n1().debug("Handling UE-initiated De-registration Request");
std::shared_ptr<nas_context> nc;
if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id))
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
else {
Logger::amf_n1().warn("No existed nas_context with amf_ue_ngap_id(0x%x)", amf_ue_ngap_id);
Logger::amf_n1().warn("No existed nas_context with amf_ue_ngap_id(0x%x)",
amf_ue_ngap_id);
return;
}
......@@ -1521,9 +1758,10 @@ void amf_n1::ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id, long am
uint8_t mobile_id_type = 0;
deregReq->getMobilityIdentityType(mobile_id_type);
Logger::amf_n1().debug("5G Mobile Identity %X", mobile_id_type);
switch(mobile_id_type) {
switch (mobile_id_type) {
case _5G_GUTI: {
Logger::amf_n1().debug("5G Mobile Identity, GUTI %s", deregReq->get_5g_guti().c_str());
Logger::amf_n1().debug("5G Mobile Identity, GUTI %s",
deregReq->get_5g_guti().c_str());
}
break;
default: {
......@@ -1537,7 +1775,8 @@ void amf_n1::ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id, long am
uint8_t buffer[512] = { 0 };
int encoded_size = deregAccept->encode2buffer(buffer, 1024);
print_buffer("amf_n1", "De-registration Accept message buffer", buffer, encoded_size);
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");
return;
......@@ -1548,13 +1787,14 @@ void amf_n1::ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id, long am
set_5gmm_state(nc, _5GMM_DEREGISTERED);
if (nc.get()->is_stacs_available) {
stacs.update_5gmm_state(nc.get()->imsi,"5GMM-DEREGISTERED");
stacs.update_5gmm_state(nc.get()->imsi, "5GMM-DEREGISTERED");
}
}
//------------------------------------------------------------------------------
void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas) {
void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, bstring nas) {
//Decode UL_NAS_TRANSPORT message
Logger::amf_n1().debug("Handling UL NAS Transport");
ULNASTransport *ulNas = new ULNASTransport();
......@@ -1562,7 +1802,7 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_i
uint8_t payload_type = ulNas->getPayloadContainerType();
uint8_t pdu_session_id = ulNas->getPduSessionId();
uint8_t request_type = ulNas->getRequestType();
SNSSAI_t snssai = {};
SNSSAI_t snssai = { };
ulNas->getSnssai(snssai);
bstring dnn = bfromcstr("default");
bstring sm_msg;
......@@ -1570,7 +1810,8 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_i
} else {
dnn = bfromcstr("default");
}
print_buffer("amf_n1", "Decoded DNN bitstring", (uint8_t*) bdata(dnn), blength(dnn));
print_buffer("amf_n1", "Decoded DNN bitstring", (uint8_t*) bdata(dnn),
blength(dnn));
switch (payload_type) {
case N1_SM_INFORMATION: {
if (!ulNas->getPayloadContainer(sm_msg)) {
......@@ -1578,7 +1819,8 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_i
return;
}
//send_itti_to_smf_services_consumer(ran_ue_ngap_id, amf_ue_ngap_id, request_type, pdu_session_id, dnn, sm_msg);
itti_smf_services_consumer *itti_msg = new itti_smf_services_consumer(TASK_AMF_N1, TASK_AMF_N11);
itti_smf_services_consumer *itti_msg = new itti_smf_services_consumer(
TASK_AMF_N1, TASK_AMF_N11);
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
itti_msg->req_type = request_type;
......@@ -1587,10 +1829,13 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_i
itti_msg->sm_msg = sm_msg;
itti_msg->snssai.sST = snssai.sst;
itti_msg->snssai.sD = std::to_string(snssai.sd);
std::shared_ptr<itti_smf_services_consumer> i = std::shared_ptr < itti_smf_services_consumer > (itti_msg);
std::shared_ptr<itti_smf_services_consumer> i = std::shared_ptr
< itti_smf_services_consumer > (itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N11", i->get_msg_name());
Logger::amf_n1().error(
"Could not send ITTI message %s to task TASK_AMF_N11",
i->get_msg_name());
}
}
......@@ -1598,9 +1843,10 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_i
}
}
//------------------------------------------------------------------------------
void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas, plmn_t plmn) {
void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, bstring nas,
plmn_t plmn) {
//Decode UL_NAS_TRANSPORT message
Logger::amf_n1().debug("Handling UL NAS Transport");
ULNASTransport *ulNas = new ULNASTransport();
......@@ -1608,7 +1854,7 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_i
uint8_t payload_type = ulNas->getPayloadContainerType();
uint8_t pdu_session_id = ulNas->getPduSessionId();
uint8_t request_type = ulNas->getRequestType();
SNSSAI_t snssai = {};
SNSSAI_t snssai = { };
ulNas->getSnssai(snssai);
bstring dnn = bfromcstr("default");
bstring sm_msg;
......@@ -1616,7 +1862,8 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_i
} else {
dnn = bfromcstr("default");
}
print_buffer("amf_n1", "Decoded DNN bitstring", (uint8_t*) bdata(dnn), blength(dnn));
print_buffer("amf_n1", "Decoded DNN bitstring", (uint8_t*) bdata(dnn),
blength(dnn));
switch (payload_type) {
case N1_SM_INFORMATION: {
if (!ulNas->getPayloadContainer(sm_msg)) {
......@@ -1624,7 +1871,8 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_i
return;
}
//send_itti_to_smf_services_consumer(ran_ue_ngap_id, amf_ue_ngap_id, request_type, pdu_session_id, dnn, sm_msg);
itti_smf_services_consumer *itti_msg = new itti_smf_services_consumer(TASK_AMF_N1, TASK_AMF_N11);
itti_smf_services_consumer *itti_msg = new itti_smf_services_consumer(
TASK_AMF_N1, TASK_AMF_N11);
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
itti_msg->req_type = request_type;
......@@ -1635,10 +1883,13 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_i
itti_msg->snssai.sD = std::to_string(snssai.sd);
itti_msg->plmn.mnc = plmn.mnc;
itti_msg->plmn.mcc = plmn.mcc;
std::shared_ptr<itti_smf_services_consumer> i = std::shared_ptr < itti_smf_services_consumer > (itti_msg);
std::shared_ptr<itti_smf_services_consumer> i = std::shared_ptr
< itti_smf_services_consumer > (itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N11", i->get_msg_name());
Logger::amf_n1().error(
"Could not send ITTI message %s to task TASK_AMF_N11",
i->get_msg_name());
}
}
......@@ -1646,20 +1897,27 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_i
}
}
//------------------------------------------------------------------------------
void amf_n1::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) {
itti_smf_services_consumer *itti_msg = new itti_smf_services_consumer(TASK_AMF_N1, TASK_AMF_N11);
void amf_n1::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) {
itti_smf_services_consumer *itti_msg = new itti_smf_services_consumer(
TASK_AMF_N1, TASK_AMF_N11);
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
itti_msg->req_type = request_type;
itti_msg->pdu_sess_id = pdu_session_id;
itti_msg->dnn = dnn;
itti_msg->sm_msg = sm_msg;
std::shared_ptr<itti_smf_services_consumer> i = std::shared_ptr < itti_smf_services_consumer > (itti_msg);
std::shared_ptr<itti_smf_services_consumer> i = std::shared_ptr
< itti_smf_services_consumer > (itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N11", i->get_msg_name());
Logger::amf_n1().error(
"Could not send ITTI message %s to task TASK_AMF_N11",
i->get_msg_name());
}
}
......@@ -1673,8 +1931,10 @@ 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);
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 };
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);
......@@ -1702,7 +1962,8 @@ void amf_n1::ue_authentication_simulator(uint8_t *rand, uint8_t *autn) {
}
//------------------------------------------------------------------------------
void amf_n1::sha256(unsigned char *message, int msg_len, unsigned char *output) {
void amf_n1::sha256(unsigned char *message, int msg_len,
unsigned char *output) {
memset(output, 0, Sha256::DIGEST_SIZE);
ctx.init();
ctx.update(message, msg_len);
......@@ -1710,12 +1971,15 @@ void amf_n1::sha256(unsigned char *message, int msg_len, unsigned char *output)
}
//------------------------------------------------------------------------------
void amf_n1::run_mobility_registration_update_procedure(std::shared_ptr<nas_context> nc) {
void amf_n1::run_mobility_registration_update_procedure(
std::shared_ptr<nas_context> nc) {
// encoding REGISTRATION ACCEPT
RegistrationAccept *regAccept = new RegistrationAccept();
regAccept->setHeader(PLAIN_5GS_MSG);
regAccept->set_5GS_Registration_Result(false, false, false, 0x01);
regAccept->set5G_GUTI(amf_cfg.guami.mcc, amf_cfg.guami.mnc, amf_cfg.guami.regionID, amf_cfg.guami.AmfSetID, amf_cfg.guami.AmfPointer, 0x264a34c0);
regAccept->set5G_GUTI(amf_cfg.guami.mcc, amf_cfg.guami.mnc,
amf_cfg.guami.regionID, amf_cfg.guami.AmfSetID,
amf_cfg.guami.AmfPointer, 0x264a34c0);
regAccept->setT3512_Value(0x5, 0x1e);
std::vector<p_tai_t> tai_list;
......@@ -1745,7 +2009,8 @@ void amf_n1::run_mobility_registration_update_procedure(std::shared_ptr<nas_cont
regAccept->set_5GS_Network_Feature_Support(0x00, 0x00);
uint8_t buffer[1024] = { 0 };
int encoded_size = regAccept->encode2buffer(buffer, 1024);
print_buffer("amf_n1", "Registration-Accept Message Buffer", buffer, encoded_size);
print_buffer("amf_n1", "Registration-Accept Message Buffer", buffer,
encoded_size);
if (!encoded_size) {
Logger::nas_mm().error("Encode Registration-Accept message error");
return;
......@@ -1755,7 +2020,9 @@ void amf_n1::run_mobility_registration_update_procedure(std::shared_ptr<nas_cont
nas_secu_ctx *secu = nc.get()->security_ctx;
//protect nas message
bstring protectedNas;
encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK, buffer, encoded_size, protectedNas);
encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
protectedNas);
string supi = "imsi-" + nc.get()->imsi;
Logger::amf_n1().debug("Key for pdu session context SUPI (%s)", supi.c_str());
......@@ -1763,7 +2030,8 @@ void amf_n1::run_mobility_registration_update_procedure(std::shared_ptr<nas_cont
if (amf_n11_inst->is_supi_to_pdu_ctx(supi)) {
psc = amf_n11_inst->supi_to_pdu_ctx(supi);
} else {
Logger::amf_n1().error("Cannot get pdu_session_context with SUPI (%s)", supi.c_str());
Logger::amf_n1().error("Cannot get pdu_session_context with SUPI (%s)",
supi.c_str());
}
uint8_t *kamf = nc.get()->kamf[secu->vector_pointer];
......@@ -1773,7 +2041,8 @@ void amf_n1::run_mobility_registration_update_procedure(std::shared_ptr<nas_cont
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 = new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
itti_initial_context_setup_request *itti_msg =
new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
itti_msg->ran_ue_ngap_id = nc.get()->ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = nc.get()->amf_ue_ngap_id;
itti_msg->kgnb = kgnb_bs;
......@@ -1781,23 +2050,28 @@ void amf_n1::run_mobility_registration_update_procedure(std::shared_ptr<nas_cont
itti_msg->is_sr = true; //service request indicator
itti_msg->pdu_session_id = psc.get()->pdu_session_id;
itti_msg->n2sm = psc.get()->n2sm;
std::shared_ptr<itti_initial_context_setup_request> i = std::shared_ptr < itti_initial_context_setup_request > (itti_msg);
std::shared_ptr<itti_initial_context_setup_request> i = std::shared_ptr
< itti_initial_context_setup_request > (itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2", i->get_msg_name());
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2",
i->get_msg_name());
}
}
//------------------------------------------------------------------------------
void amf_n1::set_5gmm_state(std::shared_ptr<nas_context> nc, _5gmm_state_t state) {
Logger::amf_n1().debug("Set 5GMM state to %s", _5gmm_state_e2str[state].c_str());
void amf_n1::set_5gmm_state(std::shared_ptr<nas_context> nc,
_5gmm_state_t state) {
Logger::amf_n1().debug("Set 5GMM state to %s",
_5gmm_state_e2str[state].c_str());
std::unique_lock lock(m_nas_context);
nc.get()->_5gmm_state = state;
//TODO:
}
//------------------------------------------------------------------------------
void amf_n1::get_5gmm_state(std::shared_ptr<nas_context> nc, _5gmm_state_t& state) {
void amf_n1::get_5gmm_state(std::shared_ptr<nas_context> nc,
_5gmm_state_t &state) {
//TODO:
state = nc.get()->_5gmm_state;
}
......
......@@ -71,9 +71,14 @@ class amf_n1 {
void handle_itti_message(itti_uplink_nas_data_ind&);
void handle_itti_message(itti_downlink_nas_transfer &itti_msg);
// nas message decode
void nas_signalling_establishment_request_handle(SecurityHeaderType type, std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg, std::string snn, uint8_t ulCount);
void uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg);
void uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg, plmn_t plmn);
void nas_signalling_establishment_request_handle(
SecurityHeaderType type, std::shared_ptr<nas_context> nc,
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg,
std::string snn, uint8_t ulCount);
void uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
bstring plain_msg);
void uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
bstring plain_msg, plmn_t plmn);
bool check_security_header_type(SecurityHeaderType &type, uint8_t *buffer);
std::map<long, std::shared_ptr<nas_context>> amfueid2nas_context; // amf ue ngap id
......@@ -86,63 +91,105 @@ class amf_n1 {
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);
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;
void set_amf_ue_ngap_id_2_nas_context(const long &amf_ue_ngap_id, std::shared_ptr<nas_context> nc);
std::shared_ptr<nas_context> amf_ue_id_2_nas_context(
const long &amf_ue_ngap_id) const;
void set_amf_ue_ngap_id_2_nas_context(const long &amf_ue_ngap_id,
std::shared_ptr<nas_context> nc);
database_t *db_desc;
//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);
void run_mobility_registration_update_procedure(
std::shared_ptr<nas_context> nc);
//authentication
bool auth_vectors_generator(std::shared_ptr<nas_context> &nc);
bool authentication_vectors_generator_in_ausf(std::shared_ptr<nas_context> &nc);
bool authentication_vectors_generator_in_udm(std::shared_ptr<nas_context> &nc);
bool authentication_vectors_generator_in_ausf(
std::shared_ptr<nas_context> &nc);
bool authentication_vectors_generator_in_udm(
std::shared_ptr<nas_context> &nc);
//mysql handlers in mysql_db.cpp
bool get_mysql_auth_info(std::string imsi, mysql_auth_info_t &resp);
void mysql_push_rand_sqn(std::string imsi, uint8_t *rand_p, uint8_t *sqn);
void mysql_increment_sqn(std::string imsi);
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 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 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);
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);
void dump_nas_message(uint8_t *buf, int len);
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);
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);
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);
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);
void set_5gmm_state(std::shared_ptr<nas_context> nc, _5gmm_state_t state);
void get_5gmm_state(std::shared_ptr<nas_context> nc, _5gmm_state_t& state);
private: //nas message handlers
void ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas);
void registration_request_handle(bool isNasSig, std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, std::string snn, 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 ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas, plmn_t plmn);
void get_5gmm_state(std::shared_ptr<nas_context> nc, _5gmm_state_t &state);
private: //nas message handlers
void ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, bstring nas);
void registration_request_handle(bool isNasSig,
std::shared_ptr<nas_context> nc,
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
std::string snn, 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 ul_nas_transport_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
bstring nas, plmn_t plmn);
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);
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);
//authentication vector
bool generate_authentication_vector();
void itti_send_dl_nas_buffer_to_task_n2(bstring &b, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id);
void itti_send_dl_nas_buffer_to_task_n2(bstring &b, uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id);
//response message
void response_registration_reject_msg(uint8_t cause_value, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id);
void response_registration_reject_msg(uint8_t cause_value,
uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id);
};
}
......
......@@ -52,8 +52,10 @@ extern "C" {
using namespace oai::smf::model;
using namespace oai::smf::api;
using namespace web;
using namespace web::http; // Common features like URIs.
using namespace web::http::client; // Common HTTP functionality
using namespace web::http;
// Common features like URIs.
using namespace web::http::client;
// Common HTTP functionality
using namespace config;
using namespace amf_application;
......@@ -64,13 +66,16 @@ extern amf_n1 *amf_n1_inst;
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 bool multipart_parser(std::string input, std::string &jsonData, std::string &n1sm, std::string &n2sm);
extern void print_buffer(const std::string app, const std::string commit,
uint8_t *buf, int len);
extern bool multipart_parser(std::string input, std::string &jsonData,
std::string &n1sm, std::string &n2sm);
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) {
std::size_t callback(const char *in, std::size_t size, std::size_t num,
std::string *out) {
const std::size_t totalBytes(size * num);
out->append(in, totalBytes);
return totalBytes;
......@@ -103,19 +108,24 @@ void amf_n11_task(void*) {
switch (msg->msg_type) {
case SMF_SERVICES_CONSUMER: {
Logger::amf_n1().info("Running SMF_SERVICES_CONSUMER");
itti_smf_services_consumer *m = dynamic_cast<itti_smf_services_consumer*>(msg);
itti_smf_services_consumer *m =
dynamic_cast<itti_smf_services_consumer*>(msg);
amf_n11_inst->handle_itti_message(ref(*m));
}
break;
case NSMF_PDU_SESSION_UPDATE_SM_CTX: {
Logger::amf_n1().info("Receive Nsmf_PDUSessionUpdateSMContext, handling ...");
itti_nsmf_pdusession_update_sm_context *m = dynamic_cast<itti_nsmf_pdusession_update_sm_context*>(msg);
Logger::amf_n1().info(
"Receive Nsmf_PDUSessionUpdateSMContext, handling ...");
itti_nsmf_pdusession_update_sm_context *m =
dynamic_cast<itti_nsmf_pdusession_update_sm_context*>(msg);
amf_n11_inst->handle_itti_message(ref(*m));
}
break;
case PDU_SESS_RES_SET_RESP: {
Logger::amf_n1().info("Receive PDU Session Resource Setup Response, handling ...");
itti_pdu_session_resource_setup_response *m = dynamic_cast<itti_pdu_session_resource_setup_response*>(msg);
Logger::amf_n1().info(
"Receive PDU Session Resource Setup Response, handling ...");
itti_pdu_session_resource_setup_response *m =
dynamic_cast<itti_pdu_session_resource_setup_response*>(msg);
amf_n11_inst->handle_itti_message(ref(*m));
}
break;
......@@ -139,18 +149,24 @@ amf_n11::~amf_n11() {
// itti message handlers
//------------------------------------------------------------------------------
void amf_n11::handle_itti_message(itti_pdu_session_resource_setup_response &itti_msg) {
void amf_n11::handle_itti_message(
itti_pdu_session_resource_setup_response &itti_msg) {
}
//------------------------------------------------------------------------------
void amf_n11::handle_itti_message(itti_nsmf_pdusession_update_sm_context &itti_msg) {
void amf_n11::handle_itti_message(
itti_nsmf_pdusession_update_sm_context &itti_msg) {
std::string supi = pduid2supi.at(itti_msg.pdu_session_id);
Logger::amf_n11().debug("Send PDU Session Update SM Context Request to SMF (SUPI %s, PDU Session ID %d)", supi.c_str(), itti_msg.pdu_session_id);
Logger::amf_n11().debug(
"Send PDU Session Update SM Context Request to SMF (SUPI %s, PDU Session ID %d)",
supi.c_str(), itti_msg.pdu_session_id);
std::shared_ptr<pdu_session_context> psc;
if (is_supi_to_pdu_ctx(supi)) {
psc = supi_to_pdu_ctx(supi);
} else {
Logger::amf_n11().error("Could not find psu_session_context with SUPI %s, Failed", supi.c_str());
Logger::amf_n11().error(
"Could not find psu_session_context with SUPI %s, Failed",
supi.c_str());
return;
}
std::string smf_addr;
......@@ -180,13 +196,15 @@ void amf_n11::handle_itti_message(itti_nsmf_pdusession_update_sm_context &itti_m
Logger::amf_n11().debug("SMF URI: %s", remote_uri.c_str());
nlohmann::json pdu_session_update_request = {};
nlohmann::json pdu_session_update_request = { };
pdu_session_update_request["n2SmInfoType"] = "PDU_RES_SETUP_RSP";
pdu_session_update_request["n2SmInfo"]["contentId"] = "n2msg";
std::string json_part = pdu_session_update_request.dump();
std::string n2SmMsg;
octet_stream_2_hex_stream((uint8_t*) bdata(itti_msg.n2sm), blength(itti_msg.n2sm), n2SmMsg);
curl_http_client(remote_uri, json_part, "", n2SmMsg, supi, itti_msg.pdu_session_id);
octet_stream_2_hex_stream((uint8_t*) bdata(itti_msg.n2sm),
blength(itti_msg.n2sm), n2SmMsg);
curl_http_client(remote_uri, json_part, "", n2SmMsg, supi,
itti_msg.pdu_session_id);
}
//------------------------------------------------------------------------------
......@@ -250,15 +268,19 @@ void amf_n11::handle_itti_message(itti_smf_services_consumer &smf) {
break;
default: {
//send Nsmf_PDUSession_UpdateSM_Context to SMF e.g., for PDU Session release request
send_pdu_session_update_sm_context_request(supi, psc, smf_addr, smf.sm_msg, dnn);
send_pdu_session_update_sm_context_request(supi, psc, smf_addr,
smf.sm_msg, dnn);
}
}
}
//------------------------------------------------------------------------------
void amf_n11::send_pdu_session_update_sm_context_request(std::string supi, std::shared_ptr<pdu_session_context> psc, std::string smf_addr, bstring sm_msg, std::string dnn) {
Logger::amf_n11().debug("Send PDU Session Update SM Context Request to SMF (SUPI %s, PDU Session ID %d)", supi.c_str(), psc.get()->pdu_session_id);
void amf_n11::send_pdu_session_update_sm_context_request(
std::string supi, std::shared_ptr<pdu_session_context> psc,
std::string smf_addr, bstring sm_msg, std::string dnn) {
Logger::amf_n11().debug(
"Send PDU Session Update SM Context Request to SMF (SUPI %s, PDU Session ID %d)",
supi.c_str(), psc.get()->pdu_session_id);
std::string smf_ip_addr, remote_uri;
//remove http port from the URI if existed
......@@ -276,19 +298,23 @@ void amf_n11::send_pdu_session_update_sm_context_request(std::string supi, std::
Logger::amf_n11().debug("SMF URI: %s", remote_uri.c_str());
nlohmann::json pdu_session_update_request = {};
nlohmann::json pdu_session_update_request = { };
pdu_session_update_request["n1SmMsg"]["contentId"] = "n1SmMsg";
std::string json_part = pdu_session_update_request.dump();
std::string n1SmMsg;
octet_stream_2_hex_stream((uint8_t*) bdata(sm_msg), blength(sm_msg), n1SmMsg);
curl_http_client(remote_uri, json_part, n1SmMsg, "", supi, psc.get()->pdu_session_id);
curl_http_client(remote_uri, json_part, n1SmMsg, "", supi,
psc.get()->pdu_session_id);
}
//------------------------------------------------------------------------------
void amf_n11::handle_pdu_session_initial_request(std::string supi, std::shared_ptr<pdu_session_context> psc, std::string smf_addr, bstring sm_msg, std::string dnn) {
Logger::amf_n11().debug("Handle PDU Session Establishment Request (SUPI %s, PDU Session ID %d)", supi.c_str(), psc.get()->pdu_session_id);
void amf_n11::handle_pdu_session_initial_request(
std::string supi, std::shared_ptr<pdu_session_context> psc,
std::string smf_addr, bstring sm_msg, std::string dnn) {
Logger::amf_n11().debug(
"Handle PDU Session Establishment Request (SUPI %s, PDU Session ID %d)",
supi.c_str(), psc.get()->pdu_session_id);
//TODO: Remove hardcoded values
std::string remote_uri = smf_addr + "/nsmf-pdusession/v1/sm-contexts"; //TODO
......@@ -302,18 +328,24 @@ void amf_n11::handle_pdu_session_initial_request(std::string supi, std::shared_p
pdu_session_establishment_request["pduSessionId"] = psc.get()->pdu_session_id;
pdu_session_establishment_request["requestType"] = "INITIAL_REQUEST"; //TODO: from SM_MSG
pdu_session_establishment_request["servingNfId"] = "servingNfId";
pdu_session_establishment_request["servingNetwork"]["mcc"] = psc.get()->plmn.mcc;
pdu_session_establishment_request["servingNetwork"]["mnc"] = psc.get()->plmn.mnc;
pdu_session_establishment_request["servingNetwork"]["mcc"] = psc.get()->plmn
.mcc;
pdu_session_establishment_request["servingNetwork"]["mnc"] = psc.get()->plmn
.mnc;
pdu_session_establishment_request["anType"] = "3GPP_ACCESS"; //TODO
pdu_session_establishment_request["smContextStatusUri"] = "smContextStatusUri";
pdu_session_establishment_request["smContextStatusUri"] =
"smContextStatusUri";
pdu_session_establishment_request["n1MessageContainer"]["n1MessageClass"] = "SM";
pdu_session_establishment_request["n1MessageContainer"]["n1MessageContent"]["contentId"] = "n1SmMsg";
pdu_session_establishment_request["n1MessageContainer"]["n1MessageClass"] =
"SM";
pdu_session_establishment_request["n1MessageContainer"]["n1MessageContent"]["contentId"] =
"n1SmMsg";
std::string json_part = pdu_session_establishment_request.dump();
std::string n1SmMsg;
octet_stream_2_hex_stream((uint8_t*) bdata(sm_msg), blength(sm_msg), n1SmMsg);
curl_http_client(remote_uri, json_part, n1SmMsg, "", supi, psc.get()->pdu_session_id);
curl_http_client(remote_uri, json_part, n1SmMsg, "", supi,
psc.get()->pdu_session_id);
}
//Context management functions
......@@ -323,13 +355,15 @@ bool amf_n11::is_supi_to_pdu_ctx(const std::string &supi) const {
return bool { supi2pdu.count(supi) > 0 };
}
std::shared_ptr<pdu_session_context> amf_n11::supi_to_pdu_ctx(const std::string &supi) const {
std::shared_ptr<pdu_session_context> amf_n11::supi_to_pdu_ctx(
const std::string &supi) const {
std::shared_lock lock(m_supi2pdu);
return supi2pdu.at(supi);
}
//------------------------------------------------------------------------------
void amf_n11::set_supi_to_pdu_ctx(const string &supi, std::shared_ptr<pdu_session_context> psc) {
void amf_n11::set_supi_to_pdu_ctx(const string &supi,
std::shared_ptr<pdu_session_context> psc) {
std::shared_lock lock(m_supi2pdu);
supi2pdu[supi] = psc;
}
......@@ -358,29 +392,40 @@ 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) {
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));
itti_n1n2_message_transfer_request *itti_msg = new itti_n1n2_message_transfer_request(TASK_AMF_N11, TASK_AMF_APP);
itti_n1n2_message_transfer_request *itti_msg =
new itti_n1n2_message_transfer_request(TASK_AMF_N11, TASK_AMF_APP);
itti_msg->n1sm = n1sm;
itti_msg->is_n2sm_set = false;
itti_msg->supi = supi;
itti_msg->pdu_session_id = pdu_session_id;
std::shared_ptr<itti_n1n2_message_transfer_request> i = std::shared_ptr < itti_n1n2_message_transfer_request > (itti_msg);
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_n1().error("Could not send ITTI message %s to task TASK_AMF_APP", i->get_msg_name());
Logger::amf_n1().error(
"Could not send ITTI message %s to task TASK_AMF_APP",
i->get_msg_name());
}
}
//------------------------------------------------------------------------------
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) {
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) {
Logger::amf_n11().debug("Call SMF service: %s", remoteUri.c_str());
std::shared_ptr<pdu_session_context> psc;
if (is_supi_to_pdu_ctx(supi)) {
psc = supi_to_pdu_ctx(supi);
} else {
Logger::amf_n11().warn("PDU Session context for SUPI %s doesn't exit!", supi.c_str());
Logger::amf_n11().warn("PDU Session context for SUPI %s doesn't exit!",
supi.c_str());
//TODO:
}
......@@ -389,16 +434,22 @@ void amf_n11::curl_http_client(std::string remoteUri, std::string jsonData, std:
if ((n1SmMsg.size() > 0) and (n2SmMsg.size() > 0)) {
//prepare the body content for Curl
parser.create_multipart_related_content(body, jsonData, CURL_MIME_BOUNDARY, n1SmMsg, n2SmMsg);
parser.create_multipart_related_content(body, jsonData, CURL_MIME_BOUNDARY,
n1SmMsg, n2SmMsg);
} else if (n1SmMsg.size() > 0) { //only N1 content
//prepare the body content for Curl
parser.create_multipart_related_content(body, jsonData, CURL_MIME_BOUNDARY, n1SmMsg, multipart_related_content_part_e::NAS);
parser.create_multipart_related_content(
body, jsonData, CURL_MIME_BOUNDARY, n1SmMsg,
multipart_related_content_part_e::NAS);
} else if (n2SmMsg.size() > 0) { //only N2 content
//prepare the body content for Curl
parser.create_multipart_related_content(body, jsonData, CURL_MIME_BOUNDARY, n2SmMsg, multipart_related_content_part_e::NGAP);
parser.create_multipart_related_content(
body, jsonData, CURL_MIME_BOUNDARY, n2SmMsg,
multipart_related_content_part_e::NGAP);
}
Logger::amf_n11().debug("Send HTTP message to SMF with body %s", body.c_str());
Logger::amf_n11().debug("Send HTTP message to SMF with body %s",
body.c_str());
uint32_t str_len = body.length();
char *body_data = (char*) malloc(str_len + 1);
......@@ -412,7 +463,8 @@ void amf_n11::curl_http_client(std::string remoteUri, std::string jsonData, std:
CURLcode res = { };
struct curl_slist *headers = nullptr;
std::string content_type = "content-type: multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY);
std::string content_type = "content-type: multipart/related; boundary="
+ std::string(CURL_MIME_BOUNDARY);
headers = curl_slist_append(headers, content_type.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, remoteUri.c_str());
......@@ -445,7 +497,8 @@ void amf_n11::curl_http_client(std::string remoteUri, std::string jsonData, std:
Logger::amf_n11().debug("Get response with HTTP code (%d)", httpCode);
//TODO: remove hardcoded HTTP Code
if (httpCode == 0) {
Logger::amf_n11().error("Cannot get response when calling %s", remoteUri.c_str());
Logger::amf_n11().error("Cannot get response when calling %s",
remoteUri.c_str());
//free curl before returning
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
......@@ -462,7 +515,8 @@ void amf_n11::curl_http_client(std::string remoteUri, std::string jsonData, std:
return;
}
if (!(multipart_parser(response, json_data_response, n1sm, n2sm))) {
Logger::amf_n11().error("Could not get N1/N2 content from the response");
Logger::amf_n11().error(
"Could not get N1/N2 content from the response");
//TODO:
}
} else {
......@@ -474,8 +528,10 @@ void amf_n11::curl_http_client(std::string remoteUri, std::string jsonData, std:
if (location_pos != std::string::npos) {
std::size_t crlf_pos = header_response.find(CRLF, location_pos);
if (crlf_pos != std::string::npos) {
std::string location = header_response.substr(location_pos + 10, crlf_pos - (location_pos + 10));
Logger::amf_n11().info("Location of the created SMF context: %s", location.c_str());
std::string location = header_response.substr(
location_pos + 10, crlf_pos - (location_pos + 10));
Logger::amf_n11().info("Location of the created SMF context: %s",
location.c_str());
psc.get()->smf_context_location = location;
}
}
......@@ -493,15 +549,18 @@ void amf_n11::curl_http_client(std::string remoteUri, std::string jsonData, std:
response_data["error"]["cause"] = "504 Gateway Timeout";
}
Logger::amf_n11().debug("Get response with jsonData: %s", json_data_response.c_str());
Logger::amf_n11().debug("Get response with jsonData: %s",
json_data_response.c_str());
msg_str_2_msg_hex(n1sm.substr(0, n1sm.length() - 2), n1sm_hex); //pdu session establishment reject bugs from SMF
print_buffer("amf_n11", "Get response with n1sm:", (uint8_t*) bdata(n1sm_hex), blength(n1sm_hex));
print_buffer("amf_n11", "Get response with n1sm:",
(uint8_t*) bdata(n1sm_hex), blength(n1sm_hex));
std::string cause = response_data["error"]["cause"];
Logger::amf_n11().error("Call Network Function services failure");
Logger::amf_n11().debug("Cause value: %s", cause.c_str());
if (!cause.compare("DNN_DENIED"))
handle_post_sm_context_response_error(httpCode, cause, n1sm_hex, supi, pdu_session_id);
handle_post_sm_context_response_error(httpCode, cause, n1sm_hex, supi,
pdu_session_id);
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
......
......@@ -44,24 +44,34 @@ class amf_n11 {
~amf_n11();
void handle_itti_message(itti_smf_services_consumer&);
void handle_pdu_session_initial_request(std::string supi, std::shared_ptr<pdu_session_context> psc, std::string smf_addr, bstring sm_msg, std::string dnn);
void handle_pdu_session_initial_request(
std::string supi, std::shared_ptr<pdu_session_context> psc,
std::string smf_addr, bstring sm_msg, std::string dnn);
void handle_itti_message(itti_pdu_session_resource_setup_response &itti_msg);
void handle_itti_message(itti_nsmf_pdusession_update_sm_context &itti_msg);
void send_pdu_session_update_sm_context_request(std::string supi, std::shared_ptr<pdu_session_context> psc, std::string smf_addr, bstring sm_msg, std::string dnn);
void send_pdu_session_update_sm_context_request(
std::string supi, std::shared_ptr<pdu_session_context> psc,
std::string smf_addr, bstring sm_msg, std::string dnn);
std::map<std::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 std::string &supi) const;
std::shared_ptr<pdu_session_context> supi_to_pdu_ctx(const std::string &supi) const;
void set_supi_to_pdu_ctx(const std::string &supi, std::shared_ptr<pdu_session_context> psc);
std::shared_ptr<pdu_session_context> supi_to_pdu_ctx(
const std::string &supi) const;
void set_supi_to_pdu_ctx(const std::string &supi,
std::shared_ptr<pdu_session_context> psc);
std::map<uint8_t, std::string> pduid2supi;
bool smf_selection_from_configuration(std::string &smf_addr);
bool smf_selection_from_context(std::string &smf_addr);
void handle_post_sm_context_response_error_400();
void handle_post_sm_context_response_error(long code, std::string cause, bstring n1sm, std::string supi, uint8_t pdu_session_id);
void handle_post_sm_context_response_error(long code, std::string cause,
bstring n1sm, std::string supi,
uint8_t pdu_session_id);
void curl_http_client(std::string remoteUri, std::string jsonData, std::string n1SmMsg, std::string n2SmMsg, std::string supi, uint8_t pdu_session_id);
void curl_http_client(std::string remoteUri, std::string jsonData,
std::string n1SmMsg, std::string n2SmMsg,
std::string supi, uint8_t pdu_session_id);
};
}
......
......@@ -40,30 +40,47 @@ void statistics::display() {
//Logger::amf_app().info("--------------------------------------------------");
//Logger::amf_app().info("| %d | %d | %d |",gNB_connected,UE_connected,UE_registred);
//Logger::amf_app().info("--------------------------------------------------");
Logger::amf_app().info("|----------------------------------------------------------------------------------------------------------------|");
Logger::amf_app().info("|----------------------------------------------------gNBs' information-------------------------------------------|");
Logger::amf_app().info("| Index | Status | Global ID | gNB Name | Tracking Area (PLMN, TAC) |");
if (gnbs.size() ==0 ) {
Logger::amf_app().info("| - | - | - | - | - |");
Logger::amf_app().info(
"|----------------------------------------------------------------------------------------------------------------|");
Logger::amf_app().info(
"|----------------------------------------------------gNBs' information-------------------------------------------|");
Logger::amf_app().info(
"| Index | Status | Global ID | gNB Name | Tracking Area (PLMN, TAC) |");
if (gnbs.size() == 0) {
Logger::amf_app().info(
"| - | - | - | - | - |");
}
//TODO: Show the list of common PLMNs
for (int i = 0; i < gnbs.size(); i++) {
Logger::amf_app().info("| %d | Connected | 0x%x | %s | %s, %d | ", i + 1, gnbs[i].gnb_id, gnbs[i].gnb_name.c_str(), (gnbs[i].mcc + gnbs[i].mnc).c_str(), gnbs[i].tac);
Logger::amf_app().info(
"| %d | Connected | 0x%x | %s | %s, %d | ",
i + 1, gnbs[i].gnb_id, gnbs[i].gnb_name.c_str(),
(gnbs[i].mcc + gnbs[i].mnc).c_str(), gnbs[i].tac);
}
Logger::amf_app().info("|----------------------------------------------------------------------------------------------------------------|");
Logger::amf_app().info(
"|----------------------------------------------------------------------------------------------------------------|");
Logger::amf_app().info("");
Logger::amf_app().info("|----------------------------------------------------------------------------------------------------------------|");
Logger::amf_app().info("|----------------------------------------------------UEs' information--------------------------------------------|");
Logger::amf_app().info("| Index | 5GMM state | IMSI | GUTI | RAN UE NGAP ID | AMF UE ID | PLMN |Cell ID|");
Logger::amf_app().info(
"|----------------------------------------------------------------------------------------------------------------|");
Logger::amf_app().info(
"|----------------------------------------------------UEs' information--------------------------------------------|");
Logger::amf_app().info(
"| Index | 5GMM state | IMSI | GUTI | RAN UE NGAP ID | AMF UE ID | PLMN |Cell ID|");
int i = 0;
for (auto const &ue : ue_infos) {
Logger::amf_app().info("|%7d|%22s|%18s|%15s|%16d|%11d|%9s|%7d|", i + 1, ue.second.registerStatus.c_str(), ue.second.imsi.c_str(), ue.second.guti.c_str(), ue.second.ranid, ue.second.amfid, (ue.second.mcc + ue.second.mnc).c_str(), ue.second.cellId);
Logger::amf_app().info("|%7d|%22s|%18s|%15s|%16d|%11d|%9s|%7d|", i + 1,
ue.second.registerStatus.c_str(),
ue.second.imsi.c_str(), ue.second.guti.c_str(),
ue.second.ranid, ue.second.amfid,
(ue.second.mcc + ue.second.mnc).c_str(),
ue.second.cellId);
i++;
}
Logger::amf_app().info("|----------------------------------------------------------------------------------------------------------------|");
Logger::amf_app().info(
"|----------------------------------------------------------------------------------------------------------------|");
Logger::amf_app().info("");
}
......@@ -75,7 +92,7 @@ statistics::statistics() {
}
//------------------------------------------------------------------------------
void statistics::update_ue_info(const ue_info_t& ue_info) {
void statistics::update_ue_info(const ue_info_t &ue_info) {
if (!(ue_info.imsi.size() > 0)) {
Logger::amf_app().warn("Update UE Info with invalid IMSI");
}
......@@ -83,23 +100,28 @@ void statistics::update_ue_info(const ue_info_t& ue_info) {
if (ue_infos.count(ue_info.imsi) > 0) {
ue_infos.erase(ue_info.imsi);
ue_infos.insert(std::pair<std::string, ue_info_t>(ue_info.imsi, ue_info));
Logger::amf_app().debug("Update UE Info (IMSI %s) success", ue_info.imsi.c_str());
Logger::amf_app().debug("Update UE Info (IMSI %s) success",
ue_info.imsi.c_str());
} else {
ue_infos.insert(std::pair<std::string, ue_info_t>(ue_info.imsi, ue_info));
Logger::amf_app().debug("Add UE Info (IMSI %s) success", ue_info.imsi.c_str());
Logger::amf_app().debug("Add UE Info (IMSI %s) success",
ue_info.imsi.c_str());
}
}
//------------------------------------------------------------------------------
void statistics::update_5gmm_state(const std::string& imsi, const std::string& state) {
void statistics::update_5gmm_state(const std::string &imsi,
const std::string &state) {
if (ue_infos.count(imsi) > 0) {
ue_info_t ue_info = ue_infos.at(imsi);
ue_info.registerStatus = state;
ue_infos.erase(ue_info.imsi);
ue_infos.insert(std::pair<std::string, ue_info_t>(imsi, ue_info));
Logger::amf_app().debug("Update UE State (IMSI %s, State %s) success", imsi.c_str(), state.c_str());
Logger::amf_app().debug("Update UE State (IMSI %s, State %s) success",
imsi.c_str(), state.c_str());
} else {
Logger::amf_app().warn("Update UE State (IMSI %s), UE does not exist!", imsi.c_str());
Logger::amf_app().warn("Update UE State (IMSI %s), UE does not exist!",
imsi.c_str());
}
}
......
......@@ -61,14 +61,13 @@ typedef struct ue_info_s {
uint32_t cellId;
} ue_info_t;
class statistics {
public:
void display();
statistics();
~statistics();
void update_ue_info(const ue_info_t& ue_info);
void update_5gmm_state(const std::string& imsi, const std::string& state);
void update_ue_info(const ue_info_t &ue_info);
void update_5gmm_state(const std::string &imsi, const std::string &state);
public:
uint32_t gNB_connected;
uint32_t UE_connected;
......
......@@ -42,7 +42,8 @@ _5GSDeregistrationType::_5GSDeregistrationType(uint8_t type) {
u1.b = type;
}
//------------------------------------------------------------------------------
_5GSDeregistrationType::_5GSDeregistrationType(_5gs_deregistration_type_t type) {
_5GSDeregistrationType::_5GSDeregistrationType(
_5gs_deregistration_type_t type) {
u1.b = 0;
u1.bf.switch_off = type.switch_off;
u1.bf.dereg_required = type.dereg_required;
......@@ -64,7 +65,7 @@ void _5GSDeregistrationType::set(_5gs_deregistration_type_t type) {
}
//------------------------------------------------------------------------------
void _5GSDeregistrationType::get(_5gs_deregistration_type_t& type) {
void _5GSDeregistrationType::get(_5gs_deregistration_type_t &type) {
type.switch_off = u1.bf.switch_off;
type.dereg_required = u1.bf.dereg_required;
type.access_type = u1.bf.access_type;
......@@ -77,7 +78,7 @@ void _5GSDeregistrationType::set(uint8_t type) {
}
//------------------------------------------------------------------------------
void _5GSDeregistrationType::get(uint8_t& type) {
void _5GSDeregistrationType::get(uint8_t &type) {
type = u1.b;
}
......@@ -85,7 +86,8 @@ void _5GSDeregistrationType::get(uint8_t& type) {
int _5GSDeregistrationType::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().error("Encoding 5GSDeregistrationType IE");
if (len < 1) {
Logger::nas_mm().error("encoding 5GSDeregistrationType error(len is less than one)");
Logger::nas_mm().error(
"encoding 5GSDeregistrationType error(len is less than one)");
return -1;
}
*buf = u1.b;
......
......@@ -34,7 +34,7 @@
namespace nas {
typedef struct _5gs_deregistration_type_s {
uint8_t iei :4;
uint8_t switch_off:1;
uint8_t switch_off :1;
uint8_t dereg_required :1;
uint8_t access_type :2;
} _5gs_deregistration_type_t;
......@@ -49,22 +49,21 @@ class _5GSDeregistrationType {
int encode2buffer(uint8_t *buf, int len);
void set(_5gs_deregistration_type_t type);
void get(_5gs_deregistration_type_t& type);
void get(_5gs_deregistration_type_t &type);
void set(uint8_t type);
void get(uint8_t& type);
void get(uint8_t &type);
public:
union {
struct {
uint8_t iei :4;
uint8_t switch_off:1;
uint8_t switch_off :1;
uint8_t dereg_required :1;
uint8_t access_type :2;
} bf;
uint8_t b;
} u1;
};
}
......
......@@ -48,7 +48,8 @@ DeregistrationRequest::~DeregistrationRequest() {
//------------------------------------------------------------------------------
void DeregistrationRequest::setHeader(uint8_t security_header_type) {
plain_header = new NasMmPlainHeader();
plain_header->setHeader(EPD_5GS_MM_MSG, security_header_type, DEREGISTRATION_REQUEST_UE_ORIGINATING);
plain_header->setHeader(EPD_5GS_MM_MSG, security_header_type,
DEREGISTRATION_REQUEST_UE_ORIGINATING);
}
//------------------------------------------------------------------------------
......@@ -57,7 +58,8 @@ void DeregistrationRequest::setDeregistrationType(uint8_t dereg_type) {
}
//------------------------------------------------------------------------------
void DeregistrationRequest::setDeregistrationType(_5gs_deregistration_type_t type) {
void DeregistrationRequest::setDeregistrationType(
_5gs_deregistration_type_t type) {
ie_deregistrationtype = new _5GSDeregistrationType(type);
}
......@@ -68,35 +70,43 @@ void DeregistrationRequest::setngKSI(uint8_t tsc, uint8_t key_set_id) {
//------------------------------------------------------------------------------
void DeregistrationRequest::getDeregistrationType(uint8_t &dereg_type) {
ie_deregistrationtype->get(dereg_type );
ie_deregistrationtype->get(dereg_type);
}
//------------------------------------------------------------------------------
void DeregistrationRequest::getDeregistrationType(_5gs_deregistration_type_t& type) {
void DeregistrationRequest::getDeregistrationType(
_5gs_deregistration_type_t &type) {
ie_deregistrationtype->get(type);
}
//------------------------------------------------------------------------------
void DeregistrationRequest::getngKSI(uint8_t& ng_ksi) {
void DeregistrationRequest::getngKSI(uint8_t &ng_ksi) {
if (ie_ngKSI) {
ng_ksi = (ie_ngKSI->getTypeOfSecurityContext()) | ie_ngKSI->getasKeyIdentifier();
ng_ksi = (ie_ngKSI->getTypeOfSecurityContext())
| ie_ngKSI->getasKeyIdentifier();
} else {
ng_ksi = 0;
}
}
//------------------------------------------------------------------------------
void DeregistrationRequest::setSUCI_SUPI_format_IMSI(const string mcc, const string mnc, const string routingInd, uint8_t protection_sch_id, const string msin) {
void DeregistrationRequest::setSUCI_SUPI_format_IMSI(const string mcc,
const string mnc,
const string routingInd,
uint8_t protection_sch_id,
const string msin) {
if (protection_sch_id != NULL_SCHEME) {
Logger::nas_mm().error("encoding suci and supi format for imsi error, please choose right interface");
Logger::nas_mm().error(
"encoding suci and supi format for imsi error, please choose right interface");
return;
} else {
ie_5gs_mobility_id = new _5GSMobilityIdentity(mcc, mnc, routingInd, protection_sch_id, msin);
ie_5gs_mobility_id = new _5GSMobilityIdentity(mcc, mnc, routingInd,
protection_sch_id, msin);
}
}
//------------------------------------------------------------------------------
void DeregistrationRequest::getMobilityIdentityType(uint8_t& type) {
void DeregistrationRequest::getMobilityIdentityType(uint8_t &type) {
if (ie_5gs_mobility_id) {
type = ie_5gs_mobility_id->gettypeOfIdentity();
} else {
......@@ -119,7 +129,7 @@ std::string DeregistrationRequest::get_5g_guti() {
if (ie_5gs_mobility_id) {
nas::_5G_GUTI_t guti;
ie_5gs_mobility_id->get5GGUTI(guti);
std::string str ;//= guti.toString();
std::string str; //= guti.toString();
return str;
} else {
return "error";
......@@ -127,7 +137,12 @@ std::string DeregistrationRequest::get_5g_guti() {
}
//------------------------------------------------------------------------------
void DeregistrationRequest::setSUCI_SUPI_format_IMSI(const string mcc, const string mnc, const string routingInd, uint8_t protection_sch_id, uint8_t hnpki, const string msin) {
void DeregistrationRequest::setSUCI_SUPI_format_IMSI(const string mcc,
const string mnc,
const string routingInd,
uint8_t protection_sch_id,
uint8_t hnpki,
const string msin) {
}
//------------------------------------------------------------------------------
......@@ -165,7 +180,8 @@ int DeregistrationRequest::encode2buffer(uint8_t *buf, int len) {
if (!(plain_header->encode2buffer(buf, len)))
return 0;
encoded_size += 3;
if (!(ie_deregistrationtype->encode2buffer(buf + encoded_size, len - encoded_size))) {
if (!(ie_deregistrationtype->encode2buffer(buf + encoded_size,
len - encoded_size))) {
if (!(ie_ngKSI->encode2buffer(buf + encoded_size, len - encoded_size))) {
encoded_size += 1;
} else {
......@@ -176,30 +192,37 @@ int DeregistrationRequest::encode2buffer(uint8_t *buf, int len) {
Logger::nas_mm().error("Encoding IE Deregistrationt Type error");
return 0;
}
if (int size = ie_5gs_mobility_id->encode2buffer(buf + encoded_size, len - encoded_size)) {
if (int size = ie_5gs_mobility_id->encode2buffer(buf + encoded_size,
len - encoded_size)) {
encoded_size += size;
} else {
Logger::nas_mm().error("Encoding IE ie_5gs_mobility_id error");
return 0;
}
Logger::nas_mm().debug("Encoded DeregistrationRequest message len (%d)", encoded_size);
Logger::nas_mm().debug("Encoded DeregistrationRequest message len (%d)",
encoded_size);
return 1;
}
//------------------------------------------------------------------------------
int DeregistrationRequest::decodefrombuffer(NasMmPlainHeader *header, uint8_t *buf, int len) {
int DeregistrationRequest::decodefrombuffer(NasMmPlainHeader *header,
uint8_t *buf, int len) {
Logger::nas_mm().debug("****Decoding DeregistrationRequest message****");
int decoded_size = 3;
plain_header = header;
ie_deregistrationtype = new _5GSDeregistrationType();
decoded_size += ie_deregistrationtype->decodefrombuffer(buf + decoded_size, len - decoded_size);
decoded_size += ie_deregistrationtype->decodefrombuffer(buf + decoded_size,
len - decoded_size);
ie_ngKSI = new NasKeySetIdentifier();
decoded_size += ie_ngKSI->decodefrombuffer(buf + decoded_size, len - decoded_size, false, true);
decoded_size += ie_ngKSI->decodefrombuffer(buf + decoded_size,
len - decoded_size, false, true);
decoded_size++;
ie_5gs_mobility_id = new _5GSMobilityIdentity();
decoded_size += ie_5gs_mobility_id->decodefrombuffer(buf + decoded_size, len - decoded_size, false);
Logger::nas_mm().debug("****Decoded DeregistrationRequest message (len %d)****", decoded_size);
decoded_size += ie_5gs_mobility_id->decodefrombuffer(buf + decoded_size,
len - decoded_size,
false);
Logger::nas_mm().debug(
"****Decoded DeregistrationRequest message (len %d)****", decoded_size);
}
......@@ -46,16 +46,21 @@ class DeregistrationRequest {
void setngKSI(uint8_t tsc, uint8_t key_set_id);
void setMobilityIdentityType(uint8_t type);
void setSUCI_SUPI_format_IMSI(const string mcc, const string mnc, const string routingInd, uint8_t protection_sch_id, const string msin);
void setSUCI_SUPI_format_IMSI(const string mcc, const string mnc, const string routingInd, uint8_t protection_sch_id, uint8_t hnpki, const string msin);
void setSUCI_SUPI_format_IMSI(const string mcc, const string mnc,
const string routingInd,
uint8_t protection_sch_id, const string msin);
void setSUCI_SUPI_format_IMSI(const string mcc, const string mnc,
const string routingInd,
uint8_t protection_sch_id, uint8_t hnpki,
const string msin);
void set5G_GUTI();
void setIMEI_IMEISV();
void set5G_S_TMSI();
void getDeregistrationType(uint8_t &dereg_type);
void getDeregistrationType(_5gs_deregistration_type_t& type);
void getngKSI(uint8_t& ng_ksi);
void getMobilityIdentityType(uint8_t& type);
void getDeregistrationType(_5gs_deregistration_type_t &type);
void getngKSI(uint8_t &ng_ksi);
void getMobilityIdentityType(uint8_t &type);
std::string get_5g_guti();
bool getSuciSupiFormatImsi(nas::SUCI_imsi_t &imsi);
......
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