Commit 2512c3d1 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'reroute_nas' into 'develop'

Reroute nas to the target AMF via AN tunnel (AMF re-allocation)

See merge request oai/cn5g/oai-cn5g-amf!93
parents 820d7ebe d694707e
......@@ -3775,6 +3775,16 @@ bool amf_n1::reroute_registration_request(std::shared_ptr<nas_context>& nc) {
} else {
Logger::amf_n1().debug(
"Could not find an appropriate target AMF to handle UE");
// Reroute NAS message via AN
std::string target_amf_set = {};
if (authorized_network_slice_info.targetAmfSetIsSet()) {
target_amf_set = authorized_network_slice_info.getTargetAmfSet();
} else {
Logger::amf_n1().debug("No Target AMF Set info available!");
return false;
}
if (reroute_nas_via_an(nc, target_amf_set)) return true;
return false;
}
......@@ -4297,6 +4307,7 @@ bool amf_n1::select_target_amf(
}
return result;
}
//------------------------------------------------------------------------------
void amf_n1::send_n1_message_notity(
const std::shared_ptr<nas_context>& nc,
......@@ -4321,3 +4332,27 @@ void amf_n1::send_n1_message_notity(
itti_msg->get_msg_name());
}
}
//------------------------------------------------------------------------------
bool amf_n1::reroute_nas_via_an(
const std::shared_ptr<nas_context>& nc,
const std::string& target_amf_set) const {
Logger::amf_n1().debug(
"Send a request to Reroute NAS message to the target AMF via AN");
std::shared_ptr<itti_rereoute_nas> itti_msg =
std::make_shared<itti_rereoute_nas>(TASK_AMF_N1, TASK_AMF_N2);
itti_msg->ran_ue_ngap_id = nc->ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = nc->amf_ue_ngap_id;
itti_msg->amf_set_id = target_amf_set;
int ret = itti_inst->send_msg(itti_msg);
if (0 != ret) {
Logger::ngap().error(
"Could not send ITTI message %s to task TASK_AMF_N2",
itti_msg->get_msg_name());
}
return true;
}
......@@ -251,6 +251,10 @@ class amf_n1 {
const std::shared_ptr<nas_context>& nc,
const std::string& target_amf) const;
bool reroute_nas_via_an(
const std::shared_ptr<nas_context>& nc,
const std::string& target_amf_set) const;
private:
void ue_initiate_de_registration_handle(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas);
......
......@@ -44,6 +44,7 @@
#include "UEContextReleaseCommand.hpp"
#include "HandoverPreparationFailure.hpp"
#include "Paging.hpp"
#include "RerouteNASRequest.hpp"
#include "amf_app.hpp"
#include "amf_config.hpp"
#include "amf_n1.hpp"
......@@ -211,6 +212,11 @@ void amf_n2_task(void* args_p) {
itti_paging* m = dynamic_cast<itti_paging*>(msg);
amf_n2_inst->handle_itti_message(ref(*m));
} break;
case REROUTE_NAS_REQ: {
Logger::amf_n2().info("Received Reroute NAS Req message, handling");
itti_rereoute_nas* m = dynamic_cast<itti_rereoute_nas*>(msg);
amf_n2_inst->handle_itti_message(ref(*m));
} break;
case TERMINATE: {
if (itti_msg_terminate* terminate =
dynamic_cast<itti_msg_terminate*>(msg)) {
......@@ -676,6 +682,14 @@ void amf_n2::handle_itti_message(itti_initial_ue_message& init_ue_msg) {
}
}
// Store InitialUEMessage for Rereoute NAS later
unc.get()->initialUEMsg.buf =
(uint8_t*) calloc(BUFFER_SIZE_1024, sizeof(uint8_t));
if (unc.get()->initialUEMsg.buf) {
unc.get()->initialUEMsg.size = init_ue_msg.initUeMsg->encode2buffer(
unc.get()->initialUEMsg.buf, BUFFER_SIZE_1024);
}
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = -1;
std::shared_ptr<itti_nas_signalling_establishment_request> i =
......@@ -2020,6 +2034,44 @@ void amf_n2::handle_itti_message(itti_uplink_ran_status_transfer& itti_msg) {
sctp_s_38412.sctp_send_msg(unc.get()->target_gnb_assoc_id, 0, &b);
}
//------------------------------------------------------------------------------
void amf_n2::handle_itti_message(itti_rereoute_nas& itti_msg) {
Logger::amf_n2().debug("Handle Reroute NAS Request message...");
std::shared_ptr<ue_ngap_context> unc = {};
if (!is_ran_ue_id_2_ue_ngap_context(itti_msg.ran_ue_ngap_id)) {
Logger::amf_n2().error(
"No UE NGAP context with ran_ue_ngap_id 0x%x", itti_msg.ran_ue_ngap_id);
return;
}
unc = ran_ue_id_2_ue_ngap_context(itti_msg.ran_ue_ngap_id);
if (unc.get()->amf_ue_ngap_id != itti_msg.amf_ue_ngap_id) {
Logger::amf_n2().error(
"AMF UE NGAP ID does not match the expected value (requested "
"amf_ue_ngap_id 0x%x, existed amf_ue_ngap_id 0x%x)",
itti_msg.amf_ue_ngap_id, unc.get()->amf_ue_ngap_id);
return;
}
RerouteNASRequest rerouteNASRequest = {};
rerouteNASRequest.setMessageType();
rerouteNASRequest.setRanUeNgapId(itti_msg.ran_ue_ngap_id);
rerouteNASRequest.setAmfUeNgapId(itti_msg.amf_ue_ngap_id);
rerouteNASRequest.setAMFSetID(itti_msg.amf_set_id);
rerouteNASRequest.setNgapMessage(
unc->initialUEMsg); // Include InitialUEMessage
// TODO: AllowedNSSAI (Optional)
uint8_t buffer[BUFFER_SIZE_1024];
int encoded_size = rerouteNASRequest.encode2buffer(buffer, BUFFER_SIZE_1024);
bstring b = blk2bstr(buffer, encoded_size);
amf_n2_inst->sctp_s_38412.sctp_send_msg(
unc.get()->gnb_assoc_id, unc.get()->sctp_stream_send, &b);
}
//------------------------------------------------------------------------------
void amf_n2::send_handover_preparation_failure(
const unsigned long amf_ue_ngap_id, const uint32_t ran_ue_ngap_id,
......
......@@ -62,6 +62,7 @@ class amf_n2 : public ngap::ngap_app {
void handle_itti_message(itti_handover_request_Ack& itti_msg);
void handle_itti_message(itti_handover_notify& itti_msg);
void handle_itti_message(itti_uplink_ran_status_transfer& itti_msg);
void handle_itti_message(itti_rereoute_nas& itti_msg);
void send_handover_preparation_failure(
const unsigned long amf_ue_ngap_id, const uint32_t ran_ue_ngap_id,
const sctp_assoc_id_t& gnb_assoc_id);
......
......@@ -68,6 +68,8 @@ class ue_ngap_context {
// state management, ue status over the air
ng_ue_state_t ng_ue_state;
uint8_t ncc; // Next Hop Chaining Counter
OCTET_STRING_t initialUEMsg;
};
#endif
......@@ -79,6 +79,7 @@ typedef enum {
DOWNLINK_NAS_TRANSFER,
NAS_SIG_ESTAB_REQ, // task amf_app
N1N2_MESSAGE_TRANSFER_REQ,
REROUTE_NAS_REQ,
NSMF_PDU_SESSION_CREATE_SM_CTX,
NSMF_PDU_SESSION_UPDATE_SM_CTX,
N11_REGISTER_NF_INSTANCE_REQUEST,
......
......@@ -297,4 +297,15 @@ class itti_uplink_ran_status_transfer : public itti_msg_n2 {
UplinkRANStatusTransfer* uplinkrantransfer;
};
class itti_rereoute_nas : public itti_msg_n2 {
public:
itti_rereoute_nas(const task_id_t origin, const task_id_t destination)
: itti_msg_n2(REROUTE_NAS_REQ, origin, destination) {}
itti_rereoute_nas(const itti_rereoute_nas& i) : itti_msg_n2(i) {}
uint32_t ran_ue_ngap_id;
long amf_ue_ngap_id;
std::string amf_set_id;
};
#endif
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file
\brief
\author
\date 2022
\email: contact@openairinterface.org
*/
#ifndef _REROUTE_NAS_REQUEST_H_
#define _REROUTE_NAS_REQUEST_H_
#include "AMF-UE-NGAP-ID.hpp"
#include "MessageType.hpp"
#include "NAS-PDU.hpp"
#include "NgapIEsStruct.hpp"
#include "RAN-UE-NGAP-ID.hpp"
#include "AllowedNssai.hpp"
#include "AMFSetID.hpp"
extern "C" {
#include "Ngap_RerouteNASRequest.h"
#include "Ngap_NGAP-PDU.h"
#include "Ngap_ProtocolIE-Field.h"
}
namespace ngap {
class RerouteNASRequest {
public:
RerouteNASRequest();
virtual ~RerouteNASRequest();
void setMessageType();
void setAmfUeNgapId(unsigned long id); // 40 bits
unsigned long getAmfUeNgapId();
void setRanUeNgapId(uint32_t id); // 32 bits
uint32_t getRanUeNgapId();
void setNgapMessage(OCTET_STRING_t& message);
bool getNgapMessage(OCTET_STRING_t& message) const;
void setAMFSetID(const std::string& amf_set_id);
void getAMFSetID(std::string& amf_set_id);
void setAllowedNssai(std::vector<S_Nssai> list);
bool getAllowedNssai(std::vector<S_Nssai>& list);
int encode2buffer(uint8_t* buf, int buf_size);
bool decodefrompdu(Ngap_NGAP_PDU_t* ngap_msg_pdu);
private:
Ngap_NGAP_PDU_t* rerouteNASRequestPdu;
Ngap_RerouteNASRequest_t* rerouteNASRequestIEs;
RAN_UE_NGAP_ID ranUeNgapId; // Mandatory
AMF_UE_NGAP_ID* amfUeNgapId; // Optional
OCTET_STRING_t ngapMessage; // Mandatory
AMFSetID amfSetID; // Mandatory
AllowedNSSAI* allowedNssai; // Optional
// SourceToTarget-AMFInformationReroute //Optional
};
} // namespace ngap
#endif
......@@ -59,7 +59,7 @@ void N1MessageNotifyApiImpl::receive_n1_message_notification(
int ret = itti_inst->send_msg(itti_msg);
if (0 != ret) {
Logger::amf_server().error(
"Could not send ITTI message %s to task TASK_AMF_N2",
"Could not send ITTI message %s to task TASK_AMF_APP",
itti_msg->get_msg_name());
}
}
......
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