Add decoding of RRC setup.

master
Fabian Eckermann 3 years ago committed by Andre Puschmann
parent 93210d9bb3
commit 1407983c75

@ -136,12 +136,17 @@ public:
private: private:
// parsers // parsers
void decode_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu); void decode_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu);
void decode_dl_ccch(srsran::unique_byte_buffer_t pdu);
// senders // senders
void send_setup_request(srsran::nr_establishment_cause_t cause); void send_setup_request(srsran::nr_establishment_cause_t cause);
void send_con_setup_complete(srsran::unique_byte_buffer_t nas_msg);
void send_ul_info_transfer(srsran::unique_byte_buffer_t nas_msg); void send_ul_info_transfer(srsran::unique_byte_buffer_t nas_msg);
void send_ul_ccch_msg(const asn1::rrc_nr::ul_ccch_msg_s& msg); void send_ul_ccch_msg(const asn1::rrc_nr::ul_ccch_msg_s& msg);
void send_ul_dcch_msg(uint32_t lcid, const asn1::rrc_nr::ul_dcch_msg_s& msg);
// helpers // helpers
void handle_sib1(const asn1::rrc_nr::sib1_s sib1); void handle_sib1(const asn1::rrc_nr::sib1_s& sib1);
bool handle_rrc_setup(const asn1::rrc_nr::rrc_setup_s& setup);
srsran::task_sched_handle task_sched; srsran::task_sched_handle task_sched;
struct cmd_msg_t { struct cmd_msg_t {
@ -186,6 +191,8 @@ private:
const static char* rrc_nr_state_text[RRC_NR_STATE_N_ITEMS]; const static char* rrc_nr_state_text[RRC_NR_STATE_N_ITEMS];
rrc_nr_state_t state = RRC_NR_STATE_IDLE; rrc_nr_state_t state = RRC_NR_STATE_IDLE;
uint8_t transaction_id = 0;
// Stores the state of the PHY configuration setting // Stores the state of the PHY configuration setting
enum { enum {
PHY_CFG_STATE_NONE = 0, PHY_CFG_STATE_NONE = 0,
@ -234,10 +241,12 @@ private:
// RRC procedures // RRC procedures
enum class cell_search_result_t { changed_cell, same_cell, no_cell }; enum class cell_search_result_t { changed_cell, same_cell, no_cell };
class cell_selection_proc; class cell_selection_proc;
class connection_setup_proc;
class connection_reconf_no_ho_proc; class connection_reconf_no_ho_proc;
class setup_request_proc; class setup_request_proc;
srsran::proc_t<cell_selection_proc, cell_search_result_t> cell_selector; srsran::proc_t<cell_selection_proc, cell_search_result_t> cell_selector;
srsran::proc_t<connection_setup_proc> conn_setup_proc;
srsran::proc_t<connection_reconf_no_ho_proc> conn_recfg_proc; srsran::proc_t<connection_reconf_no_ho_proc> conn_recfg_proc;
srsran::proc_t<setup_request_proc> setup_req_proc; srsran::proc_t<setup_request_proc> setup_req_proc;

@ -77,6 +77,26 @@ private:
srsran::proc_future_t<void> serv_cfg_fut; srsran::proc_future_t<void> serv_cfg_fut;
}; };
class rrc_nr::connection_setup_proc
{
public:
explicit connection_setup_proc(rrc_nr& parent_);
srsran::proc_outcome_t init(const asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg_,
const asn1::rrc_nr::cell_group_cfg_s cell_group_,
srsran::unique_byte_buffer_t dedicated_info_nas_);
srsran::proc_outcome_t step() { return srsran::proc_outcome_t::yield; }
static const char* name() { return "Connection Setup"; }
srsran::proc_outcome_t react(const bool& config_complete);
void then(const srsran::proc_state_t& result);
private:
// const
rrc_nr& rrc_handle;
srslog::basic_logger& logger;
// args
srsran::unique_byte_buffer_t dedicated_info_nas;
};
class rrc_nr::connection_reconf_no_ho_proc class rrc_nr::connection_reconf_no_ho_proc
{ {
public: public:

@ -31,6 +31,7 @@ rrc_nr::rrc_nr(srsran::task_sched_handle task_sched_) :
logger(srslog::fetch_basic_logger("RRC-NR")), logger(srslog::fetch_basic_logger("RRC-NR")),
task_sched(task_sched_), task_sched(task_sched_),
conn_recfg_proc(*this), conn_recfg_proc(*this),
conn_setup_proc(*this),
setup_req_proc(*this), setup_req_proc(*this),
cell_selector(*this), cell_selector(*this),
meas_cells(task_sched_) meas_cells(task_sched_)
@ -209,7 +210,66 @@ void rrc_nr::run_tti(uint32_t tti) {}
void rrc_nr::write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) void rrc_nr::write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu)
{ {
printf("RRC received PDU\n"); printf("RRC received PDU\n");
logger.debug("RX PDU, LCID: %d", lcid);
switch (static_cast<nr_srb>(lcid)) {
case nr_srb::srb0:
decode_dl_ccch(std::move(pdu));
break;
// case nr_srb::srb1:
// case nr_srb::srb2:
// decode_dl_dcch(lcid, std::move(pdu));
// break;
default:
logger.error("RX PDU with invalid bearer id: %d", lcid);
break;
}
}
void rrc_nr::decode_dl_ccch(unique_byte_buffer_t pdu)
{
asn1::cbit_ref bref(pdu->msg, pdu->N_bytes);
asn1::rrc_nr::dl_ccch_msg_s dl_ccch_msg;
if (dl_ccch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or
dl_ccch_msg.msg.type().value != dl_ccch_msg_type_c::types_opts::c1) {
logger.error(pdu->msg, pdu->N_bytes, "Failed to unpack DL-CCCH message (%d B)", pdu->N_bytes);
return;
}
log_rrc_message(
get_rb_name(srb_to_lcid(nr_srb::srb0)), Rx, pdu.get(), dl_ccch_msg, dl_ccch_msg.msg.c1().type().to_string());
dl_ccch_msg_type_c::c1_c_* c1 = &dl_ccch_msg.msg.c1();
switch (dl_ccch_msg.msg.c1().type().value) {
// case dl_ccch_msg_type_c::c1_c_::types::rrc_reject: {
// // 5.3.3.8
// rrc_conn_reject_r8_ies_s* reject_r8 = &c1->rrc_reject().crit_exts.c1().rrc_conn_reject_r8();
// logger.info("Received ConnectionReject. Wait time: %d", reject_r8->wait_time);
// srsran::console("Received ConnectionReject. Wait time: %d\n", reject_r8->wait_time);
// t300.stop();
// if (reject_r8->wait_time) {
// nas->set_barring(srsran::barring_t::all);
// t302.set(reject_r8->wait_time * 1000, [this](uint32_t tid) { timer_expired(tid); });
// t302.run();
// } else {
// // Perform the actions upon expiry of T302 if wait time is zero
// nas->set_barring(srsran::barring_t::none);
// start_go_idle();
// }
// } break;
case dl_ccch_msg_type_c::c1_c_::types::rrc_setup: {
transaction_id = c1->rrc_setup().rrc_transaction_id;
rrc_setup_s rrc_setup_copy = c1->rrc_setup();
task_sched.defer_task([this, rrc_setup_copy]() { handle_rrc_setup(rrc_setup_copy); });
break;
}
default:
logger.error("The provided DL-CCCH message type is not recognized");
break;
}
} }
void rrc_nr::write_pdu_bcch_bch(srsran::unique_byte_buffer_t pdu) {} void rrc_nr::write_pdu_bcch_bch(srsran::unique_byte_buffer_t pdu) {}
void rrc_nr::write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu) void rrc_nr::write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu)
{ {
@ -501,6 +561,51 @@ void rrc_nr::send_ul_ccch_msg(const asn1::rrc_nr::ul_ccch_msg_s& msg)
rlc->write_sdu(lcid, std::move(pdu)); rlc->write_sdu(lcid, std::move(pdu));
} }
void rrc_nr::send_ul_dcch_msg(uint32_t lcid, const ul_dcch_msg_s& msg)
{
// Reset and reuse sdu buffer if provided
unique_byte_buffer_t pdu = srsran::make_byte_buffer();
if (pdu == nullptr) {
logger.error("Couldn't allocate PDU in %s().", __FUNCTION__);
return;
}
asn1::bit_ref bref(pdu->msg, pdu->get_tailroom());
msg.pack(bref);
bref.align_bytes_zero();
pdu->N_bytes = (uint32_t)bref.distance_bytes(pdu->msg);
pdu->set_timestamp();
if (msg.msg.type() == ul_dcch_msg_type_c::types_opts::options::c1) {
log_rrc_message(get_rb_name(lcid), Tx, pdu.get(), msg, msg.msg.c1().type().to_string());
}
pdcp->write_sdu(lcid, std::move(pdu));
}
void rrc_nr::send_con_setup_complete(srsran::unique_byte_buffer_t nas_msg)
{
logger.debug("Preparing RRC Connection Setup Complete");
// Prepare ConnectionSetupComplete packet
asn1::rrc_nr::ul_dcch_msg_s ul_dcch_msg;
rrc_setup_complete_ies_s* rrc_setup_complete =
&ul_dcch_msg.msg.set_c1().set_rrc_setup_complete().crit_exts.set_rrc_setup_complete();
ul_dcch_msg.msg.c1().rrc_setup_complete().rrc_transaction_id = transaction_id;
rrc_setup_complete->sel_plmn_id = 1;
rrc_setup_complete->registered_amf_present = false;
rrc_setup_complete->guami_type_present = false;
rrc_setup_complete->s_nssai_list_present = false;
rrc_setup_complete->ng_minus5_g_s_tmsi_value_present = false;
rrc_setup_complete->ded_nas_msg.resize(nas_msg->N_bytes);
memcpy(rrc_setup_complete->ded_nas_msg.data(), nas_msg->msg, nas_msg->N_bytes);
send_ul_dcch_msg(srb_to_lcid(nr_srb::srb1), ul_dcch_msg);
}
// EUTRA-RRC interface // EUTRA-RRC interface
int rrc_nr::get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps_pdu) int rrc_nr::get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps_pdu)
{ {
@ -1504,7 +1609,6 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg)
} }
} else { } else {
logger.warning("Reconfig with with sync not present"); logger.warning("Reconfig with with sync not present");
return false;
} }
// Dedicated config // Dedicated config
@ -1597,7 +1701,6 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg)
} }
} else { } else {
logger.warning("Option pdsch_serving_cell_cfg not present"); logger.warning("Option pdsch_serving_cell_cfg not present");
return false;
} }
if (sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg_present) { if (sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg_present) {
@ -1611,7 +1714,6 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg)
} }
} else { } else {
logger.warning("Option csi_meas_cfg in spCellConfigDedicated not present"); logger.warning("Option csi_meas_cfg in spCellConfigDedicated not present");
return false;
} }
} else { } else {
@ -1804,6 +1906,37 @@ bool rrc_nr::apply_radio_bearer_cfg(const radio_bearer_cfg_s& radio_bearer_cfg)
return true; return true;
} }
bool rrc_nr::handle_rrc_setup(const rrc_setup_s& setup)
{
// Unpack masterCellGroup into container
asn1::cbit_ref bref_cg(setup.crit_exts.rrc_setup().master_cell_group.data(),
setup.crit_exts.rrc_setup().master_cell_group.size());
asn1::rrc_nr::cell_group_cfg_s cell_group;
if (cell_group.unpack(bref_cg) != asn1::SRSASN_SUCCESS) {
logger.error("Could not unpack master cell group config.");
return false;
}
asn1::json_writer js;
cell_group.to_json(js);
logger.debug("Containerized MasterCellGroup: %s", js.to_string().c_str());
// Must enter CONNECT before stopping T300
state = RRC_NR_STATE_CONNECTED;
// t300.stop();
// t302.stop();
srsran::console("RRC Connected\n");
// defer transmission of Setup Complete until PHY reconfiguration has been completed
if (not conn_setup_proc.launch(
setup.crit_exts.rrc_setup().radio_bearer_cfg, cell_group, std::move(dedicated_info_nas))) {
logger.error("Failed to initiate connection setup procedure");
return false;
}
callback_list.add_proc(conn_setup_proc);
return true;
}
// RLC interface // RLC interface
void rrc_nr::max_retx_attempted() {} void rrc_nr::max_retx_attempted() {}
void rrc_nr::protocol_failure() {} void rrc_nr::protocol_failure() {}

@ -283,6 +283,60 @@ srsran::proc_outcome_t rrc_nr::setup_request_proc::react(const cell_selection_pr
} }
} }
/******************************************
* Connection Setup Procedure
*****************************************/
// Simple procedure mainly do defer the transmission of the SetupComplete until all PHY reconfiguration are done
rrc_nr::connection_setup_proc::connection_setup_proc(srsue::rrc_nr& parent_) :
rrc_handle(parent_), logger(srslog::fetch_basic_logger("RRC"))
{}
srsran::proc_outcome_t rrc_nr::connection_setup_proc::init(const asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg_,
const asn1::rrc_nr::cell_group_cfg_s cell_group_,
srsran::unique_byte_buffer_t dedicated_info_nas_)
{
Info("Starting...");
// if (dedicated_info_nas_.get() == nullptr) {
// logger.error("Connection Setup Failed, no dedicatedInfoNAS available");
// return proc_outcome_t::error;
// }
dedicated_info_nas = std::move(dedicated_info_nas_);
// Apply the Radio Bearer configuration
if (!rrc_handle.apply_radio_bearer_cfg(radio_bearer_cfg_)) {
return proc_outcome_t::error;
}
// Apply the Cell Group configuration
if (!rrc_handle.apply_cell_group_cfg(cell_group_)) {
return proc_outcome_t::error;
}
return proc_outcome_t::yield;
}
srsran::proc_outcome_t rrc_nr::connection_setup_proc::react(const bool& config_complete)
{
if (not config_complete) {
logger.error("Connection Setup Failed");
return proc_outcome_t::error;
}
rrc_handle.send_con_setup_complete(std::move(dedicated_info_nas));
return proc_outcome_t::success;
}
void rrc_nr::connection_setup_proc::then(const srsran::proc_state_t& result)
{
if (result.is_success()) {
logger.info("Finished %s successfully", name());
return;
}
}
/************************************** /**************************************
* Basic Cell Selection Procedure * Basic Cell Selection Procedure
*************************************/ *************************************/

@ -303,6 +303,57 @@ int rrc_write_pdu_bcch_dlsch_test()
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }
int rrc_write_pdu_test()
{
srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR");
logger.set_level(srslog::basic_levels::debug);
logger.set_hex_dump_max_size(-1);
srsran::task_scheduler task_sched{512, 100};
srsran::task_sched_handle task_sched_handle(&task_sched);
rrc_nr rrc_nr(task_sched_handle);
dummy_phy dummy_phy;
dummy_mac dummy_mac;
dummy_rlc dummy_rlc;
dummy_pdcp dummy_pdcp;
dummy_gw dummy_gw;
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
rrc_nr_args_t rrc_nr_args;
TESTASSERT(rrc_nr.init(&dummy_phy,
&dummy_mac,
&dummy_rlc,
&dummy_pdcp,
&dummy_gw,
&dummy_eutra,
&dummy_sim,
task_sched.get_timer_handler(),
&dummy_stack,
rrc_nr_args) == SRSRAN_SUCCESS);
uint8_t msg[] = {0x20, 0x40, 0x04, 0x05, 0x9a, 0xe0, 0x05, 0x80, 0x08, 0x8b, 0xd7, 0x63, 0x80, 0x83, 0x0f, 0x00, 0x03,
0xa0, 0x10, 0x45, 0x41, 0xc2, 0x0a, 0x20, 0x92, 0x40, 0x0c, 0xa8, 0x00, 0x17, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x08, 0x37, 0x08, 0x82, 0x00, 0x04, 0x91, 0x12, 0x50, 0x00, 0x04, 0x82, 0x00, 0x00, 0x20, 0x69,
0x84, 0x0c, 0x55, 0x92, 0x10, 0x70, 0x00, 0x41, 0x03, 0x08, 0x14, 0x30, 0x72, 0x71, 0x02, 0x45, 0x0b,
0x18, 0x34, 0x70, 0xf2, 0x38, 0x01, 0x98, 0x00, 0x85, 0x00, 0xc0, 0x8c, 0xc0, 0x05, 0x28, 0x06, 0x08,
0x66, 0x00, 0x31, 0x40, 0x30, 0x63, 0x30, 0x01, 0x0a, 0x03, 0x84, 0x19, 0x80, 0x0a, 0x50, 0x1c, 0x28,
0xcc, 0x00, 0x62, 0x80, 0xe1, 0x86, 0x60, 0x02, 0x14, 0x0b, 0x0e, 0x33, 0x00, 0x14, 0xa0, 0x58, 0x80,
0x08, 0xc9, 0x04, 0x31, 0x20, 0x11, 0x92, 0x09, 0x62, 0x80, 0x23, 0x24, 0x14, 0xc5, 0x80, 0x46, 0x48,
0x2d, 0x8c, 0x00, 0x8c, 0x90, 0x63, 0x1a, 0x01, 0x19, 0x20, 0xd6, 0x38, 0x02, 0x32, 0x41, 0xcc, 0x78,
0xc8, 0x02, 0x82, 0x19, 0x01, 0x98, 0x00, 0xc5, 0x02, 0xc8, 0x8c, 0x80, 0x28, 0x25, 0x02, 0x42, 0x18,
0x14, 0x40, 0x20, 0x91, 0x00, 0x0a, 0x41, 0x7f, 0xf4, 0xa5, 0x26, 0x31, 0x8d, 0x80};
srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer();
memcpy(pdu->msg, msg, sizeof(msg));
pdu->N_bytes = sizeof(msg);
rrc_nr.write_pdu(0, std::move(pdu));
task_sched.run_pending_tasks();
return SRSRAN_SUCCESS;
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
srslog::init(); srslog::init();
@ -311,6 +362,7 @@ int main(int argc, char** argv)
TESTASSERT(rrc_nr_reconfig_test() == SRSRAN_SUCCESS); TESTASSERT(rrc_nr_reconfig_test() == SRSRAN_SUCCESS);
TESTASSERT(rrc_nr_conn_setup_test() == SRSRAN_SUCCESS); TESTASSERT(rrc_nr_conn_setup_test() == SRSRAN_SUCCESS);
TESTASSERT(rrc_write_pdu_bcch_dlsch_test() == SRSRAN_SUCCESS); TESTASSERT(rrc_write_pdu_bcch_dlsch_test() == SRSRAN_SUCCESS);
TESTASSERT(rrc_write_pdu_test() == SRSRAN_SUCCESS);
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }

Loading…
Cancel
Save