mirror of https://github.com/PentHertz/srsLTE.git
updated s1ap rrc interface with new asn1 lib types
This commit is contained in:
parent
61b3e6b57e
commit
b6c53d786b
|
@ -23,12 +23,12 @@
|
|||
|
||||
#include "srslte/asn1/liblte_s1ap.h"
|
||||
#include "srslte/asn1/rrc_asn1.h"
|
||||
#include "srslte/asn1/s1ap_asn1.h"
|
||||
#include "srslte/common/common.h"
|
||||
#include "srslte/common/interfaces_common.h"
|
||||
#include "srslte/common/security.h"
|
||||
#include "srslte/interfaces/rrc_interface_types.h"
|
||||
#include "srslte/interfaces/sched_interface.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifndef SRSLTE_ENB_INTERFACES_H
|
||||
|
@ -303,24 +303,24 @@ public:
|
|||
};
|
||||
|
||||
virtual void
|
||||
initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::unique_byte_buffer_t pdu) = 0;
|
||||
virtual void initial_ue(uint16_t rnti,
|
||||
LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause,
|
||||
srslte::unique_byte_buffer_t pdu,
|
||||
uint32_t m_tmsi,
|
||||
uint8_t mmec) = 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,
|
||||
asn1::s1ap::rrc_establishment_cause_e cause,
|
||||
srslte::unique_byte_buffer_t pdu,
|
||||
uint32_t m_tmsi,
|
||||
uint8_t mmec) = 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_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio) = 0;
|
||||
virtual void ue_ctxt_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT* res) = 0;
|
||||
virtual void ue_erab_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT* res) = 0;
|
||||
virtual bool is_mme_connected() = 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_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_radio) = 0;
|
||||
virtual void ue_ctxt_setup_complete(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res) = 0;
|
||||
virtual void ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::e_rab_setup_resp_s& res) = 0;
|
||||
virtual bool is_mme_connected() = 0;
|
||||
virtual bool send_ho_required(uint16_t rnti,
|
||||
uint32_t target_eci,
|
||||
srslte::plmn_id_t target_plmn,
|
||||
srslte::unique_byte_buffer_t rrc_container) = 0;
|
||||
virtual bool send_enb_status_transfer_proc(uint16_t rnti, std::vector<bearer_status_info>& bearer_status_list) = 0;
|
||||
srslte::unique_byte_buffer_t rrc_container) = 0;
|
||||
virtual bool send_enb_status_transfer_proc(uint16_t rnti, std::vector<bearer_status_info>& bearer_status_list) = 0;
|
||||
};
|
||||
|
||||
// Combined interface for PHY to access stack (MAC and RRC)
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#
|
||||
|
||||
add_executable(s1ap_test s1ap_test.cc)
|
||||
target_link_libraries(s1ap_test srslte_common srslte_asn1)
|
||||
target_link_libraries(s1ap_test srslte_common srslte_asn1 s1ap_asn1)
|
||||
add_test(s1ap_test s1ap_test)
|
||||
|
||||
add_executable(srslte_asn1_rrc_mcch_test srslte_asn1_rrc_mcch_test.cc)
|
||||
|
|
|
@ -63,18 +63,19 @@ public:
|
|||
void get_metrics(s1ap_metrics_t& m);
|
||||
|
||||
// RRC interface
|
||||
void initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::unique_byte_buffer_t pdu);
|
||||
void initial_ue(uint16_t rnti,
|
||||
LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause,
|
||||
srslte::unique_byte_buffer_t pdu,
|
||||
uint32_t m_tmsi,
|
||||
uint8_t mmec);
|
||||
void write_pdu(uint16_t rnti, srslte::unique_byte_buffer_t pdu);
|
||||
bool user_exists(uint16_t rnti);
|
||||
bool user_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio);
|
||||
void ue_ctxt_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT* res);
|
||||
void ue_erab_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT* res);
|
||||
bool is_mme_connected();
|
||||
void
|
||||
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,
|
||||
asn1::s1ap::rrc_establishment_cause_e cause,
|
||||
srslte::unique_byte_buffer_t pdu,
|
||||
uint32_t m_tmsi,
|
||||
uint8_t mmec) override;
|
||||
void write_pdu(uint16_t rnti, srslte::unique_byte_buffer_t pdu) override;
|
||||
bool user_exists(uint16_t rnti) override;
|
||||
bool user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_radio) override;
|
||||
void ue_ctxt_setup_complete(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res) override;
|
||||
void ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::e_rab_setup_resp_s& res) override;
|
||||
bool is_mme_connected() override;
|
||||
// void ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps);
|
||||
|
||||
// Stack interface
|
||||
|
@ -114,6 +115,7 @@ private:
|
|||
bool connect_mme();
|
||||
bool setup_s1();
|
||||
bool sctp_send_s1ap_pdu(LIBLTE_S1AP_S1AP_PDU_STRUCT* tx_pdu, uint32_t rnti, const char* procedure_name);
|
||||
bool sctp_send_s1ap_pdu(const asn1::s1ap::s1ap_pdu_c& tx_pdu, uint32_t rnti, const char* procedure_name);
|
||||
|
||||
bool handle_s1ap_rx_pdu(srslte::byte_buffer_t* pdu);
|
||||
bool handle_initiatingmessage(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT* msg);
|
||||
|
@ -130,21 +132,21 @@ private:
|
|||
bool handle_erabsetuprequest(LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT* msg);
|
||||
bool handle_uecontextmodifyrequest(LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONREQUEST_STRUCT* msg);
|
||||
|
||||
bool send_initialuemessage(uint16_t rnti,
|
||||
LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause,
|
||||
srslte::unique_byte_buffer_t pdu,
|
||||
bool has_tmsi,
|
||||
uint32_t m_tmsi = 0,
|
||||
uint8_t mmec = 0);
|
||||
bool send_initialuemessage(uint16_t rnti,
|
||||
asn1::s1ap::rrc_establishment_cause_e cause,
|
||||
srslte::unique_byte_buffer_t pdu,
|
||||
bool has_tmsi,
|
||||
uint32_t m_tmsi = 0,
|
||||
uint8_t mmec = 0);
|
||||
bool send_ulnastransport(uint16_t rnti, srslte::unique_byte_buffer_t pdu);
|
||||
bool send_uectxtreleaserequest(uint16_t rnti, LIBLTE_S1AP_CAUSE_STRUCT* cause);
|
||||
bool send_uectxtreleaserequest(uint16_t rnti, const asn1::s1ap::cause_c& cause);
|
||||
bool send_uectxtreleasecomplete(uint16_t rnti, uint32_t mme_ue_id, uint32_t enb_ue_id);
|
||||
bool send_initial_ctxt_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT* res_);
|
||||
bool send_initial_ctxt_setup_response(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res_);
|
||||
bool send_initial_ctxt_setup_failure(uint16_t rnti);
|
||||
bool send_erab_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT* res_);
|
||||
bool send_erab_setup_response(uint16_t rnti, const asn1::s1ap::e_rab_setup_resp_s& res_);
|
||||
// bool send_ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps)
|
||||
bool send_uectxmodifyresp(uint16_t rnti);
|
||||
bool send_uectxmodifyfailure(uint16_t rnti, LIBLTE_S1AP_CAUSE_STRUCT* cause);
|
||||
bool send_uectxmodifyfailure(uint16_t rnti, const asn1::s1ap::cause_c& cause);
|
||||
// handover
|
||||
bool send_ho_required(uint16_t rnti,
|
||||
uint32_t target_eci,
|
||||
|
|
|
@ -47,6 +47,7 @@ target_link_libraries(srsenb srsenb_radio
|
|||
srslte_upper
|
||||
srslte_radio
|
||||
rrc_asn1
|
||||
s1ap_asn1
|
||||
enb_cfg_parser
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${Boost_LIBRARIES}
|
||||
|
|
|
@ -659,7 +659,7 @@ void rrc::parse_ul_ccch(uint16_t rnti, srslte::unique_byte_buffer_t pdu)
|
|||
rrc_log->error("Not supported: ConnectionReestablishment for rnti=0x%x. Sending Connection Reject\n",
|
||||
old_rnti);
|
||||
user_it->second->send_connection_reest_rej();
|
||||
s1ap->user_release(old_rnti, LIBLTE_S1AP_CAUSERADIONETWORK_RELEASE_DUE_TO_EUTRAN_GENERATED_REASON);
|
||||
s1ap->user_release(old_rnti, asn1::s1ap::cause_radio_network_opts::release_due_to_eutran_generated_reason);
|
||||
} else {
|
||||
rrc_log->error("Received ConnectionReestablishment for rnti=0x%x without context\n", old_rnti);
|
||||
user_it->second->send_connection_reest_rej();
|
||||
|
@ -701,7 +701,7 @@ void rrc::process_rl_failure(uint16_t rnti)
|
|||
if (n_rfl == 1) {
|
||||
rrc_log->info("Radio-Link failure detected rnti=0x%x\n", rnti);
|
||||
if (s1ap->user_exists(rnti)) {
|
||||
if (!s1ap->user_release(rnti, LIBLTE_S1AP_CAUSERADIONETWORK_RADIO_CONNECTION_WITH_UE_LOST)) {
|
||||
if (!s1ap->user_release(rnti, asn1::s1ap::cause_radio_network_opts::radio_conn_with_ue_lost)) {
|
||||
rrc_log->info("Removing rnti=0x%x\n", rnti);
|
||||
}
|
||||
} else {
|
||||
|
@ -1023,7 +1023,7 @@ void rrc::ue::activity_timer_expired()
|
|||
}
|
||||
|
||||
if (parent->s1ap->user_exists(rnti)) {
|
||||
parent->s1ap->user_release(rnti, LIBLTE_S1AP_CAUSERADIONETWORK_USER_INACTIVITY);
|
||||
parent->s1ap->user_release(rnti, asn1::s1ap::cause_radio_network_opts::user_inactivity);
|
||||
} else {
|
||||
if (rnti != SRSLTE_MRNTI) {
|
||||
parent->rem_user_thread(rnti);
|
||||
|
@ -1200,11 +1200,12 @@ void rrc::ue::handle_rrc_con_setup_complete(rrc_conn_setup_complete_s* msg, srsl
|
|||
// Acknowledge Dedicated Configuration
|
||||
parent->mac->phy_config_enabled(rnti, true);
|
||||
|
||||
asn1::s1ap::rrc_establishment_cause_e s1ap_cause;
|
||||
s1ap_cause.value = (asn1::s1ap::rrc_establishment_cause_opts::options)establishment_cause.value;
|
||||
if (has_tmsi) {
|
||||
parent->s1ap->initial_ue(
|
||||
rnti, (LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM)establishment_cause.value, std::move(pdu), m_tmsi, mmec);
|
||||
parent->s1ap->initial_ue(rnti, s1ap_cause, std::move(pdu), m_tmsi, mmec);
|
||||
} else {
|
||||
parent->s1ap->initial_ue(rnti, (LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM)establishment_cause.value, std::move(pdu));
|
||||
parent->s1ap->initial_ue(rnti, s1ap_cause, std::move(pdu));
|
||||
}
|
||||
state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE;
|
||||
}
|
||||
|
@ -1380,49 +1381,36 @@ bool rrc::ue::release_erabs()
|
|||
|
||||
void rrc::ue::notify_s1ap_ue_ctxt_setup_complete()
|
||||
{
|
||||
LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT res;
|
||||
res.ext = false;
|
||||
res.E_RABFailedToSetupListCtxtSURes_present = false;
|
||||
res.CriticalityDiagnostics_present = false;
|
||||
|
||||
res.E_RABSetupListCtxtSURes.len = 0;
|
||||
res.E_RABFailedToSetupListCtxtSURes.len = 0;
|
||||
asn1::s1ap::init_context_setup_resp_s res;
|
||||
|
||||
res.protocol_ies.e_rab_setup_list_ctxt_su_res.value.resize(erabs.size());
|
||||
uint32_t i = 0;
|
||||
for (auto& erab : erabs) {
|
||||
uint32_t j = res.E_RABSetupListCtxtSURes.len++;
|
||||
res.E_RABSetupListCtxtSURes.buffer[j].ext = false;
|
||||
res.E_RABSetupListCtxtSURes.buffer[j].iE_Extensions_present = false;
|
||||
res.E_RABSetupListCtxtSURes.buffer[j].e_RAB_ID.ext = false;
|
||||
res.E_RABSetupListCtxtSURes.buffer[j].e_RAB_ID.E_RAB_ID = erab.second.id;
|
||||
uint32_to_uint8(erab.second.teid_in, res.E_RABSetupListCtxtSURes.buffer[j].gTP_TEID.buffer);
|
||||
res.protocol_ies.e_rab_setup_list_ctxt_su_res.value[i].load_info_obj(ASN1_S1AP_ID_E_RAB_SETUP_ITEM_CTXT_SU_RES);
|
||||
auto& item = res.protocol_ies.e_rab_setup_list_ctxt_su_res.value[i].value.e_rab_setup_item_ctxt_su_res();
|
||||
item.e_rab_id = erab.second.id;
|
||||
uint32_to_uint8(erab.second.teid_in, item.gtp_teid.data());
|
||||
i++;
|
||||
}
|
||||
|
||||
parent->s1ap->ue_ctxt_setup_complete(rnti, &res);
|
||||
parent->s1ap->ue_ctxt_setup_complete(rnti, res);
|
||||
}
|
||||
|
||||
void rrc::ue::notify_s1ap_ue_erab_setup_response(LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT* e)
|
||||
{
|
||||
LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT res;
|
||||
res.ext = false;
|
||||
res.E_RABSetupListBearerSURes.len = 0;
|
||||
res.E_RABFailedToSetupListBearerSURes.len = 0;
|
||||
asn1::s1ap::e_rab_setup_resp_s res;
|
||||
|
||||
res.CriticalityDiagnostics_present = false;
|
||||
res.E_RABFailedToSetupListBearerSURes_present = false;
|
||||
|
||||
for (uint32_t i = 0; i < e->len; i++) {
|
||||
res.E_RABSetupListBearerSURes_present = true;
|
||||
LIBLTE_S1AP_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT* erab = &e->buffer[i];
|
||||
uint8_t id = erab->e_RAB_ID.E_RAB_ID;
|
||||
uint32_t j = res.E_RABSetupListBearerSURes.len++;
|
||||
res.E_RABSetupListBearerSURes.buffer[j].ext = false;
|
||||
res.E_RABSetupListBearerSURes.buffer[j].iE_Extensions_present = false;
|
||||
res.E_RABSetupListBearerSURes.buffer[j].e_RAB_ID.ext = false;
|
||||
res.E_RABSetupListBearerSURes.buffer[j].e_RAB_ID.E_RAB_ID = id;
|
||||
uint32_to_uint8(erabs[id].teid_in, res.E_RABSetupListBearerSURes.buffer[j].gTP_TEID.buffer);
|
||||
res.protocol_ies.e_rab_setup_list_bearer_su_res.value.resize(e->len);
|
||||
for (uint32_t i = 0; i < e->len; ++i) {
|
||||
res.protocol_ies.e_rab_setup_list_bearer_su_res_present = true;
|
||||
auto& item = res.protocol_ies.e_rab_setup_list_bearer_su_res.value[i];
|
||||
item.load_info_obj(ASN1_S1AP_ID_E_RAB_SETUP_ITEM_BEARER_SU_RES);
|
||||
uint8_t id = e->buffer[i].e_RAB_ID.E_RAB_ID;
|
||||
item.value.e_rab_setup_item_bearer_su_res().e_rab_id = id;
|
||||
uint32_to_uint8(erabs[id].teid_in, &item.value.e_rab_setup_item_bearer_su_res().gtp_teid[0]);
|
||||
}
|
||||
|
||||
parent->s1ap->ue_erab_setup_complete(rnti, &res);
|
||||
parent->s1ap->ue_erab_setup_complete(rnti, res);
|
||||
}
|
||||
|
||||
void rrc::ue::send_connection_reest_rej()
|
||||
|
|
|
@ -40,6 +40,8 @@ using srslte::uint32_to_uint8;
|
|||
#define procWarning(fmt, ...) s1ap_ptr->s1ap_log->warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
|
||||
#define procInfo(fmt, ...) s1ap_ptr->s1ap_log->info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
|
||||
|
||||
using namespace asn1::s1ap;
|
||||
|
||||
namespace srsenb {
|
||||
|
||||
/*********************************************************
|
||||
|
@ -319,17 +321,17 @@ void s1ap::build_tai_cgi()
|
|||
/*******************************************************************************
|
||||
/* RRC interface
|
||||
********************************************************************************/
|
||||
void s1ap::initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::unique_byte_buffer_t pdu)
|
||||
void s1ap::initial_ue(uint16_t rnti, asn1::s1ap::rrc_establishment_cause_e cause, srslte::unique_byte_buffer_t pdu)
|
||||
{
|
||||
users.insert(std::make_pair(rnti, std::unique_ptr<ue>(new ue{rnti, this})));
|
||||
send_initialuemessage(rnti, cause, std::move(pdu), false);
|
||||
}
|
||||
|
||||
void s1ap::initial_ue(uint16_t rnti,
|
||||
LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause,
|
||||
srslte::unique_byte_buffer_t pdu,
|
||||
uint32_t m_tmsi,
|
||||
uint8_t mmec)
|
||||
void s1ap::initial_ue(uint16_t rnti,
|
||||
asn1::s1ap::rrc_establishment_cause_e cause,
|
||||
srslte::unique_byte_buffer_t pdu,
|
||||
uint32_t m_tmsi,
|
||||
uint8_t mmec)
|
||||
{
|
||||
users.insert(std::make_pair(rnti, std::unique_ptr<ue>(new ue{rnti, this})));
|
||||
send_initialuemessage(rnti, cause, std::move(pdu), true, m_tmsi, mmec);
|
||||
|
@ -344,7 +346,7 @@ void s1ap::write_pdu(uint16_t rnti, srslte::unique_byte_buffer_t pdu)
|
|||
}
|
||||
}
|
||||
|
||||
bool s1ap::user_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio)
|
||||
bool s1ap::user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_radio)
|
||||
{
|
||||
s1ap_log->info("User inactivity - RNTI:0x%x\n", rnti);
|
||||
|
||||
|
@ -360,14 +362,11 @@ bool s1ap::user_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_
|
|||
return false;
|
||||
}
|
||||
|
||||
LIBLTE_S1AP_CAUSE_STRUCT cause;
|
||||
cause.ext = false;
|
||||
cause.choice_type = LIBLTE_S1AP_CAUSE_CHOICE_RADIONETWORK;
|
||||
cause.choice.radioNetwork.ext = false;
|
||||
cause.choice.radioNetwork.e = cause_radio;
|
||||
cause_c cause;
|
||||
cause.set_radio_network().value = cause_radio.value;
|
||||
|
||||
ctxt->release_requested = true;
|
||||
return send_uectxtreleaserequest(rnti, &cause);
|
||||
return send_uectxtreleaserequest(rnti, cause);
|
||||
}
|
||||
|
||||
bool s1ap::user_exists(uint16_t rnti)
|
||||
|
@ -375,16 +374,16 @@ bool s1ap::user_exists(uint16_t rnti)
|
|||
return users.end() != users.find(rnti);
|
||||
}
|
||||
|
||||
void s1ap::ue_ctxt_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT* res)
|
||||
void s1ap::ue_ctxt_setup_complete(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res)
|
||||
{
|
||||
if (res->E_RABSetupListCtxtSURes.len > 0) {
|
||||
if (res.protocol_ies.e_rab_setup_list_ctxt_su_res.value.size() > 0) {
|
||||
send_initial_ctxt_setup_response(rnti, res);
|
||||
} else {
|
||||
send_initial_ctxt_setup_failure(rnti);
|
||||
}
|
||||
}
|
||||
|
||||
void s1ap::ue_erab_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT* res)
|
||||
void s1ap::ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::e_rab_setup_resp_s& res)
|
||||
{
|
||||
send_erab_setup_response(rnti, res);
|
||||
}
|
||||
|
@ -670,15 +669,12 @@ bool s1ap::handle_initialctxtsetuprequest(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETU
|
|||
if (msg->CSFallbackIndicator.e == LIBLTE_S1AP_CSFALLBACKINDICATOR_CS_FALLBACK_REQUIRED ||
|
||||
msg->CSFallbackIndicator.e == LIBLTE_S1AP_CSFALLBACKINDICATOR_CS_FALLBACK_HIGH_PRIORITY) {
|
||||
// Send RRC Release (cs-fallback-triggered) to MME
|
||||
LIBLTE_S1AP_CAUSE_STRUCT cause;
|
||||
cause.ext = false;
|
||||
cause.choice_type = LIBLTE_S1AP_CAUSE_CHOICE_RADIONETWORK;
|
||||
cause.choice.radioNetwork.ext = false;
|
||||
cause.choice.radioNetwork.e = LIBLTE_S1AP_CAUSERADIONETWORK_CS_FALLBACK_TRIGGERED;
|
||||
cause_c cause;
|
||||
cause.set_radio_network().value = cause_radio_network_opts::cs_fallback_triggered;
|
||||
|
||||
/* TODO: This should normally probably only be sent after the SecurityMode procedure has completed! */
|
||||
ctxt->release_requested = true;
|
||||
send_uectxtreleaserequest(rnti, &cause);
|
||||
send_uectxtreleaserequest(rnti, cause);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -736,12 +732,9 @@ bool s1ap::handle_uecontextmodifyrequest(LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATI
|
|||
}
|
||||
|
||||
if (!rrc->modify_ue_ctxt(rnti, msg)) {
|
||||
LIBLTE_S1AP_CAUSE_STRUCT cause;
|
||||
cause.ext = false;
|
||||
cause.choice_type = LIBLTE_S1AP_CAUSE_CHOICE_MISC;
|
||||
cause.choice.misc.ext = false;
|
||||
cause.choice.misc.e = LIBLTE_S1AP_CAUSEMISC_UNSPECIFIED;
|
||||
send_uectxmodifyfailure(rnti, &cause);
|
||||
cause_c cause;
|
||||
cause.set_misc().value = cause_misc_opts::unspecified;
|
||||
send_uectxmodifyfailure(rnti, cause);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -753,14 +746,11 @@ bool s1ap::handle_uecontextmodifyrequest(LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATI
|
|||
if (msg->CSFallbackIndicator.e == LIBLTE_S1AP_CSFALLBACKINDICATOR_CS_FALLBACK_REQUIRED ||
|
||||
msg->CSFallbackIndicator.e == LIBLTE_S1AP_CSFALLBACKINDICATOR_CS_FALLBACK_HIGH_PRIORITY) {
|
||||
// Send RRC Release (cs-fallback-triggered) to MME
|
||||
LIBLTE_S1AP_CAUSE_STRUCT cause;
|
||||
cause.ext = false;
|
||||
cause.choice_type = LIBLTE_S1AP_CAUSE_CHOICE_RADIONETWORK;
|
||||
cause.choice.radioNetwork.ext = false;
|
||||
cause.choice.radioNetwork.e = LIBLTE_S1AP_CAUSERADIONETWORK_CS_FALLBACK_TRIGGERED;
|
||||
cause_c cause;
|
||||
cause.set_radio_network().value = cause_radio_network_opts::cs_fallback_triggered;
|
||||
|
||||
ctxt->release_requested = true;
|
||||
send_uectxtreleaserequest(rnti, &cause);
|
||||
send_uectxtreleaserequest(rnti, cause);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -851,70 +841,54 @@ bool s1ap::handle_s1hocommand(LIBLTE_S1AP_MESSAGE_HANDOVERCOMMAND_STRUCT& msg)
|
|||
/* S1AP message senders
|
||||
********************************************************************************/
|
||||
|
||||
bool s1ap::send_initialuemessage(uint16_t rnti,
|
||||
LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause,
|
||||
srslte::unique_byte_buffer_t pdu,
|
||||
bool has_tmsi,
|
||||
uint32_t m_tmsi,
|
||||
uint8_t mmec)
|
||||
bool s1ap::send_initialuemessage(uint16_t rnti,
|
||||
asn1::s1ap::rrc_establishment_cause_e cause,
|
||||
srslte::unique_byte_buffer_t pdu,
|
||||
bool has_tmsi,
|
||||
uint32_t m_tmsi,
|
||||
uint8_t mmec)
|
||||
{
|
||||
if (!mme_connected) {
|
||||
return false;
|
||||
}
|
||||
srslte::byte_buffer_t msg;
|
||||
|
||||
LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu;
|
||||
tx_pdu.ext = false;
|
||||
tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE;
|
||||
|
||||
LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT* init = &tx_pdu.choice.initiatingMessage;
|
||||
init->procedureCode = LIBLTE_S1AP_PROC_ID_INITIALUEMESSAGE;
|
||||
init->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_INITIALUEMESSAGE;
|
||||
|
||||
LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT* initue = &init->choice.InitialUEMessage;
|
||||
initue->ext = false;
|
||||
initue->CellAccessMode_present = false;
|
||||
initue->CSG_Id_present = false;
|
||||
initue->GUMMEIType_present = false;
|
||||
initue->GUMMEI_ID_present = false;
|
||||
initue->GW_TransportLayerAddress_present = false;
|
||||
initue->LHN_ID_present = false;
|
||||
initue->RelayNode_Indicator_present = false;
|
||||
initue->SIPTO_L_GW_TransportLayerAddress_present = false;
|
||||
initue->S_TMSI_present = false;
|
||||
initue->Tunnel_Information_for_BBF_present = false;
|
||||
s1ap_pdu_c tx_pdu;
|
||||
tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_INIT_UE_MSG);
|
||||
init_ue_msg_ies_container& container = tx_pdu.init_msg().value.init_ue_msg().protocol_ies;
|
||||
|
||||
// S_TMSI
|
||||
if (has_tmsi) {
|
||||
initue->S_TMSI_present = true;
|
||||
initue->S_TMSI.ext = false;
|
||||
initue->S_TMSI.iE_Extensions_present = false;
|
||||
|
||||
uint32_to_uint8(m_tmsi, initue->S_TMSI.m_TMSI.buffer);
|
||||
initue->S_TMSI.mMEC.buffer[0] = mmec;
|
||||
container.s_tmsi_present = true;
|
||||
uint32_to_uint8(m_tmsi, container.s_tmsi.value.m_tmsi.data());
|
||||
container.s_tmsi.value.mmec[0] = mmec;
|
||||
}
|
||||
|
||||
// ENB_UE_S1AP_ID
|
||||
initue->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = get_user_ctxt(rnti)->eNB_UE_S1AP_ID;
|
||||
container.enb_ue_s1ap_id.value = get_user_ctxt(rnti)->eNB_UE_S1AP_ID;
|
||||
|
||||
// NAS_PDU
|
||||
memcpy(initue->NAS_PDU.buffer, pdu->msg, pdu->N_bytes);
|
||||
initue->NAS_PDU.n_octets = pdu->N_bytes;
|
||||
container.nas_pdu.value.resize(pdu->N_bytes);
|
||||
memcpy(container.nas_pdu.value.data(), pdu->msg, pdu->N_bytes);
|
||||
|
||||
// TAI
|
||||
memcpy(&initue->TAI, &tai, sizeof(LIBLTE_S1AP_TAI_STRUCT));
|
||||
container.tai.value.ie_exts_present = tai.iE_Extensions_present;
|
||||
container.tai.value.ext = tai.ext;
|
||||
memcpy(container.tai.value.tac.data(), tai.tAC.buffer, 2);
|
||||
memcpy(container.tai.value.plm_nid.data(), tai.pLMNidentity.buffer, 3);
|
||||
|
||||
// EUTRAN_CGI
|
||||
memcpy(&initue->EUTRAN_CGI, &eutran_cgi, sizeof(LIBLTE_S1AP_EUTRAN_CGI_STRUCT));
|
||||
container.eutran_cgi.value.ext = eutran_cgi.ext;
|
||||
container.eutran_cgi.value.ie_exts_present = eutran_cgi.iE_Extensions_present;
|
||||
memcpy(container.eutran_cgi.value.plm_nid.data(), eutran_cgi.pLMNidentity.buffer, 3);
|
||||
for (uint32_t i = 0; i < 28; ++i) {
|
||||
container.eutran_cgi.value.cell_id.set(i, (bool)eutran_cgi.cell_ID.buffer[i]);
|
||||
}
|
||||
|
||||
// RRC Establishment Cause
|
||||
initue->RRC_Establishment_Cause.ext = false;
|
||||
initue->RRC_Establishment_Cause.e = cause;
|
||||
container.rrc_establishment_cause.value = cause;
|
||||
|
||||
liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT*)&msg);
|
||||
s1ap_log->info_hex(msg.msg, msg.N_bytes, "Sending InitialUEMessage for RNTI:0x%x", rnti);
|
||||
|
||||
return sctp_send_s1ap_pdu(&tx_pdu, rnti, "InitialUEMessage");
|
||||
return sctp_send_s1ap_pdu(tx_pdu, rnti, "InitialUEMessage");
|
||||
}
|
||||
|
||||
bool s1ap::send_ulnastransport(uint16_t rnti, srslte::unique_byte_buffer_t pdu)
|
||||
|
@ -959,37 +933,26 @@ bool s1ap::send_ulnastransport(uint16_t rnti, srslte::unique_byte_buffer_t pdu)
|
|||
return sctp_send_s1ap_pdu(&tx_pdu, rnti, "UplinkNASTransport");
|
||||
}
|
||||
|
||||
bool s1ap::send_uectxtreleaserequest(uint16_t rnti, LIBLTE_S1AP_CAUSE_STRUCT* cause)
|
||||
bool s1ap::send_uectxtreleaserequest(uint16_t rnti, const cause_c& cause)
|
||||
{
|
||||
if (!mme_connected) {
|
||||
return false;
|
||||
}
|
||||
srslte::byte_buffer_t msg;
|
||||
|
||||
LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu;
|
||||
tx_pdu.ext = false;
|
||||
tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE;
|
||||
|
||||
LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT* init = &tx_pdu.choice.initiatingMessage;
|
||||
init->procedureCode = LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASEREQUEST;
|
||||
init->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTRELEASEREQUEST;
|
||||
|
||||
LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT* req = &init->choice.UEContextReleaseRequest;
|
||||
req->ext = false;
|
||||
req->GWContextReleaseIndication_present = false;
|
||||
s1ap_pdu_c tx_pdu;
|
||||
tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_UE_CONTEXT_RELEASE_REQUEST);
|
||||
ue_context_release_request_ies_container& container =
|
||||
tx_pdu.init_msg().value.ue_context_release_request().protocol_ies;
|
||||
|
||||
// MME_UE_S1AP_ID
|
||||
req->MME_UE_S1AP_ID.MME_UE_S1AP_ID = get_user_ctxt(rnti)->MME_UE_S1AP_ID;
|
||||
container.mme_ue_s1ap_id.value = get_user_ctxt(rnti)->MME_UE_S1AP_ID;
|
||||
// ENB_UE_S1AP_ID
|
||||
req->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = get_user_ctxt(rnti)->eNB_UE_S1AP_ID;
|
||||
container.enb_ue_s1ap_id.value = get_user_ctxt(rnti)->eNB_UE_S1AP_ID;
|
||||
|
||||
// Cause
|
||||
memcpy(&req->Cause, cause, sizeof(LIBLTE_S1AP_CAUSE_STRUCT));
|
||||
container.cause.value = cause;
|
||||
|
||||
liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT*)&msg);
|
||||
s1ap_log->info_hex(msg.msg, msg.N_bytes, "Sending UEContextReleaseRequest for RNTI:0x%x", rnti);
|
||||
|
||||
return sctp_send_s1ap_pdu(&tx_pdu, rnti, "UEContextReleaseRequest");
|
||||
return sctp_send_s1ap_pdu(tx_pdu, rnti, "UEContextReleaseRequest");
|
||||
}
|
||||
|
||||
bool s1ap::send_uectxtreleasecomplete(uint16_t rnti, uint32_t mme_ue_id, uint32_t enb_ue_id)
|
||||
|
@ -997,105 +960,73 @@ bool s1ap::send_uectxtreleasecomplete(uint16_t rnti, uint32_t mme_ue_id, uint32_
|
|||
if (!mme_connected) {
|
||||
return false;
|
||||
}
|
||||
srslte::byte_buffer_t msg;
|
||||
|
||||
LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu;
|
||||
tx_pdu.ext = false;
|
||||
tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_SUCCESSFULOUTCOME;
|
||||
s1ap_pdu_c tx_pdu;
|
||||
tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_UE_CONTEXT_RELEASE);
|
||||
auto& container = tx_pdu.successful_outcome().value.ue_context_mod_request().protocol_ies;
|
||||
container.enb_ue_s1ap_id.value = enb_ue_id;
|
||||
container.mme_ue_s1ap_id.value = mme_ue_id;
|
||||
|
||||
LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT* succ = &tx_pdu.choice.successfulOutcome;
|
||||
succ->procedureCode = LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASE;
|
||||
succ->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UECONTEXTRELEASECOMPLETE;
|
||||
|
||||
LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMPLETE_STRUCT* comp = &succ->choice.UEContextReleaseComplete;
|
||||
comp->ext = false;
|
||||
comp->CriticalityDiagnostics_present = false;
|
||||
comp->UserLocationInformation_present = false;
|
||||
|
||||
comp->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = enb_ue_id;
|
||||
comp->MME_UE_S1AP_ID.MME_UE_S1AP_ID = mme_ue_id;
|
||||
|
||||
return sctp_send_s1ap_pdu(&tx_pdu, rnti, "UEContextReleaseComplete");
|
||||
return sctp_send_s1ap_pdu(tx_pdu, rnti, "UEContextReleaseComplete");
|
||||
}
|
||||
|
||||
bool s1ap::send_initial_ctxt_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT* res_)
|
||||
bool s1ap::send_initial_ctxt_setup_response(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res_)
|
||||
{
|
||||
if (!mme_connected) {
|
||||
return false;
|
||||
}
|
||||
srslte::unique_byte_buffer_t buf = srslte::allocate_unique_buffer(*pool);
|
||||
if (!buf) {
|
||||
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_response().\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu;
|
||||
|
||||
tx_pdu.ext = false;
|
||||
tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_SUCCESSFULOUTCOME;
|
||||
|
||||
LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT* succ = &tx_pdu.choice.successfulOutcome;
|
||||
succ->procedureCode = LIBLTE_S1AP_PROC_ID_INITIALCONTEXTSETUP;
|
||||
succ->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_INITIALCONTEXTSETUPRESPONSE;
|
||||
s1ap_pdu_c tx_pdu;
|
||||
tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_INIT_CONTEXT_SETUP);
|
||||
|
||||
// Copy in the provided response message
|
||||
LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT* res = &succ->choice.InitialContextSetupResponse;
|
||||
memcpy(res, res_, sizeof(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT));
|
||||
|
||||
// Fill in the GTP bind address for all bearers
|
||||
for (uint32_t i = 0; i < res->E_RABSetupListCtxtSURes.len; i++) {
|
||||
uint8_t addr[4];
|
||||
inet_pton(AF_INET, args.gtp_bind_addr.c_str(), addr);
|
||||
liblte_unpack(addr, 4, res->E_RABSetupListCtxtSURes.buffer[i].transportLayerAddress.buffer);
|
||||
res->E_RABSetupListCtxtSURes.buffer[i].transportLayerAddress.n_bits = 32;
|
||||
res->E_RABSetupListCtxtSURes.buffer[i].transportLayerAddress.ext = false;
|
||||
}
|
||||
tx_pdu.successful_outcome().value.init_context_setup_request() = res_;
|
||||
|
||||
// Fill in the MME and eNB IDs
|
||||
res->MME_UE_S1AP_ID.MME_UE_S1AP_ID = get_user_ctxt(rnti)->MME_UE_S1AP_ID;
|
||||
res->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = get_user_ctxt(rnti)->eNB_UE_S1AP_ID;
|
||||
auto& container = tx_pdu.successful_outcome().value.init_context_setup_request().protocol_ies;
|
||||
container.mme_ue_s1ap_id.value = get_user_ctxt(rnti)->MME_UE_S1AP_ID;
|
||||
container.enb_ue_s1ap_id.value = get_user_ctxt(rnti)->eNB_UE_S1AP_ID;
|
||||
|
||||
return sctp_send_s1ap_pdu(&tx_pdu, rnti, "InitialContextSetupResponse");
|
||||
// Fill in the GTP bind address for all bearers
|
||||
for (uint32_t i = 0; i < container.e_rab_setup_list_ctxt_su_res.value.size(); ++i) {
|
||||
auto& item = container.e_rab_setup_list_ctxt_su_res.value[i].value.e_rab_setup_item_ctxt_su_res();
|
||||
item.transport_layer_address.resize(32);
|
||||
uint8_t addr[4];
|
||||
inet_pton(AF_INET, args.gtp_bind_addr.c_str(), addr);
|
||||
liblte_unpack(addr, 4, item.transport_layer_address.data());
|
||||
}
|
||||
|
||||
return sctp_send_s1ap_pdu(tx_pdu, rnti, "InitialContextSetupResponse");
|
||||
}
|
||||
|
||||
bool s1ap::send_erab_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT* res_)
|
||||
bool s1ap::send_erab_setup_response(uint16_t rnti, const e_rab_setup_resp_s& res_)
|
||||
{
|
||||
if (!mme_connected) {
|
||||
return false;
|
||||
}
|
||||
srslte::unique_byte_buffer_t buf = srslte::allocate_unique_buffer(*pool);
|
||||
if (!buf) {
|
||||
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_erab_setup_response().\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu;
|
||||
asn1::s1ap::s1ap_pdu_c tx_pdu;
|
||||
tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_E_RAB_SETUP);
|
||||
e_rab_setup_resp_s& res = tx_pdu.successful_outcome().value.e_rab_setup_request();
|
||||
|
||||
tx_pdu.ext = false;
|
||||
tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_SUCCESSFULOUTCOME;
|
||||
|
||||
LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT* succ = &tx_pdu.choice.successfulOutcome;
|
||||
succ->procedureCode = LIBLTE_S1AP_PROC_ID_E_RABSETUP;
|
||||
succ->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_E_RABSETUPRESPONSE;
|
||||
|
||||
// Copy in the provided response message
|
||||
LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT* res = &succ->choice.E_RABSetupResponse;
|
||||
memcpy(res, res_, sizeof(LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT));
|
||||
res = res_;
|
||||
|
||||
// Fill in the GTP bind address for all bearers
|
||||
for (uint32_t i = 0; i < res->E_RABSetupListBearerSURes.len; i++) {
|
||||
uint8_t addr[4];
|
||||
inet_pton(AF_INET, args.gtp_bind_addr.c_str(), addr);
|
||||
liblte_unpack(addr, 4, res->E_RABSetupListBearerSURes.buffer[i].transportLayerAddress.buffer);
|
||||
res->E_RABSetupListBearerSURes.buffer[i].transportLayerAddress.n_bits = 32;
|
||||
res->E_RABSetupListBearerSURes.buffer[i].transportLayerAddress.ext = false;
|
||||
if (res.protocol_ies.e_rab_setup_list_bearer_su_res_present) {
|
||||
for (uint32_t i = 0; i < res.protocol_ies.e_rab_setup_list_bearer_su_res.value.size(); ++i) {
|
||||
auto& item = res.protocol_ies.e_rab_setup_list_bearer_su_res.value[i].value.e_rab_setup_item_bearer_su_res();
|
||||
item.transport_layer_address.resize(32);
|
||||
uint8_t addr[4];
|
||||
inet_pton(AF_INET, args.gtp_bind_addr.c_str(), addr);
|
||||
liblte_unpack(addr, 4, item.transport_layer_address.data());
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the MME and eNB IDs
|
||||
res->MME_UE_S1AP_ID.MME_UE_S1AP_ID = get_user_ctxt(rnti)->MME_UE_S1AP_ID;
|
||||
res->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = get_user_ctxt(rnti)->eNB_UE_S1AP_ID;
|
||||
res.protocol_ies.mme_ue_s1ap_id.value = get_user_ctxt(rnti)->MME_UE_S1AP_ID;
|
||||
res.protocol_ies.enb_ue_s1ap_id.value = get_user_ctxt(rnti)->eNB_UE_S1AP_ID;
|
||||
|
||||
return sctp_send_s1ap_pdu(&tx_pdu, rnti, "E_RABSetupResponse");
|
||||
return sctp_send_s1ap_pdu(tx_pdu, rnti, "E_RABSetupResponse");
|
||||
}
|
||||
|
||||
bool s1ap::send_initial_ctxt_setup_failure(uint16_t rnti)
|
||||
|
@ -1164,35 +1095,21 @@ bool s1ap::send_uectxmodifyresp(uint16_t rnti)
|
|||
return sctp_send_s1ap_pdu(&tx_pdu, rnti, "ContextModificationFailure");
|
||||
}
|
||||
|
||||
bool s1ap::send_uectxmodifyfailure(uint16_t rnti, LIBLTE_S1AP_CAUSE_STRUCT* cause)
|
||||
bool s1ap::send_uectxmodifyfailure(uint16_t rnti, const cause_c& cause)
|
||||
{
|
||||
if (!mme_connected) {
|
||||
return false;
|
||||
}
|
||||
srslte::unique_byte_buffer_t buf = srslte::allocate_unique_buffer(*pool);
|
||||
if (!buf) {
|
||||
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_failure().\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu;
|
||||
tx_pdu.ext = false;
|
||||
tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_UNSUCCESSFULOUTCOME;
|
||||
s1ap_pdu_c tx_pdu;
|
||||
tx_pdu.set_unsuccessful_outcome().load_info_obj(ASN1_S1AP_ID_UE_CONTEXT_MOD);
|
||||
auto& container = tx_pdu.unsuccessful_outcome().value.ue_context_mod_request().protocol_ies;
|
||||
|
||||
LIBLTE_S1AP_UNSUCCESSFULOUTCOME_STRUCT* unsucc = &tx_pdu.choice.unsuccessfulOutcome;
|
||||
unsucc->procedureCode = LIBLTE_S1AP_PROC_ID_UECONTEXTMODIFICATION;
|
||||
unsucc->choice_type = LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_UECONTEXTMODIFICATIONFAILURE;
|
||||
container.enb_ue_s1ap_id.value = get_user_ctxt(rnti)->MME_UE_S1AP_ID;
|
||||
container.mme_ue_s1ap_id.value = get_user_ctxt(rnti)->eNB_UE_S1AP_ID;
|
||||
container.cause.value = cause;
|
||||
|
||||
LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONFAILURE_STRUCT* fail = &unsucc->choice.UEContextModificationFailure;
|
||||
fail->ext = false;
|
||||
fail->CriticalityDiagnostics_present = false;
|
||||
|
||||
fail->MME_UE_S1AP_ID.MME_UE_S1AP_ID = get_user_ctxt(rnti)->MME_UE_S1AP_ID;
|
||||
fail->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = get_user_ctxt(rnti)->eNB_UE_S1AP_ID;
|
||||
|
||||
memcpy(&fail->Cause, cause, sizeof(LIBLTE_S1AP_CAUSE_STRUCT));
|
||||
|
||||
return sctp_send_s1ap_pdu(&tx_pdu, rnti, "UEContextModificationFailure");
|
||||
return sctp_send_s1ap_pdu(tx_pdu, rnti, "UEContextModificationFailure");
|
||||
}
|
||||
|
||||
/*********************
|
||||
|
@ -1270,6 +1187,45 @@ bool s1ap::send_enb_status_transfer_proc(uint16_t rnti, std::vector<bearer_statu
|
|||
/* General helpers
|
||||
********************************************************************************/
|
||||
|
||||
bool s1ap::sctp_send_s1ap_pdu(const asn1::s1ap::s1ap_pdu_c& tx_pdu, uint32_t rnti, const char* procedure_name)
|
||||
{
|
||||
srslte::unique_byte_buffer_t buf = srslte::allocate_unique_buffer(*pool, false);
|
||||
if (buf == nullptr) {
|
||||
s1ap_log->error("Fatal Error: Couldn't allocate buffer for %s.\n", procedure_name);
|
||||
return false;
|
||||
}
|
||||
asn1::bit_ref bref(buf->msg, buf->get_tailroom());
|
||||
|
||||
tx_pdu.pack(bref);
|
||||
buf->N_bytes = bref.distance_bytes();
|
||||
if (rnti > 0) {
|
||||
s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending %s for rnti=0x%x", procedure_name, rnti);
|
||||
} else {
|
||||
s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending %s to MME", procedure_name);
|
||||
}
|
||||
uint16_t streamid = rnti == 0 ? NONUE_STREAM_ID : get_user_ctxt(rnti)->stream_id;
|
||||
|
||||
ssize_t n_sent = sctp_sendmsg(s1ap_socket.fd(),
|
||||
buf->msg,
|
||||
buf->N_bytes,
|
||||
(struct sockaddr*)&mme_addr,
|
||||
sizeof(struct sockaddr_in),
|
||||
htonl(PPID),
|
||||
0,
|
||||
streamid,
|
||||
0,
|
||||
0);
|
||||
if (n_sent == -1) {
|
||||
if (rnti > 0) {
|
||||
s1ap_log->error("Failed to send %s for rnti=0x%x\n", procedure_name, rnti);
|
||||
} else {
|
||||
s1ap_log->error("Failed to send %s\n", procedure_name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool s1ap::sctp_send_s1ap_pdu(LIBLTE_S1AP_S1AP_PDU_STRUCT* tx_pdu, uint32_t rnti, const char* procedure_name)
|
||||
{
|
||||
srslte::unique_byte_buffer_t buf = srslte::allocate_unique_buffer(*pool, false);
|
||||
|
|
|
@ -83,23 +83,22 @@ public:
|
|||
class s1ap_dummy : public s1ap_interface_rrc
|
||||
{
|
||||
public:
|
||||
void
|
||||
initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::unique_byte_buffer_t pdu) override
|
||||
void 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,
|
||||
LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause,
|
||||
srslte::unique_byte_buffer_t pdu,
|
||||
uint32_t m_tmsi,
|
||||
uint8_t mmec) override
|
||||
void initial_ue(uint16_t rnti,
|
||||
asn1::s1ap::rrc_establishment_cause_e cause,
|
||||
srslte::unique_byte_buffer_t pdu,
|
||||
uint32_t m_tmsi,
|
||||
uint8_t mmec) override
|
||||
{
|
||||
}
|
||||
|
||||
void write_pdu(uint16_t rnti, srslte::unique_byte_buffer_t pdu) override {}
|
||||
bool user_exists(uint16_t rnti) override { return true; }
|
||||
bool user_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio) override { return true; }
|
||||
void ue_ctxt_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT* res) override {}
|
||||
void ue_erab_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT* res) override {}
|
||||
bool user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_radio) override { return true; }
|
||||
void ue_ctxt_setup_complete(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res) override {}
|
||||
void ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::e_rab_setup_resp_s& res) override {}
|
||||
bool is_mme_connected() override { return true; }
|
||||
bool send_ho_required(uint16_t rnti,
|
||||
uint32_t target_eci,
|
||||
|
|
|
@ -23,10 +23,10 @@ add_executable(plmn_test plmn_test.cc)
|
|||
target_link_libraries(plmn_test rrc_asn1)
|
||||
|
||||
add_executable(rrc_mobility_test rrc_mobility_test.cc)
|
||||
target_link_libraries(rrc_mobility_test srsenb_rrc rrc_asn1 srslte_common srslte_asn1 enb_cfg_parser ${LIBCONFIGPP_LIBRARIES})
|
||||
target_link_libraries(rrc_mobility_test srsenb_rrc rrc_asn1 s1ap_asn1 srslte_common srslte_asn1 enb_cfg_parser ${LIBCONFIGPP_LIBRARIES})
|
||||
|
||||
add_executable(erab_setup_test erab_setup_test.cc)
|
||||
target_link_libraries(erab_setup_test srsenb_rrc rrc_asn1 srslte_common srslte_asn1 enb_cfg_parser ${LIBCONFIGPP_LIBRARIES})
|
||||
target_link_libraries(erab_setup_test srsenb_rrc rrc_asn1 s1ap_asn1 srslte_common srslte_asn1 enb_cfg_parser ${LIBCONFIGPP_LIBRARIES})
|
||||
|
||||
add_test(rrc_mobility_test rrc_mobility_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..)
|
||||
add_test(erab_setup_test erab_setup_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..)
|
||||
|
|
Loading…
Reference in New Issue