mirror of https://github.com/PentHertz/srsLTE.git
Added S1AP E-RAB release command/response handling to srsENB.
Added the ability to srsEPC to send the E-RAB release command.
This commit is contained in:
parent
783131a4e1
commit
7eebd71627
|
@ -25,6 +25,7 @@ namespace s1ap {
|
||||||
struct init_context_setup_request_s;
|
struct init_context_setup_request_s;
|
||||||
struct ue_context_mod_request_s;
|
struct ue_context_mod_request_s;
|
||||||
struct erab_setup_request_s;
|
struct erab_setup_request_s;
|
||||||
|
struct erab_release_cmd_s;
|
||||||
struct ue_paging_id_c;
|
struct ue_paging_id_c;
|
||||||
struct ho_request_s;
|
struct ho_request_s;
|
||||||
struct sourceenb_to_targetenb_transparent_container_s;
|
struct sourceenb_to_targetenb_transparent_container_s;
|
||||||
|
|
|
@ -411,6 +411,10 @@ public:
|
||||||
virtual bool modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) = 0;
|
virtual bool modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) = 0;
|
||||||
virtual bool setup_ue_erabs(uint16_t rnti, const asn1::s1ap::erab_setup_request_s& msg) = 0;
|
virtual bool setup_ue_erabs(uint16_t rnti, const asn1::s1ap::erab_setup_request_s& msg) = 0;
|
||||||
virtual bool release_erabs(uint32_t rnti) = 0;
|
virtual bool release_erabs(uint32_t rnti) = 0;
|
||||||
|
virtual void release_erabs(uint32_t rnti,
|
||||||
|
const asn1::s1ap::erab_release_cmd_s& msg,
|
||||||
|
std::vector<uint16_t>* erabs_released,
|
||||||
|
std::vector<uint16_t>* erabs_failed_to_release) = 0;
|
||||||
virtual void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& ue_paging_id) = 0;
|
virtual void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& ue_paging_id) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -456,12 +460,12 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
initial_ue(uint16_t rnti, asn1::s1ap::rrc_establishment_cause_e cause, srslte::unique_byte_buffer_t pdu) = 0;
|
initial_ue(uint16_t rnti, asn1::s1ap::rrc_establishment_cause_e cause, srslte::unique_byte_buffer_t pdu) = 0;
|
||||||
virtual void initial_ue(uint16_t rnti,
|
virtual void initial_ue(uint16_t rnti,
|
||||||
asn1::s1ap::rrc_establishment_cause_e cause,
|
asn1::s1ap::rrc_establishment_cause_e cause,
|
||||||
srslte::unique_byte_buffer_t pdu,
|
srslte::unique_byte_buffer_t pdu,
|
||||||
uint32_t m_tmsi,
|
uint32_t m_tmsi,
|
||||||
uint8_t mmec) = 0;
|
uint8_t mmec) = 0;
|
||||||
|
|
||||||
virtual void write_pdu(uint16_t rnti, srslte::unique_byte_buffer_t pdu) = 0;
|
virtual void write_pdu(uint16_t rnti, srslte::unique_byte_buffer_t pdu) = 0;
|
||||||
virtual bool user_exists(uint16_t rnti) = 0;
|
virtual bool user_exists(uint16_t rnti) = 0;
|
||||||
|
|
|
@ -59,6 +59,10 @@ public:
|
||||||
virtual nas* find_nas_ctx_from_imsi(uint64_t imsi) = 0;
|
virtual nas* find_nas_ctx_from_imsi(uint64_t imsi) = 0;
|
||||||
virtual bool send_initial_context_setup_request(uint64_t imsi, uint16_t erab_to_setup) = 0;
|
virtual bool send_initial_context_setup_request(uint64_t imsi, uint16_t erab_to_setup) = 0;
|
||||||
virtual bool send_ue_context_release_command(uint32_t mme_ue_s1ap_id) = 0;
|
virtual bool send_ue_context_release_command(uint32_t mme_ue_s1ap_id) = 0;
|
||||||
|
virtual bool send_erab_release_command(uint32_t enb_ue_s1ap_id,
|
||||||
|
uint32_t mme_ue_s1ap_id,
|
||||||
|
std::vector<uint16_t> erabs_to_release,
|
||||||
|
struct sctp_sndrcvinfo enb_sri) = 0;
|
||||||
virtual bool send_downlink_nas_transport(uint32_t enb_ue_s1ap_id,
|
virtual bool send_downlink_nas_transport(uint32_t enb_ue_s1ap_id,
|
||||||
uint32_t mme_ue_s1ap_id,
|
uint32_t mme_ue_s1ap_id,
|
||||||
srslte::byte_buffer_t* nas_msg,
|
srslte::byte_buffer_t* nas_msg,
|
||||||
|
|
|
@ -77,6 +77,10 @@ public:
|
||||||
bool modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) override;
|
bool modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) override;
|
||||||
bool setup_ue_erabs(uint16_t rnti, const asn1::s1ap::erab_setup_request_s& msg) override;
|
bool setup_ue_erabs(uint16_t rnti, const asn1::s1ap::erab_setup_request_s& msg) override;
|
||||||
bool release_erabs(uint32_t rnti) override;
|
bool release_erabs(uint32_t rnti) override;
|
||||||
|
void release_erabs(uint32_t rnti,
|
||||||
|
const asn1::s1ap::erab_release_cmd_s& msg,
|
||||||
|
std::vector<uint16_t>* erabs_released,
|
||||||
|
std::vector<uint16_t>* erabs_failed_to_release) override;
|
||||||
void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& UEPagingID) override;
|
void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& UEPagingID) override;
|
||||||
void ho_preparation_complete(uint16_t rnti, bool is_success, srslte::unique_byte_buffer_t rrc_container) override;
|
void ho_preparation_complete(uint16_t rnti, bool is_success, srslte::unique_byte_buffer_t rrc_container) override;
|
||||||
uint16_t
|
uint16_t
|
||||||
|
|
|
@ -67,7 +67,7 @@ public:
|
||||||
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
||||||
uint32_t teid_out,
|
uint32_t teid_out,
|
||||||
const asn1::unbounded_octstring<true>* nas_pdu);
|
const asn1::unbounded_octstring<true>* nas_pdu);
|
||||||
void release_erab(uint8_t erab_id);
|
bool release_erab(uint8_t erab_id);
|
||||||
void release_erabs();
|
void release_erabs();
|
||||||
|
|
||||||
// Methods to apply bearer updates
|
// Methods to apply bearer updates
|
||||||
|
|
|
@ -65,6 +65,7 @@ public:
|
||||||
bool setup_erabs(const asn1::s1ap::erab_to_be_setup_list_ctxt_su_req_l& e);
|
bool setup_erabs(const asn1::s1ap::erab_to_be_setup_list_ctxt_su_req_l& e);
|
||||||
bool setup_erabs(const asn1::s1ap::erab_to_be_setup_list_bearer_su_req_l& e);
|
bool setup_erabs(const asn1::s1ap::erab_to_be_setup_list_bearer_su_req_l& e);
|
||||||
bool release_erabs();
|
bool release_erabs();
|
||||||
|
bool release_erab(uint32_t erab_id);
|
||||||
|
|
||||||
// handover
|
// handover
|
||||||
void handle_ho_preparation_complete(bool is_success, srslte::unique_byte_buffer_t container);
|
void handle_ho_preparation_complete(bool is_success, srslte::unique_byte_buffer_t container);
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
|
|
||||||
// RRC interface
|
// RRC interface
|
||||||
void
|
void
|
||||||
initial_ue(uint16_t rnti, asn1::s1ap::rrc_establishment_cause_e cause, srslte::unique_byte_buffer_t pdu) override;
|
initial_ue(uint16_t rnti, asn1::s1ap::rrc_establishment_cause_e cause, srslte::unique_byte_buffer_t pdu) override;
|
||||||
void initial_ue(uint16_t rnti,
|
void initial_ue(uint16_t rnti,
|
||||||
asn1::s1ap::rrc_establishment_cause_e cause,
|
asn1::s1ap::rrc_establishment_cause_e cause,
|
||||||
srslte::unique_byte_buffer_t pdu,
|
srslte::unique_byte_buffer_t pdu,
|
||||||
|
@ -84,7 +84,7 @@ public:
|
||||||
|
|
||||||
// Stack interface
|
// Stack interface
|
||||||
bool
|
bool
|
||||||
handle_mme_rx_msg(srslte::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags);
|
handle_mme_rx_msg(srslte::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags);
|
||||||
void start_pcap(srslte::s1ap_pcap* pcap_);
|
void start_pcap(srslte::s1ap_pcap* pcap_);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -138,6 +138,7 @@ private:
|
||||||
bool handle_uectxtreleasecommand(const asn1::s1ap::ue_context_release_cmd_s& msg);
|
bool handle_uectxtreleasecommand(const asn1::s1ap::ue_context_release_cmd_s& msg);
|
||||||
bool handle_s1setupfailure(const asn1::s1ap::s1_setup_fail_s& msg);
|
bool handle_s1setupfailure(const asn1::s1ap::s1_setup_fail_s& msg);
|
||||||
bool handle_erabsetuprequest(const asn1::s1ap::erab_setup_request_s& msg);
|
bool handle_erabsetuprequest(const asn1::s1ap::erab_setup_request_s& msg);
|
||||||
|
bool handle_erabreleasecommand(const asn1::s1ap::erab_release_cmd_s& msg);
|
||||||
bool handle_uecontextmodifyrequest(const asn1::s1ap::ue_context_mod_request_s& msg);
|
bool handle_uecontextmodifyrequest(const asn1::s1ap::ue_context_mod_request_s& msg);
|
||||||
|
|
||||||
// bool send_ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps)
|
// bool send_ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps)
|
||||||
|
@ -156,7 +157,7 @@ private:
|
||||||
struct ts1_reloc_prep_expired {};
|
struct ts1_reloc_prep_expired {};
|
||||||
ho_prep_proc_t(s1ap::ue* ue_);
|
ho_prep_proc_t(s1ap::ue* ue_);
|
||||||
srslte::proc_outcome_t
|
srslte::proc_outcome_t
|
||||||
init(uint32_t target_eci_, srslte::plmn_id_t target_plmn_, srslte::unique_byte_buffer_t rrc_container);
|
init(uint32_t target_eci_, srslte::plmn_id_t target_plmn_, srslte::unique_byte_buffer_t rrc_container);
|
||||||
srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; }
|
srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; }
|
||||||
srslte::proc_outcome_t react(ts1_reloc_prep_expired e);
|
srslte::proc_outcome_t react(ts1_reloc_prep_expired e);
|
||||||
srslte::proc_outcome_t react(const asn1::s1ap::ho_prep_fail_s& msg);
|
srslte::proc_outcome_t react(const asn1::s1ap::ho_prep_fail_s& msg);
|
||||||
|
@ -189,6 +190,8 @@ private:
|
||||||
bool send_initial_ctxt_setup_response(const asn1::s1ap::init_context_setup_resp_s& res_);
|
bool send_initial_ctxt_setup_response(const asn1::s1ap::init_context_setup_resp_s& res_);
|
||||||
bool send_initial_ctxt_setup_failure();
|
bool send_initial_ctxt_setup_failure();
|
||||||
bool send_erab_setup_response(const asn1::s1ap::erab_setup_resp_s& res_);
|
bool send_erab_setup_response(const asn1::s1ap::erab_setup_resp_s& res_);
|
||||||
|
bool send_erab_release_response(const std::vector<uint16_t>& erabs_successfully_released,
|
||||||
|
const std::vector<uint16_t>& erabs_failed_to_release);
|
||||||
bool was_uectxtrelease_requested() const { return release_requested; }
|
bool was_uectxtrelease_requested() const { return release_requested; }
|
||||||
|
|
||||||
ue_ctxt_t ctxt = {};
|
ue_ctxt_t ctxt = {};
|
||||||
|
|
|
@ -307,6 +307,32 @@ bool rrc::release_erabs(uint32_t rnti)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rrc::release_erabs(uint32_t rnti,
|
||||||
|
const asn1::s1ap::erab_release_cmd_s& msg,
|
||||||
|
std::vector<uint16_t>* erabs_released,
|
||||||
|
std::vector<uint16_t>* erabs_failed_to_release)
|
||||||
|
{
|
||||||
|
rrc_log->info("Releasing E-RAB for 0x%x\n", rnti);
|
||||||
|
auto user_it = users.find(rnti);
|
||||||
|
|
||||||
|
if (user_it == users.end()) {
|
||||||
|
rrc_log->warning("Unrecognised rnti: 0x%x\n", rnti);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < msg.protocol_ies.erab_to_be_released_list.value.size(); i++) {
|
||||||
|
const asn1::s1ap::erab_item_s& erab_to_release =
|
||||||
|
msg.protocol_ies.erab_to_be_released_list.value[i].value.erab_item();
|
||||||
|
bool ret = user_it->second->release_erab(erab_to_release.erab_id);
|
||||||
|
if (ret) {
|
||||||
|
erabs_released->push_back(erab_to_release.erab_id);
|
||||||
|
} else {
|
||||||
|
erabs_failed_to_release->push_back(erab_to_release.erab_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
Paging functions
|
Paging functions
|
||||||
These functions use a different mutex because access different shared variables
|
These functions use a different mutex because access different shared variables
|
||||||
|
|
|
@ -258,12 +258,12 @@ int bearer_cfg_handler::add_erab(uint8_t
|
||||||
return SRSLTE_SUCCESS;
|
return SRSLTE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bearer_cfg_handler::release_erab(uint8_t erab_id)
|
bool bearer_cfg_handler::release_erab(uint8_t erab_id)
|
||||||
{
|
{
|
||||||
auto it = erabs.find(erab_id);
|
auto it = erabs.find(erab_id);
|
||||||
if (it == erabs.end()) {
|
if (it == erabs.end()) {
|
||||||
log_h->warning("The user rnti=0x%x does not contain ERAB-ID=%d\n", rnti, erab_id);
|
log_h->warning("The user rnti=0x%x does not contain ERAB-ID=%d\n", rnti, erab_id);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t drb_id = erab_id - 4;
|
uint8_t drb_id = erab_id - 4;
|
||||||
|
@ -272,6 +272,8 @@ void bearer_cfg_handler::release_erab(uint8_t erab_id)
|
||||||
|
|
||||||
erabs.erase(it);
|
erabs.erase(it);
|
||||||
erab_info_list.erase(erab_id);
|
erab_info_list.erase(erab_id);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bearer_cfg_handler::release_erabs()
|
void bearer_cfg_handler::release_erabs()
|
||||||
|
|
|
@ -318,10 +318,10 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg)
|
||||||
(uint32_t)msg->crit_exts.rrc_conn_reest_request_r8().ue_id.short_mac_i.to_number(),
|
(uint32_t)msg->crit_exts.rrc_conn_reest_request_r8().ue_id.short_mac_i.to_number(),
|
||||||
msg->crit_exts.rrc_conn_reest_request_r8().reest_cause.to_string().c_str());
|
msg->crit_exts.rrc_conn_reest_request_r8().reest_cause.to_string().c_str());
|
||||||
if (is_idle()) {
|
if (is_idle()) {
|
||||||
uint16_t old_rnti = msg->crit_exts.rrc_conn_reest_request_r8().ue_id.c_rnti.to_number();
|
uint16_t old_rnti = msg->crit_exts.rrc_conn_reest_request_r8().ue_id.c_rnti.to_number();
|
||||||
uint16_t old_pci = msg->crit_exts.rrc_conn_reest_request_r8().ue_id.pci;
|
uint16_t old_pci = msg->crit_exts.rrc_conn_reest_request_r8().ue_id.pci;
|
||||||
const enb_cell_common* old_cell = parent->cell_common_list->get_pci(old_pci);
|
const enb_cell_common* old_cell = parent->cell_common_list->get_pci(old_pci);
|
||||||
auto ue_it = parent->users.find(old_rnti);
|
auto ue_it = parent->users.find(old_rnti);
|
||||||
// Reject unrecognized rntis, and PCIs that do not belong to eNB
|
// Reject unrecognized rntis, and PCIs that do not belong to eNB
|
||||||
if (ue_it != parent->users.end() and old_cell != nullptr and
|
if (ue_it != parent->users.end() and old_cell != nullptr and
|
||||||
ue_it->second->ue_cell_list.get_enb_cc_idx(old_cell->enb_cc_idx) != nullptr) {
|
ue_it->second->ue_cell_list.get_enb_cc_idx(old_cell->enb_cc_idx) != nullptr) {
|
||||||
|
@ -333,7 +333,7 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg)
|
||||||
|
|
||||||
// Recover security setup
|
// Recover security setup
|
||||||
const enb_cell_common* pcell_cfg = get_ue_cc_cfg(UE_PCELL_CC_IDX);
|
const enb_cell_common* pcell_cfg = get_ue_cc_cfg(UE_PCELL_CC_IDX);
|
||||||
ue_security_cfg = parent->users[old_rnti]->ue_security_cfg;
|
ue_security_cfg = parent->users[old_rnti]->ue_security_cfg;
|
||||||
ue_security_cfg.regenerate_keys_handover(pcell_cfg->cell_cfg.pci, pcell_cfg->cell_cfg.dl_earfcn);
|
ue_security_cfg.regenerate_keys_handover(pcell_cfg->cell_cfg.pci, pcell_cfg->cell_cfg.dl_earfcn);
|
||||||
|
|
||||||
// send reestablishment and restore bearer configuration
|
// send reestablishment and restore bearer configuration
|
||||||
|
@ -467,12 +467,8 @@ void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu, bool phy_
|
||||||
rrc_conn_recfg_r8_ies_s& recfg_r8 = rrc_conn_recfg.crit_exts.set_c1().set_rrc_conn_recfg_r8();
|
rrc_conn_recfg_r8_ies_s& recfg_r8 = rrc_conn_recfg.crit_exts.set_c1().set_rrc_conn_recfg_r8();
|
||||||
|
|
||||||
// Fill RR Config Ded and SCells
|
// Fill RR Config Ded and SCells
|
||||||
apply_reconf_updates(recfg_r8,
|
apply_reconf_updates(
|
||||||
current_ue_cfg,
|
recfg_r8, current_ue_cfg, parent->cfg, ue_cell_list, bearer_list, ue_capabilities, phy_cfg_updated);
|
||||||
parent->cfg, ue_cell_list,
|
|
||||||
bearer_list,
|
|
||||||
ue_capabilities,
|
|
||||||
phy_cfg_updated);
|
|
||||||
|
|
||||||
// Add measConfig
|
// Add measConfig
|
||||||
if (mobility_handler != nullptr) {
|
if (mobility_handler != nullptr) {
|
||||||
|
@ -816,6 +812,11 @@ bool rrc::ue::release_erabs()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool rrc::ue::release_erab(uint32_t erab_id)
|
||||||
|
{
|
||||||
|
return bearer_list.release_erab(erab_id);
|
||||||
|
}
|
||||||
|
|
||||||
void rrc::ue::notify_s1ap_ue_erab_setup_response(const asn1::s1ap::erab_to_be_setup_list_bearer_su_req_l& e)
|
void rrc::ue::notify_s1ap_ue_erab_setup_response(const asn1::s1ap::erab_to_be_setup_list_bearer_su_req_l& e)
|
||||||
{
|
{
|
||||||
asn1::s1ap::erab_setup_resp_s res;
|
asn1::s1ap::erab_setup_resp_s res;
|
||||||
|
@ -856,8 +857,8 @@ enb_cell_common* rrc::ue::get_ue_cc_cfg(uint32_t ue_cc_idx)
|
||||||
|
|
||||||
void rrc::ue::update_scells()
|
void rrc::ue::update_scells()
|
||||||
{
|
{
|
||||||
const ue_cell_ded* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX);
|
const ue_cell_ded* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX);
|
||||||
const enb_cell_common* pcell_cfg = pcell->cell_common;
|
const enb_cell_common* pcell_cfg = pcell->cell_common;
|
||||||
|
|
||||||
if (ue_cell_list.nof_cells() == pcell_cfg->scells.size() + 1) {
|
if (ue_cell_list.nof_cells() == pcell_cfg->scells.size() + 1) {
|
||||||
// SCells already added
|
// SCells already added
|
||||||
|
|
|
@ -566,6 +566,8 @@ bool s1ap::handle_initiatingmessage(const init_msg_s& msg)
|
||||||
return handle_paging(msg.value.paging());
|
return handle_paging(msg.value.paging());
|
||||||
case s1ap_elem_procs_o::init_msg_c::types_opts::erab_setup_request:
|
case s1ap_elem_procs_o::init_msg_c::types_opts::erab_setup_request:
|
||||||
return handle_erabsetuprequest(msg.value.erab_setup_request());
|
return handle_erabsetuprequest(msg.value.erab_setup_request());
|
||||||
|
case s1ap_elem_procs_o::init_msg_c::types_opts::erab_release_cmd:
|
||||||
|
return handle_erabreleasecommand(msg.value.erab_release_cmd());
|
||||||
case s1ap_elem_procs_o::init_msg_c::types_opts::ue_context_mod_request:
|
case s1ap_elem_procs_o::init_msg_c::types_opts::ue_context_mod_request:
|
||||||
return handle_uecontextmodifyrequest(msg.value.ue_context_mod_request());
|
return handle_uecontextmodifyrequest(msg.value.ue_context_mod_request());
|
||||||
case s1ap_elem_procs_o::init_msg_c::types_opts::ho_request:
|
case s1ap_elem_procs_o::init_msg_c::types_opts::ho_request:
|
||||||
|
@ -704,6 +706,32 @@ bool s1ap::handle_erabsetuprequest(const erab_setup_request_s& msg)
|
||||||
return rrc->setup_ue_erabs(u->ctxt.rnti, msg);
|
return rrc->setup_ue_erabs(u->ctxt.rnti, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg)
|
||||||
|
{
|
||||||
|
s1ap_log->info("Received ERABReleaseCommand\n");
|
||||||
|
if (msg.ext) {
|
||||||
|
s1ap_log->warning("Not handling S1AP message extension\n");
|
||||||
|
}
|
||||||
|
ue* u = find_s1apmsg_user(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value);
|
||||||
|
if (u == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint16_t> erab_successful_release = {};
|
||||||
|
std::vector<uint16_t> erab_failed_to_release = {};
|
||||||
|
|
||||||
|
// Release E-RABs from RRC
|
||||||
|
rrc->release_erabs(u->ctxt.rnti, msg, &erab_successful_release, &erab_failed_to_release);
|
||||||
|
|
||||||
|
// Send E-RAB release response back to the MME
|
||||||
|
if (not u->send_erab_release_response(erab_successful_release, erab_failed_to_release)) {
|
||||||
|
s1ap_log->info("Failed to send ERABReleaseResponse\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool s1ap::handle_uecontextmodifyrequest(const ue_context_mod_request_s& msg)
|
bool s1ap::handle_uecontextmodifyrequest(const ue_context_mod_request_s& msg)
|
||||||
{
|
{
|
||||||
s1ap_log->info("Received UeContextModificationRequest\n");
|
s1ap_log->info("Received UeContextModificationRequest\n");
|
||||||
|
@ -1203,6 +1231,47 @@ bool s1ap::ue::send_uectxtmodifyfailure(const cause_c& cause)
|
||||||
return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UEContextModificationFailure");
|
return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UEContextModificationFailure");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool s1ap::ue::send_erab_release_response(const std::vector<uint16_t>& erabs_successfully_released,
|
||||||
|
const std::vector<uint16_t>& erabs_failed_to_release)
|
||||||
|
{
|
||||||
|
if (not s1ap_ptr->mme_connected) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
asn1::s1ap::s1ap_pdu_c tx_pdu;
|
||||||
|
tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_ERAB_RELEASE);
|
||||||
|
|
||||||
|
auto& container = tx_pdu.successful_outcome().value.erab_release_resp().protocol_ies;
|
||||||
|
container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id;
|
||||||
|
container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id;
|
||||||
|
|
||||||
|
// Fill in which E-RABs were successfully released
|
||||||
|
if (not erabs_successfully_released.empty()) {
|
||||||
|
container.erab_release_list_bearer_rel_comp_present = true;
|
||||||
|
container.erab_release_list_bearer_rel_comp.value.resize(erabs_successfully_released.size());
|
||||||
|
for (uint32_t i = 0; i < container.erab_release_list_bearer_rel_comp.value.size(); i++) {
|
||||||
|
container.erab_release_list_bearer_rel_comp.value[i].load_info_obj(
|
||||||
|
ASN1_S1AP_ID_ERAB_RELEASE_ITEM_BEARER_REL_COMP);
|
||||||
|
container.erab_release_list_bearer_rel_comp.value[i].value.erab_release_item_bearer_rel_comp().erab_id =
|
||||||
|
erabs_successfully_released[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in which E-RABs were *not* successfully released
|
||||||
|
if (not erabs_failed_to_release.empty()) {
|
||||||
|
container.erab_failed_to_release_list_present = true;
|
||||||
|
container.erab_failed_to_release_list.value.resize(erabs_failed_to_release.size());
|
||||||
|
for (uint32_t i = 0; i < container.erab_failed_to_release_list.value.size(); i++) {
|
||||||
|
container.erab_failed_to_release_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM);
|
||||||
|
container.erab_failed_to_release_list.value[i].value.erab_item().erab_id = erabs_failed_to_release[i];
|
||||||
|
container.erab_failed_to_release_list.value[i].value.erab_item().cause.set(asn1::s1ap::cause_c::types::misc);
|
||||||
|
container.erab_failed_to_release_list.value[i].value.erab_item().cause.misc() =
|
||||||
|
asn1::s1ap::cause_misc_opts::unspecified;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E_RABReleaseResponse");
|
||||||
|
}
|
||||||
/*********************
|
/*********************
|
||||||
* Handover Messages
|
* Handover Messages
|
||||||
********************/
|
********************/
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "mme_gtpc.h"
|
#include "mme_gtpc.h"
|
||||||
#include "nas.h"
|
#include "nas.h"
|
||||||
#include "s1ap_ctx_mngmt_proc.h"
|
#include "s1ap_ctx_mngmt_proc.h"
|
||||||
|
#include "s1ap_erab_mngmt_proc.h"
|
||||||
#include "s1ap_mngmt_proc.h"
|
#include "s1ap_mngmt_proc.h"
|
||||||
#include "s1ap_nas_transport.h"
|
#include "s1ap_nas_transport.h"
|
||||||
#include "s1ap_paging.h"
|
#include "s1ap_paging.h"
|
||||||
|
@ -89,10 +90,11 @@ public:
|
||||||
srslte::log_filter* m_s1ap_log;
|
srslte::log_filter* m_s1ap_log;
|
||||||
srslte::log_filter* m_nas_log;
|
srslte::log_filter* m_nas_log;
|
||||||
|
|
||||||
s1ap_mngmt_proc* m_s1ap_mngmt_proc;
|
s1ap_mngmt_proc* m_s1ap_mngmt_proc;
|
||||||
s1ap_nas_transport* m_s1ap_nas_transport;
|
s1ap_nas_transport* m_s1ap_nas_transport;
|
||||||
s1ap_ctx_mngmt_proc* m_s1ap_ctx_mngmt_proc;
|
s1ap_ctx_mngmt_proc* m_s1ap_ctx_mngmt_proc;
|
||||||
s1ap_paging* m_s1ap_paging;
|
s1ap_erab_mngmt_proc* m_s1ap_erab_mngmt_proc;
|
||||||
|
s1ap_paging* m_s1ap_paging;
|
||||||
|
|
||||||
std::map<uint32_t, uint64_t> m_tmsi_to_imsi;
|
std::map<uint32_t, uint64_t> m_tmsi_to_imsi;
|
||||||
std::map<uint16_t, enb_ctx_t*> m_active_enbs;
|
std::map<uint16_t, enb_ctx_t*> m_active_enbs;
|
||||||
|
@ -100,6 +102,10 @@ public:
|
||||||
// Interfaces
|
// Interfaces
|
||||||
virtual bool send_initial_context_setup_request(uint64_t imsi, uint16_t erab_to_setup);
|
virtual bool send_initial_context_setup_request(uint64_t imsi, uint16_t erab_to_setup);
|
||||||
virtual bool send_ue_context_release_command(uint32_t mme_ue_s1ap_id);
|
virtual bool send_ue_context_release_command(uint32_t mme_ue_s1ap_id);
|
||||||
|
virtual bool send_erab_release_command(uint32_t enb_ue_s1ap_id,
|
||||||
|
uint32_t mme_ue_s1ap_id,
|
||||||
|
std::vector<uint16_t> erabs_to_release,
|
||||||
|
struct sctp_sndrcvinfo enb_sri);
|
||||||
virtual bool send_downlink_nas_transport(uint32_t enb_ue_s1ap_id,
|
virtual bool send_downlink_nas_transport(uint32_t enb_ue_s1ap_id,
|
||||||
uint32_t mme_ue_s1ap_id,
|
uint32_t mme_ue_s1ap_id,
|
||||||
srslte::byte_buffer_t* nas_msg,
|
srslte::byte_buffer_t* nas_msg,
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* By using this file, you agree to the terms and conditions set
|
||||||
|
* forth in the LICENSE file which can be found at the top level of
|
||||||
|
* the distribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef SRSEPC_S1AP_ERAB_MNGMT_PROC_H
|
||||||
|
#define SRSEPC_S1AP_ERAB_MNGMT_PROC_H
|
||||||
|
|
||||||
|
#include "mme_gtpc.h"
|
||||||
|
#include "s1ap_common.h"
|
||||||
|
#include "srslte/asn1/s1ap.h"
|
||||||
|
#include "srslte/common/buffer_pool.h"
|
||||||
|
#include "srslte/common/common.h"
|
||||||
|
#include "srslte/common/log_filter.h"
|
||||||
|
#include <netinet/sctp.h>
|
||||||
|
|
||||||
|
namespace srsepc {
|
||||||
|
|
||||||
|
class s1ap;
|
||||||
|
|
||||||
|
class s1ap_erab_mngmt_proc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static s1ap_erab_mngmt_proc* m_instance;
|
||||||
|
static s1ap_erab_mngmt_proc* get_instance(void);
|
||||||
|
static void cleanup(void);
|
||||||
|
|
||||||
|
void init(void);
|
||||||
|
|
||||||
|
bool send_erab_release_command(uint32_t enb_ue_s1ap_id,
|
||||||
|
uint32_t mme_ue_s1ap_id,
|
||||||
|
std::vector<uint16_t> erabs_to_release,
|
||||||
|
struct sctp_sndrcvinfo enb_sri);
|
||||||
|
bool handle_erab_release_response(const asn1::s1ap::init_context_setup_resp_s& in_ctxt_resp);
|
||||||
|
|
||||||
|
private:
|
||||||
|
s1ap_erab_mngmt_proc();
|
||||||
|
virtual ~s1ap_erab_mngmt_proc();
|
||||||
|
|
||||||
|
s1ap* m_s1ap = nullptr;
|
||||||
|
srslte::log_filter* m_s1ap_log = nullptr;
|
||||||
|
|
||||||
|
s1ap_args_t m_s1ap_args;
|
||||||
|
|
||||||
|
mme_gtpc* m_mme_gtpc = nullptr;
|
||||||
|
srslte::byte_buffer_pool* m_pool = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsepc
|
||||||
|
#endif // SRSEPC_S1AP_CTX_MNGMT_PROC_H
|
|
@ -16,6 +16,7 @@
|
||||||
#include "srslte/common/security.h"
|
#include "srslte/common/security.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <inttypes.h> // for printing uint64_t
|
#include <inttypes.h> // for printing uint64_t
|
||||||
|
#include <netinet/sctp.h>
|
||||||
#include <sys/timerfd.h>
|
#include <sys/timerfd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
@ -115,14 +116,14 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id,
|
||||||
srslte::console("Attach request -- Attach type: %d\n", attach_req.eps_attach_type);
|
srslte::console("Attach request -- Attach type: %d\n", attach_req.eps_attach_type);
|
||||||
nas_log->info("Attach request -- Attach type: %d\n", attach_req.eps_attach_type);
|
nas_log->info("Attach request -- Attach type: %d\n", attach_req.eps_attach_type);
|
||||||
srslte::console("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d\n",
|
srslte::console("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d\n",
|
||||||
attach_req.ue_network_cap.eea[0],
|
attach_req.ue_network_cap.eea[0],
|
||||||
attach_req.ue_network_cap.eea[1],
|
attach_req.ue_network_cap.eea[1],
|
||||||
attach_req.ue_network_cap.eea[2],
|
attach_req.ue_network_cap.eea[2],
|
||||||
attach_req.ue_network_cap.eea[3],
|
attach_req.ue_network_cap.eea[3],
|
||||||
attach_req.ue_network_cap.eea[4],
|
attach_req.ue_network_cap.eea[4],
|
||||||
attach_req.ue_network_cap.eea[5],
|
attach_req.ue_network_cap.eea[5],
|
||||||
attach_req.ue_network_cap.eea[6],
|
attach_req.ue_network_cap.eea[6],
|
||||||
attach_req.ue_network_cap.eea[7]);
|
attach_req.ue_network_cap.eea[7]);
|
||||||
nas_log->info("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d\n",
|
nas_log->info("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d\n",
|
||||||
attach_req.ue_network_cap.eea[0],
|
attach_req.ue_network_cap.eea[0],
|
||||||
attach_req.ue_network_cap.eea[1],
|
attach_req.ue_network_cap.eea[1],
|
||||||
|
@ -133,14 +134,14 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id,
|
||||||
attach_req.ue_network_cap.eea[6],
|
attach_req.ue_network_cap.eea[6],
|
||||||
attach_req.ue_network_cap.eea[7]);
|
attach_req.ue_network_cap.eea[7]);
|
||||||
srslte::console("Attach Request -- UE Network Capabilities EIA: %d%d%d%d%d%d%d%d\n",
|
srslte::console("Attach Request -- UE Network Capabilities EIA: %d%d%d%d%d%d%d%d\n",
|
||||||
attach_req.ue_network_cap.eia[0],
|
attach_req.ue_network_cap.eia[0],
|
||||||
attach_req.ue_network_cap.eia[1],
|
attach_req.ue_network_cap.eia[1],
|
||||||
attach_req.ue_network_cap.eia[2],
|
attach_req.ue_network_cap.eia[2],
|
||||||
attach_req.ue_network_cap.eia[3],
|
attach_req.ue_network_cap.eia[3],
|
||||||
attach_req.ue_network_cap.eia[4],
|
attach_req.ue_network_cap.eia[4],
|
||||||
attach_req.ue_network_cap.eia[5],
|
attach_req.ue_network_cap.eia[5],
|
||||||
attach_req.ue_network_cap.eia[6],
|
attach_req.ue_network_cap.eia[6],
|
||||||
attach_req.ue_network_cap.eia[7]);
|
attach_req.ue_network_cap.eia[7]);
|
||||||
nas_log->info("Attach Request -- UE Network Capabilities EIA: %d%d%d%d%d%d%d%d\n",
|
nas_log->info("Attach Request -- UE Network Capabilities EIA: %d%d%d%d%d%d%d%d\n",
|
||||||
attach_req.ue_network_cap.eia[0],
|
attach_req.ue_network_cap.eia[0],
|
||||||
attach_req.ue_network_cap.eia[1],
|
attach_req.ue_network_cap.eia[1],
|
||||||
|
@ -151,7 +152,7 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id,
|
||||||
attach_req.ue_network_cap.eia[6],
|
attach_req.ue_network_cap.eia[6],
|
||||||
attach_req.ue_network_cap.eia[7]);
|
attach_req.ue_network_cap.eia[7]);
|
||||||
srslte::console("Attach Request -- MS Network Capabilities Present: %s\n",
|
srslte::console("Attach Request -- MS Network Capabilities Present: %s\n",
|
||||||
attach_req.ms_network_cap_present ? "true" : "false");
|
attach_req.ms_network_cap_present ? "true" : "false");
|
||||||
nas_log->info("Attach Request -- MS Network Capabilities Present: %s\n",
|
nas_log->info("Attach Request -- MS Network Capabilities Present: %s\n",
|
||||||
attach_req.ms_network_cap_present ? "true" : "false");
|
attach_req.ms_network_cap_present ? "true" : "false");
|
||||||
srslte::console("PDN Connectivity Request -- EPS Bearer Identity requested: %d\n", pdn_con_req.eps_bearer_id);
|
srslte::console("PDN Connectivity Request -- EPS Bearer Identity requested: %d\n", pdn_con_req.eps_bearer_id);
|
||||||
|
@ -159,7 +160,7 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id,
|
||||||
srslte::console("PDN Connectivity Request -- Procedure Transaction Id: %d\n", pdn_con_req.proc_transaction_id);
|
srslte::console("PDN Connectivity Request -- Procedure Transaction Id: %d\n", pdn_con_req.proc_transaction_id);
|
||||||
nas_log->info("PDN Connectivity Request -- Procedure Transaction Id: %d\n", pdn_con_req.proc_transaction_id);
|
nas_log->info("PDN Connectivity Request -- Procedure Transaction Id: %d\n", pdn_con_req.proc_transaction_id);
|
||||||
srslte::console("PDN Connectivity Request -- ESM Information Transfer requested: %s\n",
|
srslte::console("PDN Connectivity Request -- ESM Information Transfer requested: %s\n",
|
||||||
pdn_con_req.esm_info_transfer_flag_present ? "true" : "false");
|
pdn_con_req.esm_info_transfer_flag_present ? "true" : "false");
|
||||||
nas_log->info("PDN Connectivity Request -- ESM Information Transfer requested: %s\n",
|
nas_log->info("PDN Connectivity Request -- ESM Information Transfer requested: %s\n",
|
||||||
pdn_con_req.esm_info_transfer_flag_present ? "true" : "false");
|
pdn_con_req.esm_info_transfer_flag_present ? "true" : "false");
|
||||||
|
|
||||||
|
@ -422,9 +423,9 @@ bool nas::handle_guti_attach_request_known_ue(nas*
|
||||||
gtpc_interface_nas* gtpc = itf.gtpc;
|
gtpc_interface_nas* gtpc = itf.gtpc;
|
||||||
|
|
||||||
srslte::console("Found UE context. IMSI: %015" PRIu64 ", old eNB UE S1ap Id %d, old MME UE S1AP Id %d\n",
|
srslte::console("Found UE context. IMSI: %015" PRIu64 ", old eNB UE S1ap Id %d, old MME UE S1AP Id %d\n",
|
||||||
emm_ctx->imsi,
|
emm_ctx->imsi,
|
||||||
ecm_ctx->enb_ue_s1ap_id,
|
ecm_ctx->enb_ue_s1ap_id,
|
||||||
ecm_ctx->mme_ue_s1ap_id);
|
ecm_ctx->mme_ue_s1ap_id);
|
||||||
|
|
||||||
// Check NAS integrity
|
// Check NAS integrity
|
||||||
msg_valid = nas_ctx->integrity_check(nas_rx);
|
msg_valid = nas_ctx->integrity_check(nas_rx);
|
||||||
|
|
|
@ -74,6 +74,8 @@ int s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter* nas_log, srslte::log_f
|
||||||
m_s1ap_nas_transport->init();
|
m_s1ap_nas_transport->init();
|
||||||
m_s1ap_ctx_mngmt_proc = s1ap_ctx_mngmt_proc::get_instance(); // Context Management Procedures
|
m_s1ap_ctx_mngmt_proc = s1ap_ctx_mngmt_proc::get_instance(); // Context Management Procedures
|
||||||
m_s1ap_ctx_mngmt_proc->init();
|
m_s1ap_ctx_mngmt_proc->init();
|
||||||
|
m_s1ap_erab_mngmt_proc = s1ap_erab_mngmt_proc::get_instance(); // E-RAB Management Procedures
|
||||||
|
m_s1ap_erab_mngmt_proc->init();
|
||||||
m_s1ap_paging = s1ap_paging::get_instance(); // Paging
|
m_s1ap_paging = s1ap_paging::get_instance(); // Paging
|
||||||
m_s1ap_paging->init();
|
m_s1ap_paging->init();
|
||||||
|
|
||||||
|
@ -619,6 +621,15 @@ bool s1ap::send_ue_context_release_command(uint32_t mme_ue_s1ap_id)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool s1ap::send_erab_release_command(uint32_t enb_ue_s1ap_id,
|
||||||
|
uint32_t mme_ue_s1ap_id,
|
||||||
|
std::vector<uint16_t> erabs_to_be_released,
|
||||||
|
struct sctp_sndrcvinfo enb_sri)
|
||||||
|
{
|
||||||
|
return m_s1ap_erab_mngmt_proc->send_erab_release_command(
|
||||||
|
enb_ue_s1ap_id, mme_ue_s1ap_id, erabs_to_be_released, enb_sri);
|
||||||
|
}
|
||||||
|
|
||||||
bool s1ap::send_downlink_nas_transport(uint32_t enb_ue_s1ap_id,
|
bool s1ap::send_downlink_nas_transport(uint32_t enb_ue_s1ap_id,
|
||||||
uint32_t mme_ue_s1ap_id,
|
uint32_t mme_ue_s1ap_id,
|
||||||
srslte::byte_buffer_t* nas_msg,
|
srslte::byte_buffer_t* nas_msg,
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* By using this file, you agree to the terms and conditions set
|
||||||
|
* forth in the LICENSE file which can be found at the top level of
|
||||||
|
* the distribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "srsepc/hdr/mme/s1ap_erab_mngmt_proc.h"
|
||||||
|
#include "srsepc/hdr/mme/s1ap.h"
|
||||||
|
#include "srslte/common/bcd_helpers.h"
|
||||||
|
#include "srslte/common/buffer_pool.h"
|
||||||
|
#include "srslte/common/int_helpers.h"
|
||||||
|
#include "srslte/common/liblte_security.h"
|
||||||
|
#include <endian.h>
|
||||||
|
|
||||||
|
namespace srsepc {
|
||||||
|
|
||||||
|
s1ap_erab_mngmt_proc* s1ap_erab_mngmt_proc::m_instance = NULL;
|
||||||
|
pthread_mutex_t s1ap_erab_mngmt_proc_instance_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
s1ap_erab_mngmt_proc::s1ap_erab_mngmt_proc()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s1ap_erab_mngmt_proc::~s1ap_erab_mngmt_proc()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s1ap_erab_mngmt_proc* s1ap_erab_mngmt_proc::get_instance()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&s1ap_erab_mngmt_proc_instance_mutex);
|
||||||
|
if (NULL == m_instance) {
|
||||||
|
m_instance = new s1ap_erab_mngmt_proc();
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&s1ap_erab_mngmt_proc_instance_mutex);
|
||||||
|
return (m_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void s1ap_erab_mngmt_proc::cleanup()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&s1ap_erab_mngmt_proc_instance_mutex);
|
||||||
|
if (NULL != m_instance) {
|
||||||
|
delete m_instance;
|
||||||
|
m_instance = NULL;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&s1ap_erab_mngmt_proc_instance_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void s1ap_erab_mngmt_proc::init()
|
||||||
|
{
|
||||||
|
m_s1ap = s1ap::get_instance();
|
||||||
|
m_s1ap_log = m_s1ap->m_s1ap_log;
|
||||||
|
m_s1ap_args = m_s1ap->m_s1ap_args;
|
||||||
|
m_pool = srslte::byte_buffer_pool::get_instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool s1ap_erab_mngmt_proc::send_erab_release_command(uint32_t enb_ue_s1ap_id,
|
||||||
|
uint32_t mme_ue_s1ap_id,
|
||||||
|
std::vector<uint16_t> erabs_to_release,
|
||||||
|
struct sctp_sndrcvinfo enb_sri)
|
||||||
|
{
|
||||||
|
m_s1ap_log->info("Preparing to send E-RAB Release Command\n");
|
||||||
|
|
||||||
|
// Prepare reply PDU
|
||||||
|
s1ap_pdu_t tx_pdu;
|
||||||
|
tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_ERAB_RELEASE);
|
||||||
|
|
||||||
|
asn1::s1ap::erab_release_cmd_ies_container& erab_rel_cmd = tx_pdu.init_msg().value.erab_release_cmd().protocol_ies;
|
||||||
|
|
||||||
|
// Add MME and eNB S1AP Ids
|
||||||
|
erab_rel_cmd.mme_ue_s1ap_id.value = mme_ue_s1ap_id;
|
||||||
|
erab_rel_cmd.enb_ue_s1ap_id.value = enb_ue_s1ap_id;
|
||||||
|
|
||||||
|
// Number of E-RABs to be setup
|
||||||
|
erab_rel_cmd.erab_to_be_released_list.value.resize(erabs_to_release.size());
|
||||||
|
for (uint32_t i = 0; i < erab_rel_cmd.erab_to_be_released_list.value.size(); i++) {
|
||||||
|
erab_rel_cmd.erab_to_be_released_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM);
|
||||||
|
erab_rel_cmd.erab_to_be_released_list.value[i].value.erab_item().erab_id = erabs_to_release[i];
|
||||||
|
erab_rel_cmd.erab_to_be_released_list.value[i].value.erab_item().cause.set(asn1::s1ap::cause_c::types::misc);
|
||||||
|
erab_rel_cmd.erab_to_be_released_list.value[i].value.erab_item().cause.misc() =
|
||||||
|
asn1::s1ap::cause_misc_opts::unspecified;
|
||||||
|
m_s1ap_log->info("Sending release comman to %d\n", erabs_to_release[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_s1ap->s1ap_tx_pdu(tx_pdu, &enb_sri)) {
|
||||||
|
m_s1ap_log->error("Error sending Initial Context Setup Request.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace srsepc
|
Loading…
Reference in New Issue