mirror of https://github.com/PentHertz/srsLTE.git
- added react method to to_state<...> transitions
- s1 handover composite state simplified - the eNB now starts a HO cancellation when it receives an invalid Handover Command - the FSM log now prints the current state when it receives an unhandled event
This commit is contained in:
parent
53f1a62c64
commit
b7ed8b1858
|
@ -246,8 +246,10 @@ struct apply_first_guard_pass<FSM, type_list<> > {
|
|||
template <typename SrcState, typename Event>
|
||||
static bool trigger(FSM* f, SrcState& s, const Event& ev)
|
||||
{
|
||||
otherfsmDebug(
|
||||
static_cast<typename FSM::derived_t*>(f), "unhandled event caught: \"%s\"\n", get_type_name<Event>().c_str());
|
||||
otherfsmDebug(static_cast<typename FSM::derived_t*>(f),
|
||||
"unhandled event caught in state \"%s\": \"%s\"\n",
|
||||
get_type_name<SrcState>().c_str(),
|
||||
get_type_name<Event>().c_str());
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
@ -348,16 +350,23 @@ public:
|
|||
bool (Derived::*GuardFn)(SrcState&, const Event&) = nullptr>
|
||||
using upd = row<SrcState, SrcState, Event, ReactFn, GuardFn>;
|
||||
|
||||
template <typename DestState, typename Event, bool (Derived::*GuardFn)(const Event&) = nullptr>
|
||||
template <typename DestState,
|
||||
typename Event,
|
||||
void (Derived::*ReactFn)(const Event&) = nullptr,
|
||||
bool (Derived::*GuardFn)(const Event&) = nullptr>
|
||||
struct to_state {
|
||||
using dest_state_t = DestState;
|
||||
using event_t = Event;
|
||||
constexpr static void (Derived::*react_fn)(const Event&) = ReactFn;
|
||||
constexpr static bool (Derived::*guard_fn)(const Event&) = GuardFn;
|
||||
|
||||
template <typename SrcState>
|
||||
static bool react(derived_view* f, SrcState& s, const event_t& ev)
|
||||
{
|
||||
if (guard_fn == nullptr or (f->*guard_fn)(ev)) {
|
||||
if (react_fn != nullptr) {
|
||||
(f->*react_fn)(ev);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -153,7 +153,7 @@ private:
|
|||
struct wait_recfg_comp {};
|
||||
struct s1_source_ho_st : public subfsm_t<s1_source_ho_st> {
|
||||
ho_meas_report_ev report;
|
||||
using ho_cmd_msg = srslte::unique_byte_buffer_t;
|
||||
using ho_cmd_msg = asn1::rrc::ho_cmd_r8_ies_s;
|
||||
|
||||
struct wait_ho_req_ack_st {
|
||||
void enter(s1_source_ho_st* f, const ho_meas_report_ev& ev);
|
||||
|
@ -165,9 +165,8 @@ private:
|
|||
explicit s1_source_ho_st(rrc_mobility* parent_) : base_t(parent_) {}
|
||||
|
||||
private:
|
||||
bool send_ho_cmd(wait_ho_req_ack_st& s, const ho_cmd_msg& container);
|
||||
void handle_ho_cancel(wait_ho_req_ack_st& s, const ho_cancel_ev& ev);
|
||||
void handle_ho_cancel(status_transfer_st& s, const ho_cancel_ev& ev);
|
||||
void send_ho_cmd(wait_ho_req_ack_st& s, const ho_cmd_msg& ho_cmd);
|
||||
void handle_ho_cancel(const ho_cancel_ev& ev);
|
||||
|
||||
protected:
|
||||
using fsm = s1_source_ho_st;
|
||||
|
@ -177,10 +176,8 @@ private:
|
|||
// Start Target Event Action Guard
|
||||
// +-------------------+------------------+---------------------+-----------------------+---------------------+
|
||||
to_state< idle_st, srslte::failure_ev >,
|
||||
row< wait_ho_req_ack_st, status_transfer_st, ho_cmd_msg, nullptr, &fsm::send_ho_cmd >,
|
||||
row< wait_ho_req_ack_st, idle_st, ho_cmd_msg >,
|
||||
row< wait_ho_req_ack_st, idle_st, ho_cancel_ev, &fsm::handle_ho_cancel >,
|
||||
row< status_transfer_st, idle_st, ho_cancel_ev, &fsm::handle_ho_cancel >
|
||||
to_state< idle_st, ho_cancel_ev, &fsm::handle_ho_cancel >,
|
||||
row< wait_ho_req_ack_st, status_transfer_st, ho_cmd_msg, &fsm::send_ho_cmd >
|
||||
// +-------------------+------------------+---------------------+-----------------------+---------------------+
|
||||
>;
|
||||
// clang-format on
|
||||
|
|
|
@ -774,7 +774,25 @@ void rrc::ue::rrc_mobility::handle_ho_preparation_complete(bool is_success, srsl
|
|||
trigger(srslte::failure_ev{});
|
||||
return;
|
||||
}
|
||||
trigger(std::move(container));
|
||||
/* unpack RRC HOCmd struct and perform sanity checks */
|
||||
asn1::rrc::ho_cmd_s rrchocmd;
|
||||
{
|
||||
asn1::cbit_ref bref(container->msg, container->N_bytes);
|
||||
if (rrchocmd.unpack(bref) != asn1::SRSASN_SUCCESS) {
|
||||
get_log()->warning("Unpacking of RRC HOCommand was unsuccessful\n");
|
||||
get_log()->warning_hex(container->msg, container->N_bytes, "Received container:\n");
|
||||
trigger(ho_cancel_ev{});
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (rrchocmd.crit_exts.type().value != c1_or_crit_ext_opts::c1 or
|
||||
rrchocmd.crit_exts.c1().type().value != ho_cmd_s::crit_exts_c_::c1_c_::types_opts::ho_cmd_r8) {
|
||||
get_log()->warning("Only handling r8 Handover Commands\n");
|
||||
trigger(ho_cancel_ev{});
|
||||
return;
|
||||
}
|
||||
|
||||
trigger(rrchocmd.crit_exts.c1().ho_cmd_r8());
|
||||
}
|
||||
|
||||
bool rrc::ue::rrc_mobility::start_s1_tenb_ho(
|
||||
|
@ -996,62 +1014,40 @@ void rrc::ue::rrc_mobility::s1_source_ho_st::wait_ho_req_ack_st::enter(s1_source
|
|||
}
|
||||
}
|
||||
|
||||
bool rrc::ue::rrc_mobility::s1_source_ho_st::send_ho_cmd(wait_ho_req_ack_st& s,
|
||||
const srslte::unique_byte_buffer_t& container)
|
||||
void rrc::ue::rrc_mobility::s1_source_ho_st::send_ho_cmd(wait_ho_req_ack_st& s, const ho_cmd_r8_ies_s& ho_cmd)
|
||||
{
|
||||
/* unpack RRC HOCmd struct and perform sanity checks */
|
||||
asn1::rrc::ho_cmd_s rrchocmd;
|
||||
{
|
||||
asn1::cbit_ref bref(container->msg, container->N_bytes);
|
||||
if (rrchocmd.unpack(bref) != asn1::SRSASN_SUCCESS) {
|
||||
get_log()->warning("Unpacking of RRC HOCommand was unsuccessful\n");
|
||||
get_log()->warning_hex(container->msg, container->N_bytes, "Received container:\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (rrchocmd.crit_exts.type().value != c1_or_crit_ext_opts::c1 or
|
||||
rrchocmd.crit_exts.c1().type().value != ho_cmd_s::crit_exts_c_::c1_c_::types_opts::ho_cmd_r8) {
|
||||
get_log()->warning("Only handling r8 Handover Commands\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* unpack DL-DCCH message containing the RRCRonnectionReconf (with MobilityInfo) to be sent to the UE */
|
||||
asn1::rrc::dl_dcch_msg_s dl_dcch_msg;
|
||||
{
|
||||
asn1::cbit_ref bref(&rrchocmd.crit_exts.c1().ho_cmd_r8().ho_cmd_msg[0],
|
||||
rrchocmd.crit_exts.c1().ho_cmd_r8().ho_cmd_msg.size());
|
||||
asn1::cbit_ref bref(&ho_cmd.ho_cmd_msg[0], ho_cmd.ho_cmd_msg.size());
|
||||
if (dl_dcch_msg.unpack(bref) != asn1::SRSASN_SUCCESS) {
|
||||
get_log()->warning("Unpacking of RRC DL-DCCH message with HO Command was unsuccessful.\n");
|
||||
return false;
|
||||
trigger(ho_cancel_ev{});
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (dl_dcch_msg.msg.type().value != dl_dcch_msg_type_c::types_opts::c1 or
|
||||
dl_dcch_msg.msg.c1().type().value != dl_dcch_msg_type_c::c1_c_::types_opts::rrc_conn_recfg) {
|
||||
get_log()->warning("HandoverCommand is expected to contain an RRC Connection Reconf message inside\n");
|
||||
return false;
|
||||
trigger(ho_cancel_ev{});
|
||||
return;
|
||||
}
|
||||
asn1::rrc::rrc_conn_recfg_s& reconf = dl_dcch_msg.msg.c1().rrc_conn_recfg();
|
||||
if (not reconf.crit_exts.c1().rrc_conn_recfg_r8().mob_ctrl_info_present) {
|
||||
get_log()->warning("HandoverCommand is expected to have mobility control subfield\n");
|
||||
return false;
|
||||
trigger(ho_cancel_ev{});
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send HO Command to UE */
|
||||
if (not parent_fsm()->rrc_ue->send_dl_dcch(&dl_dcch_msg)) {
|
||||
return false;
|
||||
trigger(ho_cancel_ev{});
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Called in Source ENB during S1-Handover when there was a Reestablishment Request
|
||||
void rrc::ue::rrc_mobility::s1_source_ho_st::handle_ho_cancel(wait_ho_req_ack_st& s, const ho_cancel_ev& ev)
|
||||
{
|
||||
parent_fsm()->rrc_enb->s1ap->send_ho_cancel(parent_fsm()->rrc_ue->rnti);
|
||||
}
|
||||
|
||||
//! Called in Source ENB during S1-Handover when there was a Reestablishment Request
|
||||
void rrc::ue::rrc_mobility::s1_source_ho_st::handle_ho_cancel(status_transfer_st& s, const ho_cancel_ev& ev)
|
||||
void rrc::ue::rrc_mobility::s1_source_ho_st::handle_ho_cancel(const ho_cancel_ev& ev)
|
||||
{
|
||||
parent_fsm()->rrc_enb->s1ap->send_ho_cancel(parent_fsm()->rrc_ue->rnti);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue