s1ap - handling of ts1 reloc overall timer.

master
Francisco 4 years ago committed by Francisco Paisana
parent faa6d01e9d
commit c5fc543516

@ -23,6 +23,8 @@ namespace srsenb {
class rrc_interface_s1ap
{
public:
using failed_erab_list = std::map<uint32_t, asn1::s1ap::cause_c>;
virtual void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) = 0;
virtual void release_ue(uint16_t rnti) = 0;
virtual bool setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_request_s& msg) = 0;
@ -46,8 +48,9 @@ public:
* @param is_success true if ho cmd was received
* @param container TargeteNB RRCConnectionReconfiguration message with MobilityControlInfo
*/
enum class ho_prep_result { success, failure, timeout };
virtual void ho_preparation_complete(uint16_t rnti,
bool is_success,
ho_prep_result result,
const asn1::s1ap::ho_cmd_s& msg,
srsran::unique_byte_buffer_t container) = 0;
virtual uint16_t

@ -34,6 +34,7 @@ struct s1ap_args_t {
class s1ap_interface_rrc
{
public:
using failed_erab_list = std::map<uint32_t, asn1::s1ap::cause_c>;
struct bearer_status_info {
uint8_t erab_id;
uint16_t pdcp_dl_sn, pdcp_ul_sn;

@ -86,24 +86,23 @@ public:
void modify_erabs(
uint16_t rnti,
srsran::const_span<const asn1::s1ap::erab_to_be_modified_item_bearer_mod_req_s*> erabs_to_modify) override;
bool modify_ue_erab(uint16_t rnti,
uint8_t erab_id,
const asn1::s1ap::erab_level_qos_params_s& qos_params,
const asn1::unbounded_octstring<true>* nas_pdu);
bool release_erabs(uint32_t rnti) override;
void release_erabs(uint32_t rnti,
srsran::const_span<uint16_t> erabs_to_release,
const asn1::unbounded_octstring<true>* nas_pdu) 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,
const asn1::s1ap::ho_cmd_s& msg,
srsran::unique_byte_buffer_t rrc_container) override;
uint16_t
start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& msg,
const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container,
bool modify_ue_erab(uint16_t rnti,
uint8_t erab_id,
const asn1::s1ap::erab_level_qos_params_s& qos_params,
const asn1::unbounded_octstring<true>* nas_pdu);
bool release_erabs(uint32_t rnti) override;
void release_erabs(uint32_t rnti,
srsran::const_span<uint16_t> erabs_to_release,
const asn1::unbounded_octstring<true>* nas_pdu) override;
void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& UEPagingID) override;
void ho_preparation_complete(uint16_t rnti,
rrc::ho_prep_result result,
const asn1::s1ap::ho_cmd_s& msg,
srsran::unique_byte_buffer_t rrc_container) override;
uint16_t start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& msg,
const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container,
asn1::s1ap::cause_c& failure_cause) override;
void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs) override;
void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs) override;
// rrc_interface_pdcp
void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) override;

@ -40,7 +40,7 @@ public:
bool fill_conn_recfg_no_ho_cmd(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg);
void handle_ue_meas_report(const asn1::rrc::meas_report_s& msg, srsran::unique_byte_buffer_t pdu);
void handle_ho_preparation_complete(bool is_success,
void handle_ho_preparation_complete(rrc::ho_prep_result result,
const asn1::s1ap::ho_cmd_s& msg,
srsran::unique_byte_buffer_t container);
bool is_ho_running() const { return not is_in_state<idle_st>(); }

@ -563,11 +563,11 @@ void rrc::read_pdu_pcch(uint8_t* payload, uint32_t buffer_size)
*******************************************************************************/
void rrc::ho_preparation_complete(uint16_t rnti,
bool is_success,
ho_prep_result result,
const asn1::s1ap::ho_cmd_s& msg,
srsran::unique_byte_buffer_t rrc_container)
{
users.at(rnti)->mobility_handler->handle_ho_preparation_complete(is_success, msg, std::move(rrc_container));
users.at(rnti)->mobility_handler->handle_ho_preparation_complete(result, msg, std::move(rrc_container));
}
void rrc::set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs)

@ -403,15 +403,21 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci,
* @param is_success flag to whether an HandoverCommand or HandoverReject was received
* @param container RRC container with HandoverCommand to send to UE
*/
void rrc::ue::rrc_mobility::handle_ho_preparation_complete(bool is_success,
void rrc::ue::rrc_mobility::handle_ho_preparation_complete(rrc::ho_prep_result result,
const asn1::s1ap::ho_cmd_s& msg,
srsran::unique_byte_buffer_t container)
{
if (not is_success) {
if (result == rrc_interface_s1ap::ho_prep_result::failure) {
logger.info("Received S1AP HandoverFailure. Aborting Handover...");
trigger(srsran::failure_ev{});
return;
}
if (result == rrc_interface_s1ap::ho_prep_result::timeout) {
asn1::s1ap::cause_c cause;
cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::ts1relocprep_expiry;
trigger(ho_cancel_ev{cause});
return;
}
// Check if any E-RAB that was not admitted. Cancel Handover, in such case.
if (msg.protocol_ies.erab_to_release_list_ho_cmd_present) {

@ -916,47 +916,10 @@ void rrc::ue::send_connection_release()
}
/*
* UE context
* UE Init Context Setup Request
*/
void rrc::ue::handle_ue_init_ctxt_setup_req(const asn1::s1ap::init_context_setup_request_s& msg)
{
if (msg.protocol_ies.add_cs_fallback_ind_present) {
parent->logger.warning("Not handling AdditionalCSFallbackIndicator");
}
if (msg.protocol_ies.csg_membership_status_present) {
parent->logger.warning("Not handling CSGMembershipStatus");
}
if (msg.protocol_ies.gummei_id_present) {
parent->logger.warning("Not handling GUMMEI_ID");
}
if (msg.protocol_ies.ho_restrict_list_present) {
parent->logger.warning("Not handling HandoverRestrictionList");
}
if (msg.protocol_ies.management_based_mdt_allowed_present) {
parent->logger.warning("Not handling ManagementBasedMDTAllowed");
}
if (msg.protocol_ies.management_based_mdtplmn_list_present) {
parent->logger.warning("Not handling ManagementBasedMDTPLMNList");
}
if (msg.protocol_ies.mme_ue_s1ap_id_minus2_present) {
parent->logger.warning("Not handling MME_UE_S1AP_ID_2");
}
if (msg.protocol_ies.registered_lai_present) {
parent->logger.warning("Not handling RegisteredLAI");
}
if (msg.protocol_ies.srvcc_operation_possible_present) {
parent->logger.warning("Not handling SRVCCOperationPossible");
}
if (msg.protocol_ies.subscriber_profile_idfor_rfp_present) {
parent->logger.warning("Not handling SubscriberProfileIDforRFP");
}
if (msg.protocol_ies.trace_activation_present) {
parent->logger.warning("Not handling TraceActivation");
}
if (msg.protocol_ies.ue_radio_cap_present) {
parent->logger.warning("Not handling UERadioCapability");
}
set_bitrates(msg.protocol_ies.ueaggregate_maximum_bitrate.value);
ue_security_cfg.set_security_capabilities(msg.protocol_ies.ue_security_cap.value);
ue_security_cfg.set_security_key(msg.protocol_ies.security_key.value);
@ -986,19 +949,6 @@ bool rrc::ue::handle_ue_ctxt_mod_req(const asn1::s1ap::ue_context_mod_request_s&
}
}
if (msg.protocol_ies.add_cs_fallback_ind_present) {
parent->logger.warning("Not handling AdditionalCSFallbackIndicator");
}
if (msg.protocol_ies.csg_membership_status_present) {
parent->logger.warning("Not handling CSGMembershipStatus");
}
if (msg.protocol_ies.registered_lai_present) {
parent->logger.warning("Not handling RegisteredLAI");
}
if (msg.protocol_ies.subscriber_profile_idfor_rfp_present) {
parent->logger.warning("Not handling SubscriberProfileIDforRFP");
}
// UEAggregateMaximumBitrate
if (msg.protocol_ies.ueaggregate_maximum_bitrate_present) {
set_bitrates(msg.protocol_ies.ueaggregate_maximum_bitrate.value);

@ -34,10 +34,21 @@ using srsran::uint32_to_uint8;
#define procWarning(fmt, ...) s1ap_ptr->logger.warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
#define procInfo(fmt, ...) s1ap_ptr->logger.info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
#define WarnUnsupportFeature(cond, featurename) \
do { \
if (cond) { \
logger.warning("Not handling feature - %s", featurename); \
} \
} while (0)
using namespace asn1::s1ap;
namespace srsenb {
/*************************
* Helper Functions
************************/
asn1::bounded_bitstring<1, 160, true, true> addr_to_asn1(const char* addr_str)
{
asn1::bounded_bitstring<1, 160, true, true> transport_layer_addr(32);
@ -108,12 +119,6 @@ srsran::proc_outcome_t s1ap::ue::ho_prep_proc_t::react(const asn1::s1ap::ho_cmd_
procWarning("Not handling HandoverCommand extensions and non-intraLTE params");
}
// Check for E-RABs that could not be admitted in the target
if (msg.protocol_ies.erab_to_release_list_ho_cmd_present) {
procWarning("Not handling E-RABtoReleaseList");
// TODO
}
// In case of intra-system Handover, Target to Source Transparent Container IE shall be encoded as
// Target eNB to Source eNB Transparent Container IE
asn1::cbit_ref bref(msg.protocol_ies.target_to_source_transparent_container.value.data(),
@ -143,9 +148,13 @@ srsran::proc_outcome_t s1ap::ue::ho_prep_proc_t::react(const asn1::s1ap::ho_cmd_
void s1ap::ue::ho_prep_proc_t::then(const srsran::proc_state_t& result)
{
if (result.is_error()) {
s1ap_ptr->rrc->ho_preparation_complete(ue_ptr->ctxt.rnti, false, *ho_cmd_msg, {});
rrc_interface_s1ap::ho_prep_result ho_prep_result = ue_ptr->ts1_reloc_prep.is_expired()
? rrc_interface_s1ap::ho_prep_result::timeout
: rrc_interface_s1ap::ho_prep_result::failure;
s1ap_ptr->rrc->ho_preparation_complete(ue_ptr->ctxt.rnti, ho_prep_result, *ho_cmd_msg, {});
} else {
s1ap_ptr->rrc->ho_preparation_complete(ue_ptr->ctxt.rnti, true, *ho_cmd_msg, std::move(rrc_container));
s1ap_ptr->rrc->ho_preparation_complete(
ue_ptr->ctxt.rnti, rrc_interface_s1ap::ho_prep_result::success, *ho_cmd_msg, std::move(rrc_container));
procInfo("Completed with success");
}
}
@ -669,9 +678,21 @@ bool s1ap::handle_dlnastransport(const dl_nas_transport_s& msg)
bool s1ap::handle_initialctxtsetuprequest(const init_context_setup_request_s& msg)
{
if (msg.ext) {
logger.warning("Not handling S1AP message extension");
}
const auto& prot_ies = msg.protocol_ies;
WarnUnsupportFeature(msg.ext, "message extension");
WarnUnsupportFeature(prot_ies.add_cs_fallback_ind_present, "AdditionalCSFallbackIndicator");
WarnUnsupportFeature(prot_ies.csg_membership_status_present, "CSGMembershipStatus");
WarnUnsupportFeature(prot_ies.gummei_id_present, "GUMMEI_ID");
WarnUnsupportFeature(prot_ies.ho_restrict_list_present, "HandoverRestrictionList");
WarnUnsupportFeature(prot_ies.management_based_mdt_allowed_present, "ManagementBasedMDTAllowed");
WarnUnsupportFeature(prot_ies.management_based_mdtplmn_list_present, "ManagementBasedMDTPLMNList");
WarnUnsupportFeature(prot_ies.mme_ue_s1ap_id_minus2_present, "MME_UE_S1AP_ID_2");
WarnUnsupportFeature(prot_ies.registered_lai_present, "RegisteredLAI");
WarnUnsupportFeature(prot_ies.srvcc_operation_possible_present, "SRVCCOperationPossible");
WarnUnsupportFeature(prot_ies.subscriber_profile_idfor_rfp_present, "SubscriberProfileIDforRFP");
WarnUnsupportFeature(prot_ies.trace_activation_present, "TraceActivation");
WarnUnsupportFeature(prot_ies.ue_radio_cap_present, "UERadioCapability");
ue* u =
handle_s1apmsg_ue_id(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value);
if (u == nullptr) {
@ -690,7 +711,6 @@ bool s1ap::handle_initialctxtsetuprequest(const init_context_setup_request_s& ms
// Send RRC Release (cs-fallback-triggered) to MME
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! */
u->send_uectxtreleaserequest(cause);
}
@ -701,9 +721,8 @@ bool s1ap::handle_initialctxtsetuprequest(const init_context_setup_request_s& ms
bool s1ap::handle_paging(const asn1::s1ap::paging_s& msg)
{
if (msg.ext) {
logger.warning("Not handling S1AP message extension");
}
WarnUnsupportFeature(msg.ext, "S1AP message extension");
uint32_t ueid = msg.protocol_ies.ue_id_idx_value.value.to_number();
rrc->add_paging_id(ueid, msg.protocol_ies.ue_paging_id.value);
return true;
@ -711,9 +730,8 @@ bool s1ap::handle_paging(const asn1::s1ap::paging_s& msg)
bool s1ap::handle_erabsetuprequest(const erab_setup_request_s& msg)
{
if (msg.ext) {
logger.warning("Not handling S1AP message extension");
}
WarnUnsupportFeature(msg.ext, "S1AP message extension");
ue* u =
handle_s1apmsg_ue_id(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value);
if (u == nullptr) {
@ -873,6 +891,12 @@ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg)
bool s1ap::handle_uecontextmodifyrequest(const ue_context_mod_request_s& msg)
{
WarnUnsupportFeature(msg.ext, "S1AP message extension");
WarnUnsupportFeature(msg.protocol_ies.add_cs_fallback_ind_present, "AdditionalCSFallbackIndicator");
WarnUnsupportFeature(msg.protocol_ies.csg_membership_status_present, "CSGMembershipStatus");
WarnUnsupportFeature(msg.protocol_ies.registered_lai_present, "RegisteredLAI");
WarnUnsupportFeature(msg.protocol_ies.subscriber_profile_idfor_rfp_present, "SubscriberProfileIDforRFP");
ue* u =
handle_s1apmsg_ue_id(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value);
if (u == nullptr) {
@ -906,9 +930,7 @@ bool s1ap::handle_uecontextmodifyrequest(const ue_context_mod_request_s& msg)
bool s1ap::handle_uectxtreleasecommand(const ue_context_release_cmd_s& msg)
{
if (msg.ext) {
logger.warning("Not handling S1AP message extension");
}
WarnUnsupportFeature(msg.ext, "S1AP message extension");
ue* u = nullptr;
if (msg.protocol_ies.ue_s1ap_ids.value.type().value == ue_s1ap_ids_c::types_opts::ue_s1ap_id_pair) {
@ -1325,6 +1347,9 @@ bool s1ap::ue::send_uectxtreleasecomplete()
container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id;
container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value();
// Stop TS1 Reloc Overall
ts1_reloc_overall.stop();
// Log event.
event_logger::get().log_s1_ctx_delete(ctxt.enb_cc_idx, ctxt.mme_ue_s1ap_id.value(), ctxt.enb_ue_s1ap_id, ctxt.rnti);
@ -1834,7 +1859,11 @@ s1ap::ue::ue(s1ap* s1ap_ptr_) : s1ap_ptr(s1ap_ptr_), ho_prep_proc(this), logger(
ts1_reloc_prep.set(ts1_reloc_prep_timeout_ms,
[this](uint32_t tid) { ho_prep_proc.trigger(ho_prep_proc_t::ts1_reloc_prep_expired{}); });
ts1_reloc_overall = s1ap_ptr->task_sched.get_unique_timer();
ts1_reloc_overall.set(ts1_reloc_overall_timeout_ms, [](uint32_t tid) { /* TODO */ });
ts1_reloc_overall.set(ts1_reloc_overall_timeout_ms, [this](uint32_t tid) {
//> If the UE Context Release procedure is not initiated towards the eNB before the expiry of the timer
// TS1RELOCOverall, the eNB shall request the MME to release the UE context.
s1ap_ptr->user_release(ctxt.rnti, asn1::s1ap::cause_radio_network_opts::ts1relocoverall_expiry);
});
}
bool s1ap::ue::send_ho_required(uint32_t target_eci,

@ -181,7 +181,7 @@ public:
{}
void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& ue_paging_id) override {}
void ho_preparation_complete(uint16_t rnti,
bool is_success,
ho_prep_result result,
const asn1::s1ap::ho_cmd_s& msg,
srsran::unique_byte_buffer_t container) override
{}

@ -231,7 +231,7 @@ int test_s1ap_mobility(srsran::log_sink_spy& spy, mobility_test_params test_para
/* Test Case: HandoverPreparation has failed */
if (test_params.fail_at == mobility_test_params::test_event::ho_prep_failure) {
tester.rrc.ho_preparation_complete(tester.rnti, false, {}, nullptr);
tester.rrc.ho_preparation_complete(tester.rnti, rrc::ho_prep_result::failure, {}, nullptr);
// TESTASSERT(spy.get_error_counter() == 1);
TESTASSERT(not s1ap.last_enb_status.status_present);
return SRSRAN_SUCCESS;
@ -244,7 +244,7 @@ int test_s1ap_mobility(srsran::log_sink_spy& spy, mobility_test_params test_para
0x86, 0x0d, 0x30, 0x00, 0x0b, 0x5a, 0x02, 0x17, 0x86, 0x00, 0x05, 0xa0, 0x20};
test_helpers::copy_msg_to_buffer(pdu, ho_cmd_rrc_container);
TESTASSERT(s1ap.last_enb_status.rnti != tester.rnti);
tester.rrc.ho_preparation_complete(tester.rnti, true, asn1::s1ap::ho_cmd_s{}, std::move(pdu));
tester.rrc.ho_preparation_complete(tester.rnti, rrc::ho_prep_result::success, asn1::s1ap::ho_cmd_s{}, std::move(pdu));
TESTASSERT(s1ap.last_enb_status.status_present);
TESTASSERT(spy.get_error_counter() == 0);
asn1::rrc::dl_dcch_msg_s ho_cmd;

Loading…
Cancel
Save