Commit 79998d48 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

First version for Implicit De-registration Timer

parent de37a02e
...@@ -56,6 +56,7 @@ namespace amf_application { ...@@ -56,6 +56,7 @@ namespace amf_application {
#define TASK_AMF_APP_PERIODIC_STATISTICS (0) #define TASK_AMF_APP_PERIODIC_STATISTICS (0)
#define TASK_AMF_MOBILE_REACHABLE_TIMER_EXPIRE (1) #define TASK_AMF_MOBILE_REACHABLE_TIMER_EXPIRE (1)
#define TASK_AMF_IMPLICIT_DEREGISTRATION_TIMER_EXPIRE (2)
class amf_app { class amf_app {
private: private:
......
...@@ -119,6 +119,10 @@ void amf_n1_task(void*) { ...@@ -119,6 +119,10 @@ void amf_n1_task(void*) {
amf_n1_inst->mobile_reachable_timer_timeout( amf_n1_inst->mobile_reachable_timer_timeout(
to->timer_id, to->arg2_user); to->timer_id, to->arg2_user);
break; break;
case TASK_AMF_IMPLICIT_DEREGISTRATION_TIMER_EXPIRE:
amf_n1_inst->implicit_deregistration_timer_timeout(
to->timer_id, to->arg2_user);
break;
default: default:
Logger::amf_n1().info( Logger::amf_n1().info(
"No handler for timer(%d) with arg1_user(%d) ", to->timer_id, "No handler for timer(%d) with arg1_user(%d) ", to->timer_id,
...@@ -489,8 +493,9 @@ void amf_n1::nas_signalling_establishment_request_handle( ...@@ -489,8 +493,9 @@ void amf_n1::nas_signalling_establishment_request_handle(
nc.get()->amf_ue_ngap_id = amf_ue_ngap_id; nc.get()->amf_ue_ngap_id = amf_ue_ngap_id;
nc.get()->ran_ue_ngap_id = ran_ue_ngap_id; nc.get()->ran_ue_ngap_id = ran_ue_ngap_id;
nc.get()->serving_network = snn; nc.get()->serving_network = snn;
// stop Mobile Reachable Timer // Stop Mobile Reachable Timer/Implicit Deregistration Timer
itti_inst->timer_remove(nc.get()->mobile_reachable_timer); itti_inst->timer_remove(nc.get()->mobile_reachable_timer);
itti_inst->timer_remove(nc.get()->implicit_deregistration_timer);
// stacs.UE_connected += 1; // stacs.UE_connected += 1;
// Trigger UE Reachability Status Notify // Trigger UE Reachability Status Notify
...@@ -677,8 +682,10 @@ void amf_n1::identity_response_handle( ...@@ -677,8 +682,10 @@ void amf_n1::identity_response_handle(
nc.get()->imsi = supi; nc.get()->imsi = supi;
supi2amfId[("imsi-" + nc.get()->imsi)] = amf_ue_ngap_id; supi2amfId[("imsi-" + nc.get()->imsi)] = amf_ue_ngap_id;
supi2ranId[("imsi-" + nc.get()->imsi)] = ran_ue_ngap_id; supi2ranId[("imsi-" + nc.get()->imsi)] = ran_ue_ngap_id;
// stop Mobile Reachable Timer // Stop Mobile Reachable Timer/Implicit Deregistration Timer
itti_inst->timer_remove(nc.get()->mobile_reachable_timer); itti_inst->timer_remove(nc.get()->mobile_reachable_timer);
itti_inst->timer_remove(nc.get()->implicit_deregistration_timer);
if (nc.get()->to_be_register_by_new_suci) { if (nc.get()->to_be_register_by_new_suci) {
run_registration_procedure(nc); run_registration_procedure(nc);
} }
...@@ -932,8 +939,9 @@ void amf_n1::registration_request_handle( ...@@ -932,8 +939,9 @@ void amf_n1::registration_request_handle(
nc.get()->amf_ue_ngap_id = amf_ue_ngap_id; nc.get()->amf_ue_ngap_id = amf_ue_ngap_id;
nc.get()->ran_ue_ngap_id = ran_ue_ngap_id; nc.get()->ran_ue_ngap_id = ran_ue_ngap_id;
nc.get()->serving_network = snn; nc.get()->serving_network = snn;
// stop Mobile Reachable Timer // Stop Mobile Reachable Timer/Implicit Deregistration Timer
itti_inst->timer_remove(nc.get()->mobile_reachable_timer); itti_inst->timer_remove(nc.get()->mobile_reachable_timer);
itti_inst->timer_remove(nc.get()->implicit_deregistration_timer);
} }
nc.get()->is_imsi_present = true; nc.get()->is_imsi_present = true;
nc.get()->imsi = imsi.mcc + imsi.mnc + imsi.msin; nc.get()->imsi = imsi.mcc + imsi.mnc + imsi.msin;
...@@ -1019,8 +1027,10 @@ void amf_n1::registration_request_handle( ...@@ -1019,8 +1027,10 @@ void amf_n1::registration_request_handle(
// nc.get()->imsi = // nc.get()->imsi =
// supi2amfId[("imsi-"+nc.get()->imsi)] = amf_ue_ngap_id; // supi2amfId[("imsi-"+nc.get()->imsi)] = amf_ue_ngap_id;
// supi2ranId[("imsi-"+nc.get()->imsi)] = ran_ue_ngap_id; // supi2ranId[("imsi-"+nc.get()->imsi)] = ran_ue_ngap_id;
// stop Mobile Reachable Timer
// Stop Mobile Reachable Timer/Implicit Deregistration Timer
itti_inst->timer_remove(nc.get()->mobile_reachable_timer); itti_inst->timer_remove(nc.get()->mobile_reachable_timer);
itti_inst->timer_remove(nc.get()->implicit_deregistration_timer);
} }
} break; } break;
...@@ -3203,9 +3213,89 @@ void amf_n1::mobile_reachable_timer_timeout( ...@@ -3203,9 +3213,89 @@ void amf_n1::mobile_reachable_timer_timeout(
"No existed nas_context with amf_ue_ngap_id(0x%x)", amf_ue_ngap_id); "No existed nas_context with amf_ue_ngap_id(0x%x)", amf_ue_ngap_id);
} }
set_mobile_reachable_timer_timeout(nc, true); set_mobile_reachable_timer_timeout(nc, true);
// TODO: Start the implicit de-registration timer // TODO: Start the implicit de-registration timer
timer_id_t tid = itti_inst->timer_setup(
IMPLICIT_DEREGISTRATION_TIMER_MIN * 60, 0, TASK_AMF_N1,
TASK_AMF_IMPLICIT_DEREGISTRATION_TIMER_EXPIRE, amf_ue_ngap_id);
Logger::amf_app().startup(
"Started implicit de-registration timer (tid %d)", tid);
set_implicit_deregistration_timer(nc, tid);
}
//------------------------------------------------------------------------------
void amf_n1::implicit_deregistration_timer_timeout(
timer_id_t timer_id, uint64_t amf_ue_ngap_id) {
std::shared_ptr<nas_context> nc;
if (amf_n1_inst->is_amf_ue_id_2_nas_context(amf_ue_ngap_id))
nc = amf_n1_inst->amf_ue_id_2_nas_context(amf_ue_ngap_id);
else {
Logger::amf_n2().warn(
"No existed nas_context with amf_ue_ngap_id(0x%x)", amf_ue_ngap_id);
}
// Implicitly de-register UE
// TODO (4.2.2.3.3 Network-initiated Deregistration @3GPP TS 23.502V16.0.0):
// If the UE is in CM-CONNECTED state, the AMF may explicitly deregister the
// UE by sending a Deregistration Request message (Deregistration type, Access
// Type) to the UE
// Send PDU Session Release SM Context Request to SMF for each PDU Session
// Get all the PDU sessions
std::shared_ptr<ue_context> uc = {};
if (!find_ue_context(
nc.get()->ran_ue_ngap_id, nc.get()->amf_ue_ngap_id, uc)) {
Logger::amf_n1().warn("Cannot find the UE context");
return;
}
std::vector<std::shared_ptr<pdu_session_context>> pdu_sessions;
if (!uc.get()->get_pdu_sessions_context(pdu_sessions)) return;
for (auto p : pdu_sessions) {
std::shared_ptr<itti_nsmf_pdusession_release_sm_context> itti_msg =
std::make_shared<itti_nsmf_pdusession_release_sm_context>(
TASK_AMF_N1, TASK_AMF_N11);
itti_msg->supi = uc->supi;
itti_msg->pdu_session_id = p->pdu_session_id;
int ret = itti_inst->send_msg(itti_msg);
if (0 != ret) {
Logger::amf_n1().error(
"Could not send ITTI message %s to task TASK_AMF_N11",
itti_msg->get_msg_name());
}
}
// Send N2 UE Release command to NG-RAN if there is a N2 signalling connection
// to NG-RAN
Logger::amf_n1().debug(
"Sending ITTI UE Context Release Command to TASK_AMF_N2");
itti_ue_context_release_command* itti_msg =
new itti_ue_context_release_command(TASK_AMF_N1, TASK_AMF_N2);
itti_msg->amf_ue_ngap_id = nc.get()->amf_ue_ngap_id;
itti_msg->ran_ue_ngap_id = nc.get()->ran_ue_ngap_id;
itti_msg->cause.setChoiceOfCause(Ngap_Cause_PR_nas);
itti_msg->cause.setValue(Ngap_CauseNas_deregister);
std::shared_ptr<itti_ue_context_release_command> i =
std::shared_ptr<itti_ue_context_release_command>(itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::ngap().error(
"Could not send ITTI message %s to task TASK_AMF_N2",
i->get_msg_name());
}
} }
//------------------------------------------------------------------------------
void amf_n1::set_implicit_deregistration_timer(
std::shared_ptr<nas_context>& nc, const timer_id_t& t) {
std::unique_lock lock(m_nas_context);
nc.get()->implicit_deregistration_timer = t;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void amf_n1::set_mobile_reachable_timer( void amf_n1::set_mobile_reachable_timer(
std::shared_ptr<nas_context>& nc, const timer_id_t& t) { std::shared_ptr<nas_context>& nc, const timer_id_t& t) {
......
...@@ -195,6 +195,11 @@ class amf_n1 { ...@@ -195,6 +195,11 @@ class amf_n1 {
void set_mobile_reachable_timer( void set_mobile_reachable_timer(
std::shared_ptr<nas_context>& nc, const timer_id_t& t); std::shared_ptr<nas_context>& nc, const timer_id_t& t);
void set_implicit_deregistration_timer(
std::shared_ptr<nas_context>& nc, const timer_id_t& t);
void implicit_deregistration_timer_timeout(
timer_id_t timer_id, uint64_t amf_ue_ngap_id);
private: private:
void ue_initiate_de_registration_handle( void ue_initiate_de_registration_handle(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas); uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas);
......
...@@ -1295,7 +1295,7 @@ void amf_n2::handle_itti_message(itti_ue_context_release_complete& itti_msg) { ...@@ -1295,7 +1295,7 @@ void amf_n2::handle_itti_message(itti_ue_context_release_complete& itti_msg) {
timer_id_t tid = itti_inst->timer_setup( timer_id_t tid = itti_inst->timer_setup(
MOBILE_REACHABLE_TIMER_NO_EMERGENCY_SERVICES_MIN * 60, 0, TASK_AMF_N1, MOBILE_REACHABLE_TIMER_NO_EMERGENCY_SERVICES_MIN * 60, 0, TASK_AMF_N1,
TASK_AMF_MOBILE_REACHABLE_TIMER_EXPIRE, amf_ue_ngap_id); TASK_AMF_MOBILE_REACHABLE_TIMER_EXPIRE, amf_ue_ngap_id);
Logger::amf_app().startup("Started mobile reachable timer ( tid %d)", tid); Logger::amf_app().startup("Started mobile reachable timer (tid %d)", tid);
amf_n1_inst->set_mobile_reachable_timer(nc, tid); amf_n1_inst->set_mobile_reachable_timer(nc, tid);
amf_n1_inst->set_mobile_reachable_timer_timeout(nc, false); amf_n1_inst->set_mobile_reachable_timer_timeout(nc, false);
......
...@@ -27,4 +27,5 @@ ...@@ -27,4 +27,5 @@
#define T3512_TIMER_VALUE_MIN 54 // 54 minutes #define T3512_TIMER_VALUE_MIN 54 // 54 minutes
#define MOBILE_REACHABLE_TIMER_NO_EMERGENCY_SERVICES_MIN \ #define MOBILE_REACHABLE_TIMER_NO_EMERGENCY_SERVICES_MIN \
(T3512_TIMER_VALUE_MIN + 4) // T3512 + 4, not for emergency services (T3512_TIMER_VALUE_MIN + 4) // T3512 + 4, not for emergency services
#define IMPLICIT_DEREGISTRATION_TIMER_MIN (T3512_TIMER_VALUE_MIN + 4)
#endif #endif
...@@ -67,6 +67,7 @@ nas_context::nas_context() : _vector(), _5g_he_av(), _5g_av(), kamf() { ...@@ -67,6 +67,7 @@ nas_context::nas_context() : _vector(), _5g_he_av(), _5g_av(), kamf() {
nas_status = CM_IDLE; nas_status = CM_IDLE;
is_mobile_reachable_timer_timeout = false; is_mobile_reachable_timer_timeout = false;
mobile_reachable_timer = ITTI_INVALID_TIMER_ID; mobile_reachable_timer = ITTI_INVALID_TIMER_ID;
implicit_deregistration_timer = ITTI_INVALID_TIMER_ID;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
......
...@@ -74,6 +74,7 @@ class nas_context { ...@@ -74,6 +74,7 @@ class nas_context {
_5gmm_state_t _5gmm_state; _5gmm_state_t _5gmm_state;
bool is_mobile_reachable_timer_timeout; bool is_mobile_reachable_timer_timeout;
timer_id_t mobile_reachable_timer; timer_id_t mobile_reachable_timer;
timer_id_t implicit_deregistration_timer;
// parameters from Registration request // parameters from Registration request
uint8_t registration_type : 3; uint8_t registration_type : 3;
......
...@@ -116,11 +116,13 @@ class itti_nsmf_pdusession_release_sm_context : public itti_msg_n11 { ...@@ -116,11 +116,13 @@ class itti_nsmf_pdusession_release_sm_context : public itti_msg_n11 {
itti_nsmf_pdusession_release_sm_context( itti_nsmf_pdusession_release_sm_context(
const itti_nsmf_pdusession_release_sm_context& i) const itti_nsmf_pdusession_release_sm_context& i)
: itti_msg_n11(i) { : itti_msg_n11(i) {
supi = i.supi; supi = i.supi;
pdu_session_id = i.pdu_session_id;
} }
public: public:
std::string supi; std::string supi;
uint8_t pdu_session_id;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
......
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