Commit d91a9bbe authored by gauthier's avatar gauthier
Browse files

DL DATA NOTIFICATION UP TO SGW-C (UP no split, SX-C connected to PGW-C)

parent c11a93f1
......@@ -44,7 +44,7 @@ public:
gtpc_tx_id = 0;
}
itti_s5s8_msg(const itti_s5s8_msg& i) : itti_msg(i), l_endpoint(i.l_endpoint),
itti_s5s8_msg(const itti_s5s8_msg& i) : itti_msg(i), l_endpoint(i.l_endpoint),
r_endpoint(i.r_endpoint), teid(i.teid), gtpc_tx_id(i.gtpc_tx_id) {}
itti_s5s8_msg(const itti_s5s8_msg& i, const task_id_t orig, const task_id_t dest) :
......@@ -327,4 +327,72 @@ public:
gtpv2c::gtpv2c_delete_bearer_command gtp_ies;
} ;
//-----------------------------------------------------------------------------
/** @class itti_s5s8_downlink_data_notification
* @brief Downlink Data Notification, not in spec but necessary due to SGWU and PGWU tied together.
*
* The Downlink Data Notification message is sent on the S5S8 interface by the SGW to the MME as part of the S1 paging procedure.
*/
class itti_s5s8_downlink_data_notification : public itti_s5s8_msg {
public:
itti_s5s8_downlink_data_notification(const task_id_t origin, const task_id_t destination):
itti_s5s8_msg(S5S8_DOWNLINK_DATA_NOTIFICATION, origin, destination) {
}
itti_s5s8_downlink_data_notification(const itti_s5s8_downlink_data_notification& i) : itti_s5s8_msg(i) {
gtp_ies = i.gtp_ies;
}
itti_s5s8_downlink_data_notification(const itti_s5s8_downlink_data_notification& i, const task_id_t orig, const task_id_t dest) :
itti_s5s8_msg(i, orig, dest) {
gtp_ies = i.gtp_ies;
}
const char* get_msg_name() {return typeid(itti_s5s8_downlink_data_notification).name();};
gtpv2c::gtpv2c_downlink_data_notification gtp_ies;
} ;
//-----------------------------------------------------------------------------
/** @class itti_s5s8_downlink_data_notification_acknowledge
* @brief Downlink Data Notification Acknowledge, not in spec but necessary due to SGWU and PGWU tied together.
*
* The Downlink Data Notification Acknowledge message is sent on the S5S8 interface by the MME to the SGW as part of the S1 paging procedure.
*/
class itti_s5s8_downlink_data_notification_acknowledge : public itti_s5s8_msg {
public:
itti_s5s8_downlink_data_notification_acknowledge(const task_id_t origin, const task_id_t destination):
itti_s5s8_msg(S5S8_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE, origin, destination) {
}
itti_s5s8_downlink_data_notification_acknowledge(const itti_s5s8_downlink_data_notification_acknowledge& i) : itti_s5s8_msg(i) {
gtp_ies = i.gtp_ies;
}
itti_s5s8_downlink_data_notification_acknowledge(const itti_s5s8_downlink_data_notification_acknowledge& i, const task_id_t orig, const task_id_t dest) :
itti_s5s8_msg(i, orig, dest) {
gtp_ies = i.gtp_ies;
}
const char* get_msg_name() {return typeid(itti_s5s8_downlink_data_notification_acknowledge).name();};
gtpv2c::gtpv2c_downlink_data_notification_acknowledge gtp_ies;
} ;
//-----------------------------------------------------------------------------
/** @class itti_s5s8_downlink_data_notification_failure_indication
* @brief Downlink Data Notification Failure Indication, not in spec but necessary due to SGWU and PGWU tied together.
*
*/
class itti_s5s8_downlink_data_notification_failure_indication : public itti_s5s8_msg {
public:
itti_s5s8_downlink_data_notification_failure_indication(const task_id_t origin, const task_id_t destination):
itti_s5s8_msg(S5S8_DOWNLINK_DATA_NOTIFICATION_FAILURE_INDICATION, origin, destination) {
}
itti_s5s8_downlink_data_notification_failure_indication(const itti_s5s8_downlink_data_notification_failure_indication& i) : itti_s5s8_msg(i) {
gtp_ies = i.gtp_ies;
}
itti_s5s8_downlink_data_notification_failure_indication(const itti_s5s8_downlink_data_notification_failure_indication& i, const task_id_t orig, const task_id_t dest) :
itti_s5s8_msg(i, orig, dest) {
gtp_ies = i.gtp_ies;
}
const char* get_msg_name() {return typeid(itti_s5s8_downlink_data_notification_failure_indication).name();};
gtpv2c::gtpv2c_downlink_data_notification_failure_indication gtp_ies;
} ;
#endif /* ITTI_MSG_S5S8_HPP_INCLUDED_ */
......@@ -835,6 +835,18 @@ gtpv2c_msg::gtpv2c_msg(const gtpv2c_release_access_bearers_response& gtp_ies) :
//if (gtp_ies.first) {std::shared_ptr<xxx> sie(new xxx(gtp_ies.uci.second)); add_ie(sie);}
}
//------------------------------------------------------------------------------
gtpv2c_msg::gtpv2c_msg(const gtpv2c_downlink_data_notification& gtp_ies) : gtpv2c_msg_header() {
ies = {};
set_message_type(GTP_DOWNLINK_DATA_NOTIFICATION);
if (gtp_ies.ie_presence_mask & DOWNLINK_DATA_NOTIFICATION_PR_IE_CAUSE) {std::shared_ptr<gtpv2c_cause_ie> sie(new gtpv2c_cause_ie(gtp_ies.cause)); add_ie(sie);}
if (gtp_ies.ie_presence_mask & DOWNLINK_DATA_NOTIFICATION_PR_IE_EPS_BEARER_ID) {std::shared_ptr<gtpv2c_eps_bearer_id_ie> sie(new gtpv2c_eps_bearer_id_ie(gtp_ies.eps_bearer_id)); add_ie(sie);}
// TODO if (gtp_ies.ie_presence_mask & DOWNLINK_DATA_NOTIFICATION_PR_IE_ARP) {std::shared_ptr<gtpv2c_arp_ie> sie(new gtpv2c_arp_ie(gtp_ies.arp)); add_ie(sie);}
if (gtp_ies.ie_presence_mask & GTPV2C_MODIFY_BEARER_REQUEST_PR_IE_IMSI) {std::shared_ptr<gtpv2c_imsi_ie> sie(new gtpv2c_imsi_ie(gtp_ies.imsi)); add_ie(sie);}
if (gtp_ies.ie_presence_mask & DOWNLINK_DATA_NOTIFICATION_PR_IE_SENDER_FTEID_FOR_CP) {std::shared_ptr<gtpv2c_fully_qualified_teid_ie> sie(new gtpv2c_fully_qualified_teid_ie(gtp_ies.sender_fteid_for_cp)); add_ie(sie);}
if (gtp_ies.ie_presence_mask & DOWNLINK_DATA_NOTIFICATION_PR_IE_INDICATION_FLAGS) {std::shared_ptr<gtpv2c_indication_ie> sie(new gtpv2c_indication_ie(gtp_ies.indication_flags)); add_ie(sie);}
}
//------------------------------------------------------------------------------
gtpv2c_msg::gtpv2c_msg(const gtpv2c_echo_request& gtp_ies) : gtpv2c_msg_header() {
ies = {};
set_message_type(GTP_ECHO_REQUEST);
......
......@@ -354,6 +354,7 @@ public:
explicit gtpv2c_msg(const gtpv2c_modify_bearer_response& gtp_ies);
explicit gtpv2c_msg(const gtpv2c_release_access_bearers_request& gtp_ies);
explicit gtpv2c_msg(const gtpv2c_release_access_bearers_response& gtp_ies);
explicit gtpv2c_msg(const gtpv2c_downlink_data_notification& gtp_ies);
~gtpv2c_msg() {
ies.clear();
......
......@@ -314,8 +314,8 @@ uint32_t gtpv2c_stack::send_initial_message(const endpoint& dest, const gtpv2c_e
pending_procedures.insert(std::pair<uint32_t, gtpv2c_procedure>(msg.get_sequence_number(), proc));
gtpc_tx_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.gtpc_tx_id, msg.get_sequence_number()));
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
uint32_t gtpv2c_stack::send_initial_message(const endpoint& dest, const teid_t teid, const gtpv2c_create_session_request& gtp_ies, const task_id_t& task_id, const uint64_t gtp_tx_id)
......@@ -340,7 +340,7 @@ uint32_t gtpv2c_stack::send_initial_message(const endpoint& dest, const teid_t t
pending_procedures.insert(std::pair<uint32_t, gtpv2c_procedure>(msg.get_sequence_number(), proc));
gtpc_tx_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.gtpc_tx_id, msg.get_sequence_number()));
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -364,7 +364,7 @@ uint32_t gtpv2c_stack::send_initial_message(const endpoint& dest, const teid_t t
pending_procedures.insert(std::pair<uint32_t, gtpv2c_procedure>(msg.get_sequence_number(), proc));
gtpc_tx_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.gtpc_tx_id, msg.get_sequence_number()));
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -388,7 +388,7 @@ uint32_t gtpv2c_stack::send_initial_message(const endpoint& dest, const teid_t t
pending_procedures.insert(std::pair<uint32_t, gtpv2c_procedure>(msg.get_sequence_number(), proc));
gtpc_tx_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.gtpc_tx_id, msg.get_sequence_number()));
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -413,10 +413,34 @@ uint32_t gtpv2c_stack::send_initial_message(const endpoint& dest, const teid_t t
gtpc_tx_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.gtpc_tx_id, msg.get_sequence_number()));
start_msg_retry_timer(proc, GTPV2C_T3_RESPONSE_MS, task_id, msg.get_sequence_number());
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
uint32_t gtpv2c_stack::send_initial_message(const endpoint& dest, const teid_t teid, const gtpv2c_downlink_data_notification& gtp_ies, const task_id_t& task_id, const uint64_t gtp_tx_id)
{
std::ostringstream oss(std::ostringstream::binary);
gtpv2c_msg msg(gtp_ies);
msg.set_teid(teid);
msg.set_sequence_number(get_next_seq_num());
msg.dump_to(oss);
std::string bstream = oss.str();
Logger::gtpv2_c().trace( "Sending %s, seq %d, teid " TEID_FMT ", proc " PROC_ID_FMT "", gtp_ies.get_msg_name(), msg.get_sequence_number(), msg.get_teid(), gtp_tx_id);
gtpv2c_procedure proc = {};
proc.initial_msg_type = msg.get_message_type();
proc.gtpc_tx_id = gtp_tx_id;
proc.retry_msg = std::make_shared<gtpv2c_msg>(msg);
proc.remote_endpoint = dest;
start_msg_retry_timer(proc, GTPV2C_T3_RESPONSE_MS, task_id, msg.get_sequence_number());
start_proc_cleanup_timer(proc, GTPV2C_PROC_TIME_OUT_MS, task_id, msg.get_sequence_number());
pending_procedures.insert(std::pair<uint32_t, gtpv2c_procedure>(msg.get_sequence_number(), proc));
gtpc_tx_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.gtpc_tx_id, msg.get_sequence_number()));
start_msg_retry_timer(proc, GTPV2C_T3_RESPONSE_MS, task_id, msg.get_sequence_number());
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
void gtpv2c_stack::send_triggered_message(const endpoint& dest, const gtpv2c_echo_response& gtp_ies, const uint64_t gtp_tx_id, const gtpv2c_transaction_action& a)
{
......@@ -429,7 +453,7 @@ void gtpv2c_stack::send_triggered_message(const endpoint& dest, const gtpv2c_ech
msg.dump_to(oss);
std::string bstream = oss.str();
Logger::gtpv2_c().trace( "Sending %s, seq %d, teid " TEID_FMT ", proc " PROC_ID_FMT "", gtp_ies.get_msg_name(), msg.get_sequence_number(), msg.get_teid(), gtp_tx_id);
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
if (a == DELETE_TX) {
std::map<uint32_t , gtpv2c_procedure>::iterator it_proc = pending_procedures.find(it->second);
......@@ -456,7 +480,7 @@ void gtpv2c_stack::send_triggered_message(const endpoint& r_endpoint, const teid
msg.dump_to(oss);
std::string bstream = oss.str();
Logger::gtpv2_c().trace( "Sending %s, seq %d, teid " TEID_FMT ", proc " PROC_ID_FMT "", gtp_ies.get_msg_name(), msg.get_sequence_number(), msg.get_teid(), gtp_tx_id);
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), r_endpoint);
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), r_endpoint);
if (a == DELETE_TX) {
std::map<uint32_t , gtpv2c_procedure>::iterator it_proc = pending_procedures.find(it->second);
......@@ -483,7 +507,7 @@ void gtpv2c_stack::send_triggered_message(const endpoint& r_endpoint, const teid
msg.dump_to(oss);
std::string bstream = oss.str();
Logger::gtpv2_c().trace( "Sending %s, seq %d, teid " TEID_FMT ", proc " PROC_ID_FMT "", gtp_ies.get_msg_name(), msg.get_sequence_number(), msg.get_teid(), gtp_tx_id);
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), r_endpoint);
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), r_endpoint);
if (a == DELETE_TX) {
std::map<uint32_t , gtpv2c_procedure>::iterator it_proc = pending_procedures.find(it->second);
......@@ -510,7 +534,7 @@ void gtpv2c_stack::send_triggered_message(const endpoint& r_endpoint, const teid
msg.dump_to(oss);
std::string bstream = oss.str();
Logger::gtpv2_c().trace( "Sending %s, seq %d, teid " TEID_FMT ", proc " PROC_ID_FMT "", gtp_ies.get_msg_name(), msg.get_sequence_number(), msg.get_teid(), gtp_tx_id);
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), r_endpoint);
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), r_endpoint);
if (a == DELETE_TX) {
std::map<uint32_t , gtpv2c_procedure>::iterator it_proc = pending_procedures.find(it->second);
......@@ -537,7 +561,7 @@ void gtpv2c_stack::send_triggered_message(const endpoint& r_endpoint, const teid
msg.dump_to(oss);
std::string bstream = oss.str();
Logger::gtpv2_c().trace( "Sending %s, seq %d, teid " TEID_FMT ", proc " PROC_ID_FMT "", gtp_ies.get_msg_name(), msg.get_sequence_number(), msg.get_teid(), gtp_tx_id);
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), r_endpoint);
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), r_endpoint);
if (a == DELETE_TX) {
std::map<uint32_t , gtpv2c_procedure>::iterator it_proc = pending_procedures.find(it->second);
......
......@@ -43,7 +43,7 @@
#include "msg_gtpv2c.hpp"
namespace gtpv2c {
static const uint16_t default_port = 2123;
class gtpv2c_procedure {
......@@ -139,6 +139,7 @@ public:
virtual uint32_t send_initial_message(const endpoint& r_endpoint, const teid_t teid, const gtpv2c_delete_session_request& gtp_ies, const task_id_t& task_id, const uint64_t gtp_tx_id);
virtual uint32_t send_initial_message(const endpoint& r_endpoint, const teid_t teid, const gtpv2c_modify_bearer_request& gtp_ies, const task_id_t& task_id, const uint64_t gtp_tx_id);
virtual uint32_t send_initial_message(const endpoint& r_endpoint, const teid_t teid, const gtpv2c_release_access_bearers_request& gtp_ies, const task_id_t& task_id, const uint64_t gtp_tx_id);
virtual uint32_t send_initial_message(const endpoint& r_endpoint, const teid_t teid, const gtpv2c_downlink_data_notification& gtp_ies, const task_id_t& task_id, const uint64_t gtp_tx_id);
virtual void send_triggered_message(const endpoint& r_endpoint, const teid_t teid, const gtpv2c_create_session_response& gtp_ies, const uint64_t gtp_tx_id, const gtpv2c_transaction_action& a = DELETE_TX);
virtual void send_triggered_message(const endpoint& r_endpoint, const teid_t teid, const gtpv2c_delete_session_response& gtp_ies, const uint64_t gtp_tx_id, const gtpv2c_transaction_action& a = DELETE_TX);
......
......@@ -106,6 +106,9 @@ typedef enum {
S5S8_DELETE_SESSION_RESPONSE,
S5S8_RELEASE_ACCESS_BEARERS_REQUEST,
S5S8_RELEASE_ACCESS_BEARERS_RESPONSE,
S5S8_DOWNLINK_DATA_NOTIFICATION,
S5S8_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE,
S5S8_DOWNLINK_DATA_NOTIFICATION_FAILURE_INDICATION,
SXAB_HEARTBEAT_REQUEST,
SXAB_HEARTBEAT_RESPONSE,
SXAB_PFCP_PFD_MANAGEMENT_REQUEST,
......
......@@ -224,9 +224,7 @@ void pgw_app_task (void*)
break;
case SXAB_SESSION_REPORT_REQUEST:
if (itti_sxab_session_report_request* m = dynamic_cast<itti_sxab_session_report_request*>(msg)) {
pgw_app_inst->handle_itti_msg(std::ref(*m));
}
pgw_app_inst->handle_itti_msg(std::static_pointer_cast<itti_sxab_session_report_request>(shared_msg));
break;
case S5S8_CREATE_SESSION_REQUEST:
......@@ -581,9 +579,16 @@ void pgw_app::handle_itti_msg (itti_sxab_session_deletion_response& smresp)
}
//------------------------------------------------------------------------------
void pgw_app::handle_itti_msg (itti_sxab_session_report_request& snr)
void pgw_app::handle_itti_msg (std::shared_ptr<itti_sxab_session_report_request> snr)
{
Logger::pgwc_app().debug("Received SXAB SESSION REPORT REQUEST seid" TEID_FMT " pfcp_tx_id %" PRIX64" ", snr.seid, snr.trxn_id);
std::shared_ptr<pgw_context> pc = {};
std::shared_lock<std::shared_mutex> lpc;
if (seid_2_pgw_context(snr->seid, pc, lpc)) {
pc.get()->handle_itti_msg(snr);
lpc.unlock();
} else {
Logger::pgwc_app().debug("Received SXAB SESSION REPORT REQUEST seid" TEID_FMT " pfcp_tx_id %" PRIX64", pgw_context not found, discarded!", snr->seid, snr->trxn_id);
}
}
......@@ -127,7 +127,7 @@ public:
void handle_itti_msg (itti_sxab_session_establishment_response& m);
void handle_itti_msg (itti_sxab_session_modification_response& m);
void handle_itti_msg (itti_sxab_session_deletion_response& m);
void handle_itti_msg (itti_sxab_session_report_request& snr);
void handle_itti_msg (std::shared_ptr<itti_sxab_session_report_request> snr);
void handle_itti_msg (itti_sxab_association_setup_request& m);
void restore_sx_sessions(const seid_t& seid) const;
......
......@@ -122,6 +122,28 @@ pgw_eps_bearer& pgw_pdn_connection::get_eps_bearer(const ebi_t& ebi)
return eps_bearers[ebi.ebi];
}
//------------------------------------------------------------------------------
bool pgw_pdn_connection::find_eps_bearer(const pfcp::pdr_id_t& pdr_id, pgw_eps_bearer& bearer)
{
for (std::map<uint8_t,pgw_eps_bearer>::iterator it=eps_bearers.begin(); it!=eps_bearers.end(); ++it) {
if ((it->second.pdr_id_ul == pdr_id) || (it->second.pdr_id_dl == pdr_id)) {
bearer = it->second;
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
bool pgw_pdn_connection::has_eps_bearer(const pfcp::pdr_id_t& pdr_id, ebi_t& ebi)
{
for (std::map<uint8_t,pgw_eps_bearer>::iterator it=eps_bearers.begin(); it!=eps_bearers.end(); ++it) {
if ((it->second.pdr_id_ul == pdr_id) || (it->second.pdr_id_dl == pdr_id)) {
ebi = it->second.ebi;
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
void pgw_pdn_connection::remove_eps_bearer(const ebi_t& ebi)
{
......@@ -233,6 +255,23 @@ bool apn_context::find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is
return false;
}
}
//------------------------------------------------------------------------------
bool apn_context::find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_ptr<pgw_pdn_connection>& pdn, ebi_t& ebi, std::shared_lock<std::shared_mutex>& lock_found)
{
std::shared_lock lock(m_pdn_connections);
for (auto pit : pdn_connections) {
std::shared_lock<std::shared_mutex> lock_pdn = {};
if (pit->has_eps_bearer(pdr_id, ebi)) {
pdn = pit; // May make pair
lock_found.swap(lock_pdn);
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
void apn_context::delete_pdn_connection(std::shared_ptr<pgw_pdn_connection>& pdn_connection)
{
......@@ -290,6 +329,23 @@ bool pgw_context::find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is
}
return false;
}
//------------------------------------------------------------------------------
bool pgw_context::find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_ptr<pgw_pdn_connection>& pdn, ebi_t& ebi, std::shared_lock<std::shared_mutex>& lock_found)
{
std::shared_lock lock(m_apns);
for (auto ait : apns) {
std::shared_ptr<pgw_pdn_connection> sp;
std::shared_lock<std::shared_mutex> lock_pdn = {};
if (ait->find_pdn_connection(pdr_id, sp, ebi, lock_pdn)) {
pdn = sp; // May make pair
lock_found.swap(lock_pdn);
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
bool pgw_context::find_pdn_connection(const std::string& apn, const teid_t xgw_s5s8c_teid, const bool is_local_teid, pdn_duo_t& pdn_connection, std::shared_lock<std::shared_mutex>& lock_found)
{
......@@ -544,7 +600,7 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_create_session_requ
}
// Static IP address allocation
} else if ((paa_res) && (paa.is_ip_assigned())) {
set_paa = true;
set_paa = true;
}
} else {
// TODO allocation via DHCP
......@@ -565,7 +621,7 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_create_session_requ
}
// Static IP address allocation
} else if ((paa_res) && (paa.is_ip_assigned())) {
set_paa = true;
set_paa = true;
}
}
break;
......@@ -581,7 +637,7 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_create_session_requ
cause.pce = 1;
}
} else if ((paa_res) && (paa.is_ip_assigned())) {
set_paa = true;
set_paa = true;
}
}
break;
......@@ -814,14 +870,14 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_release_access_bear
}
} else {
Logger::pgwc_app().warn( "S5S8 RELEASE_ACCESS_BEARERS_REQUEST procedure TODO");
pgw_app_inst->send_release_access_bearers_response_cause_request_accepted (s5_trigger->gtpc_tx_id, sp->sgw_fteid_s5_s8_cp.teid_gre_key,
pgw_app_inst->send_release_access_bearers_response_cause_request_accepted (s5_trigger->gtpc_tx_id, sp->sgw_fteid_s5_s8_cp.teid_gre_key,
s5_trigger->r_endpoint);
}
lock_pdn.unlock();
}
} else {
Logger::pgwc_app().info( "S5S8 RELEASE_ACCESS_BEARERS_REQUEST procedure failed, context not found");
pgw_app_inst->send_release_access_bearers_response_cause_context_not_found (s5_trigger->gtpc_tx_id, sp->sgw_fteid_s5_s8_cp.teid_gre_key,
pgw_app_inst->send_release_access_bearers_response_cause_context_not_found (s5_trigger->gtpc_tx_id, sp->sgw_fteid_s5_s8_cp.teid_gre_key,
s5_trigger->r_endpoint);
}
}
......@@ -870,6 +926,49 @@ void pgw_context::handle_itti_msg (itti_sxab_session_deletion_response& sdresp)
}
std::cout << toString() << std::endl;
}
//------------------------------------------------------------------------------
void pgw_context::handle_itti_msg (std::shared_ptr<itti_sxab_session_report_request>& req)
{
pfcp::report_type_t report_type;
if (req->pfcp_ies.get(report_type)) {
pfcp::pdr_id_t pdr_id;
// Downlink Data Report
if (report_type.dldr) {
pfcp::downlink_data_report data_report;
if (req->pfcp_ies.get(data_report)) {
pfcp::pdr_id_t pdr_id;
if (data_report.get(pdr_id)) {
std::shared_lock<std::shared_mutex> lp;
std::shared_ptr<pgw_pdn_connection> ppc = {};
ebi_t ebi;
if (find_pdn_connection(pdr_id, ppc, ebi, lp)) {
downlink_data_report_procedure* p = new downlink_data_report_procedure(req);
std::shared_ptr<pgw_procedure> sproc = std::shared_ptr<pgw_procedure>(p);
insert_procedure(sproc);
if (p->run(shared_from_this(), ppc, ebi)) {
// TODO handle error code
Logger::pgwc_app().info( "S11 CREATE_SESSION_REQUEST procedure failed");
remove_procedure(p);
} else {
}
}
}
}
}
// Usage Report
if (report_type.usar) {
Logger::pgwc_app().debug("TODO PFCP_SESSION_REPORT_REQUEST/Usage Report");
}
// Error Indication Report
if (report_type.erir) {
Logger::pgwc_app().debug("TODO PFCP_SESSION_REPORT_REQUEST/Error Indication Report");
}
// User Plane Inactivity Report
if (report_type.upir) {
Logger::pgwc_app().debug("TODO PFCP_SESSION_REPORT_REQUEST/User Plane Inactivity Report");
}
}
}
//------------------------------------------------------------------------------
std::string pgw_context::toString() const
......
......@@ -161,6 +161,8 @@ public:
//pgw_eps_bearer& get_eps_bearer(const ebi_t& ebi) {return eps_bearers[ebi.ebi];}
void add_eps_bearer(pgw_eps_bearer& eps_bearer);
pgw_eps_bearer& get_eps_bearer(const ebi_t& ebi);
bool find_eps_bearer(const pfcp::pdr_id_t& pdr_id, pgw_eps_bearer& bearer);
bool has_eps_bearer(const pfcp::pdr_id_t& pdr_id, ebi_t& ebi);
void remove_eps_bearer(const ebi_t& ebi);
void remove_eps_bearer(pgw_eps_bearer& bearer);
void set(const paa_t& paa);
......@@ -247,6 +249,7 @@ public:
void insert_pdn_connection(std::shared_ptr<pgw_pdn_connection>& sp);
bool find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is_local_teid, std::shared_ptr<pgw_pdn_connection>& pdn, std::shared_lock<std::shared_mutex>& lock_found);
bool find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_ptr<pgw_pdn_connection>& pdn, ebi_t& ebi, std::shared_lock<std::shared_mutex>& lock_found);
void delete_pdn_connection(std::shared_ptr<pgw_pdn_connection>& pdn_connection);
int get_num_pdn_connections() const {return pdn_connections.size();};
// deallocate_ressources is for releasing LTE resources prior to the deletion of objects
......@@ -291,6 +294,7 @@ public:
bool find_pdn_connection(const std::string& apn, const teid_t xgw_s5s8c_teid, const bool is_local_teid, pdn_duo_t& pdn_connection, std::shared_lock<std::shared_mutex>& lock_found);
bool find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is_local_teid, pdn_duo_t& pdn_connection, std::shared_lock<std::shared_mutex>& lock_found);
bool find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_ptr<pgw_pdn_connection>& pdn, ebi_t& ebi, std::shared_lock<std::shared_mutex>& lock_found);
void insert_apn(std::shared_ptr<apn_context>& sa);
bool find_apn_context(const std::string& apn, std::shared_ptr<apn_context>& apn_context, std::shared_lock<std::shared_mutex>& lock_found);
int get_num_apn_contexts() {return apns.size();};
......@@ -305,6 +309,7 @@ public:
void handle_itti_msg (itti_sxab_session_establishment_response& );
void handle_itti_msg (itti_sxab_session_modification_response& );
void handle_itti_msg (itti_sxab_session_deletion_response& );
void handle_itti_msg (std::shared_ptr<itti_sxab_session_report_request>&);
std::string toString() const;
......
......@@ -80,6 +80,12 @@ void pgw_s5s8_task (void *args_p)
}
break;
case S5S8_DOWNLINK_DATA_NOTIFICATION:
if (itti_s5s8_downlink_data_notification* m = dynamic_cast<itti_s5s8_downlink_data_notification*>(msg)) {
pgw_s5s8_inst->send_msg(ref(*m));
}
break;
case TIME_OUT:
if (itti_msg_timeout* to = dynamic_cast<itti_msg_timeout*>(msg)) {
Logger::pgwc_s5s8().debug( "TIME-OUT event timer id %d", to->timer_id);
......@@ -133,6 +139,11 @@ void pgw_s5s8::send_msg(itti_s5s8_release_access_bearers_response& i)
send_triggered_message(i.r_endpoint, i.teid, i.gtp_ies, i.gtpc_tx_id);
}
//------------------------------------------------------------------------------
void pgw_s5s8::send_msg(itti_s5s8_downlink_data_notification& i)
{
send_initial_message(i.r_endpoint, i.teid, i.gtp_ies, TASK_PGWC_S5S8, i.gtpc_tx_id);
}
//------------------------------------------------------------------------------
void pgw_s5s8::handle_receive_create_session_request(gtpv2c_msg& msg, const endpoint& remote_endpoint)
{
bool error = true;
......@@ -334,7 +345,7 @@ void pgw_s5s8::handle_receive_gtpv2c_msg(gtpv2c_msg& msg, const endpoint& remote
}
}
//------------------------------------------------------------------------------
void pgw_s5s8::handle_receive(char* recv_buffer, const std::size_t bytes_transferred,
void pgw_s5s8::handle_receive(char* recv_buffer, const std::size_t bytes_transferred,
const endpoint& remote_endpoint)
{
//Logger::pgwc_s5s8().info( "handle_receive(%d bytes)", bytes_transferred);
......
......@@ -57,6 +57,7 @@ public:
void send_msg(itti_s5s8_delete_session_response& m);
void send_msg(itti_s5s8_modify_bearer_response& m);
void send_msg(itti_s5s8_release_access_bearers_response& m);
void send_msg(itti_s5s8_downlink_data_notification& i);
void time_out_itti_event(const uint32_t timer_id);
};
......
......@@ -933,4 +933,29 @@ void delete_session_procedure::handle_itti_msg (itti_sxab_session_deletion_respo
Logger::pgwc_app().error( "Could not send ITTI message %s to task TASK_PGWC_S5S8", s5_triggered_pending->gtp_ies.get_msg_name());
}
}
//------------------------------------------------------------------------------
int downlink_data_report_procedure::run(std::shared_ptr<pgwc::pgw_context> context,
std::shared_ptr<pgwc::pgw_pdn_connection> pdn, const ebi_t& e)
{
ppc = pdn;
pc = context;
ebi = e;
itti_s5s8_downlink_data_notification *s5 = new itti_s5s8_downlink_data_notification(TASK_PGWC_APP, TASK_PGWC_S5S8);
s5->teid = ppc->sgw_fteid_s5_s8_cp.teid_gre_key;
s5->gtpc_tx_id = this->trxn_id;
s5->r_endpoint = endpoint(ppc->sgw_fteid_s5_s8_cp.ipv4_address, pgw_cfg.s5s8_cp.port);
s5->gtp_ies.set(e);
s5_triggered = std::shared_ptr<itti_s5s8_downlink_data_notification>(s5);
Logger::pgwc_app().info( "Sending ITTI message %s to task TASK_PGWC_S5S8", s5->gtp_ies.get_msg_name());
int ret = itti_inst->send_msg(s5_triggered);
if (RETURNok != ret) {
Logger::pgwc_app().error( "Could not send ITTI message %s to task TASK_PGWC_S5S8", s5->gtp_ies.get_msg_name());
return RETURNerror;
}
return RETURNok;
}
......@@ -105,8 +105,8 @@ public:
std::shared_ptr<itti_s5s8_create_session_request> s5_trigger;
std::shared_ptr<itti_s5s8_create_session_response> s5_triggered_pending;
std::shared_ptr<itti_sxab_session_establishment_request> sx_triggered;
std::shared_ptr<pgw_pdn_connection> ppc;
std::shared_ptr<pgwc::pgw_context> pc;
std::shared_ptr<pgw_pdn_connection> ppc;
std::shared_ptr<pgwc::pgw_context> pc;
};
//------------------------------------------------------------------------------
......@@ -124,8 +124,8 @@ public:
std::shared_ptr<itti_s5s8_modify_bearer_request> s5_trigger;
std::shared_ptr<itti_s5s8_modify_bearer_response> s5_triggered_pending;
std::shared_ptr<itti_sxab_session_modification_request> sx_triggered;
std::shared_ptr<pgw_pdn_connection> ppc;
std::shared_ptr<pgwc::pgw_context> pc;
std::shared_ptr<pgw_pdn_connection> ppc;
std::shared_ptr<pgwc::pgw_context> pc;
};
//------------------------------------------------------------------------------
class release_access_bearers_procedure : public pgw_procedure {
......@@ -142,8 +142,8 @@ public: