Commit 6a06fd2e authored by gauthier's avatar gauthier

S11 Downlink Data Notification sent

parent d91a9bbe
...@@ -391,6 +391,10 @@ public: ...@@ -391,6 +391,10 @@ public:
itti_s11_msg(i, orig, dest) { itti_s11_msg(i, orig, dest) {
gtp_ies = i.gtp_ies; gtp_ies = i.gtp_ies;
} }
itti_s11_downlink_data_notification(const gtpv2c::gtpv2c_downlink_data_notification& ies, const task_id_t orig, const task_id_t dest) :
itti_s11_downlink_data_notification(orig, dest) {
gtp_ies = ies;
}
const char* get_msg_name() {return typeid(itti_s11_downlink_data_notification).name();}; const char* get_msg_name() {return typeid(itti_s11_downlink_data_notification).name();};
gtpv2c::gtpv2c_downlink_data_notification gtp_ies; gtpv2c::gtpv2c_downlink_data_notification gtp_ies;
......
...@@ -56,23 +56,27 @@ static std::string string_to_hex(const std::string& input) ...@@ -56,23 +56,27 @@ static std::string string_to_hex(const std::string& input)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
gtpv2c_stack::gtpv2c_stack(const string& ip_address, const unsigned short port_num, const util::thread_sched_params& sched_params) : gtpv2c_stack::gtpv2c_stack(const string& ip_address, const unsigned short port_num, const util::thread_sched_params& sched_params) :
udp_s(udp_server(ip_address.c_str(), port_num)), udp_s(udp_server(ip_address.c_str(), port_num)),
udp_s_allocated(ip_address.c_str(), 0){ udp_s_allocated(ip_address.c_str(), 0), m_seq_num() {
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
seq_num = (uint32_t)ts.tv_nsec & 0x7FFFFFFF;
Logger::gtpv2_c().info( "gtpv2c_stack created listening to %s:%d initial seq num %d", ip_address.c_str(), port_num, seq_num);
Logger::gtpv2_c().info( "gtpv2c_stack created listening to %s:%d", ip_address.c_str(), port_num);
gtpc_tx_id2seq_num = {}; gtpc_tx_id2seq_num = {};
proc_cleanup_timers = {}; proc_cleanup_timers = {};
msg_out_retry_timers = {}; msg_out_retry_timers = {};
pending_procedures = {}; pending_procedures = {};
id = 0; id = 0;
srand (time(NULL));
seq_num = rand() & 0x7FFFFFFF;
restart_counter = 0; restart_counter = 0;
udp_s.start_receive(this, sched_params); udp_s.start_receive(this, sched_params);
udp_s_allocated.start_receive(this, sched_params); udp_s_allocated.start_receive(this, sched_params);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
uint32_t gtpv2c_stack::get_next_seq_num() { uint32_t gtpv2c_stack::get_next_seq_num() {
std::unique_lock lock(m_seq_num);
seq_num++; seq_num++;
if (seq_num & 0x80000000) { if (seq_num & 0x80000000) {
seq_num = 0; seq_num = 0;
...@@ -195,7 +199,9 @@ void gtpv2c_stack::start_msg_retry_timer(gtpv2c_procedure& p, uint32_t time_out_ ...@@ -195,7 +199,9 @@ void gtpv2c_stack::start_msg_retry_timer(gtpv2c_procedure& p, uint32_t time_out_
if (!p.retry_timer_id) { if (!p.retry_timer_id) {
p.retry_timer_id = itti_inst->timer_setup (time_out_milli_seconds/1000, time_out_milli_seconds%1000, task_id); p.retry_timer_id = itti_inst->timer_setup (time_out_milli_seconds/1000, time_out_milli_seconds%1000, task_id);
msg_out_retry_timers.insert(std::pair<timer_id_t, uint32_t>(p.retry_timer_id, seq_num)); msg_out_retry_timers.insert(std::pair<timer_id_t, uint32_t>(p.retry_timer_id, seq_num));
//Logger::gtpv2_c().trace( "Started Msg retry timer %d, proc " PROC_ID_FMT ", seq %d",p.retry_timer_id, p.gtpc_tx_id, seq_num); #if TRACE_IS_ON
Logger::gtpv2_c().trace( "Started Msg retry timer %d, proc " PROC_ID_FMT ", seq %d",p.retry_timer_id, p.gtpc_tx_id, seq_num);
#endif
} else { } else {
Logger::gtpv2_c().error( "Try to overwrite Msg retry timer %d, proc " PROC_ID_FMT ", seq %d!",p.retry_timer_id, p.gtpc_tx_id, seq_num); Logger::gtpv2_c().error( "Try to overwrite Msg retry timer %d, proc " PROC_ID_FMT ", seq %d!",p.retry_timer_id, p.gtpc_tx_id, seq_num);
} }
...@@ -206,7 +212,9 @@ void gtpv2c_stack::stop_msg_retry_timer(gtpv2c_procedure& p) ...@@ -206,7 +212,9 @@ void gtpv2c_stack::stop_msg_retry_timer(gtpv2c_procedure& p)
if (p.retry_timer_id) { if (p.retry_timer_id) {
itti_inst->timer_remove(p.retry_timer_id); itti_inst->timer_remove(p.retry_timer_id);
msg_out_retry_timers.erase(p.retry_timer_id); msg_out_retry_timers.erase(p.retry_timer_id);
//Logger::gtpv2_c().trace( "Stopped Msg retry timer %d, proc " PROC_ID_FMT ", seq %d",p.retry_timer_id, p.gtpc_tx_id, p.retry_msg->get_sequence_number()); #if TRACE_IS_ON
Logger::gtpv2_c().trace( "Stopped Msg retry timer %d, proc " PROC_ID_FMT ", seq %d",p.retry_timer_id, p.gtpc_tx_id, p.retry_msg->get_sequence_number());
#endif
p.retry_timer_id = 0; p.retry_timer_id = 0;
} }
} }
...@@ -215,7 +223,9 @@ void gtpv2c_stack::stop_msg_retry_timer(timer_id_t& t) ...@@ -215,7 +223,9 @@ void gtpv2c_stack::stop_msg_retry_timer(timer_id_t& t)
{ {
itti_inst->timer_remove(t); itti_inst->timer_remove(t);
msg_out_retry_timers.erase(t); msg_out_retry_timers.erase(t);
//Logger::gtpv2_c().trace( "Stopped Msg retry timer %d",t); #if TRACE_IS_ON
Logger::gtpv2_c().trace( "Stopped Msg retry timer %d",t);
#endif
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void gtpv2c_stack::start_proc_cleanup_timer(gtpv2c_procedure& p, uint32_t time_out_milli_seconds, const task_id_t& task_id, const uint32_t& seq_num) void gtpv2c_stack::start_proc_cleanup_timer(gtpv2c_procedure& p, uint32_t time_out_milli_seconds, const task_id_t& task_id, const uint32_t& seq_num)
...@@ -223,7 +233,9 @@ void gtpv2c_stack::start_proc_cleanup_timer(gtpv2c_procedure& p, uint32_t time_o ...@@ -223,7 +233,9 @@ void gtpv2c_stack::start_proc_cleanup_timer(gtpv2c_procedure& p, uint32_t time_o
if (!p.proc_cleanup_timer_id) { if (!p.proc_cleanup_timer_id) {
p.proc_cleanup_timer_id = itti_inst->timer_setup (time_out_milli_seconds/1000, time_out_milli_seconds%1000, task_id); p.proc_cleanup_timer_id = itti_inst->timer_setup (time_out_milli_seconds/1000, time_out_milli_seconds%1000, task_id);
proc_cleanup_timers.insert(std::pair<timer_id_t, uint32_t>(p.proc_cleanup_timer_id, seq_num)); proc_cleanup_timers.insert(std::pair<timer_id_t, uint32_t>(p.proc_cleanup_timer_id, seq_num));
//Logger::gtpv2_c().trace( "Started proc cleanup timer %d, proc " PROC_ID_FMT " t-out %" PRIu32" ms",p.proc_cleanup_timer_id,p.gtpc_tx_id, time_out_milli_seconds); #if TRACE_IS_ON
Logger::gtpv2_c().trace( "Started proc cleanup timer %d, proc " PROC_ID_FMT " t-out %" PRIu32" ms",p.proc_cleanup_timer_id,p.gtpc_tx_id, time_out_milli_seconds);
#endif
} else { } else {
Logger::gtpv2_c().error( "Try to overwrite proc cleanup timer %d, proc " PROC_ID_FMT " t-out %" PRIu32" ms",p.proc_cleanup_timer_id,p.gtpc_tx_id, time_out_milli_seconds); Logger::gtpv2_c().error( "Try to overwrite proc cleanup timer %d, proc " PROC_ID_FMT " t-out %" PRIu32" ms",p.proc_cleanup_timer_id,p.gtpc_tx_id, time_out_milli_seconds);
} }
...@@ -232,7 +244,9 @@ void gtpv2c_stack::start_proc_cleanup_timer(gtpv2c_procedure& p, uint32_t time_o ...@@ -232,7 +244,9 @@ void gtpv2c_stack::start_proc_cleanup_timer(gtpv2c_procedure& p, uint32_t time_o
void gtpv2c_stack::stop_proc_cleanup_timer(gtpv2c_procedure& p) void gtpv2c_stack::stop_proc_cleanup_timer(gtpv2c_procedure& p)
{ {
itti_inst->timer_remove(p.proc_cleanup_timer_id); itti_inst->timer_remove(p.proc_cleanup_timer_id);
//Logger::gtpv2_c().trace( "Stopped proc cleanup timer %d, proc " PROC_ID_FMT "",p.proc_cleanup_timer_id, p.gtpc_tx_id); #if TRACE_IS_ON
Logger::gtpv2_c().trace( "Stopped proc cleanup timer %d, proc " PROC_ID_FMT "",p.proc_cleanup_timer_id, p.gtpc_tx_id);
#endif
msg_out_retry_timers.erase(p.proc_cleanup_timer_id); msg_out_retry_timers.erase(p.proc_cleanup_timer_id);
p.proc_cleanup_timer_id = 0; p.proc_cleanup_timer_id = 0;
} }
...@@ -411,7 +425,6 @@ uint32_t gtpv2c_stack::send_initial_message(const endpoint& dest, const teid_t t ...@@ -411,7 +425,6 @@ uint32_t gtpv2c_stack::send_initial_message(const endpoint& dest, const teid_t t
start_proc_cleanup_timer(proc, GTPV2C_PROC_TIME_OUT_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)); 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())); 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(); return msg.get_sequence_number();
...@@ -436,7 +449,6 @@ uint32_t gtpv2c_stack::send_initial_message(const endpoint& dest, const teid_t t ...@@ -436,7 +449,6 @@ uint32_t gtpv2c_stack::send_initial_message(const endpoint& dest, const teid_t t
start_proc_cleanup_timer(proc, GTPV2C_PROC_TIME_OUT_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)); 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())); 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(); return msg.get_sequence_number();
......
...@@ -98,8 +98,9 @@ protected: ...@@ -98,8 +98,9 @@ protected:
udp_server udp_s; udp_server udp_s;
udp_server udp_s_allocated; udp_server udp_s_allocated;
// seems no need for std::atomic_uint32_t // seems no need for atomic
uint32_t seq_num; uint32_t seq_num;
std::mutex m_seq_num;
uint32_t restart_counter; uint32_t restart_counter;
std::map<uint64_t, uint32_t> gtpc_tx_id2seq_num; std::map<uint64_t, uint32_t> gtpc_tx_id2seq_num;
...@@ -147,6 +148,9 @@ public: ...@@ -147,6 +148,9 @@ public:
virtual void send_triggered_message(const endpoint& r_endpoint, const teid_t teid, const gtpv2c_release_access_bearers_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_release_access_bearers_response& gtp_ies, const uint64_t gtp_tx_id, const gtpv2c_transaction_action& a = DELETE_TX);
void time_out_event(const uint32_t timer_id, const task_id_t& task_id, bool &error); void time_out_event(const uint32_t timer_id, const task_id_t& task_id, bool &error);
}; };
} // namespace gtpv2c } // namespace gtpv2c
......
...@@ -3518,6 +3518,13 @@ public: ...@@ -3518,6 +3518,13 @@ public:
void set(const imsi_t& v, const uint8_t instance = 0) {imsi = v;ie_presence_mask |= DOWNLINK_DATA_NOTIFICATION_PR_IE_IMSI;} void set(const imsi_t& v, const uint8_t instance = 0) {imsi = v;ie_presence_mask |= DOWNLINK_DATA_NOTIFICATION_PR_IE_IMSI;}
void set(const fteid_t& v, const uint8_t instance = 0) {sender_fteid_for_cp = v;ie_presence_mask |= DOWNLINK_DATA_NOTIFICATION_PR_IE_SENDER_FTEID_FOR_CP;} void set(const fteid_t& v, const uint8_t instance = 0) {sender_fteid_for_cp = v;ie_presence_mask |= DOWNLINK_DATA_NOTIFICATION_PR_IE_SENDER_FTEID_FOR_CP;}
void set(const indication_t& v, const uint8_t instance = 0) {indication_flags = v;ie_presence_mask |= DOWNLINK_DATA_NOTIFICATION_PR_IE_INDICATION_FLAGS;} void set(const indication_t& v, const uint8_t instance = 0) {indication_flags = v;ie_presence_mask |= DOWNLINK_DATA_NOTIFICATION_PR_IE_INDICATION_FLAGS;}
bool get(cause_t& v, const uint8_t instance = 0) const {if (ie_presence_mask & DOWNLINK_DATA_NOTIFICATION_PR_IE_CAUSE) {v = cause;return true;}return false;}
bool get(ebi_t& v, const uint8_t instance = 0) const {if (ie_presence_mask & DOWNLINK_DATA_NOTIFICATION_PR_IE_EPS_BEARER_ID) {v = eps_bearer_id;return true;}return false;}
bool get(arp_t& v, const uint8_t instance = 0) const {if (ie_presence_mask & DOWNLINK_DATA_NOTIFICATION_PR_IE_ARP) {v = arp;return true;}return false;}
bool get(imsi_t& v, const uint8_t instance = 0) const {if (ie_presence_mask & DOWNLINK_DATA_NOTIFICATION_PR_IE_IMSI) {v = imsi;return true;}return false;}
bool get(fteid_t& v, const uint8_t instance = 0) const {if (ie_presence_mask & DOWNLINK_DATA_NOTIFICATION_PR_IE_SENDER_FTEID_FOR_CP) {v = sender_fteid_for_cp;return true;}return false;}
bool get(indication_t& v, const uint8_t instance = 0) const {if (ie_presence_mask & DOWNLINK_DATA_NOTIFICATION_PR_IE_INDICATION_FLAGS) {v = indication_flags;return true;}return false;}
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <thread> #include <thread>
#include <signal.h> #include <signal.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> // srand
#include <unistd.h> // get_pid(), pause() #include <unistd.h> // get_pid(), pause()
using namespace gtpv2c; using namespace gtpv2c;
...@@ -65,6 +66,7 @@ void my_app_signal_handler(int s){ ...@@ -65,6 +66,7 @@ void my_app_signal_handler(int s){
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
srand (time(NULL));
// Logger // Logger
Logger::init( "spgwc" ); Logger::init( "spgwc" );
......
...@@ -46,8 +46,10 @@ pfcp_l4_stack::pfcp_l4_stack(const string& ip_address, const unsigned short port ...@@ -46,8 +46,10 @@ pfcp_l4_stack::pfcp_l4_stack(const string& ip_address, const unsigned short port
pending_procedures = {}; pending_procedures = {};
id = 0; id = 0;
srand (time(NULL));
seq_num = rand() & 0x7FFFFFFF; timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
seq_num = (uint32_t)ts.tv_nsec & 0x7FFFFFFF;
restart_counter = 0; restart_counter = 0;
udp_s_8805.start_receive(this, sched_params); udp_s_8805.start_receive(this, sched_params);
udp_s_allocated.start_receive(this, sched_params); udp_s_allocated.start_receive(this, sched_params);
......
...@@ -208,6 +208,12 @@ void sgwc_app_task (void *args_p) ...@@ -208,6 +208,12 @@ void sgwc_app_task (void *args_p)
} }
break; break;
case S5S8_DOWNLINK_DATA_NOTIFICATION:
if (itti_s5s8_downlink_data_notification* m = dynamic_cast<itti_s5s8_downlink_data_notification*>(msg)) {
sgwc_app_inst->handle_itti_msg(ref(*m));
}
break;
case S11_DELETE_SESSION_REQUEST: case S11_DELETE_SESSION_REQUEST:
if (itti_s11_delete_session_request* m = dynamic_cast<itti_s11_delete_session_request*>(msg)) { if (itti_s11_delete_session_request* m = dynamic_cast<itti_s11_delete_session_request*>(msg)) {
sgwc_app_inst->handle_itti_msg(ref(*m)); sgwc_app_inst->handle_itti_msg(ref(*m));
...@@ -462,10 +468,10 @@ void sgwc_app::handle_itti_msg (itti_s5s8_delete_session_response& m) ...@@ -462,10 +468,10 @@ void sgwc_app::handle_itti_msg (itti_s5s8_delete_session_response& m)
} }
Logger::sgwc_app().debug("sgw_eps_bearer_context: %s!", p.first->toString().c_str()); Logger::sgwc_app().debug("sgw_eps_bearer_context: %s!", p.first->toString().c_str());
} else { } else {
Logger::sgwc_app().debug("Received S5S8 DELETE_SESSION_RESPONSE with dest teid " TEID_FMT ", SGW contexts not found, ignore DSResp", m.teid); Logger::sgwc_app().debug("Received S5S8 DELETE_SESSION_RESPONSE with dest teid " TEID_FMT ", SGW contexts not found, ignore!", m.teid);
} }
} else { } else {
Logger::sgwc_app().debug("Received S5S8 DELETE_SESSION_RESPONSE with dest teid " TEID_FMT " unknown, ignore DSResp", m.teid); Logger::sgwc_app().debug("Received S5S8 DELETE_SESSION_RESPONSE with dest teid " TEID_FMT " unknown, ignore!", m.teid);
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -478,10 +484,10 @@ void sgwc_app::handle_itti_msg (itti_s5s8_modify_bearer_response& m) ...@@ -478,10 +484,10 @@ void sgwc_app::handle_itti_msg (itti_s5s8_modify_bearer_response& m)
p.first->handle_itti_msg(m, p.second); p.first->handle_itti_msg(m, p.second);
Logger::sgwc_app().debug("sgw_eps_bearer_context: %s!", p.first->toString().c_str()); Logger::sgwc_app().debug("sgw_eps_bearer_context: %s!", p.first->toString().c_str());
} else { } else {
Logger::sgwc_app().debug("Received S5S8 MODIFY_BEARER_RESPONSE with dest teid " TEID_FMT ", SGW contexts not found, ignore CSResp", m.teid); Logger::sgwc_app().debug("Received S5S8 MODIFY_BEARER_RESPONSE with dest teid " TEID_FMT ", SGW contexts not found, ignore!", m.teid);
} }
} else { } else {
Logger::sgwc_app().debug("Received S5S8 MODIFY_BEARER_RESPONSE with dest teid " TEID_FMT " unknown, ignore CSResp", m.teid); Logger::sgwc_app().debug("Received S5S8 MODIFY_BEARER_RESPONSE with dest teid " TEID_FMT " unknown, ignore!", m.teid);
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -494,10 +500,27 @@ void sgwc_app::handle_itti_msg (itti_s5s8_release_access_bearers_response& m) ...@@ -494,10 +500,27 @@ void sgwc_app::handle_itti_msg (itti_s5s8_release_access_bearers_response& m)
p.first->handle_itti_msg(m, p.second); p.first->handle_itti_msg(m, p.second);
Logger::sgwc_app().debug("sgw_eps_bearer_context: %s!", p.first->toString().c_str()); Logger::sgwc_app().debug("sgw_eps_bearer_context: %s!", p.first->toString().c_str());
} else { } else {
Logger::sgwc_app().debug("Received S5S8 RELEASE_ACCESS_BEARERS_RESPONSE with dest teid " TEID_FMT ", SGW contexts not found, ignore CSResp", m.teid); Logger::sgwc_app().debug("Received S5S8 RELEASE_ACCESS_BEARERS_RESPONSE with dest teid " TEID_FMT ", SGW contexts not found, ignore!", m.teid);
}
} else {
Logger::sgwc_app().debug("Received S5S8 RELEASE_ACCESS_BEARERS_RESPONSE with dest teid " TEID_FMT " unknown, ignore!", m.teid);
}
}
//------------------------------------------------------------------------------
void sgwc_app::handle_itti_msg (itti_s5s8_downlink_data_notification& m)
{
Logger::sgwc_app().debug("Received S5S8 DOWNLINK_DATA_NOTIFICATION sender teid " TEID_FMT " gtpc_tx_id " PROC_ID_FMT " ", m.teid, m.gtpc_tx_id);
if (is_s5s8sgw_teid_2_sgw_contexts(m.teid)) {
std::pair<std::shared_ptr<sgw_eps_bearer_context>, std::shared_ptr<sgw_pdn_connection>> p = s5s8sgw_teid_2_sgw_contexts(m.teid);
if ((p.first.get()) && (p.second.get())) {
p.first->handle_itti_msg(m, p.second);
Logger::sgwc_app().debug("sgw_eps_bearer_context: %s!", p.first->toString().c_str());
} else {
Logger::sgwc_app().debug("Received S5S8 DOWNLINK_DATA_NOTIFICATION with dest teid " TEID_FMT ", SGW contexts not found, ignore!", m.teid);
} }
} else { } else {
Logger::sgwc_app().debug("Received S5S8 RELEASE_ACCESS_BEARERS_RESPONSE with dest teid " TEID_FMT " unknown, ignore CSResp", m.teid); Logger::sgwc_app().debug("Received S5S8 DOWNLINK_DATA_NOTIFICATION with dest teid " TEID_FMT " unknown, ignore!", m.teid);
} }
} }
...@@ -118,6 +118,7 @@ public: ...@@ -118,6 +118,7 @@ public:
void handle_itti_msg (itti_s5s8_delete_session_response& m); void handle_itti_msg (itti_s5s8_delete_session_response& m);
void handle_itti_msg (itti_s5s8_modify_bearer_response& m); void handle_itti_msg (itti_s5s8_modify_bearer_response& m);
void handle_itti_msg (itti_s5s8_release_access_bearers_response& m); void handle_itti_msg (itti_s5s8_release_access_bearers_response& m);
void handle_itti_msg (itti_s5s8_downlink_data_notification& m);
}; };
} }
......
...@@ -210,6 +210,23 @@ void sgw_eps_bearer_context::create_procedure(itti_s11_delete_session_request& d ...@@ -210,6 +210,23 @@ void sgw_eps_bearer_context::create_procedure(itti_s11_delete_session_request& d
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void sgw_eps_bearer_context::create_procedure(itti_s5s8_downlink_data_notification& ddn, std::shared_ptr<sgw_pdn_connection> spc)
{
downlink_data_notification_procedure* p = new downlink_data_notification_procedure(ddn);
insert_procedure(p);
int rc = p->run(shared_from_this(), spc);
switch (rc) {
case RETURNerror:
// TODO handle error code
Logger::sgwc_app().info( "S5S8 DOWNLINK_DATA_NOTIFICATION procedure failed");
case RETURNclear:
remove_procedure(p);
break;
case RETURNok:
default:;
}
}
//------------------------------------------------------------------------------
void sgw_eps_bearer_context::insert_procedure(sebc_procedure* proc) void sgw_eps_bearer_context::insert_procedure(sebc_procedure* proc)
{ {
pending_procedures.push_back(shared_ptr<sebc_procedure>(proc)); pending_procedures.push_back(shared_ptr<sebc_procedure>(proc));
...@@ -358,6 +375,17 @@ void sgw_eps_bearer_context::handle_itti_msg (itti_s5s8_delete_session_response& ...@@ -358,6 +375,17 @@ void sgw_eps_bearer_context::handle_itti_msg (itti_s5s8_delete_session_response&
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void sgw_eps_bearer_context::handle_itti_msg (itti_s5s8_downlink_data_notification& ddn, std::shared_ptr<sgw_pdn_connection> spc)
{
shared_ptr<sebc_procedure> sp = find_procedure(ddn.gtpc_tx_id);
if (sp.get()) {
Logger::sgwc_app().error("S5S8 DOWNLINK_DATA_NOTIFICATION ignored, existing procedure found gtpc_tx_id %d!", ddn.gtpc_tx_id);
return;
} else {
create_procedure(ddn, spc);
}
}
//------------------------------------------------------------------------------
std::string sgw_eps_bearer_context::toString() const std::string sgw_eps_bearer_context::toString() const
{ {
std::string s = {}; std::string s = {};
......
...@@ -207,6 +207,7 @@ public: ...@@ -207,6 +207,7 @@ public:
void create_procedure(itti_s11_modify_bearer_request& ); void create_procedure(itti_s11_modify_bearer_request& );
void create_procedure(itti_s11_delete_session_request& ); void create_procedure(itti_s11_delete_session_request& );
void create_procedure(itti_s11_release_access_bearers_request& ); void create_procedure(itti_s11_release_access_bearers_request& );
void create_procedure(itti_s5s8_downlink_data_notification&, std::shared_ptr<sgw_pdn_connection> spc);
void insert_procedure(sebc_procedure* proc); void insert_procedure(sebc_procedure* proc);
std::shared_ptr<sebc_procedure> find_procedure(const uint64_t& gtpc_tx_id); std::shared_ptr<sebc_procedure> find_procedure(const uint64_t& gtpc_tx_id);
...@@ -227,6 +228,7 @@ public: ...@@ -227,6 +228,7 @@ public:
void handle_itti_msg (itti_s5s8_delete_session_response& m, std::shared_ptr<sgw_pdn_connection> spc); void handle_itti_msg (itti_s5s8_delete_session_response& m, std::shared_ptr<sgw_pdn_connection> spc);
void handle_itti_msg (itti_s5s8_modify_bearer_response& m, std::shared_ptr<sgw_pdn_connection> spc); void handle_itti_msg (itti_s5s8_modify_bearer_response& m, std::shared_ptr<sgw_pdn_connection> spc);
void handle_itti_msg (itti_s5s8_release_access_bearers_response& m, std::shared_ptr<sgw_pdn_connection> spc); void handle_itti_msg (itti_s5s8_release_access_bearers_response& m, std::shared_ptr<sgw_pdn_connection> spc);
void handle_itti_msg (itti_s5s8_downlink_data_notification& m, std::shared_ptr<sgw_pdn_connection> spc);
std::string toString() const; std::string toString() const;
......
...@@ -39,22 +39,26 @@ extern itti_mw *itti_inst; ...@@ -39,22 +39,26 @@ extern itti_mw *itti_inst;
extern sgwc_app *sgwc_app_inst; extern sgwc_app *sgwc_app_inst;
extern sgwc_config sgwc_cfg; extern sgwc_config sgwc_cfg;
void sebc_procedure::handle_itti_msg (itti_s5s8_create_session_response& csresp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc) void sebc_procedure::handle_itti_msg (itti_s5s8_create_session_response& resp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc)
{ {
Logger::sgwc_app().error( "Unhandled message itti_s5s8_create_session_response"); Logger::sgwc_app().error( "Unhandled message itti_s5s8_create_session_response");
} }
void sebc_procedure::handle_itti_msg (itti_s5s8_delete_session_response& dsresp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc) void sebc_procedure::handle_itti_msg (itti_s5s8_delete_session_response& resp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc)
{ {
Logger::sgwc_app().error( "Unhandled message itti_s5s8_delete_session_response"); Logger::sgwc_app().error( "Unhandled message itti_s5s8_delete_session_response");
} }
void sebc_procedure::handle_itti_msg (itti_s5s8_modify_bearer_response& dsresp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc) void sebc_procedure::handle_itti_msg (itti_s5s8_modify_bearer_response& resp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc)
{ {
Logger::sgwc_app().error( "Unhandled message itti_s5s8_modify_bearer_response"); Logger::sgwc_app().error( "Unhandled message itti_s5s8_modify_bearer_response");
} }
void sebc_procedure::handle_itti_msg (itti_s5s8_release_access_bearers_response& dsresp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc) void sebc_procedure::handle_itti_msg (itti_s5s8_release_access_bearers_response& resp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc)
{ {
Logger::sgwc_app().error( "Unhandled message itti_s5s8_release_access_bearers_response"); Logger::sgwc_app().error( "Unhandled message itti_s5s8_release_access_bearers_response");
} }
void sebc_procedure::handle_itti_msg (itti_s5s8_downlink_data_notification& resp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc)
{
Logger::sgwc_app().error( "Unhandled message itti_s5s8_downlink_data_notification");
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int create_session_request_procedure::run(shared_ptr<sgw_eps_bearer_context> c) int create_session_request_procedure::run(shared_ptr<sgw_eps_bearer_context> c)
...@@ -820,3 +824,41 @@ void release_access_bearers_request_procedure::handle_itti_msg (itti_s5s8_releas ...@@ -820,3 +824,41 @@ void release_access_bearers_request_procedure::handle_itti_msg (itti_s5s8_releas
} }
} }
//------------------------------------------------------------------------------
int downlink_data_notification_procedure::run(std::shared_ptr<sgw_eps_bearer_context> sebc, std::shared_ptr<sgw_pdn_connection> pdn)
{
if ((nullptr == sebc.get()) || (nullptr == pdn.get())) {
return RETURNerror;
} else {
ebc = sebc;
pdn_connection = pdn;
ebi_t ebi = {};
if (not (msg.gtp_ies.get(ebi))) {
Logger::sgwc_app().error( "downlink_data_notification_procedure: Could not get ebi in %s", msg.get_msg_name());
return RETURNerror;
}
std::shared_ptr<sgw_eps_bearer> b = {};
if (not pdn_connection->get_eps_bearer(ebi, b)) {
Logger::sgwc_app().error( "downlink_data_notification_procedure: Could not get EPS bearer context %d", ebi.ebi);
return RETURNerror;
}
itti_s11_downlink_data_notification *s11 = new itti_s11_downlink_data_notification(msg.gtp_ies, TASK_SGWC_APP, TASK_SGWC_S11);
s11->teid = ebc->mme_fteid_s11.teid_gre_key;
s11->gtpc_tx_id = get_trxn_id();
s11->r_endpoint = endpoint(ebc->mme_fteid_s11.ipv4_address, gtpv2c::default_port);
s11_triggered = std::shared_ptr<itti_s11_downlink_data_notification>(s11);
Logger::pgwc_app().info( "Sending ITTI message %s to task TASK_SGWC_S11", s11->gtp_ies.get_msg_name());
int ret = itti_inst->send_msg(s11_triggered);
if (RETURNok != ret) {
Logger::pgwc_app().error( "Could not send ITTI message %s to task TASK_SGWC_S11", s11->gtp_ies.get_msg_name());
return RETURNerror;
}
return RETURNok;
}
}
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
*/ */
#include "itti_msg_s11.hpp" #include "itti_msg_s11.hpp"
#include "itti_msg_s5s8.hpp"
#include "msg_gtpv2c.hpp" #include "msg_gtpv2c.hpp"
#include "uint_generator.hpp" #include "uint_generator.hpp"
...@@ -62,6 +63,7 @@ public: ...@@ -62,6 +63,7 @@ public:
virtual void handle_itti_msg (itti_s5s8_delete_session_response& resp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc); virtual void handle_itti_msg (itti_s5s8_delete_session_response& resp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc);
virtual void handle_itti_msg (itti_s5s8_modify_bearer_response& resp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc); virtual void handle_itti_msg (itti_s5s8_modify_bearer_response& resp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc);
virtual void handle_itti_msg (itti_s5s8_release_access_bearers_response& resp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc); virtual void handle_itti_msg (itti_s5s8_release_access_bearers_response& resp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc);
virtual void handle_itti_msg (itti_s5s8_downlink_data_notification& resp, std::shared_ptr<sgw_eps_bearer_context> ebc, std::shared_ptr<sgw_pdn_connection> spc);
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -162,6 +164,25 @@ public: ...@@ -162,6 +164,25 @@ public:
std::shared_ptr<sgw_eps_bearer_context> ebc; std::shared_ptr<sgw_eps_bearer_context> ebc;
std::shared_ptr<sgw_pdn_connection> pdn_connection; std::shared_ptr<sgw_pdn_connection> pdn_connection;
}; };
//------------------------------------------------------------------------------
class downlink_data_notification_procedure : public sebc_procedure {
public:
explicit downlink_data_notification_procedure(itti_s5s8_downlink_data_notification& msg) : sebc_procedure(msg.gtpc_tx_id), msg(msg),
s11_triggered(), ebc(), pdn_connection() {}
int run(std::shared_ptr<sgw_eps_bearer_context> context,
std::shared_ptr<sgw_pdn_connection> spc);
//void handle_itti_msg (itti_sxab_session_report_response& resp);
//~downlink_data_notification_procedure() {}
itti_s5s8_downlink_data_notification msg;
std::shared_ptr<itti_s11_downlink_data_notification> s11_triggered;
std::shared_ptr<sgw_eps_bearer_context> ebc;
std::shared_ptr<sgw_pdn_connection> pdn_connection;
};
} }
#include "sgwc_eps_bearer_context.hpp" #include "sgwc_eps_bearer_context.hpp"
......
...@@ -96,6 +96,12 @@ void sgw_s11_task (void *args_p) ...@@ -96,6 +96,12 @@ void sgw_s11_task (void *args_p)
} }
break; break;
case S11_DOWNLINK_DATA_NOTIFICATION:
if (itti_s11_downlink_data_notification* m = dynamic_cast<itti_s11_downlink_data_notification*>(msg)) {
sgw_s11_inst->send_msg(ref(*m));
}
break;
case TIME_OUT: case TIME_OUT:
if (itti_msg_timeout* to = dynamic_cast<itti_msg_timeout*>(msg)) { if (itti_msg_timeout* to = dynamic_cast<itti_msg_timeout*>(msg)) {
Logger::sgwc_s11().debug( "TIME-OUT event timer id %d", to->timer_id); Logger::sgwc_s11().debug( "TIME-OUT event timer id %d", to->timer_id);
...@@ -148,6 +154,11 @@ void sgw_s11::send_msg(itti_s11_release_access_bearers_response& i) ...@@ -148,6 +154,11 @@ void sgw_s11::send_msg(itti_s11_release_access_bearers_response& i)
send_triggered_message(i.r_endpoint, i.teid, i.gtp_ies, i.gtpc_tx_id); send_triggered_message(i.r_endpoint, i.teid, i.gtp_ies, i.gtpc_tx_id);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void sgw_s11::send_msg(itti_s11_downlink_data_notification& i)
{
send_initial_message(i.r_endpoint, i.teid, i.gtp_ies, TASK_SGWC_S11, i.gtpc_tx_id);
}
//------------------------------------------------------------------------------
void sgw_s11::handle_receive_create_session_request(gtpv2c_msg& msg, const endpoint& remote_endpoint) void sgw_s11::handle_receive_create_session_request(gtpv2c_msg& msg, const endpoint& remote_endpoint)
{ {
bool error = true; bool error = true;
......
...@@ -59,6 +59,7 @@ public: ...@@ -59,6 +59,7 @@ public:
void send_msg(itti_s11_delete_session_response& m); void send_msg(itti_s11_delete_session_response& m);
void send_msg(itti_s11_modify_bearer_response& m); void send_msg(itti_s11_modify_bearer_response& m);
void send_msg(itti_s11_release_access_bearers_response& m); void send_msg(itti_s11_release_access_bearers_response& m);
void send_msg(itti_s11_downlink_data_notification& m);
void send_echo_response(const endpoint& r_endpoint, const uint64_t trxn_id); void send_echo_response(const endpoint& r_endpoint, const uint64_t trxn_id);
......
...@@ -221,6 +221,29 @@ void sgw_s5s8::handle_receive_delete_session_response(gtpv2c_msg& msg, const end ...@@ -221,6 +221,29 @@ void sgw_s5s8::handle_receive_delete_session_response(gtpv2c_msg& msg, const end
} }
// else ignore // else ignore
} }
//------------------------------------------------------------------------------
void sgw_s5s8::handle_receive_downlink_data_notification(gtpv2c::gtpv2c_msg& msg, const endpoint& remote_endpoint)
{
bool error = true;
uint64_t gtpc_tx_id = 0;
gtpv2c_downlink_data_notification msg_ies_container = {};
msg.to_core_type(msg_ies_container);
handle_receive_message_cb(msg, remote_endpoint, TASK_SGWC_S5S8, error, gtpc_tx_id);
if (!error) {
itti_s5s8_downlink_data_notification *itti_msg = new itti_s5s8_downlink_data_notification(TASK_SGWC_S5S8, TASK_SGWC_APP);
itti_msg->gtp_ies = msg_ies_container;
itti_msg->r_endpoint = remote_endpoint;
itti_msg->gtpc_tx_id = gtpc_tx_id;
itti_msg->teid = msg.get_teid();
std::shared_ptr<itti_s5s8_downlink_data_notification> i = std::shared_ptr<itti_s5s8_downlink_data_notification>(itti_msg);
int ret = itti_inst->send_msg(i);
if (RETURNok != ret) {
Logger::sgwc_s5s8().error( "Could not send ITTI message %s to task TASK_SGWC_APP", i->get_msg_name());
}
}
// else ignore
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void sgw_s5s8::handle_receive_gtpv2c_msg(gtpv2c_msg& msg, const endpoint& remote_endpoint) void sgw_s5s8::handle_receive_gtpv2c_msg(gtpv2c_msg& msg, const endpoint& remote_endpoint)
...@@ -254,6 +277,10 @@ void sgw_s5s8::handle_receive_gtpv2c_msg(gtpv2c_msg& msg, const endpoint& remote ...@@ -254,6 +277,10 @@ void sgw_s5s8::handle_receive_gtpv2c_msg(gtpv2c_msg& msg, const endpoint& remote
handle_receive_release_access_bearers_response(msg, remote_endpoint); handle_receive_release_access_bearers_response(msg, remote_endpoint);
} }
break; break;
case GTP_DOWNLINK_DATA_NOTIFICATION: {
handle_receive_downlink_data_notification(msg, remote_endpoint);
}
break;
case GTP_CHANGE_NOTIFICATION_REQUEST: case GTP_CHANGE_NOTIFICATION_REQUEST:
case GTP_CHANGE_NOTIFICATION_RESPONSE: case GTP_CHANGE_NOTIFICATION_RESPONSE:
...@@ -315,7 +342,6 @@ void sgw_s5s8::handle_receive_gtpv2c_msg(gtpv2c_msg& msg, const endpoint& remote ...@@ -315,7 +342,6 @@ void sgw_s5s8::handle_receive_gtpv2c_msg(gtpv2c_msg& msg, const endpoint& remote
case GTP_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST: case GTP_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST:
case GTP_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE: case GTP_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE:
case GTP_RELEASE_ACCESS_BEARERS_REQUEST: case GTP_RELEASE_ACCESS_BEARERS_REQUEST:
case GTP_DOWNLINK_DATA_NOTIFICATION:
case GTP_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE: case GTP_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE:
case GTP_PGW_RESTART_NOTIFICATION: case GTP_PGW_RESTART_NOTIFICATION:
case GTP_PGW_RESTART_NOTIFICATION_ACKNOWLEDGE: case GTP_PGW_RESTART_NOTIFICATION_ACKNOWLEDGE:
......
...@@ -45,6 +45,7 @@ private: ...@@ -45,6 +45,7 @@ private:
void handle_receive_delete_session_response(gtpv2c::gtpv2c_msg& msg, const endpoint& remote_endpoint); void handle_receive_delete_session_response(gtpv2c::gtpv2c_msg& msg, const endpoint& remote_endpoint);
void handle_receive_modify_bearer_response(gtpv2c::gtpv2c_msg& msg, const endpoint& remote_endpoint); void handle_receive_modify_bearer_response(gtpv2c::gtpv2c_msg& msg, const endpoint& remote_endpoint);
void handle_receive_release_access_bearers_response(gtpv2c::gtpv2c_msg& msg, const endpoint& remote_endpoint); void handle_receive_release_access_bearers_response(gtpv2c::gtpv2c_msg& msg, const endpoint& remote_endpoint);
void handle_receive_downlink_data_notification(gtpv2c::gtpv2c_msg& msg, const endpoint& remote_endpoint);
public: public:
sgw_s5s8(); sgw_s5s8();
......
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