different way to retrieve a proc future

master
Francisco Paisana 5 years ago
parent 171e26ee68
commit 91d83fc20d

@ -30,7 +30,7 @@
namespace srslte { namespace srslte {
enum class proc_outcome_t { repeat, yield, success, error }; enum class proc_outcome_t { yield, success, error };
/************************************************************************************** /**************************************************************************************
* helper functions for method optional overloading * helper functions for method optional overloading
@ -184,11 +184,12 @@ class proc_future_t
public: public:
proc_future_t() = default; proc_future_t() = default;
explicit proc_future_t(const std::shared_ptr<proc_result_t<ResultType> >& p_) : ptr(p_) {} explicit proc_future_t(const std::shared_ptr<proc_result_t<ResultType> >& p_) : ptr(p_) {}
bool is_error() const { return ptr->is_error(); } bool is_error() const { return not is_empty() and ptr->is_error(); }
bool is_success() const { return ptr->is_success(); } bool is_success() const { return not is_empty() and ptr->is_success(); }
bool is_complete() const { return ptr->is_complete(); } bool is_complete() const { return not is_empty() and ptr->is_complete(); }
const ResultType* value() const { return is_success() ? ptr->value() : nullptr; } const ResultType* value() const { return is_success() ? ptr->value() : nullptr; }
bool is_valid() const { return ptr != nullptr; } bool is_empty() const { return ptr == nullptr; }
void clear() { ptr->clear(); }
private: private:
std::shared_ptr<proc_result_t<ResultType> > ptr; std::shared_ptr<proc_result_t<ResultType> > ptr;
@ -210,8 +211,6 @@ using proc_future_state_t = proc_future_t<void>;
* executes a procedure "action" based on its current internal state, * executes a procedure "action" based on its current internal state,
* and return a proc_outcome_t variable with possible values: * and return a proc_outcome_t variable with possible values:
* - yield - the procedure performed the action but hasn't completed yet. * - yield - the procedure performed the action but hasn't completed yet.
* - repeat - the same as yield, but explicitly asking that run() should
* recall step() again (probably the procedure state has changed)
* - error - the procedure has finished unsuccessfully * - error - the procedure has finished unsuccessfully
* - success - the procedure has completed successfully * - success - the procedure has completed successfully
************************************************************************************/ ************************************************************************************/
@ -223,9 +222,8 @@ public:
//! common proc::run() interface. Returns true if procedure is still running //! common proc::run() interface. Returns true if procedure is still running
bool run() bool run()
{ {
proc_outcome_t outcome = proc_outcome_t::repeat; if (is_busy()) {
while (is_busy() and outcome == proc_outcome_t::repeat) { proc_outcome_t outcome = step();
outcome = step();
handle_outcome(outcome); handle_outcome(outcome);
} }
return is_busy(); return is_busy();
@ -292,20 +290,21 @@ public:
//! method to handle external events. "T" must have the method "T::react(const Event&)" for the trigger to take effect //! method to handle external events. "T" must have the method "T::react(const Event&)" for the trigger to take effect
template <class Event> template <class Event>
void trigger(Event&& e) bool trigger(Event&& e)
{ {
if (is_busy()) { if (is_busy()) {
proc_outcome_t outcome = proc_ptr->react(std::forward<Event>(e)); proc_outcome_t outcome = proc_ptr->react(std::forward<Event>(e));
handle_outcome(outcome); handle_outcome(outcome);
if (outcome == proc_outcome_t::repeat) {
run();
}
} }
return is_busy();
} }
//! returns an object which the user can use to check if the procedure has ended. //! returns an object which the user can use to check if the procedure has ended.
proc_future_type get_future() proc_future_type get_future()
{ {
if (is_idle()) {
return proc_future_type{};
}
if (future_result == nullptr) { if (future_result == nullptr) {
future_result = std::make_shared<proc_result_type>(); future_result = std::make_shared<proc_result_type>();
} }
@ -326,16 +325,22 @@ public:
proc_state = proc_base_t::proc_status_t::on_going; proc_state = proc_base_t::proc_status_t::on_going;
proc_outcome_t init_ret = proc_ptr->init(std::forward<Args>(args)...); proc_outcome_t init_ret = proc_ptr->init(std::forward<Args>(args)...);
handle_outcome(init_ret); handle_outcome(init_ret);
switch (init_ret) { return init_ret != proc_outcome_t::error;
case proc_outcome_t::error:
return false;
case proc_outcome_t::repeat:
run(); // call run right away
break;
default:
break;
} }
return true;
//! launch a procedure, returning a future where the result is going to be saved
template <class... Args>
bool launch(proc_future_type* fut, Args&&... args)
{
if (is_busy()) {
fut->clear();
return fut;
}
proc_state = proc_base_t::proc_status_t::on_going;
*fut = get_future();
proc_outcome_t init_ret = proc_ptr->init(std::forward<Args>(args)...);
handle_outcome(init_ret);
return init_ret != proc_outcome_t::error;
} }
protected: protected:

@ -216,7 +216,7 @@ static_assert(std::is_same<typename srslte::proc_t<custom_proc, std::string>::re
int test_local_1() int test_local_1()
{ {
/* /*
* Description: Test if a procedure is cleaned automatically after is lifetime has ended * Description: Test if a procedure is cleaned automatically after its lifetime has ended
*/ */
new_test(); new_test();
printf("\n--- Test %s ---\n", __func__); printf("\n--- Test %s ---\n", __func__);
@ -297,8 +297,9 @@ int test_callback_2()
srslte::proc_t<custom_proc, int> proc; srslte::proc_t<custom_proc, int> proc;
TESTASSERT(not proc.is_busy()); TESTASSERT(not proc.is_busy());
srslte::proc_future_t<int> fut = proc.get_future(); srslte::proc_future_t<int> fut = proc.get_future();
TESTASSERT(fut.is_empty());
TESTASSERT(proc.launch(3)); TESTASSERT(proc.launch(&fut, 3));
TESTASSERT(proc.is_busy()); TESTASSERT(proc.is_busy());
callbacks.add_proc(std::move(proc)); callbacks.add_proc(std::move(proc));
TESTASSERT(callbacks.size() == 1); TESTASSERT(callbacks.size() == 1);
@ -391,8 +392,8 @@ int test_complete_callback_1()
TESTASSERT(proc.then_always(continuation_task) == 0) TESTASSERT(proc.then_always(continuation_task) == 0)
} }
srslte::proc_future_t<std::string> fut = proc.get_future(); srslte::proc_future_t<std::string> fut;
TESTASSERT(proc.launch()); TESTASSERT(proc.launch(&fut));
TESTASSERT(proc.get()->exit_val == "init") TESTASSERT(proc.get()->exit_val == "init")
while (proc.run()) { while (proc.run()) {
TESTASSERT(proc.get()->exit_val == "init") TESTASSERT(proc.get()->exit_val == "init")

@ -91,14 +91,13 @@ proc_outcome_t rrc::cell_search_proc::handle_cell_found(const phy_interface_rrc_
} }
Info("Cell has no SIB1. Obtaining SIB1...\n"); Info("Cell has no SIB1. Obtaining SIB1...\n");
si_acquire_fut = rrc_ptr->si_acquirer.get_future(); if (not rrc_ptr->si_acquirer.launch(&si_acquire_fut, 0)) {
if (not rrc_ptr->si_acquirer.launch(0)) {
// disallow concurrent si_acquire // disallow concurrent si_acquire
Error("SI Acquire is already running...\n"); Error("SI Acquire is already running...\n");
return proc_outcome_t::error; return proc_outcome_t::error;
} }
state = state_t::si_acquire; state = state_t::si_acquire;
return proc_outcome_t::repeat; return step();
} }
proc_outcome_t rrc::cell_search_proc::react(const cell_search_event_t& event) proc_outcome_t rrc::cell_search_proc::react(const cell_search_event_t& event)
@ -178,7 +177,7 @@ proc_outcome_t rrc::si_acquire_proc::init(uint32_t sib_index_)
} }
} }
return proc_outcome_t::repeat; return step();
} }
proc_outcome_t rrc::si_acquire_proc::step() proc_outcome_t rrc::si_acquire_proc::step()
@ -261,7 +260,7 @@ proc_outcome_t rrc::serving_cell_config_proc::init(const std::vector<uint32_t>&
req_idx = 0; req_idx = 0;
search_state = search_state_t::next_sib; search_state = search_state_t::next_sib;
return proc_outcome_t::repeat; return step();
} }
proc_outcome_t rrc::serving_cell_config_proc::step() proc_outcome_t rrc::serving_cell_config_proc::step()
@ -273,13 +272,12 @@ proc_outcome_t rrc::serving_cell_config_proc::step()
if (not rrc_ptr->serving_cell->has_sib(required_sib)) { if (not rrc_ptr->serving_cell->has_sib(required_sib)) {
Info("Cell has no SIB%d. Obtaining SIB%d\n", required_sib + 1, required_sib + 1); Info("Cell has no SIB%d. Obtaining SIB%d\n", required_sib + 1, required_sib + 1);
si_acquire_fut = rrc_ptr->si_acquirer.get_future(); if (not rrc_ptr->si_acquirer.launch(&si_acquire_fut, required_sib)) {
if (not rrc_ptr->si_acquirer.launch(required_sib)) {
Error("SI Acquire is already running...\n"); Error("SI Acquire is already running...\n");
return proc_outcome_t::error; return proc_outcome_t::error;
} }
search_state = search_state_t::si_acquire; search_state = search_state_t::si_acquire;
return proc_outcome_t::repeat; return step();
} else { } else {
// UE had SIB already. Handle its SIB // UE had SIB already. Handle its SIB
Info("Cell has SIB%d\n", required_sib + 1); Info("Cell has SIB%d\n", required_sib + 1);
@ -313,7 +311,7 @@ proc_outcome_t rrc::serving_cell_config_proc::step()
// continue with remaining SIBs // continue with remaining SIBs
search_state = search_state_t::next_sib; search_state = search_state_t::next_sib;
req_idx++; req_idx++;
return proc_outcome_t::repeat; return step();
} }
return proc_outcome_t::yield; return proc_outcome_t::yield;
} }
@ -342,7 +340,7 @@ proc_outcome_t rrc::cell_selection_proc::init()
neigh_index = 0; neigh_index = 0;
cs_result = cs_result_t::no_cell; cs_result = cs_result_t::no_cell;
state = search_state_t::cell_selection; state = search_state_t::cell_selection;
return proc_outcome_t::repeat; return step();
} }
proc_outcome_t rrc::cell_selection_proc::step_cell_selection() proc_outcome_t rrc::cell_selection_proc::step_cell_selection()
@ -366,7 +364,7 @@ proc_outcome_t rrc::cell_selection_proc::step_cell_selection()
if (rrc_ptr->phy->cell_select(&rrc_ptr->serving_cell->phy_cell)) { if (rrc_ptr->phy->cell_select(&rrc_ptr->serving_cell->phy_cell)) {
Info("Wait PHY to be in-synch\n"); Info("Wait PHY to be in-synch\n");
state = search_state_t::wait_in_sync; state = search_state_t::wait_in_sync;
return proc_outcome_t::repeat; return step();
} else { } else {
rrc_ptr->phy_sync_state = phy_unknown_sync; rrc_ptr->phy_sync_state = phy_unknown_sync;
Error("Could not camp on serving cell.\n"); Error("Could not camp on serving cell.\n");
@ -393,20 +391,18 @@ proc_outcome_t rrc::cell_selection_proc::step_cell_selection()
// If can not find any suitable cell, search again // If can not find any suitable cell, search again
Info("Cell selection and reselection in IDLE did not find any suitable cell. Searching again\n"); Info("Cell selection and reselection in IDLE did not find any suitable cell. Searching again\n");
cell_search_fut = rrc_ptr->cell_searcher.get_future(); if (not rrc_ptr->cell_searcher.launch(&cell_search_fut)) {
if (not rrc_ptr->cell_searcher.launch()) {
return proc_outcome_t::error; return proc_outcome_t::error;
} }
state = search_state_t::cell_search; state = search_state_t::cell_search;
return proc_outcome_t::repeat; return step();
} }
proc_outcome_t rrc::cell_selection_proc::step_wait_in_sync() proc_outcome_t rrc::cell_selection_proc::step_wait_in_sync()
{ {
if (rrc_ptr->phy_sync_state == phy_in_sync) { if (rrc_ptr->phy_sync_state == phy_in_sync) {
Info("PHY is in SYNC\n"); Info("PHY is in SYNC\n");
serv_cell_cfg_fut = rrc_ptr->serv_cell_cfg.get_future(); if (not rrc_ptr->serv_cell_cfg.launch(&serv_cell_cfg_fut, rrc_ptr->ue_required_sibs)) {
if (not rrc_ptr->serv_cell_cfg.launch(rrc_ptr->ue_required_sibs)) {
return proc_outcome_t::error; return proc_outcome_t::error;
} }
state = search_state_t::cell_config; state = search_state_t::cell_config;
@ -444,7 +440,7 @@ proc_outcome_t rrc::cell_selection_proc::step_cell_config()
// resume cell selection // resume cell selection
state = search_state_t::cell_selection; state = search_state_t::cell_selection;
++neigh_index; ++neigh_index;
return proc_outcome_t::repeat; return step();
} }
proc_outcome_t rrc::cell_selection_proc::step() proc_outcome_t rrc::cell_selection_proc::step()
@ -481,12 +477,11 @@ proc_outcome_t rrc::plmn_search_proc::init()
{ {
Info("Starting PLMN search\n"); Info("Starting PLMN search\n");
nof_plmns = 0; nof_plmns = 0;
cell_search_fut = rrc_ptr->cell_searcher.get_future(); if (not rrc_ptr->cell_searcher.launch(&cell_search_fut)) {
if (not rrc_ptr->cell_searcher.launch()) {
Error("Failed due to fail to init cell search...\n"); Error("Failed due to fail to init cell search...\n");
return proc_outcome_t::error; return proc_outcome_t::error;
} }
return proc_outcome_t::repeat; return step();
} }
/* NAS interface to search for available PLMNs. /* NAS interface to search for available PLMNs.
@ -529,14 +524,13 @@ proc_outcome_t rrc::plmn_search_proc::step()
return proc_outcome_t::success; return proc_outcome_t::success;
} }
cell_search_fut = rrc_ptr->cell_searcher.get_future(); if (not rrc_ptr->cell_searcher.launch(&cell_search_fut)) {
if (not rrc_ptr->cell_searcher.launch()) {
Error("Failed due to fail to init cell search...\n"); Error("Failed due to fail to init cell search...\n");
return proc_outcome_t::error; return proc_outcome_t::error;
} }
// run again // run again
return proc_outcome_t::repeat; return step();
} }
void rrc::plmn_search_proc::then(const srslte::proc_state_t& result) const void rrc::plmn_search_proc::then(const srslte::proc_state_t& result) const
@ -624,7 +618,7 @@ proc_outcome_t rrc::connection_request_proc::step()
Info("Waiting for RRCConnectionSetup/Reject or expiry\n"); Info("Waiting for RRCConnectionSetup/Reject or expiry\n");
rrc_ptr->dedicated_info_nas = std::move(dedicated_info_nas); rrc_ptr->dedicated_info_nas = std::move(dedicated_info_nas);
state = state_t::wait_t300; state = state_t::wait_t300;
return proc_outcome_t::repeat; return step();
} else if (state == state_t::wait_t300) { } else if (state == state_t::wait_t300) {
// Wait until t300 stops due to RRCConnectionSetup/Reject or expiry // Wait until t300 stops due to RRCConnectionSetup/Reject or expiry
@ -684,13 +678,12 @@ srslte::proc_outcome_t rrc::connection_request_proc::react(const cell_selection_
// timeAlignmentCommon applied in configure_serving_cell // timeAlignmentCommon applied in configure_serving_cell
Info("Configuring serving cell...\n"); Info("Configuring serving cell...\n");
serv_cfg_fut = rrc_ptr->serv_cell_cfg.get_future(); if (not rrc_ptr->serv_cell_cfg.launch(&serv_cfg_fut, rrc_ptr->ue_required_sibs)) {
if (not rrc_ptr->serv_cell_cfg.launch(rrc_ptr->ue_required_sibs)) {
Error("Attach request failed to configure serving cell...\n"); Error("Attach request failed to configure serving cell...\n");
return proc_outcome_t::error; return proc_outcome_t::error;
} }
state = state_t::config_serving_cell; state = state_t::config_serving_cell;
return proc_outcome_t::repeat; return step();
} else { } else {
switch (cs_ret) { switch (cs_ret) {
case cs_result_t::same_cell: case cs_result_t::same_cell:
@ -721,7 +714,7 @@ proc_outcome_t rrc::process_pcch_proc::init(const asn1::rrc::paging_s& paging_)
paging_idx = 0; paging_idx = 0;
state = state_t::next_record; state = state_t::next_record;
Info("starting...\n"); Info("starting...\n");
return proc_outcome_t::repeat; return step();
} }
proc_outcome_t rrc::process_pcch_proc::step() proc_outcome_t rrc::process_pcch_proc::step()
@ -743,7 +736,7 @@ proc_outcome_t rrc::process_pcch_proc::step()
return proc_outcome_t::error; return proc_outcome_t::error;
} }
state = state_t::nas_paging; state = state_t::nas_paging;
return proc_outcome_t::repeat; return step();
} else { } else {
Warning("Received paging while in CONNECT\n"); Warning("Received paging while in CONNECT\n");
} }
@ -757,8 +750,7 @@ proc_outcome_t rrc::process_pcch_proc::step()
rrc_ptr->serving_cell->reset_sibs(); rrc_ptr->serving_cell->reset_sibs();
// create a serving cell config procedure and push it to callback list // create a serving cell config procedure and push it to callback list
serv_cfg_fut = rrc_ptr->serv_cell_cfg.get_future(); if (not rrc_ptr->serv_cell_cfg.launch(&serv_cfg_fut, rrc_ptr->ue_required_sibs)) {
if (not rrc_ptr->serv_cell_cfg.launch(rrc_ptr->ue_required_sibs)) {
Error("Failed to initiate a serving cell configuration procedure\n"); Error("Failed to initiate a serving cell configuration procedure\n");
return proc_outcome_t::error; return proc_outcome_t::error;
} }
@ -767,7 +759,7 @@ proc_outcome_t rrc::process_pcch_proc::step()
return proc_outcome_t::success; return proc_outcome_t::success;
} }
state = state_t::serv_cell_cfg; state = state_t::serv_cell_cfg;
return proc_outcome_t::repeat; return step();
} else if (state == state_t::nas_paging) { } else if (state == state_t::nas_paging) {
// wait for trigger // wait for trigger
return proc_outcome_t::yield; return proc_outcome_t::yield;
@ -799,7 +791,7 @@ proc_outcome_t rrc::process_pcch_proc::react(paging_complete e)
paging_idx++; paging_idx++;
state = state_t::next_record; state = state_t::next_record;
Info("Received paging complete event\n"); Info("Received paging complete event\n");
return proc_outcome_t::repeat; return step();
} }
/************************************** /**************************************
@ -841,8 +833,7 @@ rrc::cell_reselection_proc::cell_reselection_proc(srsue::rrc* rrc_) : rrc_ptr(rr
proc_outcome_t rrc::cell_reselection_proc::init() proc_outcome_t rrc::cell_reselection_proc::init()
{ {
Info("Starting...\n"); Info("Starting...\n");
cell_selection_fut = rrc_ptr->cell_selector.get_future(); if (not rrc_ptr->cell_selector.launch(&cell_selection_fut)) {
if (not rrc_ptr->cell_selector.launch()) {
Error("Failed to initiate a Cell Selection procedure...\n"); Error("Failed to initiate a Cell Selection procedure...\n");
return proc_outcome_t::error; return proc_outcome_t::error;
} }

@ -213,7 +213,7 @@ proc_outcome_t nas::rrc_connect_proc::react(nas::rrc_connect_proc::connection_re
// Wait until attachment. If doing a service request is already attached // Wait until attachment. If doing a service request is already attached
state = state_t::wait_attach; state = state_t::wait_attach;
// wake up proc // wake up proc
return proc_outcome_t::repeat; return step();
} else { } else {
ProcError("Could not establish RRC connection\n"); ProcError("Could not establish RRC connection\n");
return proc_outcome_t::error; return proc_outcome_t::error;

Loading…
Cancel
Save