Commit 9f2d8e57 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

update N4/pfcp_association (SMF initiated)

parent 456483a0
......@@ -72,7 +72,9 @@ void smf_n4_task (void *args_p)
case N4_ASSOCIATION_SETUP_REQUEST:
if (itti_n4_association_setup_request* m = dynamic_cast<itti_n4_association_setup_request*>(msg)) {
smf_n4_inst->handle_itti_msg(ref(*m));
// m->trxn_id = smf_n4_inst->generate_trxn_id();
smf_n4_inst->send_association_setup_request(ref(*m));
//smf_n4_inst->handle_itti_msg(ref(*m));
}
break;
......@@ -238,6 +240,8 @@ void smf_n4::handle_receive_pfcp_msg(pfcp_msg& msg, const endpoint& remote_endpo
case PFCP_PFCP_PFD_MANAGEMENT_REQUEST:
case PFCP_PFCP_PFD_MANAGEMENT_RESPONSE:
case PFCP_ASSOCIATION_SETUP_RESPONSE:
handle_receive_association_setup_response(msg, remote_endpoint);
break;
case PFCP_ASSOCIATION_UPDATE_REQUEST:
case PFCP_ASSOCIATION_UPDATE_RESPONSE:
case PFCP_ASSOCIATION_RELEASE_REQUEST:
......@@ -314,16 +318,16 @@ void smf_n4::handle_receive_association_setup_request(pfcp::pfcp_msg& msg, const
Logger::smf_n4().warn("Received N4 ASSOCIATION SETUP REQUEST without recovery time stamp IE!, ignore message");
return;
}
bool restore_sx_sessions = false;
bool restore_n4_sessions = false;
if (msg_ies_container.up_function_features.first) {
// Should be detected by lower layers
pfcp_associations::get_instance().add_association(msg_ies_container.node_id.second, msg_ies_container.recovery_time_stamp.second, msg_ies_container.up_function_features.second, restore_sx_sessions);
pfcp_associations::get_instance().add_association(msg_ies_container.node_id.second, msg_ies_container.recovery_time_stamp.second, msg_ies_container.up_function_features.second, restore_n4_sessions);
} else {
pfcp_associations::get_instance().add_association(msg_ies_container.node_id.second, msg_ies_container.recovery_time_stamp.second, restore_sx_sessions);
pfcp_associations::get_instance().add_association(msg_ies_container.node_id.second, msg_ies_container.recovery_time_stamp.second, restore_n4_sessions);
}
// always yes (for the time being)
itti_n4_association_setup_response a(TASK_SMF_N4, TASK_SPGWU_SX);
itti_n4_association_setup_response a(TASK_SMF_N4, TASK_SMF_N4);
a.trxn_id = trxn_id;
pfcp::cause_t cause = {.cause_value = pfcp::CAUSE_VALUE_REQUEST_ACCEPTED};
a.pfcp_ies.set(cause);
......@@ -334,7 +338,6 @@ void smf_n4::handle_receive_association_setup_request(pfcp::pfcp_msg& msg, const
a.pfcp_ies.set(r);
a.pfcp_ies.set(cp_function_features);
if (node_id.node_id_type == pfcp::NODE_ID_TYPE_IPV4_ADDRESS) {
//a.l_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address_v4(smf_cfg.sx.addr4), 0);
a.r_endpoint = remote_endpoint;
send_n4_msg(a);
} else {
......@@ -346,12 +349,44 @@ void smf_n4::handle_receive_association_setup_request(pfcp::pfcp_msg& msg, const
return;
}
if (restore_sx_sessions) {
pfcp_associations::get_instance().restore_sx_sessions(msg_ies_container.node_id.second);
if (restore_n4_sessions) {
pfcp_associations::get_instance().restore_n4_sessions(msg_ies_container.node_id.second);
}
}
}
//------------------------------------------------------------------------------
void smf_n4::handle_receive_association_setup_response(pfcp::pfcp_msg& msg, const endpoint& remote_endpoint)
{
//TODO: To be completed
Logger::smf_n4().info("Received N4 ASSOCIATION SETUP RESPONSE from an UPF");
bool error = true;
uint64_t trxn_id = 0;
pfcp_association_setup_response msg_ies_container = {};
msg.to_core_type(msg_ies_container);
handle_receive_message_cb(msg, remote_endpoint, TASK_SMF_N4, error, trxn_id);
if (!error) {
if (not msg_ies_container.node_id.first) {
// Should be detected by lower layers
Logger::smf_app().warn("Received N4 ASSOCIATION SETUP RESPONSE without node id IE!, ignore message");
return;
}
if (not msg_ies_container.recovery_time_stamp.first) {
// Should be detected by lower layers
Logger::smf_app().warn("Received N4 ASSOCIATION SETUP RESPONSE without recovery time stamp IE!, ignore message");
return;
}
Logger::smf_app().info("Received N4 ASSOCIATION SETUP RESPONSE");
bool restore_n4_sessions = false;
if (msg_ies_container.up_function_features.first) {
pfcp_associations::get_instance().add_association(msg_ies_container.node_id.second, msg_ies_container.recovery_time_stamp.second, msg_ies_container.up_function_features.second, restore_n4_sessions);
} else {
pfcp_associations::get_instance().add_association(msg_ies_container.node_id.second, msg_ies_container.recovery_time_stamp.second, restore_n4_sessions);
}
}
}
//------------------------------------------------------------------------------
void smf_n4::handle_receive_session_establishment_response(pfcp::pfcp_msg& msg, const endpoint& remote_endpoint)
{
......@@ -523,4 +558,10 @@ void smf_n4::time_out_itti_event(const uint32_t timer_id)
}
}
//------------------------------------------------------------------------------
void smf_n4::send_association_setup_request(itti_n4_association_setup_request& i)
{
i.trxn_id = generate_trxn_id();
send_request(i.r_endpoint, i.pfcp_ies, TASK_SMF_N4, i.trxn_id);
}
......@@ -87,6 +87,7 @@ public:
void send_n4_msg (itti_n4_session_modification_request& s);
void send_n4_msg (itti_n4_session_deletion_request& s);
void send_n4_msg (itti_n4_session_report_response& s);
void send_association_setup_request(itti_n4_association_setup_request& i);
void send_heartbeat_request(std::shared_ptr<pfcp_association>& a);
void send_heartbeat_response(const endpoint& r_endpoint, const uint64_t trxn_id);
......@@ -97,6 +98,7 @@ public:
void handle_receive_heartbeat_request(pfcp::pfcp_msg& msg, const endpoint& r_endpoint);
void handle_receive_heartbeat_response(pfcp::pfcp_msg& msg, const endpoint& r_endpoint);
void handle_receive_association_setup_request(pfcp::pfcp_msg& msg, const endpoint& r_endpoint);
void handle_receive_association_setup_response(pfcp::pfcp_msg& msg, const endpoint& remote_endpoint);
void handle_receive_session_establishment_response(pfcp::pfcp_msg& msg, const endpoint& r_endpoint);
void handle_receive_session_modification_response(pfcp::pfcp_msg& msg, const endpoint& r_endpoint);
......
......@@ -298,10 +298,10 @@ int smf_app::process_pco_request(
if (smf_cfg.force_push_pco) {
pco_ids.ci_ip_address_allocation_via_nas_signalling = true;
if (!pco_ids.ci_dns_server_ipv4_address_request) {
process_pco_dns_server_request(pco_resp, NULL);
process_pco_dns_server_request(pco_resp, nullptr);
}
if (!pco_ids.ci_ipv4_link_mtu_request) {
process_pco_link_mtu_request(pco_resp, NULL);
process_pco_link_mtu_request(pco_resp, nullptr);
}
}
return RETURNok;
......
......@@ -69,30 +69,30 @@ void pfcp_association::notify_del_session(const pfcp::fseid_t& cp_fseid)
// }
// }
//------------------------------------------------------------------------------
void pfcp_association::restore_sx_sessions()
void pfcp_association::restore_n4_sessions()
{
std::unique_lock<std::mutex> l(m_sessions);
if (sessions.size()) {
is_restore_sessions_pending = true;
sx_session_restore_procedure * restore_proc = new sx_session_restore_procedure(sessions);
n4_session_restore_procedure * restore_proc = new n4_session_restore_procedure(sessions);
restore_proc->run();
}
}
//------------------------------------------------------------------------------
bool pfcp_associations::add_association(pfcp::node_id_t& node_id, pfcp::recovery_time_stamp_t& recovery_time_stamp, bool& restore_sx_sessions)
bool pfcp_associations::add_association(pfcp::node_id_t& node_id, pfcp::recovery_time_stamp_t& recovery_time_stamp, bool& restore_n4_sessions)
{
std::shared_ptr<pfcp_association> sa = std::shared_ptr<pfcp_association>(nullptr);
if (get_association(node_id, sa)) {
itti_inst->timer_remove(sa->timer_heartbeat);
if (sa->recovery_time_stamp == recovery_time_stamp) {
restore_sx_sessions = false;
restore_n4_sessions = false;
} else {
restore_sx_sessions = true;
restore_n4_sessions = true;
}
sa->recovery_time_stamp = recovery_time_stamp;
sa->function_features = {};
} else {
restore_sx_sessions = false;
restore_n4_sessions = false;
pfcp_association* association = new pfcp_association(node_id, recovery_time_stamp);
sa = std::shared_ptr<pfcp_association>(association);
sa->recovery_time_stamp = recovery_time_stamp;
......@@ -103,21 +103,21 @@ bool pfcp_associations::add_association(pfcp::node_id_t& node_id, pfcp::recovery
return true;
}
//------------------------------------------------------------------------------
bool pfcp_associations::add_association(pfcp::node_id_t& node_id, pfcp::recovery_time_stamp_t& recovery_time_stamp, pfcp::up_function_features_s& function_features, bool& restore_sx_sessions)
bool pfcp_associations::add_association(pfcp::node_id_t& node_id, pfcp::recovery_time_stamp_t& recovery_time_stamp, pfcp::up_function_features_s& function_features, bool& restore_n4_sessions)
{
std::shared_ptr<pfcp_association> sa = std::shared_ptr<pfcp_association>(nullptr);
if (get_association(node_id, sa)) {
itti_inst->timer_remove(sa->timer_heartbeat);
if (sa->recovery_time_stamp == recovery_time_stamp) {
restore_sx_sessions = false;
restore_n4_sessions = false;
} else {
restore_sx_sessions = true;
restore_n4_sessions = true;
}
sa->recovery_time_stamp = recovery_time_stamp;
sa->function_features.first = true;
sa->function_features.second = function_features;
} else {
restore_sx_sessions = false;
restore_n4_sessions = false;
pfcp_association* association = new pfcp_association(node_id, recovery_time_stamp, function_features);
sa = std::shared_ptr<pfcp_association>(association);
sa->recovery_time_stamp = recovery_time_stamp;
......@@ -157,11 +157,11 @@ bool pfcp_associations::get_association(const pfcp::fseid_t& cp_fseid, std::shar
}
//------------------------------------------------------------------------------
void pfcp_associations::restore_sx_sessions(const pfcp::node_id_t& node_id)
void pfcp_associations::restore_n4_sessions(const pfcp::node_id_t& node_id)
{
std::shared_ptr<pfcp_association> sa = {};
if (get_association(node_id, sa)) {
sa->restore_sx_sessions();
sa->restore_n4_sessions();
}
}
//------------------------------------------------------------------------------
......@@ -256,3 +256,19 @@ void pfcp_associations::notify_del_session(const pfcp::fseid_t& cp_fseid)
}
}
//------------------------------------------------------------------------------
bool pfcp_associations::add_peer_candidate_node(const pfcp::node_id_t& node_id)
{
for (std::vector<std::shared_ptr<pfcp_association>>::iterator it=pending_associations.begin(); it < pending_associations.end(); ++it) {
if ((*it)->node_id == node_id) {
// TODO purge sessions of this node
Logger::smf_app().info( "TODO purge sessions of this node");
pending_associations.erase(it);
break;
}
}
pfcp_association* association = new pfcp_association(node_id);
std::shared_ptr<pfcp_association> s = std::shared_ptr<pfcp_association>(association);
pending_associations.push_back(s);
return true;
}
......@@ -100,7 +100,7 @@ public:
bool has_session(const pfcp::fseid_t& cp_fseid);
void notify_del_session(const pfcp::fseid_t& cp_fseid);
//void del_sessions();
void restore_sx_sessions();
void restore_n4_sessions();
void set(const pfcp::up_function_features_s& ff) {function_features.first = true; function_features.second = ff;};
};
......@@ -132,21 +132,22 @@ public:
pfcp_associations(pfcp_associations const&) = delete;
void operator=(pfcp_associations const&) = delete;
bool add_association(pfcp::node_id_t& node_id, pfcp::recovery_time_stamp_t& recovery_time_stamp, bool& restore_sx_sessions);
bool add_association(pfcp::node_id_t& node_id, pfcp::recovery_time_stamp_t& recovery_time_stamp, pfcp::up_function_features_s& function_features, bool& restore_sx_sessions);
bool add_association(pfcp::node_id_t& node_id, pfcp::recovery_time_stamp_t& recovery_time_stamp, bool& restore_n4_sessions);
bool add_association(pfcp::node_id_t& node_id, pfcp::recovery_time_stamp_t& recovery_time_stamp, pfcp::up_function_features_s& function_features, bool& restore_n4_sessions);
bool get_association(const pfcp::node_id_t& node_id, std::shared_ptr<pfcp_association>& sa) const;
bool get_association(const pfcp::fseid_t& cp_fseid, std::shared_ptr<pfcp_association>& sa) const;
void notify_add_session(const pfcp::node_id_t& node_id, const pfcp::fseid_t& cp_fseid);
void notify_del_session(const pfcp::fseid_t& cp_fseid);
void restore_sx_sessions(const pfcp::node_id_t& node_id);
void restore_n4_sessions(const pfcp::node_id_t& node_id);
void initiate_heartbeat_request(timer_id_t timer_id, uint64_t arg2_user);
void timeout_heartbeat_request(timer_id_t timer_id, uint64_t arg2_user);
void handle_receive_heartbeat_response(const uint64_t trxn_id);
bool select_up_node(pfcp::node_id_t& node_id, const int node_selection_criteria);
bool add_peer_candidate_node(const pfcp::node_id_t& node_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