Commit dac9170e authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Fix issues to support multiple PDU Sessions

parent 06da6485
......@@ -216,6 +216,16 @@ bool amf_app::find_pdu_session_context(
return true;
}
bool amf_app::get_pdu_sessions_context(
const string& supi,
std::vector<std::shared_ptr<pdu_session_context>>& sessions_ctx) {
if (!is_supi_2_ue_context(supi)) return false;
std::shared_ptr<ue_context> uc = {};
uc = supi_2_ue_context(supi);
if (!uc.get()->get_pdu_sessions_context(sessions_ctx)) return false;
return true;
}
//------------------------------------------------------------------------------
void amf_app::handle_itti_message(
itti_n1n2_message_transfer_request& itti_msg) {
......
......@@ -92,6 +92,9 @@ class amf_app {
const string& supi, const std::uint8_t pdu_session_id,
std::shared_ptr<pdu_session_context>& psc);
bool get_pdu_sessions_context(
const string& supi,
std::vector<std::shared_ptr<pdu_session_context>>& sessions_ctx);
// SMF Client response handlers
void handle_post_sm_context_response_error_400();
// others
......
......@@ -122,8 +122,7 @@ amf_n1::amf_n1() {
Logger::amf_n1().error("Cannot create task TASK_AMF_N1");
throw std::runtime_error("Cannot create task TASK_AMF_N1");
}
Logger::amf_n1().startup("Started");
Logger::amf_n1().debug("Construct amf_n1 successfully");
Logger::amf_n1().startup("amf_n1 started");
}
//------------------------------------------------------------------------------
......@@ -604,7 +603,8 @@ void amf_n1::service_request_handle(
// get PDU session status
std::vector<uint8_t> pdu_session_to_be_activated = {};
std::bitset<16> pdu_session_status_bits((uint16_t) 0x0200);
std::bitset<16> pdu_session_status_bits(
(uint16_t) serReq->getPduSessionStatus());
for (int i = 0; i < 15; i++) {
if (pdu_session_status_bits.test(i)) {
......@@ -951,7 +951,8 @@ void amf_n1::registration_request_handle(
// TODO: check if the List Of PDU Sessions To Be Activated is available
// regReq->getPduSessionStatus()
Logger::amf_n1().debug("Network handling mobility registration ...");
run_mobility_registration_update_procedure(nc);
run_mobility_registration_update_procedure(
nc, regReq->getUplinkDataStatus(), regReq->getPduSessionStatus());
} break;
case PERIODIC_REGISTRATION_UPDATING: {
......@@ -2408,7 +2409,8 @@ void amf_n1::sha256(
//------------------------------------------------------------------------------
void amf_n1::run_mobility_registration_update_procedure(
std::shared_ptr<nas_context> nc) {
std::shared_ptr<nas_context> nc, uint16_t uplink_data_status,
uint16_t pdu_session_status) {
// encoding REGISTRATION ACCEPT
std::unique_ptr<RegistrationAccept> regAccept =
std::make_unique<RegistrationAccept>();
......@@ -2442,8 +2444,6 @@ void amf_n1::run_mobility_registration_update_procedure(
// std::string guti = amf_cfg.guami.mcc + amf_cfg.guami.mnc +
// amf_cfg.guami.regionID + amf_cfg.guami.AmfSetID + amf_cfg.guami.AmfPointer
// + "0001";
std::string guti = "1234567890"; // TODO: need modify
Logger::amf_n1().debug("Allocated GUTI %s", guti.c_str());
regAccept->set_5GS_Network_Feature_Support(0x00, 0x00);
uint8_t buffer[1024] = {0};
......@@ -2464,25 +2464,39 @@ void amf_n1::run_mobility_registration_update_procedure(
string supi = "imsi-" + nc.get()->imsi;
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)) {
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());
}
*/
std::shared_ptr<pdu_session_context> psc = {};
string ue_context_key = "app_ue_ranid_" + to_string(nc->ran_ue_ngap_id) +
":amfid_" + to_string(nc->amf_ue_ngap_id);
std::shared_ptr<ue_context> uc;
std::shared_ptr<ue_context> uc = {};
uc = amf_app_inst->ran_amf_id_2_ue_context(ue_context_key);
if (uc.get() == nullptr) {
Logger::amf_n1().warn(
"Cannot find the UE context with key %s", ue_context_key.c_str());
return;
}
// get PDU session status
std::vector<uint8_t> pdu_session_to_be_activated = {};
std::bitset<16> pdu_session_status_bits((uint16_t) pdu_session_status);
for (int i = 0; i < 15; i++) {
if (pdu_session_status_bits.test(i)) {
if (i <= 7)
pdu_session_to_be_activated.push_back(8 + i);
else if (i > 8)
pdu_session_to_be_activated.push_back(i - 8);
}
}
if (pdu_session_to_be_activated.size() > 0) {
for (auto i : pdu_session_to_be_activated)
Logger::amf_n1().debug("PDU session to be activated %d", i);
}
if (pdu_session_to_be_activated.size() > 0) {
// get PDU session context for 1 PDU session for now
// TODO: multiple PDU sessions
uc->find_pdu_session_context(pdu_session_to_be_activated[0], psc);
}
uint8_t* kamf = nc.get()->kamf[secu->vector_pointer];
......@@ -2490,7 +2504,6 @@ void amf_n1::run_mobility_registration_update_procedure(
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
print_buffer("amf_n1", "kamf", kamf, 32);
// 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);
......@@ -2499,11 +2512,12 @@ void amf_n1::run_mobility_registration_update_procedure(
itti_msg->kgnb = kgnb_bs;
itti_msg->nas = protectedNas;
itti_msg->is_sr = true; // service request indicator
// TODO: should not get from Pdu_session_context
// TODO: should come from NAS (if UE includes in the List Of PDU Sessions To
// Be Activated)
itti_msg->pdu_session_id = psc.get()->pdu_session_id;
itti_msg->n2sm = psc.get()->n2sm;
if (psc.get() != nullptr) {
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);
int ret = itti_inst->send_msg(i);
......
......@@ -104,7 +104,8 @@ class amf_n1 {
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);
std::shared_ptr<nas_context> nc, uint16_t uplink_data_status,
uint16_t pdu_session_status);
// authentication
bool auth_vectors_generator(std::shared_ptr<nas_context>& nc);
......
......@@ -64,6 +64,7 @@ extern amf_config amf_cfg;
extern amf_n11* amf_n11_inst;
extern amf_n1* amf_n1_inst;
extern amf_app* amf_app_inst;
extern statistics stacs;
extern void msg_str_2_msg_hex(std::string msg, bstring& b);
extern void convert_string_2_hex(std::string& input, std::string& output);
......@@ -139,11 +140,10 @@ void amf_n11_task(void*) {
//------------------------------------------------------------------------------
amf_n11::amf_n11() {
if (itti_inst->create_task(TASK_AMF_N11, amf_n11_task, nullptr)) {
Logger::amf_n11().error("Cannot create task TASK_AMF_N1");
throw std::runtime_error("Cannot create task TASK_AMF_N1");
Logger::amf_n11().error("Cannot create task TASK_AMF_N11");
throw std::runtime_error("Cannot create task TASK_AMF_N11");
}
Logger::amf_n11().startup("Started");
Logger::amf_n11().debug("Construct amf_n1 successfully");
Logger::amf_n11().startup("amf_n11 started");
}
//------------------------------------------------------------------------------
......@@ -165,7 +165,6 @@ void amf_n11::handle_itti_message(
if (uc.get() != nullptr) {
supi = uc->supi;
}
// 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)",
......@@ -216,6 +215,8 @@ void amf_n11::handle_itti_message(
(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);
stacs.display();
}
//------------------------------------------------------------------------------
......@@ -237,19 +238,17 @@ void amf_n11::handle_itti_message(itti_smf_services_consumer& smf) {
if (!uc.get()->find_pdu_session_context(smf.pdu_sess_id, psc)) {
psc = std::shared_ptr<pdu_session_context>(new pdu_session_context());
uc.get()->add_pdu_session_context(smf.pdu_sess_id, psc);
set_supi_to_pdu_ctx(supi, psc); // TODO: should be removed
Logger::amf_n11().debug("Create a PDU Session Context");
}
pduid2supi[smf.pdu_sess_id] = supi;
psc.get()->amf_ue_ngap_id = nc.get()->amf_ue_ngap_id;
psc.get()->ran_ue_ngap_id = nc.get()->ran_ue_ngap_id;
psc.get()->req_type = smf.req_type;
psc.get()->pdu_session_id = smf.pdu_sess_id;
psc.get()->snssai.sST = smf.snssai.sST;
psc.get()->snssai.sD = smf.snssai.sD;
psc.get()->plmn.mcc = smf.plmn.mcc;
psc.get()->plmn.mnc = smf.plmn.mnc;
psc.get()->amf_ue_ngap_id = nc.get()->amf_ue_ngap_id;
psc.get()->ran_ue_ngap_id = nc.get()->ran_ue_ngap_id;
psc.get()->req_type = smf.req_type;
psc.get()->pdu_session_id = smf.pdu_sess_id;
psc.get()->snssai.sST = smf.snssai.sST;
psc.get()->snssai.sD = smf.snssai.sD;
psc.get()->plmn.mcc = smf.plmn.mcc;
psc.get()->plmn.mnc = smf.plmn.mnc;
// parse binary dnn and store
std::string dnn = "default";
......@@ -423,11 +422,17 @@ void amf_n11::handle_pdu_session_initial_request(
//------------------------------------------------------------------------------
void amf_n11::handle_itti_message(
itti_nsmf_pdusession_release_sm_context& itti_msg) {
// TTN: Should be replace by new mechanism to support multiple PDU sessions
// Need PDU session ID
std::shared_ptr<pdu_session_context> psc = supi_to_pdu_ctx(itti_msg.supi);
string smf_addr;
std::string smf_api_version;
// TODO: Need PDU session ID
uint8_t pdu_session_id = 1; // Hardcoded
std::shared_ptr<pdu_session_context> psc = {};
if (!amf_app_inst->find_pdu_session_context(
itti_msg.supi, pdu_session_id, psc)) {
Logger::amf_n11().warn(
"PDU Session context for SUPI %s doesn't exit!", itti_msg.supi.c_str());
return;
}
string smf_addr, smf_api_version;
if (!psc.get()->smf_available) {
Logger::amf_n11().error("No SMF is available for this PDU session");
......@@ -450,26 +455,6 @@ void amf_n11::handle_itti_message(
remote_uri, json_part, "", "", itti_msg.supi, psc.get()->pdu_session_id);
}
// Context management functions
//------------------------------------------------------------------------------
bool amf_n11::is_supi_to_pdu_ctx(const std::string& supi) const {
std::shared_lock lock(m_supi2pdu);
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_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) {
std::shared_lock lock(m_supi2pdu);
supi2pdu[supi] = psc;
}
// SMF selection
//------------------------------------------------------------------------------
bool amf_n11::smf_selection_from_configuration(
......
......@@ -57,16 +57,6 @@ class amf_n11 {
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::map<uint8_t, std::string> pduid2supi;
bool smf_selection_from_configuration(
std::string& smf_addr, std::string& smf_api_version);
void handle_post_sm_context_response_error_400();
......
......@@ -201,8 +201,7 @@ amf_n2::amf_n2(const std::string& address, const uint16_t port_num)
Logger::amf_n2().error("Cannot create task TASK_AMF_N2");
throw std::runtime_error("Cannot create task TASK_AMF_N2");
}
Logger::amf_n2().startup("Started");
Logger::amf_n2().debug("Construct amf_n2 successfully");
Logger::amf_n2().startup("amf_n2 started");
}
//------------------------------------------------------------------------------
......@@ -1114,25 +1113,36 @@ void amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
// handoverrequest->setSourceToTarget_TransparentContainer(sourceTotarget);
string supi = "imsi-" + nc.get()->imsi;
// TODO: REMOVE supi_to_pdu_ctx (need PDU Session ID)/ list of PDU Session ID
std::shared_ptr<pdu_session_context> psc =
amf_n11_inst->supi_to_pdu_ctx(supi);
// Get all the active PDU sessions
std::vector<std::shared_ptr<pdu_session_context>> pdu_sessions = {};
if (!amf_app_inst->get_pdu_sessions_context(supi, pdu_sessions)) {
Logger::amf_n2().warn("Error when retrieving the active PDU Sessions!");
}
std::vector<PDUSessionResourceSetupRequestItem_t> list;
PDUSessionResourceSetupRequestItem_t item;
item.pduSessionId = psc.get()->pdu_session_id;
item.s_nssai.sst = "01";
item.s_nssai.sd = "";
item.pduSessionNAS_PDU = NULL;
bstring n2sm = psc.get()->n2sm;
if (blength(psc.get()->n2sm) != 0) {
item.pduSessionResourceSetupRequestTransfer.buf =
(uint8_t*) bdata(psc.get()->n2sm);
item.pduSessionResourceSetupRequestTransfer.size = blength(psc.get()->n2sm);
} else {
Logger::amf_n2().error("n2sm empty!");
if (pdu_sessions.size() > 0) {
for (auto pdu_session : pdu_sessions) {
if (pdu_session.get() != nullptr) {
item.pduSessionId = pdu_session.get()->pdu_session_id;
item.s_nssai.sst = pdu_session.get()->snssai.sST;
item.s_nssai.sd = pdu_session.get()->snssai.sD;
item.pduSessionNAS_PDU = NULL;
bstring n2sm = pdu_session.get()->n2sm;
if (blength(pdu_session.get()->n2sm) != 0) {
item.pduSessionResourceSetupRequestTransfer.buf =
(uint8_t*) bdata(pdu_session.get()->n2sm);
item.pduSessionResourceSetupRequestTransfer.size =
blength(pdu_session.get()->n2sm);
} else {
Logger::amf_n2().error("n2sm empty!");
}
list.push_back(item);
}
}
}
list.push_back(item);
handoverrequest->setPduSessionResourceSetupList(list);
handoverrequest->setAllowedNSSAI(Allowed_Nssai);
handoverrequest->setSourceToTarget_TransparentContainer(sourceTotarget);
......
......@@ -42,25 +42,22 @@ void statistics::display() {
"information-------------------------------------------|");
Logger::amf_app().info(
"| Index | Status | Global ID | gNB "
"Name | PLMN |");
"Name | PLMN |");
if (gnbs.size() == 0) {
Logger::amf_app().info(
"| - | - | - | "
"- | |");
"- | - |");
}
int i = 1;
for (auto const& gnb : gnbs) {
Logger::amf_app().info(
"| %d | Connected | 0x%x | %s "
" | %s, %s | ",
" | %s, %s | ",
i, gnb.second.gnb_id, gnb.second.gnb_name.c_str(),
gnb.second.mcc.c_str(), gnb.second.mnc.c_str());
Logger::amf_app().info(
"| Supported TA list %s "
" "
" |",
gnb.second.plmn_to_string().c_str());
"| Supported TA list %s|", gnb.second.plmn_to_string().c_str());
i++;
}
......@@ -82,7 +79,7 @@ void statistics::display() {
i = 0;
for (auto const& ue : ue_infos) {
Logger::amf_app().info(
"|%7d|%22s|%18s|%15s|%16d|%11d|%3s, %3s|%7d|", i + 1,
"|%7d|%22s|%18s|%15s|%16d|%11d| %3s,%3s |%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.c_str(), ue.second.mnc.c_str(), ue.second.cellId);
......
......@@ -46,19 +46,19 @@ typedef struct {
// long nrCellId;
std::string plmn_to_string() const {
std::string s = {};
s.append("PLMN List: ");
// s.append("PLMN List: ");
for (auto supported_item : plmn_list) {
s.append("TAC " + std::to_string(supported_item.tac));
s.append("PLMNs (");
s.append(", PLMN ");
for (auto plmn_slice : supported_item.b_plmn_list) {
s.append("(MCC " + plmn_slice.mcc);
s.append(", MNC " + plmn_slice.mnc);
for (auto slice : plmn_slice.slice_list) {
s.append("(SST " + slice.sst + ", SD " + slice.sd + ")");
s.append(" (SST " + slice.sst + ", SD " + slice.sd + "), ");
}
s.append(")");
s.append("),");
}
s.append(")");
s.append("), ");
}
return s;
}
......
......@@ -56,3 +56,12 @@ void ue_context::add_pdu_session_context(
void ue_context::copy_pdu_sessions(std::shared_ptr<ue_context>& ue_ctx) {
pdu_sessions = ue_ctx->pdu_sessions;
}
bool ue_context::get_pdu_sessions_context(
std::vector<std::shared_ptr<pdu_session_context>>& sessions_ctx) {
std::shared_lock lock(m_pdu_session);
for (auto s : pdu_sessions) {
sessions_ctx.push_back(s.second);
}
return true;
}
......@@ -55,6 +55,8 @@ class ue_context {
const std::uint8_t& session_id,
const std::shared_ptr<pdu_session_context>& context);
void copy_pdu_sessions(std::shared_ptr<ue_context>& ue_ctx);
bool get_pdu_sessions_context(
std::vector<std::shared_ptr<pdu_session_context>>& sessions_ctx);
public:
uint32_t ran_ue_ngap_id; // 32bits
......
......@@ -53,6 +53,7 @@ using namespace amf_application;
extern itti_mw* itti_inst;
extern amf_n1* amf_n1_inst;
extern amf_n11* amf_n11_inst;
extern amf_app* amf_app_inst;
typedef int (*ngap_message_decoded_callback)(
const sctp_assoc_id_t assoc_id, const sctp_stream_id_t stream,
......@@ -406,16 +407,16 @@ int ngap_amf_handle_pdu_session_resource_setup_response(
amf_n1_inst->amf_ue_id_2_nas_context(amf_ue_ngap_id);
string supi = "imsi-" + nct.get()->imsi;
std::shared_ptr<pdu_session_context> psc;
if (amf_n11_inst->is_supi_to_pdu_ctx(supi)) {
psc = amf_n11_inst->supi_to_pdu_ctx(supi);
if (!psc) {
Logger::amf_n1().error("connot get pdu_session_context");
return 0;
if (amf_app_inst->find_pdu_session_context(
supi, list_fail[0].pduSessionId, psc)) {
if (psc.get() == nullptr) {
Logger::amf_n1().error("Cannot get pdu_session_context");
return -1;
}
}
psc.get()->isn2sm_avaliable = false;
Logger::ngap().debug(
"receive pdu session resource setup response fail(multi pdu session "
"Receive pdu session resource setup response fail (multi pdu session "
"id),set pdu session context isn2sm_avaliable = false");
/*Logger::ngap().debug("Sending itti ue context release command to
TASK_AMF_N2"); itti_ue_context_release_command * itti_msg = new
......
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