Commit 034367f5 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'refactor_ue_context_mapping' into 'develop'

Refactor ue context mapping

See merge request oai/cn5g/oai-cn5g-amf!178
parents 44c7397a b2ac87a8
......@@ -213,20 +213,13 @@ bool amf_app::is_ran_amf_id_2_ue_context(const string& ue_context_key) const {
return false;
}
//------------------------------------------------------------------------------
std::shared_ptr<ue_context> amf_app::ran_amf_id_2_ue_context(
const string& ue_context_key) const {
std::shared_lock lock(m_ue_ctx_key);
return ue_ctx_key.at(ue_context_key);
}
//------------------------------------------------------------------------------
bool amf_app::ran_amf_id_2_ue_context(
const std::string& ue_context_key, std::shared_ptr<ue_context>& uc) const {
std::shared_lock lock(m_ue_ctx_key);
if (ue_ctx_key.count(ue_context_key) > 0) {
if (ue_ctx_key.at(ue_context_key) == nullptr) return false;
uc = ue_ctx_key.at(ue_context_key);
if (uc == nullptr) return false;
return true;
}
return false;
......@@ -242,7 +235,6 @@ void amf_app::set_ran_amf_id_2_ue_context(
//------------------------------------------------------------------------------
bool amf_app::is_supi_2_ue_context(const string& supi) const {
std::shared_lock lock(m_supi2ue_ctx);
// return bool{supi2ue_ctx.count(supi) > 0};
if (supi2ue_ctx.count(supi) > 0) {
if (supi2ue_ctx.at(supi) != nullptr) {
return true;
......@@ -251,20 +243,13 @@ bool amf_app::is_supi_2_ue_context(const string& supi) const {
return false;
}
//------------------------------------------------------------------------------
std::shared_ptr<ue_context> amf_app::supi_2_ue_context(
const string& supi) const {
std::shared_lock lock(m_supi2ue_ctx);
return supi2ue_ctx.at(supi);
}
//------------------------------------------------------------------------------
bool amf_app::supi_2_ue_context(
const std::string& supi, std::shared_ptr<ue_context>& uc) const {
std::shared_lock lock(m_supi2ue_ctx);
if (supi2ue_ctx.count(supi) > 0) {
if (supi2ue_ctx.at(supi) == nullptr) return false;
uc = supi2ue_ctx.at(supi);
if (uc == nullptr) return false;
return true;
}
return false;
......@@ -396,7 +381,7 @@ void amf_app::handle_itti_message(
Logger::amf_app().debug(
"No existing UE Context, Create a new one with ran_amf_id %s",
ue_context_key.c_str());
uc = std::shared_ptr<ue_context>(new ue_context());
uc = std::make_shared<ue_context>();
set_ran_amf_id_2_ue_context(ue_context_key, uc);
}
......@@ -527,7 +512,8 @@ void amf_app::handle_itti_message(itti_sbi_n1_message_notification& itti_msg) {
if (ue_ctx.supiIsSet()) {
supi = ue_ctx.getSupi();
if (!is_supi_2_ue_context(supi)) {
// Update UE Context
if (!supi_2_ue_context(supi, uc)) {
// Create a new UE Context
Logger::amf_app().debug(
"No existing UE Context, Create a new one with SUPI %s",
......@@ -536,8 +522,6 @@ void amf_app::handle_itti_message(itti_sbi_n1_message_notification& itti_msg) {
uc->amf_ue_ngap_id = -1;
uc->supi = supi;
set_supi_2_ue_context(supi, uc);
} else { // Update UE Context
uc = supi_2_ue_context(supi);
}
}
......@@ -565,7 +549,7 @@ void amf_app::handle_itti_message(itti_sbi_n1_message_notification& itti_msg) {
string ue_context_key =
conv::get_ue_context_key(ran_ue_ngap_id, amf_ue_ngap_id);
if (!is_ran_amf_id_2_ue_context(ue_context_key)) {
if (!ran_amf_id_2_ue_context(ue_context_key, uc)) {
Logger::amf_app().debug(
"No existing UE Context associated with UE Context Key %s",
ue_context_key.c_str());
......@@ -574,16 +558,9 @@ void amf_app::handle_itti_message(itti_sbi_n1_message_notification& itti_msg) {
Logger::amf_app().debug(
"Create a new UE Context with UE Context Key",
ue_context_key.c_str());
uc = std::shared_ptr<ue_context>(new ue_context());
uc = std::make_shared<ue_context>();
}
set_ran_amf_id_2_ue_context(ue_context_key, uc);
} else {
uc = ran_amf_id_2_ue_context(ue_context_key);
}
// Return if UE Context is still invalid
if (!uc) {
Logger::amf_app().error("Failed to get UE Context");
return;
}
// Update info for UE context
......@@ -897,18 +874,19 @@ uint32_t amf_app::generate_tmsi() {
bool amf_app::generate_5g_guti(
const uint32_t ranid, const long amfid, string& mcc, string& mnc,
uint32_t& tmsi) {
string ue_context_key = conv::get_ue_context_key(ranid, amfid);
if (!is_ran_amf_id_2_ue_context(ue_context_key)) {
string ue_context_key = conv::get_ue_context_key(ranid, amfid);
std::shared_ptr<ue_context> uc = {};
if (!ran_amf_id_2_ue_context(ue_context_key, uc)) {
Logger::amf_app().error(
"No UE context for ran_amf_id %s, exit", ue_context_key.c_str());
return false;
}
std::shared_ptr<ue_context> uc = {};
uc = ran_amf_id_2_ue_context(ue_context_key);
mcc = uc->tai.mcc;
mnc = uc->tai.mnc;
tmsi = generate_tmsi();
uc->tmsi = tmsi;
mcc = uc->tai.mcc;
mnc = uc->tai.mnc;
tmsi = generate_tmsi();
uc->tmsi = tmsi;
return true;
}
......
......@@ -198,14 +198,6 @@ class amf_app {
*/
bool is_ran_amf_id_2_ue_context(const std::string& ue_context_key) const;
/*
* Get UE context associated with an UE Context Key
* @param [const std::string&] ue_context_key: UE Context Key
* @return shared pointer to the context
*/
std::shared_ptr<ue_context> ran_amf_id_2_ue_context(
const std::string& ue_context_key) const;
/*
* Get UE context associated with an UE Context Key and verify if this pointer
* is nullptr
......@@ -232,13 +224,6 @@ class amf_app {
*/
bool is_supi_2_ue_context(const string& supi) const;
/*
* Get UE context associated with a SUPI
* @param [const std::string&] supi: UE SUPI
* @return shared pointer to the context
*/
std::shared_ptr<ue_context> supi_2_ue_context(const string& supi) const;
/*
* Get UE context associated with a SUPI
* @param [const std::string&] supi: SUPI
......
......@@ -124,6 +124,7 @@ typedef struct auth_conf_s {
std::string mysql_pass;
std::string mysql_db;
std::string random;
nlohmann::json to_json() const {
nlohmann::json json_data = {};
json_data["mysql_server"] = this->mysql_server;
......@@ -231,6 +232,7 @@ typedef struct guami_s {
typedef struct slice_s {
uint8_t sst;
uint32_t sd;
bool operator==(const struct slice_s& s) const {
if ((s.sst == this->sst) && (s.sd == this->sd)) {
return true;
......@@ -238,13 +240,15 @@ typedef struct slice_s {
return false;
}
}
bool operator>(const struct slice_s& s) const {
if (this->sst > s.sst) return true;
if (this->sst == s.sst) {
if (this->sd > s.sd) return true;
if (this->sd <= s.sd) return false;
return (this->sd > s.sd);
}
return false;
}
nlohmann::json to_json() const {
nlohmann::json json_data = {};
json_data["sst"] = this->sst;
......
This diff is collapsed.
......@@ -108,19 +108,21 @@ class amf_n1 {
SecurityHeaderType_t& type, const uint8_t* buffer, const uint32_t length);
/*
* Verify if a UE NAS context associated with a GUTI exist
* Verify if a UE NAS context associated with a GUTI exists
* @param [const std::string&] guti: UE GUTI
* @return true if UE NAS context exist, otherwise false
* @return true if the UE NAS context exists, otherwise false
*/
bool is_guti_2_nas_context(const std::string& guti) const;
/*
* Get UE NAS context associated with a GUTI
* Get UE NAS context associated with a GUTI if the context exists and is not
* null
* @param [const std::string&] guti: UE GUTI
* @return shared pointer to the UE NAS context
* @param [std::shared_ptr<nas_context>&] nc: UE NAS Context
* @return true if the context exists and is not null, otherwise return false
*/
std::shared_ptr<nas_context> guti_2_nas_context(
const std::string& guti) const;
bool guti_2_nas_context(
const std::string& guti, std::shared_ptr<nas_context>& nc) const;
/*
* Store an UE NAS context associated with a GUTI
......@@ -139,29 +141,22 @@ class amf_n1 {
bool remove_guti_2_nas_context(const std::string& guti);
/*
* Verify if a UE NAS context associated with an AMF UE NGAP ID exist
* Verify if a UE NAS context associated with an AMF UE NGAP ID exists
* @param [const long& ] amf_ue_ngap_id: AMF UE NGAP ID
* @return true if UE NAS context exist, otherwise false
* @return true if UE NAS context exists, otherwise false
*/
bool is_amf_ue_id_2_nas_context(const long& amf_ue_ngap_id) const;
/*
* Verify if a UE NAS context associated with an AMF UE NGAP ID exist
* Verify if a UE NAS context associated with an AMF UE NGAP ID exists and is
* not null
* @param [const long& ] amf_ue_ngap_id: AMF UE NGAP ID
* @param [std::shared_ptr<nas_context>&] nc: pointer to UE NAS context
* @return true if UE NAS context exist, otherwise false
* @return true if the UE NAS context exists (and not null), otherwise false
*/
bool is_amf_ue_id_2_nas_context(
bool amf_ue_id_2_nas_context(
const long& amf_ue_ngap_id, std::shared_ptr<nas_context>& nc) const;
/*
* Get UE NAS context associated with an AMF UE NGAP ID
* @param [const long& ] amf_ue_ngap_id: AMF UE NGAP ID
* @return shared pointer to the UE NAS context
*/
std::shared_ptr<nas_context> amf_ue_id_2_nas_context(
const long& amf_ue_ngap_id) const;
/*
* Store an UE NAS context associated with an AMF UE NGAP ID
* @param [const long& ] amf_ue_ngap_id: AMF UE NGAP ID
......@@ -228,10 +223,12 @@ class amf_n1 {
/*
* Get UE NAS context associated with an IMSI
* @param [const std::string&] imsi: UE IMSI
* @return shared pointer to the UE NAS context
* @param [const std::shared_ptr<nas_context>&] nc: pointer to UE NAS context
* @return true if the NAS context exists and is not null, otherwise return
* false
*/
std::shared_ptr<nas_context> imsi_2_nas_context(
const std::string& imsi) const;
bool imsi_2_nas_context(
const std::string& imsi, std::shared_ptr<nas_context>&) const;
/*
* Store an UE NAS context associated with an IMSI
......
This diff is collapsed.
......@@ -225,28 +225,21 @@ class amf_n2 : public ngap::ngap_app {
const uint32_t& ran_ue_ngap_id, std::vector<nas::SNSSAI_t>& common_nssai);
/*
* Get UE NGAP context associated with a RAN UE NGAP ID
* @param [const uint32_t&] ran_ue_ngap_id: RAN UE NGAP ID
* @return shared pointer to the UE NGAP context
*/
// std::shared_ptr<ue_ngap_context> ran_ue_id_2_ue_ngap_context(
// const uint32_t& ran_ue_ngap_id) const;
/*
* Verify whether a UE NGAP context associated with a RAN UE NGAP ID exist
* Get the UE NGAP context associated with a RAN UE NGAP ID if it exists and
* not null
* @param [const uint32_t&] ran_ue_ngap_id: RAN UE NGAP ID
* @param [std::shared_ptr<ue_ngap_context>&] unc: shared pointer to the
* existing UE NGAP context
* @return true if exist, otherwise return false
* @return true if the context exists and is not null, otherwise return false
*/
bool ran_ue_id_2_ue_ngap_context(
const uint32_t& ran_ue_ngap_id,
std::shared_ptr<ue_ngap_context>& unc) const;
/*
* Verify whether a UE NGAP context associated with a RAN UE NGAP ID exist
* Verify whether a UE NGAP context associated with a RAN UE NGAP ID exists
* @param [const uint32_t&] ran_ue_ngap_id: RAN UE NGAP ID
* @return true if exist, otherwise return false
* @return true if the context exists and is not null, otherwise return false
*/
bool is_ran_ue_id_2_ue_ngap_context(const uint32_t& ran_ue_ngap_id) const;
......@@ -276,29 +269,23 @@ class amf_n2 : public ngap::ngap_app {
void remove_ue_context_with_ran_ue_ngap_id(const uint32_t& ran_ue_ngap_id);
/*
* Get UE NGAP context associated with a AMF UE NGAP ID
* @param [const unsigned long&] amf_ue_ngap_id: AMF UE NGAP ID
* @return shared pointer to the UE NGAP context
*/
std::shared_ptr<ue_ngap_context> amf_ue_id_2_ue_ngap_context(
const unsigned long& amf_ue_ngap_id) const;
/*
* Verify whether a UE NGAP context associated with a AMF UE NGAP ID exist
* Verify whether a UE NGAP context associated with a AMF UE NGAP ID exists
* and is not null
* @param [const unsigned long&] amf_ue_ngap_id: AMF UE NGAP ID
* @return true if exist, otherwise return false
* @return true if the context exists and is not null, otherwise return false
*/
bool is_amf_ue_id_2_ue_ngap_context(
const unsigned long& amf_ue_ngap_id) const;
/*
* Verify whether a UE NGAP context associated with a AMF UE NGAP ID exist
* Get UE NGAP context associated with a AMF UE NGAP ID if the context exists
* and is not null
* @param [const unsigned long&] amf_ue_ngap_id: AMF UE NGAP ID
* @param [std::shared_ptr<ue_ngap_context>&] unc: store the pointer to UE
* NGAP context
* @return true if exist, otherwise return false
* @return true if the context exists and is not null, otherwise return false
*/
bool is_amf_ue_id_2_ue_ngap_context(
bool amf_ue_id_2_ue_ngap_context(
const unsigned long& amf_ue_ngap_id,
std::shared_ptr<ue_ngap_context>& unc) const;
......
......@@ -202,22 +202,13 @@ void amf_sbi::handle_itti_message(
string ue_context_key = conv::get_ue_context_key(
itti_msg.ran_ue_ngap_id, itti_msg.amf_ue_ngap_id);
std::shared_ptr<ue_context> uc = {};
if (!amf_app_inst->is_ran_amf_id_2_ue_context(ue_context_key)) {
if (!amf_app_inst->ran_amf_id_2_ue_context(ue_context_key, uc)) {
Logger::amf_sbi().error(
"No UE context for %s exit", ue_context_key.c_str());
return;
}
uc = amf_app_inst->ran_amf_id_2_ue_context(ue_context_key);
std::string supi = {};
if (uc != nullptr) {
supi = uc->supi;
} else {
Logger::amf_sbi().error(
"Could not find UE context with key %s", ue_context_key.c_str());
return;
}
std::string supi = uc->supi;
Logger::amf_sbi().debug(
"Send PDU Session Update SM Context Request to SMF (SUPI %s, PDU Session "
......@@ -287,7 +278,7 @@ void amf_sbi::handle_itti_message(itti_nsmf_pdusession_create_sm_context& smf) {
Logger::amf_sbi().debug("Handle ITTI SMF_PDU_SESSION_CREATE_SM_CTX");
std::shared_ptr<nas_context> nc = {};
if (!amf_n1_inst->is_amf_ue_id_2_nas_context(smf.amf_ue_ngap_id, nc)) {
if (!amf_n1_inst->amf_ue_id_2_nas_context(smf.amf_ue_ngap_id, nc)) {
Logger::amf_sbi().error(
"No UE NAS context with amf_ue_ngap_id (" AMF_UE_NGAP_ID_FMT ")",
smf.amf_ue_ngap_id);
......@@ -301,14 +292,7 @@ void amf_sbi::handle_itti_message(itti_nsmf_pdusession_create_sm_context& smf) {
Logger::amf_sbi().info(
"Find ue_context in amf_app using UE Context Key: %s",
ue_context_key.c_str());
if (!amf_app_inst->is_ran_amf_id_2_ue_context(ue_context_key)) {
Logger::amf_sbi().error(
"No UE context for %s exit", ue_context_key.c_str());
return;
}
uc = amf_app_inst->ran_amf_id_2_ue_context(ue_context_key);
if (!uc) {
if (!amf_app_inst->ran_amf_id_2_ue_context(ue_context_key, uc)) {
Logger::amf_sbi().error(
"No UE context for %s exit", ue_context_key.c_str());
return;
......
......@@ -43,11 +43,14 @@ typedef enum {
NGAP_RESETING,
NGAP_READY,
NGAP_SHUTDOWN
} amf_ng_gnb_state_t;
} ng_gnb_state_t;
static const std::vector<std::string> ng_gnb_state_str = {
"NGAP_INIT", "NGAP_RESETTING", "NGAP_READY", "NGAP_SHUTDOWN"};
class gnb_context {
public:
amf_ng_gnb_state_t ng_state;
ng_gnb_state_t ng_state;
std::string gnb_name;
long globalRanNodeId;
......
......@@ -88,10 +88,10 @@ void ngap_app::handle_sctp_new_association(
"Ready to handle new NGAP SCTP association request (id %d)", assoc_id);
std::shared_ptr<gnb_context> gc = {};
if (!is_assoc_id_2_gnb_context(assoc_id, gc)) {
if (!assoc_id_2_gnb_context(assoc_id, gc)) {
Logger::ngap().debug(
"Create a new gNB context with assoc_id (%d)", assoc_id);
gc = std::shared_ptr<gnb_context>(new gnb_context());
gc = std::make_shared<gnb_context>();
set_assoc_id_2_gnb_context(assoc_id, gc);
} else {
if (gc->ng_state == NGAP_RESETING || gc->ng_state == NGAP_SHUTDOWN) {
......@@ -135,23 +135,20 @@ uint32_t ngap_app::getPpid() {
bool ngap_app::is_assoc_id_2_gnb_context(
const sctp_assoc_id_t& assoc_id) const {
std::shared_lock lock(m_assoc2gnbContext);
return bool{assoc2gnbContext.count(assoc_id) > 0};
}
//------------------------------------------------------------------------------
std::shared_ptr<gnb_context> ngap_app::assoc_id_2_gnb_context(
const sctp_assoc_id_t& assoc_id) const {
std::shared_lock lock(m_assoc2gnbContext);
return assoc2gnbContext.at(assoc_id);
if (assoc2gnbContext.count(assoc_id) > 0) {
if (assoc2gnbContext.at(assoc_id) != nullptr) return true;
}
return false;
}
//------------------------------------------------------------------------------
bool ngap_app::is_assoc_id_2_gnb_context(
bool ngap_app::assoc_id_2_gnb_context(
const sctp_assoc_id_t& assoc_id, std::shared_ptr<gnb_context>& gc) {
std::shared_lock lock(m_assoc2gnbContext);
if (assoc2gnbContext.count(assoc_id) > 0) {
if (assoc2gnbContext.at(assoc_id) == nullptr) return false;
gc = assoc2gnbContext.at(assoc_id);
if (gc != nullptr) return true;
return true;
}
return false;
}
......@@ -167,14 +164,22 @@ void ngap_app::set_assoc_id_2_gnb_context(
//------------------------------------------------------------------------------
bool ngap_app::is_gnb_id_2_gnb_context(const long& gnb_id) const {
std::shared_lock lock(m_gnbid2gnbContext);
return bool{gnbid2gnbContext.count(gnb_id) > 0};
if (gnbid2gnbContext.count(gnb_id) > 0) {
if (gnbid2gnbContext.at(gnb_id) != nullptr) return true;
}
return false;
}
//------------------------------------------------------------------------------
std::shared_ptr<gnb_context> ngap_app::gnb_id_2_gnb_context(
const long& gnb_id) const {
bool ngap_app::gnb_id_2_gnb_context(
const long& gnb_id, std::shared_ptr<gnb_context>& gc) const {
std::shared_lock lock(m_gnbid2gnbContext);
return gnbid2gnbContext.at(gnb_id);
if (gnbid2gnbContext.count(gnb_id) > 0) {
if (gnbid2gnbContext.at(gnb_id) == nullptr) return false;
gc = gnbid2gnbContext.at(gnb_id);
return true;
}
return false;
}
//------------------------------------------------------------------------------
......
......@@ -23,7 +23,6 @@
#define _NGAP_APPLICATION_H_
#include <map>
#include <memory>
#include <shared_mutex>
#include "gNB_context.hpp"
......@@ -33,9 +32,6 @@ using namespace sctp;
namespace ngap {
static const std::vector<std::string> ng_gnb_state_str = {
"NGAP_INIT", "NGAP_RESETTING", "NGAP_READY", "NGAP_SHUTDOWN"};
class ngap_app : public sctp_application {
public:
ngap_app(const std::string& address, const uint16_t port_num);
......@@ -87,22 +83,14 @@ class ngap_app : public sctp_application {
bool is_assoc_id_2_gnb_context(const sctp_assoc_id_t& assoc_id) const;
/*
* Verify whether an association id associated with a GNB context exist
* Get the gNB Context associated with an association Id if exist
* @param [const sctp_assoc_id_t&] assoc_id: gNB association ID
* @param [std::shared_ptr<gnb_context>&] gc: store the gNB context if exist
* @return true if exist, otherwise return false
* @return true if the context exists and not null, otherwise return false
*/
bool is_assoc_id_2_gnb_context(
bool assoc_id_2_gnb_context(
const sctp_assoc_id_t& assoc_id, std::shared_ptr<gnb_context>& gc);
/*
* Get the gNB Context associated with an association id
* @param [const sctp_assoc_id_t&] assoc_id: gNB association ID
* @return the pointer to the gNB context
*/
std::shared_ptr<gnb_context> assoc_id_2_gnb_context(
const sctp_assoc_id_t& assoc_id) const;
/*
* Store gNB Context associated with an association id
* @param [const sctp_assoc_id_t&] assoc_id: gNB association ID
......@@ -129,11 +117,13 @@ class ngap_app : public sctp_application {
const long& gnb_id, const std::shared_ptr<gnb_context>& gc);
/*
* Get the gNB Context associated with a gNB id
* Get the gNB Context associated with a gNB id if exits and not null
* @param [const long& ] gnb_id: gNB ID
* @return the pointer to the gNB context
* @param [const std::shared_ptr<gnb_context>&] gc: pointer to the gNB context
* @return true if the context exists and not null, otherwise return false
*/
std::shared_ptr<gnb_context> gnb_id_2_gnb_context(const long& gnb_id) const;
bool gnb_id_2_gnb_context(
const long& gnb_id, std::shared_ptr<gnb_context>& gc) const;
/*
* Remove the gNB Context associated with a gNB id
......
......@@ -428,7 +428,7 @@ int ngap_amf_handle_pdu_session_resource_setup_response(
new itti_nsmf_pdusession_update_sm_context(TASK_NGAP, TASK_AMF_SBI);
long amf_ue_ngap_id = pdu_session_resource_setup_resp->getAmfUeNgapId();
std::shared_ptr<nas_context> nct = {};
if (!amf_n1_inst->is_amf_ue_id_2_nas_context(amf_ue_ngap_id, nct)) {
if (!amf_n1_inst->amf_ue_id_2_nas_context(amf_ue_ngap_id, nct)) {
Logger::ngap().error(
"No UE NAS context with amf_ue_ngap_id (0x%x)", amf_ue_ngap_id);
return RETURNerror;
......@@ -497,7 +497,7 @@ int ngap_amf_handle_pdu_session_resource_setup_response(
long amf_ue_ngap_id = pdu_session_resource_setup_resp->getAmfUeNgapId();
std::shared_ptr<nas_context> nct = {};
if (!amf_n1_inst->is_amf_ue_id_2_nas_context(amf_ue_ngap_id, nct)) {
if (!amf_n1_inst->amf_ue_id_2_nas_context(amf_ue_ngap_id, nct)) {
Logger::ngap().error(
"No UE NAS context with amf_ue_ngap_id (0x%x)", amf_ue_ngap_id);
return RETURNerror;
......
......@@ -40,16 +40,16 @@ extern "C" {
#include "bstrlib.h"
}
#include <iostream>
namespace sctp {
//------------------------------------------------------------------------------
sctp_application::~sctp_application() {}
//------------------------------------------------------------------------------
sctp_server::sctp_server(const char* address, const uint16_t port_num) {
Logger::sctp().debug("creating socket!!");
Logger::sctp().debug("Creating socket!");
create_socket(address, port_num);
app_ = nullptr;
// pthread_t thread_;
app_ = nullptr;
sctp_desc = {};
serverAddr_ = {};
events_ = {};
......@@ -64,13 +64,13 @@ int sctp_server::create_socket(const char* address, const uint16_t port_num) {
struct addrinfo* res;
if (getaddrinfo(address, 0, NULL, &res) < 0) {
Logger::sctp().error(
"getaddrinfo on %s: %s:%d", address, strerror(errno), errno);
"Getaddrinfo on %s: %s:%d", address, strerror(errno), errno);
return RETURNerror;
} else {
Logger::sctp().debug("getaddrinfo on %s was OK", address);
Logger::sctp().debug("Getaddrinfo on %s was OK", address);
}
if ((socket_ = socket(res->ai_family, SOCK_STREAM, IPPROTO_SCTP)) < 0) {
Logger::sctp().error("socket: %s:%d", strerror(errno), errno);
Logger::sctp().error("Socket: %s:%d", strerror(errno), errno);
return RETURNerror;
}
Logger::sctp().info("Created socket (%d)", socket_);
......@@ -88,9 +88,16 @@ int sctp_server::create_socket(const char* address, const uint16_t port_num) {
events_.sctp_data_io_event = 1;
events_.sctp_shutdown_event = 1;
events_.sctp_association_event = 1;
setsockopt(socket_, IPPROTO_SCTP, SCTP_EVENTS, &events_, 8);
listen(socket_, 5);
return 0;
// TODO:
// events_.sctp_send_failure_event = 1;
// events_.sctp_partial_delivery_event = 1;
// events_.sctp_address_event = 1;
// events_.sctp_peer_error_event = 1;
setsockopt(socket_, IPPROTO_SCTP, SCTP_EVENTS, &events_, sizeof(events_));
listen(socket_, 5); // the queue length for completely established sockets
// waiting to be accepted
return RETURNok;
}
//------------------------------------------------------------------------------
......@@ -102,17 +109,19 @@ void sctp_server::start_receive(sctp_application* app) {
//------------------------------------------------------------------------------
void* sctp_server::sctp_receiver_thread(void* arg) {
sctp_server* ptr = (sctp_server*) arg;
Logger::sctp().info("Create pthread to receive sctp message");
Logger::sctp().info("Create pthread to receive SCTP message");
int fdmax;
int clientsock;
fd_set master;
fd_set read_fds;
if (arg == NULL) pthread_exit(NULL);
FD_ZERO(&master);
FD_ZERO(&read_fds);
FD_SET(ptr->getSocket(), &master);
fdmax = ptr->getSocket();
while (1) {
while (true) {
memcpy(&read_fds, &master, sizeof(master));
if (select(fdmax + 1, &read_fds, NULL, NULL, NULL) == -1) {
Logger::sctp().error(
......@@ -125,7 +134,7 @@ void* sctp_server::sctp_receiver_thread(void* arg) {
if (i == ptr->getSocket()) {
if ((clientsock = accept(ptr->getSocket(), NULL, NULL)) < 0) {
Logger::sctp().error(
"[socket(%d)] accept() error: %s:%d", ptr->getSocket(),
"[socket(%d)] Accept() error: %s:%d", ptr->getSocket(),
strerror(errno), errno);
pthread_exit(NULL);
} else {
......@@ -159,19 +168,24 @@ int sctp_server::sctp_read_from_socket(int sd, uint32_t ppid) {
struct sctp_sndrcvinfo sinfo = {0};
struct sockaddr_in6 addr = {0};
uint8_t buffer[SCTP_RECV_BUFFER_SIZE];
if (sd < 0) return RETURNerror;
memset((void*) &addr, 0, sizeof(struct sockaddr_in6));
from_len = (socklen_t) sizeof(struct sockaddr_in6);
memset((void*) &sinfo, 0, sizeof(struct sctp_sndrcvinfo));
int n = sctp_recvmsg(
sd, (void*) buffer, SCTP_RECV_BUFFER_SIZE, (struct sockaddr*) &addr,
&from_len, &sinfo, &flags);
if (n < 0) {
Logger::sctp().error("sctp_recvmsg error:: %s:%d", strerror(errno), errno);
return SCTP_RC_ERROR;
}
if (flags & MSG_NOTIFICATION) {
union sctp_notification* snp = (union sctp_notification*) buffer;
switch (snp->sn_header.sn_type) {
case SCTP_SHUTDOWN_EVENT: {
Logger::sctp().debug("SCTP Shutdown Event received");
......@@ -181,6 +195,7 @@ int sctp_server::sctp_read_from_socket(int sd, uint32_t ppid) {
case SCTP_ASSOC_CHANGE: {
Logger::sctp().debug("SCTP Association Change event received");
return handle_assoc_change(sd, ppid, &snp->sn_assoc_change);
break;
}
default: {
Logger::sctp().error(
......@@ -195,17 +210,20 @@ int sctp_server::sctp_read_from_socket(int sd, uint32_t ppid) {
return SCTP_RC_ERROR;
}
association->messages_recv++;
if (ntohl(sinfo.sinfo_ppid) != association->ppid) {
Logger::sctp().error(
"Received data from peer with unsolicited PPID (%d), expecting (%d)",
ntohl(sinfo.sinfo_ppid), association->ppid);
return SCTP_RC_ERROR;
}
Logger::sctp().info(
"****[Assoc_id %d, Socket %d] Received a msg (length %d) from port %d, "
"on stream %d, PPID %d ****",
"[Assoc_id %d, Socket %d] Received a msg (length %d) from port %d, "
"on stream %d, PPID %d",
sinfo.sinfo_assoc_id, sd, n, ntohs(addr.sin6_port), sinfo.sinfo_stream,
ntohl(sinfo.sinfo_ppid));
bstring payload = blk2bstr(buffer, n);
// Handle payload
app_->handle_receive(
......@@ -231,6 +249,7 @@ int sctp_server::sctp_handle_reset(const sctp_assoc_id_t assoc_id) {
int sctp_server::handle_assoc_change(
int sd, uint32_t ppid, struct sctp_assoc_change* sctp_assoc_changed) {
int rc = SCTP_RC_NORMAL_READ;
switch (sctp_assoc_changed->sac_state) {
case SCTP_COMM_UP: {
if (add_new_association(sd, ppid, sctp_assoc_changed) == NULL) {
......@@ -260,9 +279,10 @@ int sctp_server::handle_assoc_change(
}
default:
Logger::sctp().error(
"Unhandled sctp message (%d)", sctp_assoc_changed->sac_state);
"Unhandled SCTP message (%d)", sctp_assoc_changed->sac_state);
break;
}
return rc;
}
......@@ -280,7 +300,9 @@ sctp_association_t* sctp_server::add_new_association(
Logger::sctp().debug(
"Add new association with id (%d)",
(sctp_assoc_id_t) sctp_assoc_changed->sac_assoc_id);
sctp_ctx.push_back(new_association);
sctp_get_localaddresses(sd, NULL, NULL);
sctp_get_peeraddresses(
sd, &new_association->peer_addresses,
......@@ -288,6 +310,7 @@ sctp_association_t* sctp_server::add_new_association(
app_->handle_sctp_new_association(
new_association->assoc_id, new_association->instreams,
new_association->outstreams);
return new_association;
}
......@@ -295,14 +318,17 @@ sctp_association_t* sctp_server::add_new_association(
sctp_association_t* sctp_server::sctp_is_assoc_in_list(
sctp_assoc_id_t assoc_id) {
sctp_association_t* assoc_desc = NULL;
if (assoc_id < 0) {
return NULL;
}
for (int i = 0; i < sctp_ctx.size(); i++) {
if (sctp_ctx[i]->assoc_id == assoc_id) {
return sctp_ctx[i];
}
}
return assoc_desc;
}
......@@ -311,12 +337,15 @@ int sctp_server::sctp_get_peeraddresses(
int sock, struct sockaddr** remote_addr, int* nb_remote_addresses) {
int nb;
struct sockaddr* temp_addr_p = NULL;
if ((nb = sctp_getpaddrs(sock, -1, &temp_addr_p)) <= 0) {
Logger::sctp().error("Failed to retrieve peer addresses");
return RETURNerror;
}
Logger::sctp().info("----------------------");
Logger::sctp().info("Peer addresses:");
for (int j = 0; j < nb; j++) {
if (temp_addr_p[j].sa_family == AF_INET) {
char address[16] = {0};
......@@ -337,13 +366,16 @@ int sctp_server::sctp_get_peeraddresses(
}
}
}
Logger::sctp().info("----------------------");
if (remote_addr != NULL && nb_remote_addresses != NULL) {
*nb_remote_addresses = nb;
*remote_addr = temp_addr_p;
} else {
sctp_freepaddrs((struct sockaddr*) temp_addr_p);
}
return RETURNok;
}
......@@ -356,6 +388,7 @@ int sctp_server::sctp_get_localaddresses(
Logger::sctp().error("Failed to retrieve local addresses");
return RETURNerror;
}
if (temp_addr_p) {
Logger::sctp().info("----------------------");
Logger::sctp().info("Local addresses:");
......@@ -382,6 +415,7 @@ int sctp_server::sctp_get_localaddresses(
" - Unknown address family %d", temp_addr_p[j].sa_family);
}
}
if (local_addr != NULL && nb_local_addresses != NULL) {
*nb_local_addresses = nb;
*local_addr = temp_addr_p;
......@@ -389,6 +423,7 @@ int sctp_server::sctp_get_localaddresses(
sctp_freeladdrs((struct sockaddr*) temp_addr_p);
}
}
return RETURNok;
}
......
......@@ -22,19 +22,18 @@
#ifndef _SCTP_SERVER_H_
#define _SCTP_SERVER_H_
#include <thread>
#include "common_defs.h"
#include "endpoint.hpp"
#include <thread>
#include <vector>
extern "C" {
#include <netinet/in.h>
#include <netinet/sctp.h>
#include "bstrlib.h"
}
#include <iostream>
#include <vector>
#define SCTP_RECV_BUFFER_SIZE 2048
#define SCTP_RC_ERROR -1
......@@ -47,20 +46,19 @@ typedef uint16_t sctp_stream_id_t;
typedef uint32_t sctp_assoc_id_t;
typedef struct sctp_association_s {
struct sctp_association_s* next_assoc; ///< Next association in the list
struct sctp_association_s* next_assoc; // Next association in the list
struct sctp_association_s*
previous_assoc; ///< Previous association in the list
int sd; ///< Socket descriptor
uint32_t ppid; ///< Payload protocol Identifier
uint16_t
instreams; ///< Number of input streams negociated for this connection
previous_assoc; // Previous association in the list
int sd; // Socket descriptor
uint32_t ppid; // Payload protocol Identifier
uint16_t instreams; // Number of input streams negociated for this connection
uint16_t
outstreams; ///< Number of output strams negotiated for this connection
sctp_assoc_id_t assoc_id; ///< SCTP association id for the connection
uint32_t messages_recv; ///< Number of messages received on this connection
uint32_t messages_sent; ///< Number of messages sent on this connection
outstreams; // Number of output strams negotiated for this connection
sctp_assoc_id_t assoc_id; // SCTP association id for the connection
uint32_t messages_recv; // Number of messages received on this connection
uint32_t messages_sent; // Number of messages sent on this connection
struct sockaddr* peer_addresses; ///< A list of peer addresses
struct sockaddr* peer_addresses; // A list of peer addresses
int nb_peer_addresses;
} sctp_association_t;
......@@ -75,6 +73,7 @@ typedef struct sctp_descriptor_s {
class sctp_application {
public:
virtual ~sctp_application();
virtual void handle_receive(
bstring payload, sctp_assoc_id_t assoc_id, sctp_stream_id_t stream,
sctp_stream_id_t instreams, sctp_stream_id_t outstreams) = 0;
......
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